mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 11:52:19 +00:00
Merge branch 'main' into 5830
This commit is contained in:
commit
738098bfd0
182 changed files with 6685 additions and 1140 deletions
6
.github/workflows/benchmarks.yml
vendored
6
.github/workflows/benchmarks.yml
vendored
|
@ -1,12 +1,8 @@
|
|||
on:
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
name: Benchmarks
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
ROC_NUM_WORKERS: 1
|
||||
|
|
1
.github/workflows/ci_cleanup.yml
vendored
1
.github/workflows/ci_cleanup.yml
vendored
|
@ -1,4 +1,5 @@
|
|||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 5 * * 1'
|
||||
|
||||
|
|
17
.github/workflows/ci_cleanup_nix_mac.yml
vendored
Normal file
17
.github/workflows/ci_cleanup_nix_mac.yml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 5 * * *'
|
||||
|
||||
name: Clean up nix on mac mini m1
|
||||
|
||||
jobs:
|
||||
clean-mac-mini-arm64:
|
||||
runs-on: [self-hosted, macOS, ARM64]
|
||||
timeout-minutes: 120
|
||||
steps:
|
||||
- name: Clean up nix store
|
||||
run: nix-store --gc
|
||||
|
||||
- name: Clean up old nix shells
|
||||
run: rm -rf /private/tmp/nix-shell.*
|
99
.github/workflows/ci_manager.yml
vendored
Normal file
99
.github/workflows/ci_manager.yml
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
on:
|
||||
pull_request:
|
||||
|
||||
name: CI manager
|
||||
|
||||
# cancel current runs when a new commit is pushed
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check-changes:
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
run_tests: ${{ steps.filecheck.outputs.run_tests }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Check if only css, html or md files changed
|
||||
id: filecheck
|
||||
run: |
|
||||
git fetch origin ${{ github.base_ref }}
|
||||
if git diff --name-only origin/${{ github.base_ref }} HEAD | grep -qvE '(\.md$|\.css$|\.html$)'; then
|
||||
echo "run_tests=full" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "run_tests=none" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- run: echo "debug output ${{ steps.filecheck.outputs.run_tests }}"
|
||||
|
||||
start-nix-linux-x86-64-tests:
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.run_tests == 'full'
|
||||
uses: ./.github/workflows/nix_linux_x86_64.yml
|
||||
|
||||
start-nix-linux-aarch64-build-default-test:
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.run_tests == 'full'
|
||||
uses: ./.github/workflows/nix_linux_arm64_default.yml
|
||||
|
||||
start-nix-linux-aarch64-cargo-build-test:
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.run_tests == 'full'
|
||||
uses: ./.github/workflows/nix_linux_arm64_cargo.yml
|
||||
|
||||
start-nix-macos-apple-silicon-tests:
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.run_tests == 'full'
|
||||
uses: ./.github/workflows/nix_macos_apple_silicon.yml
|
||||
|
||||
start-macos-x86-64-tests:
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.run_tests == 'full'
|
||||
uses: ./.github/workflows/ubuntu_x86_64.yml
|
||||
|
||||
start-ubuntu-x86-64-tests:
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.run_tests == 'full'
|
||||
uses: ./.github/workflows/ubuntu_x86_64.yml
|
||||
|
||||
start-windows-release-build-test:
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.run_tests == 'full'
|
||||
uses: ./.github/workflows/windows_release_build.yml
|
||||
|
||||
start-windows-tests:
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.run_tests == 'full'
|
||||
uses: ./.github/workflows/windows_tests.yml
|
||||
|
||||
start-roc-benchmarks:
|
||||
needs: check-changes
|
||||
if: needs.check-changes.outputs.run_tests == 'full'
|
||||
uses: ./.github/workflows/benchmarks.yml
|
||||
|
||||
finish-full:
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [
|
||||
start-nix-linux-x86-64-tests,
|
||||
start-nix-linux-aarch64-build-default-test,
|
||||
start-nix-linux-aarch64-cargo-build-test,
|
||||
start-nix-macos-apple-silicon-tests,
|
||||
start-macos-x86-64-tests,
|
||||
start-ubuntu-x86-64-tests,
|
||||
start-windows-release-build-test,
|
||||
start-windows-tests,
|
||||
start-roc-benchmarks
|
||||
]
|
||||
steps:
|
||||
- run: echo "all workflows succeeded!"
|
||||
|
||||
finish-none:
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [check-changes]
|
||||
if: needs.check-changes.outputs.run_tests == 'none'
|
||||
steps:
|
||||
- run: echo "Only non-code files changed. CI manager did not run any workflows."
|
||||
|
6
.github/workflows/macos_x86_64.yml
vendored
6
.github/workflows/macos_x86_64.yml
vendored
|
@ -1,12 +1,8 @@
|
|||
on:
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
name: Macos x86-64 rust tests
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
|
|
6
.github/workflows/nix_linux_arm64_cargo.yml
vendored
6
.github/workflows/nix_linux_arm64_cargo.yml
vendored
|
@ -1,12 +1,8 @@
|
|||
on:
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
name: test cargo build on linux arm64 inside nix
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
on:
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
name: test default.nix on linux arm64
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
|
|
6
.github/workflows/nix_linux_x86_64.yml
vendored
6
.github/workflows/nix_linux_x86_64.yml
vendored
|
@ -1,12 +1,8 @@
|
|||
on:
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
name: Nix linux x86_64 cargo test
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
on:
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
name: Nix apple silicon cargo test
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
|
|
6
.github/workflows/nix_macos_x86_64.yml
vendored
6
.github/workflows/nix_macos_x86_64.yml
vendored
|
@ -1,12 +1,8 @@
|
|||
on:
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
name: Nix macOS x86_64 cargo test
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
|
|
6
.github/workflows/ubuntu_x86_64.yml
vendored
6
.github/workflows/ubuntu_x86_64.yml
vendored
|
@ -1,12 +1,8 @@
|
|||
on:
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
name: CI
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
|
|
6
.github/workflows/windows_release_build.yml
vendored
6
.github/workflows/windows_release_build.yml
vendored
|
@ -1,12 +1,8 @@
|
|||
on:
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
name: windows - release build
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
|
|
6
.github/workflows/windows_tests.yml
vendored
6
.github/workflows/windows_tests.yml
vendored
|
@ -1,12 +1,8 @@
|
|||
on:
|
||||
pull_request:
|
||||
workflow_call:
|
||||
|
||||
name: windows - subset of tests
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ install-zig-llvm:
|
|||
RUN apt -y install libssl-dev
|
||||
RUN OPENSSL_NO_VENDOR=1 cargo install wasm-pack
|
||||
# sccache
|
||||
RUN cargo install sccache
|
||||
RUN cargo install sccache --locked
|
||||
RUN sccache -V
|
||||
ENV RUSTC_WRAPPER=/usr/local/cargo/bin/sccache
|
||||
ENV SCCACHE_DIR=/earthbuild/sccache_dir
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Work in progress!
|
||||
|
||||
Roc is not ready for a 0.1 release yet, but we do have:
|
||||
[Roc](https://www.roc-lang.org) is not ready for a 0.1 release yet, but we do have:
|
||||
|
||||
- [**installation** guide](https://github.com/roc-lang/roc/tree/main/getting_started)
|
||||
- [**tutorial**](https://roc-lang.org/tutorial)
|
||||
|
@ -30,6 +30,9 @@ If you would like your company to become a corporate sponsor of Roc's developmen
|
|||
|
||||
We'd also like to express our gratitude to our generous [individual sponsors](https://github.com/sponsors/roc-lang/)! A special thanks to those sponsoring $25/month or more:
|
||||
|
||||
* [Drew Lazzeri](https://github.com/asteroidb612)
|
||||
* [Alex Binaei](https://github.com/mrmizz)
|
||||
* [Jono Mallanyk](https://github.com/jonomallanyk)
|
||||
* [Chris Packett](https://github.com/chris-packett)
|
||||
* [James Birtles](https://github.com/jamesbirtles)
|
||||
* [Ivo Balbaert](https://github.com/Ivo-Balbaert)
|
||||
|
|
|
@ -1136,19 +1136,6 @@ fn roc_dev_native(
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
memory.reset();
|
||||
}
|
||||
ChildProcessMsg::Dbg => {
|
||||
roc_repl_expect::run::render_dbgs_in_memory(
|
||||
&mut writer,
|
||||
arena,
|
||||
&mut expectations,
|
||||
&interns,
|
||||
&layout_interner,
|
||||
&memory,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
memory.reset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -333,7 +333,10 @@ fn main() -> io::Result<()> {
|
|||
}
|
||||
}
|
||||
FormatMode::WriteToStdout => {
|
||||
std::io::stdout().lock().write_all(src.as_bytes()).unwrap();
|
||||
std::io::stdout()
|
||||
.lock()
|
||||
.write_all(formatted_src.as_bytes())
|
||||
.unwrap();
|
||||
|
||||
0
|
||||
}
|
||||
|
|
|
@ -562,11 +562,11 @@ mod cli_run {
|
|||
x : Num *
|
||||
x = 42
|
||||
|
||||
[<ignored for tests> 19:9] 42
|
||||
[<ignored for tests> 20:9] "Fjoer en ferdjer frieten oan dyn geve lea"
|
||||
[<ignored for tests> 13:9] "abc"
|
||||
[<ignored for tests> 13:9] 10
|
||||
[<ignored for tests> 13:9] A (B C)
|
||||
[#UserApp] 42
|
||||
[#UserApp] "Fjoer en ferdjer frieten oan dyn geve lea"
|
||||
[#UserApp] "abc"
|
||||
[#UserApp] 10
|
||||
[#UserApp] (A (B C))
|
||||
Program finished!
|
||||
"#
|
||||
),
|
||||
|
@ -873,7 +873,7 @@ mod cli_run {
|
|||
This roc file can print it's own source code. The source is:
|
||||
|
||||
app "ingested-file"
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.6.0/QOQW08n38nHHrVVkJNiPIjzjvbR3iMjXeFY5w1aT46w.tar.br" }
|
||||
packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.7.0/bkGby8jb0tmZYsy2hg1E_B2QrCgcSTxdUlHtETwm5m4.tar.br" }
|
||||
imports [
|
||||
pf.Stdout,
|
||||
"ingested-file.roc" as ownCode : Str,
|
||||
|
@ -900,7 +900,7 @@ mod cli_run {
|
|||
&[],
|
||||
&[],
|
||||
&[],
|
||||
"30256\n",
|
||||
"30461\n",
|
||||
UseValgrind::No,
|
||||
TestCliCommands::Run,
|
||||
)
|
||||
|
@ -942,7 +942,7 @@ mod cli_run {
|
|||
test_roc_app_slim(
|
||||
"examples",
|
||||
"inspect-logging.roc",
|
||||
r#"{people: [{firstName: "John", lastName: "Smith", age: 27, hasBeard: true, favoriteColor: Blue}, {firstName: "Debby", lastName: "Johnson", age: 47, hasBeard: false, favoriteColor: Green}, {firstName: "Jane", lastName: "Doe", age: 33, hasBeard: false, favoriteColor: (RGB (255, 255, 0))}], friends: [{2}, {2}, {0, 1}]}
|
||||
r#"{friends: [{2}, {2}, {0, 1}], people: [{age: 27, favoriteColor: Blue, firstName: "John", hasBeard: Bool.true, lastName: "Smith"}, {age: 47, favoriteColor: Green, firstName: "Debby", hasBeard: Bool.false, lastName: "Johnson"}, {age: 33, favoriteColor: (RGB (255, 255, 0)), firstName: "Jane", hasBeard: Bool.false, lastName: "Doe"}]}
|
||||
"#,
|
||||
UseValgrind::Yes,
|
||||
)
|
||||
|
|
|
@ -38,13 +38,23 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
|
|||
return memset(dst, value, size);
|
||||
}
|
||||
|
||||
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||
_ = tag_id;
|
||||
|
||||
export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
const msg = @as([*:0]const u8, @ptrCast(c_ptr));
|
||||
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
||||
std.process.exit(0);
|
||||
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) callconv(.C) void {
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
stderr.print("[{s}] {s}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
|
||||
}
|
||||
|
||||
extern fn kill(pid: c_int, sig: c_int) c_int;
|
||||
|
|
|
@ -38,13 +38,23 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
|
|||
return memset(dst, value, size);
|
||||
}
|
||||
|
||||
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||
_ = tag_id;
|
||||
|
||||
export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
const msg = @as([*:0]const u8, @ptrCast(c_ptr));
|
||||
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
||||
std.process.exit(0);
|
||||
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) callconv(.C) void {
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
stderr.print("[{s}] {s}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
|
||||
}
|
||||
|
||||
extern fn kill(pid: c_int, sig: c_int) c_int;
|
||||
|
|
|
@ -38,13 +38,23 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
|
|||
return memset(dst, value, size);
|
||||
}
|
||||
|
||||
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||
_ = tag_id;
|
||||
|
||||
export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
const msg = @as([*:0]const u8, @ptrCast(c_ptr));
|
||||
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
||||
std.process.exit(0);
|
||||
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) callconv(.C) void {
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
stderr.print("[{s}] {s}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
|
||||
}
|
||||
|
||||
extern fn kill(pid: c_int, sig: c_int) c_int;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
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;
|
||||
|
@ -50,13 +52,23 @@ export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
|||
free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))));
|
||||
}
|
||||
|
||||
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||
_ = tag_id;
|
||||
|
||||
export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
const msg = @as([*:0]const u8, @ptrCast(c_ptr));
|
||||
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
||||
std.process.exit(0);
|
||||
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) callconv(.C) void {
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
stderr.print("[{s}] {s}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
|
||||
}
|
||||
|
||||
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
|
||||
|
|
|
@ -49,13 +49,23 @@ export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
|||
free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))));
|
||||
}
|
||||
|
||||
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||
_ = tag_id;
|
||||
|
||||
export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
const msg = @as([*:0]const u8, @ptrCast(c_ptr));
|
||||
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
||||
std.process.exit(0);
|
||||
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) callconv(.C) void {
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
stderr.print("[{s}] {s}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
|
||||
}
|
||||
|
||||
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
|
||||
|
|
|
@ -54,13 +54,23 @@ export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
|||
free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))));
|
||||
}
|
||||
|
||||
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||
_ = tag_id;
|
||||
|
||||
export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
const msg = @as([*:0]const u8, @ptrCast(c_ptr));
|
||||
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
||||
std.process.exit(0);
|
||||
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) callconv(.C) void {
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
stderr.print("[{s}] {s}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
|
||||
}
|
||||
|
||||
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
|
||||
|
|
|
@ -44,13 +44,18 @@ export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
|
|||
free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))));
|
||||
}
|
||||
|
||||
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void {
|
||||
export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
|
||||
_ = tag_id;
|
||||
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
const msg = @as([*:0]const u8, @ptrCast(c_ptr));
|
||||
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
|
||||
std.process.exit(0);
|
||||
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) 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}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
|
||||
}
|
||||
|
||||
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
|
||||
|
|
|
@ -11,10 +11,14 @@ fn roc_alloc(_: usize, _: u32) callconv(.C) ?*anyopaque {
|
|||
fn roc_panic(_: *anyopaque, _: u32) callconv(.C) void {
|
||||
@panic("Not needed for dec benchmark");
|
||||
}
|
||||
fn roc_dbg(_: *anyopaque, _: *anyopaque) callconv(.C) void {
|
||||
@panic("Not needed for dec benchmark");
|
||||
}
|
||||
|
||||
comptime {
|
||||
@export(roc_alloc, .{ .name = "roc_alloc", .linkage = .Strong });
|
||||
@export(roc_panic, .{ .name = "roc_panic", .linkage = .Strong });
|
||||
@export(roc_dbg, .{ .name = "roc_dbg", .linkage = .Strong });
|
||||
}
|
||||
|
||||
var timer: Timer = undefined;
|
||||
|
@ -100,16 +104,16 @@ pub fn main() !void {
|
|||
const f64Atan = try avg_runs(f64, n, atanF64, f1);
|
||||
|
||||
try stdout.print("\n\nDec/F64:\n", .{});
|
||||
try stdout.print("addition: {d:0.2}\n", .{@intToFloat(f64, decAdd) / @intToFloat(f64, f64Add)});
|
||||
try stdout.print("subtraction: {d:0.2}\n", .{@intToFloat(f64, decSub) / @intToFloat(f64, f64Sub)});
|
||||
try stdout.print("multiplication: {d:0.2}\n", .{@intToFloat(f64, decMul) / @intToFloat(f64, f64Mul)});
|
||||
try stdout.print("division: {d:0.2}\n", .{@intToFloat(f64, decDiv) / @intToFloat(f64, f64Div)});
|
||||
try stdout.print("sin: {d:0.2}\n", .{@intToFloat(f64, decSin) / @intToFloat(f64, f64Sin)});
|
||||
try stdout.print("cos: {d:0.2}\n", .{@intToFloat(f64, decCos) / @intToFloat(f64, f64Cos)});
|
||||
try stdout.print("tan: {d:0.2}\n", .{@intToFloat(f64, decTan) / @intToFloat(f64, f64Tan)});
|
||||
try stdout.print("asin: {d:0.2}\n", .{@intToFloat(f64, decAsin) / @intToFloat(f64, f64Asin)});
|
||||
try stdout.print("acos: {d:0.2}\n", .{@intToFloat(f64, decAcos) / @intToFloat(f64, f64Acos)});
|
||||
try stdout.print("atan: {d:0.2}\n", .{@intToFloat(f64, decAtan) / @intToFloat(f64, f64Atan)});
|
||||
try stdout.print("addition: {d:0.2}\n", .{@as(f64, @floatFromInt(decAdd)) / @as(f64, @floatFromInt(f64Add))});
|
||||
try stdout.print("subtraction: {d:0.2}\n", .{@as(f64, @floatFromInt(decSub)) / @as(f64, @floatFromInt(f64Sub))});
|
||||
try stdout.print("multiplication: {d:0.2}\n", .{@as(f64, @floatFromInt(decMul)) / @as(f64, @floatFromInt(f64Mul))});
|
||||
try stdout.print("division: {d:0.2}\n", .{@as(f64, @floatFromInt(decDiv)) / @as(f64, @floatFromInt(f64Div))});
|
||||
try stdout.print("sin: {d:0.2}\n", .{@as(f64, @floatFromInt(decSin)) / @as(f64, @floatFromInt(f64Sin))});
|
||||
try stdout.print("cos: {d:0.2}\n", .{@as(f64, @floatFromInt(decCos)) / @as(f64, @floatFromInt(f64Cos))});
|
||||
try stdout.print("tan: {d:0.2}\n", .{@as(f64, @floatFromInt(decTan)) / @as(f64, @floatFromInt(f64Tan))});
|
||||
try stdout.print("asin: {d:0.2}\n", .{@as(f64, @floatFromInt(decAsin)) / @as(f64, @floatFromInt(f64Asin))});
|
||||
try stdout.print("acos: {d:0.2}\n", .{@as(f64, @floatFromInt(decAcos)) / @as(f64, @floatFromInt(f64Acos))});
|
||||
try stdout.print("atan: {d:0.2}\n", .{@as(f64, @floatFromInt(decAtan)) / @as(f64, @floatFromInt(f64Atan))});
|
||||
}
|
||||
|
||||
fn avg_runs(comptime T: type, comptime n: usize, comptime op: fn (T, T) T, v: T) !u64 {
|
||||
|
|
|
@ -96,7 +96,3 @@ pub fn notifyParent(shared_buffer: [*]u8, tag: u32) callconv(.C) void {
|
|||
pub fn notifyParentExpect(shared_buffer: [*]u8) callconv(.C) void {
|
||||
notifyParent(shared_buffer, 1);
|
||||
}
|
||||
|
||||
pub fn notifyParentDbg(shared_buffer: [*]u8) callconv(.C) void {
|
||||
notifyParent(shared_buffer, 2);
|
||||
}
|
||||
|
|
|
@ -231,6 +231,7 @@ comptime {
|
|||
|
||||
// Utils
|
||||
comptime {
|
||||
exportUtilsFn(utils.test_dbg, "test_dbg");
|
||||
exportUtilsFn(utils.test_panic, "test_panic");
|
||||
exportUtilsFn(utils.increfRcPtrC, "incref_rc_ptr");
|
||||
exportUtilsFn(utils.decrefRcPtrC, "decref_rc_ptr");
|
||||
|
@ -249,7 +250,6 @@ comptime {
|
|||
exportUtilsFn(expect.expectFailedStartSharedBuffer, "expect_failed_start_shared_buffer");
|
||||
exportUtilsFn(expect.expectFailedStartSharedFile, "expect_failed_start_shared_file");
|
||||
exportUtilsFn(expect.notifyParentExpect, "notify_parent_expect");
|
||||
exportUtilsFn(expect.notifyParentDbg, "notify_parent_dbg");
|
||||
|
||||
// sets the buffer used for expect failures
|
||||
@export(expect.setSharedBuffer, .{ .name = "set_shared_buffer", .linkage = .Weak });
|
||||
|
|
|
@ -20,6 +20,13 @@ extern fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, align
|
|||
// This should never be passed a null pointer.
|
||||
extern fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void;
|
||||
|
||||
extern fn roc_dbg(file_path: *anyopaque, message: *anyopaque) callconv(.C) void;
|
||||
|
||||
// Since roc_dbg is never used by the builtins, we need at export a function that uses it to stop DCE.
|
||||
pub fn test_dbg(file_path: *anyopaque, message: *anyopaque) callconv(.C) void {
|
||||
roc_dbg(file_path, message);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -40,6 +47,11 @@ fn testing_roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int
|
|||
return mmap(addr, length, prot, flags, fd, offset);
|
||||
}
|
||||
|
||||
fn testing_roc_dbg(file_path: *anyopaque, message: *anyopaque) callconv(.C) void {
|
||||
_ = message;
|
||||
_ = file_path;
|
||||
}
|
||||
|
||||
comptime {
|
||||
// During tests, use the testing allocators to satisfy these functions.
|
||||
if (builtin.is_test) {
|
||||
|
@ -47,6 +59,7 @@ comptime {
|
|||
@export(testing_roc_realloc, .{ .name = "roc_realloc", .linkage = .Strong });
|
||||
@export(testing_roc_dealloc, .{ .name = "roc_dealloc", .linkage = .Strong });
|
||||
@export(testing_roc_panic, .{ .name = "roc_panic", .linkage = .Strong });
|
||||
@export(testing_roc_dbg, .{ .name = "roc_dbg", .linkage = .Strong });
|
||||
|
||||
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
|
||||
@export(testing_roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
|
||||
|
|
|
@ -32,6 +32,7 @@ interface Dict
|
|||
Str,
|
||||
Num.{ Nat, U64, U8, I8 },
|
||||
Hash.{ Hasher, Hash },
|
||||
Inspect.{ Inspect, Inspector, InspectFormatter },
|
||||
]
|
||||
|
||||
## A [dictionary](https://en.wikipedia.org/wiki/Associative_array) that lets you
|
||||
|
@ -108,6 +109,9 @@ Dict k v := {
|
|||
Hash {
|
||||
hash: hashDict,
|
||||
},
|
||||
Inspect {
|
||||
toInspector: toInspectorDict,
|
||||
},
|
||||
]
|
||||
|
||||
isEq : Dict k v, Dict k v -> Bool where k implements Hash & Eq, v implements Eq
|
||||
|
@ -126,6 +130,11 @@ isEq = \xs, ys ->
|
|||
hashDict : hasher, Dict k v -> hasher where k implements Hash & Eq, v implements Hash, hasher implements Hasher
|
||||
hashDict = \hasher, dict -> Hash.hashUnordered hasher (toList dict) List.walk
|
||||
|
||||
toInspectorDict : Dict k v -> Inspector f where k implements Inspect & Hash & Eq, v implements Inspect, f implements InspectFormatter
|
||||
toInspectorDict = \dict ->
|
||||
fmt <- Inspect.custom
|
||||
Inspect.apply (Inspect.dict dict walk Inspect.toInspector Inspect.toInspector) fmt
|
||||
|
||||
## Return an empty dictionary.
|
||||
## ```
|
||||
## emptyDict = Dict.empty {}
|
||||
|
|
|
@ -15,6 +15,7 @@ interface Inspect
|
|||
record,
|
||||
bool,
|
||||
str,
|
||||
function,
|
||||
opaque,
|
||||
u8,
|
||||
i8,
|
||||
|
@ -26,16 +27,19 @@ interface Inspect
|
|||
i64,
|
||||
u128,
|
||||
i128,
|
||||
nat,
|
||||
f32,
|
||||
f64,
|
||||
dec,
|
||||
custom,
|
||||
apply,
|
||||
toInspector,
|
||||
DbgFormatter,
|
||||
toDbgStr,
|
||||
]
|
||||
imports [
|
||||
Bool.{ Bool },
|
||||
Num.{ U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64, Dec },
|
||||
Num.{ U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64, Dec, Nat },
|
||||
List,
|
||||
Str,
|
||||
]
|
||||
|
@ -56,12 +60,13 @@ InspectFormatter implements
|
|||
set : set, ElemWalker state set elem, (elem -> Inspector f) -> Inspector f where f implements InspectFormatter
|
||||
dict : dict, KeyValWalker state dict key value, (key -> Inspector f), (value -> Inspector f) -> Inspector f where f implements InspectFormatter
|
||||
|
||||
# Note opaque is used for both opaque types and functions.
|
||||
# The auto deriver for functions probably could put the function type.
|
||||
# For regular opaque types, I think we can use the type name, though that may lead to some reflection related issues that still need to be discussed.
|
||||
# As a simple baseline, it can just use the exact words `opaque` and `function` for now.
|
||||
# In text, this would render as `<opaque>`, `<function>`, etc
|
||||
opaque : Str -> Inspector f where f implements InspectFormatter
|
||||
# In text, this would render as `<opaque>`
|
||||
# TODO: Pass the type name to opaque so that it can be displayed.
|
||||
opaque : * -> Inspector f where f implements InspectFormatter
|
||||
|
||||
# In text, this would render as `<function>`
|
||||
# TODO: Maybe pass the the function name or signiture to function so that it can be displayed.
|
||||
function : * -> Inspector f where f implements InspectFormatter
|
||||
|
||||
u8 : U8 -> Inspector f where f implements InspectFormatter
|
||||
i8 : I8 -> Inspector f where f implements InspectFormatter
|
||||
|
@ -73,6 +78,7 @@ InspectFormatter implements
|
|||
i64 : I64 -> Inspector f where f implements InspectFormatter
|
||||
u128 : U128 -> Inspector f where f implements InspectFormatter
|
||||
i128 : I128 -> Inspector f where f implements InspectFormatter
|
||||
nat : Nat -> Inspector f where f implements InspectFormatter
|
||||
f32 : F32 -> Inspector f where f implements InspectFormatter
|
||||
f64 : F64 -> Inspector f where f implements InspectFormatter
|
||||
dec : Dec -> Inspector f where f implements InspectFormatter
|
||||
|
@ -80,7 +86,7 @@ InspectFormatter implements
|
|||
Inspector f := f -> f where f implements InspectFormatter
|
||||
|
||||
custom : (f -> f) -> Inspector f where f implements InspectFormatter
|
||||
custom = @Inspector
|
||||
custom = \fn -> @Inspector fn
|
||||
|
||||
apply : Inspector f, f -> f where f implements InspectFormatter
|
||||
apply = \@Inspector fn, fmt -> fn fmt
|
||||
|
@ -92,3 +98,252 @@ inspect : val -> f where val implements Inspect, f implements InspectFormatter
|
|||
inspect = \val ->
|
||||
(@Inspector valFn) = toInspector val
|
||||
valFn (init {})
|
||||
|
||||
# The current default formatter for inspect.
|
||||
# This just returns a simple string for debugging.
|
||||
# More powerful formatters will likely be wanted in the future.
|
||||
DbgFormatter := { data : Str }
|
||||
implements [
|
||||
InspectFormatter {
|
||||
init: dbgInit,
|
||||
list: dbgList,
|
||||
set: dbgSet,
|
||||
dict: dbgDict,
|
||||
tag: dbgTag,
|
||||
tuple: dbgTuple,
|
||||
record: dbgRecord,
|
||||
bool: dbgBool,
|
||||
str: dbgStr,
|
||||
opaque: dbgOpaque,
|
||||
function: dbgFunction,
|
||||
u8: dbgU8,
|
||||
i8: dbgI8,
|
||||
u16: dbgU16,
|
||||
i16: dbgI16,
|
||||
u32: dbgU32,
|
||||
i32: dbgI32,
|
||||
u64: dbgU64,
|
||||
i64: dbgI64,
|
||||
u128: dbgU128,
|
||||
i128: dbgI128,
|
||||
nat: dbgNat,
|
||||
f32: dbgF32,
|
||||
f64: dbgF64,
|
||||
dec: dbgDec,
|
||||
},
|
||||
]
|
||||
|
||||
dbgInit : {} -> DbgFormatter
|
||||
dbgInit = \{} -> @DbgFormatter { data: "" }
|
||||
|
||||
dbgList : list, ElemWalker (DbgFormatter, Bool) list elem, (elem -> Inspector DbgFormatter) -> Inspector DbgFormatter
|
||||
dbgList = \content, walkFn, toDbgInspector ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "["
|
||||
|> \f1 ->
|
||||
(f2, prependSep), elem <- walkFn content (f1, Bool.false)
|
||||
f3 =
|
||||
if prependSep then
|
||||
dbgWrite f2 ", "
|
||||
else
|
||||
f2
|
||||
|
||||
elem
|
||||
|> toDbgInspector
|
||||
|> apply f3
|
||||
|> \f4 -> (f4, Bool.true)
|
||||
|> .0
|
||||
|> dbgWrite "]"
|
||||
|
||||
dbgSet : set, ElemWalker (DbgFormatter, Bool) set elem, (elem -> Inspector DbgFormatter) -> Inspector DbgFormatter
|
||||
dbgSet = \content, walkFn, toDbgInspector ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "{"
|
||||
|> \f1 ->
|
||||
(f2, prependSep), elem <- walkFn content (f1, Bool.false)
|
||||
f3 =
|
||||
if prependSep then
|
||||
dbgWrite f2 ", "
|
||||
else
|
||||
f2
|
||||
|
||||
elem
|
||||
|> toDbgInspector
|
||||
|> apply f3
|
||||
|> \f4 -> (f4, Bool.true)
|
||||
|> .0
|
||||
|> dbgWrite "}"
|
||||
|
||||
dbgDict : dict, KeyValWalker (DbgFormatter, Bool) dict key value, (key -> Inspector DbgFormatter), (value -> Inspector DbgFormatter) -> Inspector DbgFormatter
|
||||
dbgDict = \d, walkFn, keyToInspector, valueToInspector ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "{"
|
||||
|> \f1 ->
|
||||
(f2, prependSep), key, value <- walkFn d (f1, Bool.false)
|
||||
f3 =
|
||||
if prependSep then
|
||||
dbgWrite f2 ", "
|
||||
else
|
||||
f2
|
||||
|
||||
apply (keyToInspector key) f3
|
||||
|> dbgWrite ": "
|
||||
|> \x -> apply (valueToInspector value) x
|
||||
|> \f4 -> (f4, Bool.true)
|
||||
|> .0
|
||||
|> dbgWrite "}"
|
||||
|
||||
dbgTag : Str, List (Inspector DbgFormatter) -> Inspector DbgFormatter
|
||||
dbgTag = \name, fields ->
|
||||
if List.isEmpty fields then
|
||||
f0 <- custom
|
||||
dbgWrite f0 name
|
||||
else
|
||||
f0 <- custom
|
||||
dbgWrite f0 "("
|
||||
|> dbgWrite name
|
||||
|> \f1 ->
|
||||
f2, inspector <- List.walk fields f1
|
||||
dbgWrite f2 " "
|
||||
|> \x -> apply inspector x
|
||||
|> dbgWrite ")"
|
||||
|
||||
dbgTuple : List (Inspector DbgFormatter) -> Inspector DbgFormatter
|
||||
dbgTuple = \fields ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "("
|
||||
|> \f1 ->
|
||||
(f2, prependSep), inspector <- List.walk fields (f1, Bool.false)
|
||||
f3 =
|
||||
if prependSep then
|
||||
dbgWrite f2 ", "
|
||||
else
|
||||
f2
|
||||
|
||||
apply inspector f3
|
||||
|> \f4 -> (f4, Bool.true)
|
||||
|> .0
|
||||
|> dbgWrite ")"
|
||||
|
||||
dbgRecord : List { key : Str, value : Inspector DbgFormatter } -> Inspector DbgFormatter
|
||||
dbgRecord = \fields ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "{"
|
||||
|> \f1 ->
|
||||
(f2, prependSep), { key, value } <- List.walk fields (f1, Bool.false)
|
||||
f3 =
|
||||
if prependSep then
|
||||
dbgWrite f2 ", "
|
||||
else
|
||||
f2
|
||||
|
||||
dbgWrite f3 key
|
||||
|> dbgWrite ": "
|
||||
|> \x -> apply value x
|
||||
|> \f4 -> (f4, Bool.true)
|
||||
|> .0
|
||||
|> dbgWrite "}"
|
||||
|
||||
dbgBool : Bool -> Inspector DbgFormatter
|
||||
dbgBool = \b ->
|
||||
if b then
|
||||
f0 <- custom
|
||||
dbgWrite f0 "Bool.true"
|
||||
else
|
||||
f0 <- custom
|
||||
dbgWrite f0 "Bool.false"
|
||||
|
||||
dbgStr : Str -> Inspector DbgFormatter
|
||||
dbgStr = \s ->
|
||||
f0 <- custom
|
||||
f0
|
||||
|> dbgWrite "\""
|
||||
|> dbgWrite s # TODO: Should we be escaping strings for dbg/logging?
|
||||
|> dbgWrite "\""
|
||||
|
||||
dbgOpaque : * -> Inspector DbgFormatter
|
||||
dbgOpaque = \_ ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "<opaque>"
|
||||
|
||||
dbgFunction : * -> Inspector DbgFormatter
|
||||
dbgFunction = \_ ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 "<function>"
|
||||
|
||||
dbgU8 : U8 -> Inspector DbgFormatter
|
||||
dbgU8 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgI8 : I8 -> Inspector DbgFormatter
|
||||
dbgI8 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgU16 : U16 -> Inspector DbgFormatter
|
||||
dbgU16 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgI16 : I16 -> Inspector DbgFormatter
|
||||
dbgI16 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgU32 : U32 -> Inspector DbgFormatter
|
||||
dbgU32 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgI32 : I32 -> Inspector DbgFormatter
|
||||
dbgI32 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgU64 : U64 -> Inspector DbgFormatter
|
||||
dbgU64 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgI64 : I64 -> Inspector DbgFormatter
|
||||
dbgI64 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgU128 : U128 -> Inspector DbgFormatter
|
||||
dbgU128 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgI128 : I128 -> Inspector DbgFormatter
|
||||
dbgI128 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgNat : Nat -> Inspector DbgFormatter
|
||||
dbgNat = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgF32 : F32 -> Inspector DbgFormatter
|
||||
dbgF32 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgF64 : F64 -> Inspector DbgFormatter
|
||||
dbgF64 = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgDec : Dec -> Inspector DbgFormatter
|
||||
dbgDec = \num ->
|
||||
f0 <- custom
|
||||
dbgWrite f0 (num |> Num.toStr)
|
||||
|
||||
dbgWrite : DbgFormatter, Str -> DbgFormatter
|
||||
dbgWrite = \@DbgFormatter { data }, added ->
|
||||
@DbgFormatter { data: Str.concat data added }
|
||||
|
||||
toDbgStr : DbgFormatter -> Str
|
||||
toDbgStr = \@DbgFormatter { data } -> data
|
||||
|
|
|
@ -25,6 +25,7 @@ interface Set
|
|||
Dict.{ Dict },
|
||||
Num.{ Nat },
|
||||
Hash.{ Hash, Hasher },
|
||||
Inspect.{ Inspect, Inspector, InspectFormatter },
|
||||
]
|
||||
|
||||
## Provides a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type))
|
||||
|
@ -37,6 +38,9 @@ Set k := Dict.Dict k {} where k implements Hash & Eq
|
|||
Hash {
|
||||
hash: hashSet,
|
||||
},
|
||||
Inspect {
|
||||
toInspector: toInspectorSet,
|
||||
},
|
||||
]
|
||||
|
||||
isEq : Set k, Set k -> Bool where k implements Hash & Eq
|
||||
|
@ -53,6 +57,11 @@ isEq = \xs, ys ->
|
|||
hashSet : hasher, Set k -> hasher where k implements Hash & Eq, hasher implements Hasher
|
||||
hashSet = \hasher, @Set inner -> Hash.hash hasher inner
|
||||
|
||||
toInspectorSet : Set k -> Inspector f where k implements Inspect & Hash & Eq, f implements InspectFormatter
|
||||
toInspectorSet = \set ->
|
||||
fmt <- Inspect.custom
|
||||
Inspect.apply (Inspect.set set walk Inspect.toInspector) fmt
|
||||
|
||||
## Creates a new empty `Set`.
|
||||
## ```
|
||||
## emptySet = Set.empty {}
|
||||
|
|
|
@ -440,7 +440,6 @@ pub const UTILS_EXPECT_FAILED_START_SHARED_FILE: &str =
|
|||
"roc_builtins.utils.expect_failed_start_shared_file";
|
||||
pub const UTILS_EXPECT_READ_ENV_SHARED_BUFFER: &str = "roc_builtins.utils.read_env_shared_buffer";
|
||||
pub const NOTIFY_PARENT_EXPECT: &str = "roc_builtins.utils.notify_parent_expect";
|
||||
pub const NOTIFY_PARENT_DBG: &str = "roc_builtins.utils.notify_parent_dbg";
|
||||
|
||||
pub const UTILS_LONGJMP: &str = "longjmp";
|
||||
pub const UTILS_SETJMP: &str = "setjmp";
|
||||
|
|
|
@ -670,12 +670,12 @@ fn deep_copy_expr_help<C: CopyEnv>(env: &mut C, copied: &mut Vec<Variable>, expr
|
|||
},
|
||||
|
||||
Dbg {
|
||||
loc_condition,
|
||||
loc_message,
|
||||
loc_continuation,
|
||||
variable,
|
||||
symbol,
|
||||
} => Dbg {
|
||||
loc_condition: Box::new(loc_condition.map(|e| go_help!(e))),
|
||||
loc_message: Box::new(loc_message.map(|e| go_help!(e))),
|
||||
loc_continuation: Box::new(loc_continuation.map(|e| go_help!(e))),
|
||||
variable: sub!(*variable),
|
||||
symbol: *symbol,
|
||||
|
|
|
@ -718,6 +718,7 @@ fn canonicalize_opaque<'a>(
|
|||
|
||||
let ability_region = ability.region;
|
||||
|
||||
// Op := {} has [Eq]
|
||||
let (ability, members) = match ability.value {
|
||||
ast::TypeAnnotation::Apply(module_name, ident, []) => {
|
||||
match make_apply_symbol(env, region, scope, module_name, ident) {
|
||||
|
|
|
@ -213,6 +213,48 @@ fn is_eq<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
)
|
||||
}
|
||||
|
||||
fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
||||
let alloc_pat = |it| env.arena.alloc(Loc::at(DERIVED_REGION, it));
|
||||
let alloc_expr = |it| env.arena.alloc(Loc::at(DERIVED_REGION, it));
|
||||
|
||||
let payload = "#payload";
|
||||
|
||||
// \@Opaq payload
|
||||
let opaque_ref = alloc_pat(ast::Pattern::OpaqueRef(at_opaque));
|
||||
let opaque_apply_pattern = ast::Pattern::Apply(
|
||||
opaque_ref,
|
||||
&*env
|
||||
.arena
|
||||
.alloc([Loc::at(DERIVED_REGION, ast::Pattern::Identifier(payload))]),
|
||||
);
|
||||
|
||||
// Inspect.toInspector payload
|
||||
let call_member = alloc_expr(ast::Expr::Apply(
|
||||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "Inspect",
|
||||
ident: "toInspector",
|
||||
}),
|
||||
&*env.arena.alloc([&*alloc_expr(ast::Expr::Var {
|
||||
module_name: "",
|
||||
ident: payload,
|
||||
})]),
|
||||
roc_module::called_via::CalledVia::Space,
|
||||
));
|
||||
|
||||
// TODO: change the derived implementation to be something that includes the opaque symbol in
|
||||
// the derivation, e.g. something like
|
||||
//
|
||||
// \@Opaq payload ->
|
||||
// Inspect.opaqueWrapper "toString symbol" payload
|
||||
|
||||
// \@Opaq payload -> Inspect.toInspector payload
|
||||
ast::Expr::Closure(
|
||||
env.arena
|
||||
.alloc([Loc::at(DERIVED_REGION, opaque_apply_pattern)]),
|
||||
call_member,
|
||||
)
|
||||
}
|
||||
|
||||
pub const DERIVED_REGION: Region = Region::zero();
|
||||
|
||||
pub(crate) fn synthesize_member_impl<'a>(
|
||||
|
@ -232,6 +274,10 @@ pub(crate) fn synthesize_member_impl<'a>(
|
|||
Symbol::DECODE_DECODER => (format!("#{opaque_name}_decoder"), decoder(env, at_opaque)),
|
||||
Symbol::HASH_HASH => (format!("#{opaque_name}_hash"), hash(env, at_opaque)),
|
||||
Symbol::BOOL_IS_EQ => (format!("#{opaque_name}_isEq"), is_eq(env, at_opaque)),
|
||||
Symbol::INSPECT_TO_INSPECTOR => (
|
||||
format!("#{opaque_name}_toInspector"),
|
||||
to_inspector(env, at_opaque),
|
||||
),
|
||||
other => internal_error!("{:?} is not a derivable ability member!", other),
|
||||
};
|
||||
|
||||
|
|
|
@ -269,7 +269,7 @@ pub enum Expr {
|
|||
},
|
||||
|
||||
Dbg {
|
||||
loc_condition: Box<Loc<Expr>>,
|
||||
loc_message: Box<Loc<Expr>>,
|
||||
loc_continuation: Box<Loc<Expr>>,
|
||||
variable: Variable,
|
||||
symbol: Symbol,
|
||||
|
@ -1062,10 +1062,10 @@ pub fn canonicalize_expr<'a>(
|
|||
})
|
||||
}
|
||||
ast::Expr::RecordBuilder(_) => {
|
||||
unreachable!("RecordBuilder should have been desugared by now")
|
||||
internal_error!("RecordBuilder should have been desugared by now")
|
||||
}
|
||||
ast::Expr::Backpassing(_, _, _) => {
|
||||
unreachable!("Backpassing should have been desugared by now")
|
||||
internal_error!("Backpassing should have been desugared by now")
|
||||
}
|
||||
ast::Expr::Closure(loc_arg_patterns, loc_body_expr) => {
|
||||
let (closure_data, output) =
|
||||
|
@ -1246,11 +1246,14 @@ pub fn canonicalize_expr<'a>(
|
|||
output,
|
||||
)
|
||||
}
|
||||
ast::Expr::Dbg(condition, continuation) => {
|
||||
ast::Expr::Dbg(_, _) => {
|
||||
internal_error!("Dbg should have been desugared by now")
|
||||
}
|
||||
ast::Expr::LowLevelDbg(message, continuation) => {
|
||||
let mut output = Output::default();
|
||||
|
||||
let (loc_condition, output1) =
|
||||
canonicalize_expr(env, var_store, scope, condition.region, &condition.value);
|
||||
let (loc_message, output1) =
|
||||
canonicalize_expr(env, var_store, scope, message.region, &message.value);
|
||||
|
||||
let (loc_continuation, output2) = canonicalize_expr(
|
||||
env,
|
||||
|
@ -1263,17 +1266,17 @@ pub fn canonicalize_expr<'a>(
|
|||
output.union(output1);
|
||||
output.union(output2);
|
||||
|
||||
// the symbol is used to bind the condition `x = condition`, and identify this `dbg`.
|
||||
// the symbol is used to bind the message `x = message`, and identify this `dbg`.
|
||||
// That would cause issues if we dbg a variable, like `dbg y`, because in the IR we
|
||||
// cannot alias variables. Hence, we make the dbg use that same variable `y`
|
||||
let symbol = match &loc_condition.value {
|
||||
let symbol = match &loc_message.value {
|
||||
Expr::Var(symbol, _) => *symbol,
|
||||
_ => scope.gen_unique_symbol(),
|
||||
};
|
||||
|
||||
(
|
||||
Dbg {
|
||||
loc_condition: Box::new(loc_condition),
|
||||
loc_message: Box::new(loc_message),
|
||||
loc_continuation: Box::new(loc_continuation),
|
||||
variable: var_store.fresh(),
|
||||
symbol,
|
||||
|
@ -2094,14 +2097,14 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
|||
}
|
||||
|
||||
Dbg {
|
||||
loc_condition,
|
||||
loc_message,
|
||||
loc_continuation,
|
||||
variable,
|
||||
symbol,
|
||||
} => {
|
||||
let loc_condition = Loc {
|
||||
region: loc_condition.region,
|
||||
value: inline_calls(var_store, loc_condition.value),
|
||||
let loc_message = Loc {
|
||||
region: loc_message.region,
|
||||
value: inline_calls(var_store, loc_message.value),
|
||||
};
|
||||
|
||||
let loc_continuation = Loc {
|
||||
|
@ -2110,7 +2113,7 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
|||
};
|
||||
|
||||
Dbg {
|
||||
loc_condition: Box::new(loc_condition),
|
||||
loc_message: Box::new(loc_message),
|
||||
loc_continuation: Box::new(loc_continuation),
|
||||
variable,
|
||||
symbol,
|
||||
|
@ -2338,10 +2341,10 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
|||
loc_answer.value
|
||||
}
|
||||
Some(_) => {
|
||||
unreachable!("Tried to inline a non-function");
|
||||
internal_error!("Tried to inline a non-function");
|
||||
}
|
||||
None => {
|
||||
unreachable!(
|
||||
internal_error!(
|
||||
"Tried to inline a builtin that wasn't registered: {:?}",
|
||||
symbol
|
||||
);
|
||||
|
@ -2395,6 +2398,7 @@ pub fn is_valid_interpolation(expr: &ast::Expr<'_>) -> bool {
|
|||
| ast::Expr::MalformedClosure => true,
|
||||
// Newlines are disallowed inside interpolation, and these all require newlines
|
||||
ast::Expr::Dbg(_, _)
|
||||
| ast::Expr::LowLevelDbg(_, _)
|
||||
| ast::Expr::Defs(_, _)
|
||||
| ast::Expr::Expect(_, _)
|
||||
| ast::Expr::When(_, _)
|
||||
|
@ -3328,7 +3332,7 @@ impl crate::traverse::Visitor for ExpectCollector {
|
|||
.insert(loc_condition.region, lookups_in_cond.to_vec());
|
||||
}
|
||||
Expr::Dbg {
|
||||
loc_condition,
|
||||
loc_message,
|
||||
variable,
|
||||
symbol,
|
||||
..
|
||||
|
@ -3336,7 +3340,7 @@ impl crate::traverse::Visitor for ExpectCollector {
|
|||
let lookup = DbgLookup {
|
||||
symbol: *symbol,
|
||||
var: *variable,
|
||||
region: loc_condition.region,
|
||||
region: loc_message.region,
|
||||
ability_info: None,
|
||||
};
|
||||
|
||||
|
|
|
@ -996,7 +996,7 @@ fn fix_values_captured_in_closure_expr(
|
|||
..
|
||||
}
|
||||
| Dbg {
|
||||
loc_condition,
|
||||
loc_message: loc_condition,
|
||||
loc_continuation,
|
||||
..
|
||||
} => {
|
||||
|
|
|
@ -8,7 +8,8 @@ use roc_module::called_via::{BinOp, CalledVia};
|
|||
use roc_module::ident::ModuleName;
|
||||
use roc_parse::ast::Expr::{self, *};
|
||||
use roc_parse::ast::{
|
||||
AssignedField, Collection, RecordBuilderField, StrLiteral, StrSegment, ValueDef, WhenBranch,
|
||||
AssignedField, Collection, Pattern, RecordBuilderField, StrLiteral, StrSegment, ValueDef,
|
||||
WhenBranch,
|
||||
};
|
||||
use roc_region::all::{Loc, Region};
|
||||
|
||||
|
@ -70,7 +71,10 @@ fn desugar_value_def<'a>(arena: &'a Bump, def: &'a ValueDef<'a>) -> ValueDef<'a>
|
|||
use ValueDef::*;
|
||||
|
||||
match def {
|
||||
Body(loc_pattern, loc_expr) => Body(loc_pattern, desugar_expr(arena, loc_expr)),
|
||||
Body(loc_pattern, loc_expr) => Body(
|
||||
desugar_loc_pattern(arena, loc_pattern),
|
||||
desugar_expr(arena, loc_expr),
|
||||
),
|
||||
ann @ Annotation(_, _) => *ann,
|
||||
AnnotatedBody {
|
||||
ann_pattern,
|
||||
|
@ -238,7 +242,10 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
|||
}
|
||||
Closure(loc_patterns, loc_ret) => arena.alloc(Loc {
|
||||
region: loc_expr.region,
|
||||
value: Closure(loc_patterns, desugar_expr(arena, loc_ret)),
|
||||
value: Closure(
|
||||
desugar_loc_patterns(arena, loc_patterns),
|
||||
desugar_expr(arena, loc_ret),
|
||||
),
|
||||
}),
|
||||
Backpassing(loc_patterns, loc_body, loc_ret) => {
|
||||
// loc_patterns <- loc_body
|
||||
|
@ -249,7 +256,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
|||
let desugared_body = desugar_expr(arena, loc_body);
|
||||
|
||||
let desugared_ret = desugar_expr(arena, loc_ret);
|
||||
let closure = Expr::Closure(loc_patterns, desugared_ret);
|
||||
let desugared_loc_patterns = desugar_loc_patterns(arena, loc_patterns);
|
||||
let closure = Expr::Closure(desugared_loc_patterns, desugared_ret);
|
||||
let loc_closure = Loc::at(loc_expr.region, closure);
|
||||
|
||||
match &desugared_body.value {
|
||||
|
@ -352,10 +360,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
|||
let mut desugared_branches = Vec::with_capacity_in(branches.len(), arena);
|
||||
|
||||
for branch in branches.iter() {
|
||||
let desugared = desugar_expr(arena, &branch.value);
|
||||
|
||||
let mut alternatives = Vec::with_capacity_in(branch.patterns.len(), arena);
|
||||
alternatives.extend(branch.patterns.iter().copied());
|
||||
let desugared_expr = desugar_expr(arena, &branch.value);
|
||||
let desugared_patterns = desugar_loc_patterns(arena, branch.patterns);
|
||||
|
||||
let desugared_guard = if let Some(guard) = &branch.guard {
|
||||
Some(*desugar_expr(arena, guard))
|
||||
|
@ -363,11 +369,9 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
|||
None
|
||||
};
|
||||
|
||||
let alternatives = alternatives.into_bump_slice();
|
||||
|
||||
desugared_branches.push(&*arena.alloc(WhenBranch {
|
||||
patterns: alternatives,
|
||||
value: *desugared,
|
||||
patterns: desugared_patterns,
|
||||
value: *desugared_expr,
|
||||
guard: desugared_guard,
|
||||
}));
|
||||
}
|
||||
|
@ -457,13 +461,48 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
|||
})
|
||||
}
|
||||
Dbg(condition, continuation) => {
|
||||
let desugared_condition = &*arena.alloc(desugar_expr(arena, condition));
|
||||
// Desugars a `dbg x` statement into
|
||||
// `roc_dbg (Inspect.toDbgStr (Inspect.inspect x))`
|
||||
let desugared_continuation = &*arena.alloc(desugar_expr(arena, continuation));
|
||||
|
||||
let region = condition.region;
|
||||
// TODO desugar this in canonicalization instead, so we can work
|
||||
// in terms of integers exclusively and not need to create strings
|
||||
// which canonicalization then needs to look up, check if they're exposed, etc
|
||||
let inspect = Var {
|
||||
module_name: ModuleName::INSPECT,
|
||||
ident: "inspect",
|
||||
};
|
||||
let loc_inspect_fn_var = arena.alloc(Loc {
|
||||
value: inspect,
|
||||
region,
|
||||
});
|
||||
let desugared_inspect_args = arena.alloc([desugar_expr(arena, condition)]);
|
||||
|
||||
let inspector = arena.alloc(Loc {
|
||||
value: Apply(loc_inspect_fn_var, desugared_inspect_args, CalledVia::Space),
|
||||
region,
|
||||
});
|
||||
|
||||
let to_dbg_str = Var {
|
||||
module_name: ModuleName::INSPECT,
|
||||
ident: "toDbgStr",
|
||||
};
|
||||
let loc_to_dbg_str_fn_var = arena.alloc(Loc {
|
||||
value: to_dbg_str,
|
||||
region,
|
||||
});
|
||||
let to_dbg_str_args = arena.alloc([&*inspector]);
|
||||
let dbg_str = arena.alloc(Loc {
|
||||
value: Apply(loc_to_dbg_str_fn_var, to_dbg_str_args, CalledVia::Space),
|
||||
region,
|
||||
});
|
||||
arena.alloc(Loc {
|
||||
value: Dbg(desugared_condition, desugared_continuation),
|
||||
value: LowLevelDbg(dbg_str, desugared_continuation),
|
||||
region: loc_expr.region,
|
||||
})
|
||||
}
|
||||
LowLevelDbg(_, _) => unreachable!("Only exists after desugaring"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -544,6 +583,85 @@ fn desugar_field<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
fn desugar_loc_patterns<'a>(
|
||||
arena: &'a Bump,
|
||||
loc_patterns: &'a [Loc<Pattern<'a>>],
|
||||
) -> &'a [Loc<Pattern<'a>>] {
|
||||
Vec::from_iter_in(
|
||||
loc_patterns.iter().map(|loc_pattern| Loc {
|
||||
region: loc_pattern.region,
|
||||
value: desugar_pattern(arena, loc_pattern.value),
|
||||
}),
|
||||
arena,
|
||||
)
|
||||
.into_bump_slice()
|
||||
}
|
||||
|
||||
fn desugar_loc_pattern<'a>(
|
||||
arena: &'a Bump,
|
||||
loc_pattern: &'a Loc<Pattern<'a>>,
|
||||
) -> &'a Loc<Pattern<'a>> {
|
||||
arena.alloc(Loc {
|
||||
region: loc_pattern.region,
|
||||
value: desugar_pattern(arena, loc_pattern.value),
|
||||
})
|
||||
}
|
||||
|
||||
fn desugar_pattern<'a>(arena: &'a Bump, pattern: Pattern<'a>) -> Pattern<'a> {
|
||||
use roc_parse::ast::Pattern::*;
|
||||
|
||||
match pattern {
|
||||
Identifier(_)
|
||||
| Tag(_)
|
||||
| OpaqueRef(_)
|
||||
| NumLiteral(_)
|
||||
| NonBase10Literal { .. }
|
||||
| FloatLiteral(_)
|
||||
| StrLiteral(_)
|
||||
| Underscore(_)
|
||||
| SingleQuote(_)
|
||||
| ListRest(_)
|
||||
| Malformed(_)
|
||||
| MalformedIdent(_, _)
|
||||
| QualifiedIdentifier { .. } => pattern,
|
||||
|
||||
Apply(tag, arg_patterns) => {
|
||||
// Skip desugaring the tag, it should either be a Tag or OpaqueRef
|
||||
let desugared_arg_patterns = Vec::from_iter_in(
|
||||
arg_patterns.iter().map(|arg_pattern| Loc {
|
||||
region: arg_pattern.region,
|
||||
value: desugar_pattern(arena, arg_pattern.value),
|
||||
}),
|
||||
arena,
|
||||
)
|
||||
.into_bump_slice();
|
||||
|
||||
Apply(tag, desugared_arg_patterns)
|
||||
}
|
||||
RecordDestructure(field_patterns) => {
|
||||
RecordDestructure(field_patterns.map_items(arena, |field_pattern| Loc {
|
||||
region: field_pattern.region,
|
||||
value: desugar_pattern(arena, field_pattern.value),
|
||||
}))
|
||||
}
|
||||
RequiredField(name, field_pattern) => {
|
||||
RequiredField(name, desugar_loc_pattern(arena, field_pattern))
|
||||
}
|
||||
OptionalField(name, expr) => OptionalField(name, desugar_expr(arena, expr)),
|
||||
Tuple(patterns) => Tuple(patterns.map_items(arena, |elem_pattern| Loc {
|
||||
region: elem_pattern.region,
|
||||
value: desugar_pattern(arena, elem_pattern.value),
|
||||
})),
|
||||
List(patterns) => List(patterns.map_items(arena, |elem_pattern| Loc {
|
||||
region: elem_pattern.region,
|
||||
value: desugar_pattern(arena, elem_pattern.value),
|
||||
})),
|
||||
As(sub_pattern, symbol) => As(desugar_loc_pattern(arena, sub_pattern), symbol),
|
||||
SpaceBefore(sub_pattern, _spaces) => desugar_pattern(arena, *sub_pattern),
|
||||
SpaceAfter(sub_pattern, _spaces) => desugar_pattern(arena, *sub_pattern),
|
||||
}
|
||||
}
|
||||
|
||||
struct RecordBuilderArg<'a> {
|
||||
closure: &'a Loc<Expr<'a>>,
|
||||
apply_exprs: Vec<'a, &'a Loc<Expr<'a>>>,
|
||||
|
|
|
@ -387,11 +387,11 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr, var: Variable) {
|
|||
}
|
||||
Expr::Dbg {
|
||||
variable,
|
||||
loc_condition,
|
||||
loc_message,
|
||||
loc_continuation,
|
||||
symbol: _,
|
||||
} => {
|
||||
visitor.visit_expr(&loc_condition.value, loc_condition.region, *variable);
|
||||
visitor.visit_expr(&loc_message.value, loc_message.region, *variable);
|
||||
visitor.visit_expr(
|
||||
&loc_continuation.value,
|
||||
loc_continuation.region,
|
||||
|
|
|
@ -741,7 +741,7 @@ pub fn constrain_expr(
|
|||
}
|
||||
|
||||
Dbg {
|
||||
loc_condition,
|
||||
loc_message,
|
||||
loc_continuation,
|
||||
variable,
|
||||
symbol: _,
|
||||
|
@ -749,12 +749,12 @@ pub fn constrain_expr(
|
|||
let dbg_type = constraints.push_variable(*variable);
|
||||
let expected_dbg = constraints.push_expected_type(Expected::NoExpectation(dbg_type));
|
||||
|
||||
let cond_con = constrain_expr(
|
||||
let message_con = constrain_expr(
|
||||
types,
|
||||
constraints,
|
||||
env,
|
||||
loc_condition.region,
|
||||
&loc_condition.value,
|
||||
loc_message.region,
|
||||
&loc_message.value,
|
||||
expected_dbg,
|
||||
);
|
||||
|
||||
|
@ -767,7 +767,7 @@ pub fn constrain_expr(
|
|||
expected,
|
||||
);
|
||||
|
||||
constraints.exists_many([*variable], [cond_con, continuation_con])
|
||||
constraints.exists_many([*variable], [message_con, continuation_con])
|
||||
}
|
||||
|
||||
If {
|
||||
|
|
1089
crates/compiler/derive/src/inspect.rs
Normal file
1089
crates/compiler/derive/src/inspect.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -19,7 +19,7 @@ use util::Env;
|
|||
mod decoding;
|
||||
mod encoding;
|
||||
mod hash;
|
||||
|
||||
mod inspect;
|
||||
mod util;
|
||||
|
||||
pub(crate) const DERIVED_SYNTH: ModuleId = ModuleId::DERIVED_SYNTH;
|
||||
|
@ -79,6 +79,9 @@ fn build_derived_body(
|
|||
decoding::derive_decoder(&mut env, decoder_key, derived_symbol)
|
||||
}
|
||||
DeriveKey::Hash(hash_key) => hash::derive_hash(&mut env, hash_key, derived_symbol),
|
||||
DeriveKey::ToInspector(to_inspector_key) => {
|
||||
inspect::derive_to_inspector(&mut env, to_inspector_key, derived_symbol)
|
||||
}
|
||||
};
|
||||
|
||||
let def = Def {
|
||||
|
|
|
@ -55,6 +55,7 @@ impl FlatEncodable {
|
|||
FlatType::Record(fields, ext) => {
|
||||
let (fields_iter, ext) = fields.unsorted_iterator_and_ext(subs, ext);
|
||||
|
||||
// TODO someday we can put #[cfg(debug_assertions)] around this, but for now let's always do it.
|
||||
check_derivable_ext_var(subs, ext, |ext| {
|
||||
matches!(ext, Content::Structure(FlatType::EmptyRecord))
|
||||
})?;
|
||||
|
@ -71,6 +72,7 @@ impl FlatEncodable {
|
|||
FlatType::Tuple(elems, ext) => {
|
||||
let (elems_iter, ext) = elems.sorted_iterator_and_ext(subs, ext);
|
||||
|
||||
// TODO someday we can put #[cfg(debug_assertions)] around this, but for now let's always do it.
|
||||
check_derivable_ext_var(subs, ext, |ext| {
|
||||
matches!(ext, Content::Structure(FlatType::EmptyTuple))
|
||||
})?;
|
||||
|
@ -89,6 +91,7 @@ impl FlatEncodable {
|
|||
// `t`-prefixed payload types.
|
||||
let (tags_iter, ext) = tags.unsorted_tags_and_ext(subs, ext);
|
||||
|
||||
// TODO someday we can put #[cfg(debug_assertions)] around this, but for now let's always do it.
|
||||
check_derivable_ext_var(subs, ext.var(), |ext| {
|
||||
matches!(ext, Content::Structure(FlatType::EmptyTagUnion))
|
||||
})?;
|
||||
|
@ -115,10 +118,9 @@ impl FlatEncodable {
|
|||
)))
|
||||
}
|
||||
FlatType::EmptyRecord => Ok(Key(FlatEncodableKey::Record(vec![]))),
|
||||
FlatType::EmptyTuple => todo!(),
|
||||
FlatType::EmptyTagUnion => Ok(Key(FlatEncodableKey::TagUnion(vec![]))),
|
||||
//
|
||||
FlatType::Func(..) => Err(Underivable),
|
||||
FlatType::EmptyTuple => unreachable!("Somehow Encoding derivation got an expression that's an empty tuple, which shouldn't be possible!"),
|
||||
},
|
||||
Content::Alias(sym, _, real_var, _) => match from_builtin_symbol(sym) {
|
||||
Some(lambda) => lambda,
|
||||
|
@ -129,9 +131,7 @@ impl FlatEncodable {
|
|||
Content::RangedNumber(range) => {
|
||||
Self::from_var(subs, range.default_compilation_variable())
|
||||
}
|
||||
//
|
||||
Content::RecursionVar { structure, .. } => Self::from_var(subs, structure),
|
||||
//
|
||||
Content::Error => Err(Underivable),
|
||||
Content::FlexVar(_)
|
||||
| Content::RigidVar(_)
|
||||
|
|
211
crates/compiler/derive_key/src/inspect.rs
Normal file
211
crates/compiler/derive_key/src/inspect.rs
Normal file
|
@ -0,0 +1,211 @@
|
|||
use roc_module::{
|
||||
ident::{Lowercase, TagName},
|
||||
symbol::Symbol,
|
||||
};
|
||||
use roc_types::{
|
||||
subs::{Content, FlatType, GetSubsSlice, Subs, Variable},
|
||||
types::AliasKind,
|
||||
};
|
||||
|
||||
use crate::util::{
|
||||
check_derivable_ext_var, debug_name_fn, debug_name_record, debug_name_tag, debug_name_tuple,
|
||||
};
|
||||
|
||||
#[derive(Hash, Debug)]
|
||||
pub enum FlatInspectable {
|
||||
Immediate(Symbol),
|
||||
Key(FlatInspectableKey),
|
||||
}
|
||||
|
||||
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
|
||||
pub enum FlatInspectableKey {
|
||||
List(/* takes one variable */),
|
||||
Set(/* takes one variable */),
|
||||
Dict(/* takes two variables */),
|
||||
// Unfortunate that we must allocate here, c'est la vie
|
||||
Record(Vec<Lowercase>),
|
||||
Tuple(u32),
|
||||
TagUnion(Vec<(TagName, u16)>),
|
||||
Function(u32 /* arity; +1 for return type */),
|
||||
/// This means specifically an opaque type where the author hasn't requested that it derive Inspect (or implemented it)
|
||||
Opaque,
|
||||
Error,
|
||||
}
|
||||
|
||||
impl FlatInspectableKey {
|
||||
pub(crate) fn debug_name(&self) -> String {
|
||||
match self {
|
||||
FlatInspectableKey::List() => "list".to_string(),
|
||||
FlatInspectableKey::Set() => "set".to_string(),
|
||||
FlatInspectableKey::Dict() => "dict".to_string(),
|
||||
FlatInspectableKey::Record(fields) => debug_name_record(fields),
|
||||
FlatInspectableKey::Tuple(arity) => debug_name_tuple(*arity),
|
||||
FlatInspectableKey::TagUnion(tags) => debug_name_tag(tags),
|
||||
FlatInspectableKey::Function(arity) => debug_name_fn(*arity),
|
||||
FlatInspectableKey::Error => "error".to_string(),
|
||||
FlatInspectableKey::Opaque => "opaque".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FlatInspectable {
|
||||
pub(crate) fn from_var(subs: &Subs, var: Variable) -> FlatInspectable {
|
||||
use FlatInspectable::*;
|
||||
|
||||
match *subs.get_content_without_compacting(var) {
|
||||
Content::Structure(flat_type) => match flat_type {
|
||||
FlatType::Apply(sym, _) => match sym {
|
||||
Symbol::LIST_LIST => Key(FlatInspectableKey::List()),
|
||||
Symbol::SET_SET => Key(FlatInspectableKey::Set()),
|
||||
Symbol::DICT_DICT => Key(FlatInspectableKey::Dict()),
|
||||
Symbol::STR_STR => Immediate(Symbol::INSPECT_STR),
|
||||
_ => Immediate(Symbol::INSPECT_OPAQUE),
|
||||
},
|
||||
FlatType::Record(fields, ext) => {
|
||||
let (fields_iter, ext) = fields.unsorted_iterator_and_ext(subs, ext);
|
||||
|
||||
// TODO someday we can put #[cfg(debug_assertions)] around this, but for now let's always do it.
|
||||
check_derivable_ext_var(subs, ext, |ext| {
|
||||
matches!(ext, Content::Structure(FlatType::EmptyRecord))
|
||||
}).expect("Compiler error: unexpected nonempty ext var when deriving Inspect for record");
|
||||
|
||||
let mut field_names = Vec::with_capacity(fields.len());
|
||||
for (field_name, _) in fields_iter {
|
||||
field_names.push(field_name.clone());
|
||||
}
|
||||
|
||||
field_names.sort();
|
||||
|
||||
Key(FlatInspectableKey::Record(field_names))
|
||||
}
|
||||
FlatType::Tuple(elems, ext) => {
|
||||
let (elems_iter, ext) = elems.sorted_iterator_and_ext(subs, ext);
|
||||
|
||||
// TODO someday we can put #[cfg(debug_assertions)] around this, but for now let's always do it.
|
||||
check_derivable_ext_var(subs, ext, |ext| {
|
||||
matches!(ext, Content::Structure(FlatType::EmptyTuple))
|
||||
}).expect("Compiler error: unexpected nonempty ext var when deriving Inspect for tuple");
|
||||
|
||||
Key(FlatInspectableKey::Tuple(elems_iter.count() as _))
|
||||
}
|
||||
FlatType::TagUnion(tags, ext) | FlatType::RecursiveTagUnion(_, tags, ext) => {
|
||||
// The recursion var doesn't matter, because the derived implementation will only
|
||||
// look on the surface of the tag union type, and more over the payloads of the
|
||||
// arguments will be left generic for the monomorphizer to fill in with the
|
||||
// appropriate type. That is,
|
||||
// [ A t1, B t1 t2 ]
|
||||
// and
|
||||
// [ A t1, B t1 t2 ] as R
|
||||
// look the same on the surface, because `R` is only somewhere inside of the
|
||||
// `t`-prefixed payload types.
|
||||
let (tags_iter, ext) = tags.unsorted_tags_and_ext(subs, ext);
|
||||
|
||||
// TODO someday we can put #[cfg(debug_assertions)] around this, but for now let's always do it.
|
||||
check_derivable_ext_var(subs, ext.var(), |ext| {
|
||||
matches!(ext, Content::Structure(FlatType::EmptyTagUnion))
|
||||
}).expect("Compiler error: unexpected nonempty ext var when deriving Inspect for tag union");
|
||||
|
||||
let mut tag_names_and_payload_sizes: Vec<_> = tags_iter
|
||||
.tags
|
||||
.into_iter()
|
||||
.map(|(name, payload_slice)| {
|
||||
let payload_size = payload_slice.len();
|
||||
(name.clone(), payload_size as _)
|
||||
})
|
||||
.collect();
|
||||
|
||||
tag_names_and_payload_sizes.sort_by(|(t1, _), (t2, _)| t1.cmp(t2));
|
||||
|
||||
Key(FlatInspectableKey::TagUnion(tag_names_and_payload_sizes))
|
||||
}
|
||||
FlatType::FunctionOrTagUnion(names_index, _, _) => {
|
||||
Key(FlatInspectableKey::TagUnion(
|
||||
subs.get_subs_slice(names_index)
|
||||
.iter()
|
||||
.map(|t| (t.clone(), 0))
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
FlatType::EmptyRecord => Key(FlatInspectableKey::Record(Vec::new())),
|
||||
FlatType::EmptyTagUnion => Key(FlatInspectableKey::TagUnion(Vec::new())),
|
||||
FlatType::Func(..) => {
|
||||
Immediate(Symbol::INSPECT_FUNCTION)
|
||||
}
|
||||
FlatType::EmptyTuple => unreachable!("Somehow Inspect derivation got an expression that's an empty tuple, which shouldn't be possible!"),
|
||||
},
|
||||
Content::Alias(sym, _, real_var, kind) => match Self::from_builtin_alias(sym) {
|
||||
Some(lambda) => lambda,
|
||||
|
||||
_ => {
|
||||
match kind {
|
||||
AliasKind::Structural => {
|
||||
Self::from_var(subs, real_var)
|
||||
}
|
||||
// Special case, an unbound `Frac *` will become a `Dec`.
|
||||
AliasKind::Opaque if matches!(*subs.get_content_without_compacting(real_var), Content::FlexVar(_) | Content::FlexAbleVar(_, _)) => {
|
||||
Immediate(Symbol::INSPECT_DEC)
|
||||
}
|
||||
AliasKind::Opaque if sym.is_builtin() => {
|
||||
Self::from_var(subs, real_var)
|
||||
}
|
||||
AliasKind::Opaque => {
|
||||
// There are two cases in which `Inspect` can be derived for an opaque
|
||||
// type.
|
||||
// 1. An opaque type claims to implement `Inspect` and asks us to
|
||||
// auto-derive it. E.g.
|
||||
//
|
||||
// ```text
|
||||
// Op := {} implements [Inspect]
|
||||
// ```
|
||||
//
|
||||
// In this case, we generate a synthetic implementation during
|
||||
// canonicalization that defers to `inspect`ing the inner type. As
|
||||
// such, this case is never reached in this branch.
|
||||
//
|
||||
// 2. An opaque type does not explicitly claim to implement
|
||||
// `Inspect`. In this case, we print a default opaque string for
|
||||
// the opaque type.
|
||||
Immediate(Symbol::INSPECT_OPAQUE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
Content::RangedNumber(range) => {
|
||||
Self::from_var(subs, range.default_compilation_variable())
|
||||
}
|
||||
Content::RecursionVar { structure, .. } => Self::from_var(subs, structure),
|
||||
Content::Error => Key(FlatInspectableKey::Error),
|
||||
Content::FlexVar(_)
|
||||
| Content::RigidVar(_)
|
||||
| Content::FlexAbleVar(_, _)
|
||||
| Content::RigidAbleVar(_, _)
|
||||
| Content::LambdaSet(_) | Content::ErasedLambda => {
|
||||
unreachable!("There must have been a bug in the solver, because we're trying to derive Inspect on a non-concrete type.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn from_builtin_alias(symbol: Symbol) -> Option<FlatInspectable> {
|
||||
use FlatInspectable::*;
|
||||
|
||||
match symbol {
|
||||
Symbol::BOOL_BOOL => Some(Immediate(Symbol::INSPECT_BOOL)),
|
||||
Symbol::NUM_U8 | Symbol::NUM_UNSIGNED8 => Some(Immediate(Symbol::INSPECT_U8)),
|
||||
Symbol::NUM_U16 | Symbol::NUM_UNSIGNED16 => Some(Immediate(Symbol::INSPECT_U16)),
|
||||
Symbol::NUM_U32 | Symbol::NUM_UNSIGNED32 => Some(Immediate(Symbol::INSPECT_U32)),
|
||||
Symbol::NUM_U64 | Symbol::NUM_UNSIGNED64 => Some(Immediate(Symbol::INSPECT_U64)),
|
||||
Symbol::NUM_U128 | Symbol::NUM_UNSIGNED128 => Some(Immediate(Symbol::INSPECT_U128)),
|
||||
Symbol::NUM_I8 | Symbol::NUM_SIGNED8 => Some(Immediate(Symbol::INSPECT_I8)),
|
||||
Symbol::NUM_I16 | Symbol::NUM_SIGNED16 => Some(Immediate(Symbol::INSPECT_I16)),
|
||||
Symbol::NUM_I32 | Symbol::NUM_SIGNED32 => Some(Immediate(Symbol::INSPECT_I32)),
|
||||
Symbol::NUM_I64 | Symbol::NUM_SIGNED64 => Some(Immediate(Symbol::INSPECT_I64)),
|
||||
Symbol::NUM_I128 | Symbol::NUM_SIGNED128 => Some(Immediate(Symbol::INSPECT_I128)),
|
||||
Symbol::NUM_DEC | Symbol::NUM_DECIMAL => Some(Immediate(Symbol::INSPECT_DEC)),
|
||||
Symbol::NUM_F32 | Symbol::NUM_BINARY32 => Some(Immediate(Symbol::INSPECT_F32)),
|
||||
Symbol::NUM_F64 | Symbol::NUM_BINARY64 => Some(Immediate(Symbol::INSPECT_F64)),
|
||||
Symbol::NUM_NAT | Symbol::NUM_NATURAL => Some(Immediate(Symbol::INSPECT_NAT)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,12 +16,14 @@
|
|||
pub mod decoding;
|
||||
pub mod encoding;
|
||||
pub mod hash;
|
||||
pub mod inspect;
|
||||
mod util;
|
||||
|
||||
use decoding::{FlatDecodable, FlatDecodableKey};
|
||||
use encoding::{FlatEncodable, FlatEncodableKey};
|
||||
use hash::{FlatHash, FlatHashKey};
|
||||
|
||||
use inspect::{FlatInspectable, FlatInspectableKey};
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_types::subs::{Subs, Variable};
|
||||
|
||||
|
@ -40,6 +42,7 @@ pub enum DeriveKey {
|
|||
ToEncoder(FlatEncodableKey),
|
||||
Decoder(FlatDecodableKey),
|
||||
Hash(FlatHashKey),
|
||||
ToInspector(FlatInspectableKey),
|
||||
}
|
||||
|
||||
impl DeriveKey {
|
||||
|
@ -48,6 +51,7 @@ impl DeriveKey {
|
|||
DeriveKey::ToEncoder(key) => format!("toEncoder_{}", key.debug_name()),
|
||||
DeriveKey::Decoder(key) => format!("decoder_{}", key.debug_name()),
|
||||
DeriveKey::Hash(key) => format!("hash_{}", key.debug_name()),
|
||||
DeriveKey::ToInspector(key) => format!("toInspector_{}", key.debug_name()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +81,7 @@ pub enum DeriveBuiltin {
|
|||
Decoder,
|
||||
Hash,
|
||||
IsEq,
|
||||
ToInspector,
|
||||
}
|
||||
|
||||
impl TryFrom<Symbol> for DeriveBuiltin {
|
||||
|
@ -88,6 +93,7 @@ impl TryFrom<Symbol> for DeriveBuiltin {
|
|||
Symbol::DECODE_DECODER => Ok(DeriveBuiltin::Decoder),
|
||||
Symbol::HASH_HASH => Ok(DeriveBuiltin::Hash),
|
||||
Symbol::BOOL_IS_EQ => Ok(DeriveBuiltin::IsEq),
|
||||
Symbol::INSPECT_TO_INSPECTOR => Ok(DeriveBuiltin::ToInspector),
|
||||
_ => Err(value),
|
||||
}
|
||||
}
|
||||
|
@ -121,6 +127,10 @@ impl Derived {
|
|||
Symbol::BOOL_STRUCTURAL_EQ,
|
||||
))
|
||||
}
|
||||
DeriveBuiltin::ToInspector => match FlatInspectable::from_var(subs, var) {
|
||||
FlatInspectable::Immediate(imm) => Ok(Derived::Immediate(imm)),
|
||||
FlatInspectable::Key(repr) => Ok(Derived::Key(DeriveKey::ToInspector(repr))),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,6 +161,12 @@ impl Derived {
|
|||
Symbol::BOOL_STRUCTURAL_EQ,
|
||||
))
|
||||
}
|
||||
DeriveBuiltin::ToInspector => {
|
||||
match inspect::FlatInspectable::from_builtin_alias(symbol).unwrap() {
|
||||
FlatInspectable::Immediate(imm) => Ok(Derived::Immediate(imm)),
|
||||
FlatInspectable::Key(repr) => Ok(Derived::Key(DeriveKey::ToInspector(repr))),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,3 +60,7 @@ pub(crate) fn debug_name_tag(tags: &[(TagName, u16)]) -> String {
|
|||
str.push(']');
|
||||
str
|
||||
}
|
||||
|
||||
pub(crate) fn debug_name_fn(arity: u32) -> String {
|
||||
format!("(arity:{arity} -> _)")
|
||||
}
|
||||
|
|
|
@ -62,6 +62,9 @@ impl<'a> Formattable for Expr<'a> {
|
|||
condition.is_multiline() || continuation.is_multiline()
|
||||
}
|
||||
Dbg(condition, continuation) => condition.is_multiline() || continuation.is_multiline(),
|
||||
LowLevelDbg(_, _) => unreachable!(
|
||||
"LowLevelDbg should only exist after desugaring, not during formatting"
|
||||
),
|
||||
|
||||
If(branches, final_else) => {
|
||||
final_else.is_multiline()
|
||||
|
@ -435,6 +438,9 @@ impl<'a> Formattable for Expr<'a> {
|
|||
Dbg(condition, continuation) => {
|
||||
fmt_dbg(buf, condition, continuation, self.is_multiline(), indent);
|
||||
}
|
||||
LowLevelDbg(_, _) => unreachable!(
|
||||
"LowLevelDbg should only exist after desugaring, not during formatting"
|
||||
),
|
||||
If(branches, final_else) => {
|
||||
fmt_if(buf, branches, final_else, self.is_multiline(), indent);
|
||||
}
|
||||
|
|
|
@ -726,6 +726,9 @@ impl<'a> RemoveSpaces<'a> for Expr<'a> {
|
|||
arena.alloc(a.remove_spaces(arena)),
|
||||
arena.alloc(b.remove_spaces(arena)),
|
||||
),
|
||||
Expr::LowLevelDbg(_, _) => unreachable!(
|
||||
"LowLevelDbg should only exist after desugaring, not during formatting"
|
||||
),
|
||||
Expr::Apply(a, b, c) => Expr::Apply(
|
||||
arena.alloc(a.remove_spaces(arena)),
|
||||
b.remove_spaces(arena),
|
||||
|
|
|
@ -365,6 +365,7 @@ impl CallConv<AArch64GeneralReg, AArch64FloatReg, AArch64Assembler> for AArch64C
|
|||
/// 213568: f90033fd str x29, [sp, #96]
|
||||
const SHADOW_SPACE_SIZE: u8 = 16;
|
||||
|
||||
// These are registers that a called function must save and restore if it wants to use them.
|
||||
#[inline(always)]
|
||||
fn general_callee_saved(reg: &AArch64GeneralReg) -> bool {
|
||||
matches!(
|
||||
|
|
|
@ -82,8 +82,8 @@ pub trait CallConv<GeneralReg: RegTrait, FloatReg: RegTrait, ASM: Assembler<Gene
|
|||
|
||||
fn setup_stack(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
general_saved_regs: &[GeneralReg],
|
||||
float_saved_regs: &[FloatReg],
|
||||
saved_general_regs: &[GeneralReg],
|
||||
saved_float_regs: &[FloatReg],
|
||||
requested_stack_size: i32,
|
||||
fn_call_stack_size: i32,
|
||||
) -> i32;
|
||||
|
@ -900,8 +900,11 @@ impl<
|
|||
let mut out = bumpalo::vec![in self.env.arena];
|
||||
|
||||
// Setup stack.
|
||||
let used_general_regs = self.storage_manager.general_used_callee_saved_regs();
|
||||
let used_float_regs = self.storage_manager.float_used_callee_saved_regs();
|
||||
let (used_general_regs, used_float_regs) = self
|
||||
.storage_manager
|
||||
.used_callee_saved_regs
|
||||
.as_vecs(self.env.arena);
|
||||
|
||||
let aligned_stack_size = CC::setup_stack(
|
||||
&mut out,
|
||||
&used_general_regs,
|
||||
|
@ -1199,6 +1202,12 @@ impl<
|
|||
max_branch_stack_size =
|
||||
std::cmp::max(max_branch_stack_size, self.storage_manager.stack_size());
|
||||
base_storage.update_fn_call_stack_size(self.storage_manager.fn_call_stack_size());
|
||||
|
||||
// make sure that used callee-saved registers get saved/restored even if used in only
|
||||
// one of the branches of the switch
|
||||
base_storage
|
||||
.used_callee_saved_regs
|
||||
.extend(&self.storage_manager.used_callee_saved_regs);
|
||||
}
|
||||
self.storage_manager = base_storage;
|
||||
self.literal_map = base_literal_map;
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::{
|
|||
pointer_layouts, sign_extended_int_builtins, single_register_floats,
|
||||
single_register_int_builtins, single_register_integers, single_register_layouts, Env,
|
||||
};
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::collections::{CollectIn, Vec};
|
||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||
use roc_collections::all::{MutMap, MutSet};
|
||||
use roc_error_macros::{internal_error, todo_lambda_erasure};
|
||||
|
@ -118,10 +118,7 @@ pub struct StorageManager<
|
|||
general_used_regs: Vec<'a, (GeneralReg, Symbol)>,
|
||||
float_used_regs: Vec<'a, (FloatReg, Symbol)>,
|
||||
|
||||
// TODO: it probably would be faster to make these a list that linearly scans rather than hashing.
|
||||
// used callee saved regs must be tracked for pushing and popping at the beginning/end of the function.
|
||||
general_used_callee_saved_regs: MutSet<GeneralReg>,
|
||||
float_used_callee_saved_regs: MutSet<FloatReg>,
|
||||
pub(crate) used_callee_saved_regs: UsedCalleeRegisters<GeneralReg, FloatReg>,
|
||||
|
||||
free_stack_chunks: Vec<'a, (i32, u32)>,
|
||||
stack_size: u32,
|
||||
|
@ -152,16 +149,62 @@ pub fn new_storage_manager<
|
|||
join_param_map: MutMap::default(),
|
||||
general_free_regs: bumpalo::vec![in env.arena],
|
||||
general_used_regs: bumpalo::vec![in env.arena],
|
||||
general_used_callee_saved_regs: MutSet::default(),
|
||||
// must be saved on entering a function, and restored before returning
|
||||
used_callee_saved_regs: UsedCalleeRegisters::default(),
|
||||
float_free_regs: bumpalo::vec![in env.arena],
|
||||
float_used_regs: bumpalo::vec![in env.arena],
|
||||
float_used_callee_saved_regs: MutSet::default(),
|
||||
free_stack_chunks: bumpalo::vec![in env.arena],
|
||||
stack_size: 0,
|
||||
fn_call_stack_size: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// optimization idea: use a bitset
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct UsedCalleeRegisters<GeneralReg, FloatReg> {
|
||||
general: MutSet<GeneralReg>,
|
||||
float: MutSet<FloatReg>,
|
||||
}
|
||||
|
||||
impl<GeneralReg: RegTrait, FloatReg: RegTrait> UsedCalleeRegisters<GeneralReg, FloatReg> {
|
||||
fn clear(&mut self) {
|
||||
self.general.clear();
|
||||
self.float.clear();
|
||||
}
|
||||
|
||||
fn insert_general(&mut self, reg: GeneralReg) -> bool {
|
||||
self.general.insert(reg)
|
||||
}
|
||||
|
||||
fn insert_float(&mut self, reg: FloatReg) -> bool {
|
||||
self.float.insert(reg)
|
||||
}
|
||||
|
||||
pub(crate) fn extend(&mut self, other: &Self) {
|
||||
self.general.extend(other.general.iter().copied());
|
||||
self.float.extend(other.float.iter().copied());
|
||||
}
|
||||
|
||||
pub(crate) fn as_vecs<'a>(
|
||||
&self,
|
||||
arena: &'a bumpalo::Bump,
|
||||
) -> (Vec<'a, GeneralReg>, Vec<'a, FloatReg>) {
|
||||
(
|
||||
self.general.iter().copied().collect_in(arena),
|
||||
self.float.iter().copied().collect_in(arena),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<GeneralReg, FloatReg> Default for UsedCalleeRegisters<GeneralReg, FloatReg> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
general: Default::default(),
|
||||
float: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
'a,
|
||||
'r,
|
||||
|
@ -175,16 +218,16 @@ impl<
|
|||
self.symbol_storage_map.clear();
|
||||
self.allocation_map.clear();
|
||||
self.join_param_map.clear();
|
||||
self.general_used_callee_saved_regs.clear();
|
||||
self.used_callee_saved_regs.clear();
|
||||
self.general_free_regs.clear();
|
||||
self.general_used_regs.clear();
|
||||
self.general_free_regs
|
||||
.extend_from_slice(CC::GENERAL_DEFAULT_FREE_REGS);
|
||||
self.float_used_callee_saved_regs.clear();
|
||||
self.float_free_regs.clear();
|
||||
self.float_used_regs.clear();
|
||||
self.float_free_regs
|
||||
.extend_from_slice(CC::FLOAT_DEFAULT_FREE_REGS);
|
||||
self.used_callee_saved_regs.clear();
|
||||
self.free_stack_chunks.clear();
|
||||
self.stack_size = 0;
|
||||
self.fn_call_stack_size = 0;
|
||||
|
@ -198,18 +241,6 @@ impl<
|
|||
self.fn_call_stack_size
|
||||
}
|
||||
|
||||
pub fn general_used_callee_saved_regs(&self) -> Vec<'a, GeneralReg> {
|
||||
let mut used_regs = bumpalo::vec![in self.env.arena];
|
||||
used_regs.extend(&self.general_used_callee_saved_regs);
|
||||
used_regs
|
||||
}
|
||||
|
||||
pub fn float_used_callee_saved_regs(&self) -> Vec<'a, FloatReg> {
|
||||
let mut used_regs = bumpalo::vec![in self.env.arena];
|
||||
used_regs.extend(&self.float_used_callee_saved_regs);
|
||||
used_regs
|
||||
}
|
||||
|
||||
/// Returns true if the symbol is storing a primitive value.
|
||||
pub fn is_stored_primitive(&self, sym: &Symbol) -> bool {
|
||||
matches!(
|
||||
|
@ -223,7 +254,7 @@ impl<
|
|||
fn get_general_reg(&mut self, buf: &mut Vec<'a, u8>) -> GeneralReg {
|
||||
if let Some(reg) = self.general_free_regs.pop() {
|
||||
if CC::general_callee_saved(®) {
|
||||
self.general_used_callee_saved_regs.insert(reg);
|
||||
self.used_callee_saved_regs.insert_general(reg);
|
||||
}
|
||||
reg
|
||||
} else if !self.general_used_regs.is_empty() {
|
||||
|
@ -240,7 +271,7 @@ impl<
|
|||
fn get_float_reg(&mut self, buf: &mut Vec<'a, u8>) -> FloatReg {
|
||||
if let Some(reg) = self.float_free_regs.pop() {
|
||||
if CC::float_callee_saved(®) {
|
||||
self.float_used_callee_saved_regs.insert(reg);
|
||||
self.used_callee_saved_regs.insert_float(reg);
|
||||
}
|
||||
reg
|
||||
} else if !self.float_used_regs.is_empty() {
|
||||
|
|
|
@ -199,6 +199,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Syste
|
|||
];
|
||||
const SHADOW_SPACE_SIZE: u8 = 0;
|
||||
|
||||
// These are registers that a called function must save and restore if it wants to use them.
|
||||
#[inline(always)]
|
||||
fn general_callee_saved(reg: &X86_64GeneralReg) -> bool {
|
||||
matches!(
|
||||
|
@ -1409,6 +1410,8 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Windo
|
|||
];
|
||||
const SHADOW_SPACE_SIZE: u8 = 32;
|
||||
|
||||
// These are registers that a called function must save and restore if it wants to use them.
|
||||
//
|
||||
// Refer https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170#callercallee-saved-registers
|
||||
// > The x64 ABI considers registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15, and XMM6-XMM15 nonvolatile.
|
||||
// > They must be saved and restored by a function that uses them.
|
||||
|
|
|
@ -57,6 +57,14 @@ impl AssemblyBackendMode {
|
|||
AssemblyBackendMode::Repl => true,
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_roc_dbg(self) -> bool {
|
||||
match self {
|
||||
AssemblyBackendMode::Binary => false,
|
||||
AssemblyBackendMode::Test => true,
|
||||
AssemblyBackendMode::Repl => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Env<'a> {
|
||||
|
|
|
@ -296,6 +296,23 @@ fn generate_roc_panic<'a, B: Backend<'a>>(backend: &mut B, output: &mut Object)
|
|||
}
|
||||
}
|
||||
|
||||
fn generate_roc_dbg<'a, B: Backend<'a>>(_backend: &mut B, output: &mut Object) {
|
||||
let text_section = output.section_id(StandardSection::Text);
|
||||
let proc_symbol = Symbol {
|
||||
name: "roc_dbg".as_bytes().to_vec(),
|
||||
value: 0,
|
||||
size: 0,
|
||||
kind: SymbolKind::Text,
|
||||
scope: SymbolScope::Dynamic,
|
||||
weak: false,
|
||||
section: SymbolSection::Section(text_section),
|
||||
flags: SymbolFlags::None,
|
||||
};
|
||||
let _proc_id = output.add_symbol(proc_symbol);
|
||||
// TODO: Actually generate an impl instead of just an empty symbol.
|
||||
// At a minimum, it should just be a ret.
|
||||
}
|
||||
|
||||
fn generate_wrapper<'a, B: Backend<'a>>(
|
||||
backend: &mut B,
|
||||
output: &mut Object,
|
||||
|
@ -412,6 +429,10 @@ fn build_object<'a, B: Backend<'a>>(
|
|||
generate_longjmp(&mut backend, &mut output);
|
||||
}
|
||||
|
||||
if backend.env().mode.generate_roc_dbg() {
|
||||
generate_roc_dbg(&mut backend, &mut output);
|
||||
}
|
||||
|
||||
if backend.env().mode.generate_allocators() {
|
||||
generate_wrapper(
|
||||
&mut backend,
|
||||
|
|
|
@ -897,20 +897,7 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
|
|||
let function = self.module.get_function("roc_panic").unwrap();
|
||||
let tag_id = self.context.i32_type().const_int(tag as u32 as u64, false);
|
||||
|
||||
let msg = match env.target_info.ptr_width() {
|
||||
PtrWidth::Bytes4 => {
|
||||
// we need to pass the message by reference, but we currently hold the value.
|
||||
let alloca = env
|
||||
.builder
|
||||
.new_build_alloca(message.get_type(), "alloca_panic_msg");
|
||||
env.builder.new_build_store(alloca, message);
|
||||
alloca.into()
|
||||
}
|
||||
PtrWidth::Bytes8 => {
|
||||
// string is already held by reference
|
||||
message
|
||||
}
|
||||
};
|
||||
let msg = self.string_to_arg(env, message);
|
||||
|
||||
let call = self
|
||||
.builder
|
||||
|
@ -919,6 +906,45 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
|
|||
call.set_call_convention(C_CALL_CONV);
|
||||
}
|
||||
|
||||
pub fn call_dbg(
|
||||
&self,
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
location: BasicValueEnum<'ctx>,
|
||||
message: BasicValueEnum<'ctx>,
|
||||
) {
|
||||
let function = self.module.get_function("roc_dbg").unwrap();
|
||||
|
||||
let loc = self.string_to_arg(env, location);
|
||||
let msg = self.string_to_arg(env, message);
|
||||
|
||||
let call = self
|
||||
.builder
|
||||
.new_build_call(function, &[loc.into(), msg.into()], "roc_dbg");
|
||||
|
||||
call.set_call_convention(C_CALL_CONV);
|
||||
}
|
||||
|
||||
fn string_to_arg(
|
||||
&self,
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
string: BasicValueEnum<'ctx>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
match env.target_info.ptr_width() {
|
||||
PtrWidth::Bytes4 => {
|
||||
// we need to pass the string by reference, but we currently hold the value.
|
||||
let alloca = env
|
||||
.builder
|
||||
.new_build_alloca(string.get_type(), "alloca_string");
|
||||
env.builder.new_build_store(alloca, string);
|
||||
alloca.into()
|
||||
}
|
||||
PtrWidth::Bytes8 => {
|
||||
// string is already held by reference
|
||||
string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_debug_info(module: &Module<'ctx>) -> (DebugInfoBuilder<'ctx>, DICompileUnit<'ctx>) {
|
||||
module.create_debug_info_builder(
|
||||
true,
|
||||
|
@ -3502,26 +3528,16 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
|
|||
|
||||
Dbg {
|
||||
symbol,
|
||||
variable: specialized_var,
|
||||
variable: _,
|
||||
remainder,
|
||||
} => {
|
||||
if env.mode.runs_expects() {
|
||||
let shared_memory = crate::llvm::expect::SharedMemoryPointer::get(env);
|
||||
let region = unsafe { std::mem::transmute::<_, roc_region::all::Region>(*symbol) };
|
||||
|
||||
crate::llvm::expect::clone_to_shared_memory(
|
||||
env,
|
||||
layout_interner,
|
||||
scope,
|
||||
layout_ids,
|
||||
&shared_memory,
|
||||
*symbol,
|
||||
region,
|
||||
&[*symbol],
|
||||
&[*specialized_var],
|
||||
);
|
||||
|
||||
crate::llvm::expect::notify_parent_dbg(env, &shared_memory);
|
||||
// TODO: Change location to `filename:line_number`
|
||||
// let region = unsafe { std::mem::transmute::<_, roc_region::all::Region>(*symbol) };
|
||||
let location =
|
||||
build_string_literal(env, parent, symbol.module_string(&env.interns));
|
||||
let message = scope.load_symbol(symbol);
|
||||
env.call_dbg(env, location, message);
|
||||
}
|
||||
|
||||
build_exp_stmt(
|
||||
|
|
|
@ -150,16 +150,6 @@ pub(crate) fn notify_parent_expect(env: &Env, shared_memory: &SharedMemoryPointe
|
|||
);
|
||||
}
|
||||
|
||||
pub(crate) fn notify_parent_dbg(env: &Env, shared_memory: &SharedMemoryPointer) {
|
||||
let func = env.module.get_function(bitcode::NOTIFY_PARENT_DBG).unwrap();
|
||||
|
||||
env.builder.new_build_call(
|
||||
func,
|
||||
&[shared_memory.0.into()],
|
||||
"call_expect_failed_finalize",
|
||||
);
|
||||
}
|
||||
|
||||
// Shape of expect frame:
|
||||
//
|
||||
// ===
|
||||
|
|
|
@ -160,6 +160,9 @@ pub fn add_default_roc_externs(env: &Env<'_, '_, '_>) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: generate a valid impl of dbg here.
|
||||
unreachable_function(env, "roc_dbg");
|
||||
|
||||
match env.target_info.operating_system {
|
||||
roc_target::OperatingSystem::Windows => {
|
||||
// We don't need these functions on Windows
|
||||
|
|
|
@ -289,6 +289,11 @@ mod dummy_platform_functions {
|
|||
unimplemented!("It is not valid to call roc panic from within the compiler. Please use the \"platform\" feature if this is a platform.")
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn roc_dbg(_loc: *mut c_void, _msg: *mut c_void) {
|
||||
unimplemented!("It is not valid to call roc dbg from within the compiler. Please use the \"platform\" feature if this is a platform.")
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn roc_memset(_dst: *mut c_void, _c: i32, _n: usize) -> *mut c_void {
|
||||
unimplemented!("It is not valid to call roc memset from within the compiler. Please use the \"platform\" feature if this is a platform.")
|
||||
|
|
|
@ -2252,7 +2252,7 @@ impl<'a> LowLevelCall<'a> {
|
|||
|
||||
fn num_to_str(&self, backend: &mut WasmBackend<'a, '_>) {
|
||||
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
||||
match backend.layout_interner.get_repr(arg_layout) {
|
||||
match backend.layout_interner.runtime_representation(arg_layout) {
|
||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||
self.load_args_and_call_zig(backend, &bitcode::STR_FROM_INT[width])
|
||||
}
|
||||
|
|
|
@ -5982,6 +5982,60 @@ In roc, functions are always written as a lambda, like{}
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn provides_missing_to_in_app_header() {
|
||||
report_header_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
app "broken"
|
||||
provides [main]
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── WEIRD PROVIDES ──────────────────────────────────────── /code/proj/Main.roc ─
|
||||
|
||||
I am partway through parsing a header, but I got stuck here:
|
||||
|
||||
1│ app "broken"
|
||||
2│ provides [main]
|
||||
^
|
||||
|
||||
I am expecting the `to` keyword next, like:
|
||||
|
||||
to pf
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn provides_to_missing_platform_in_app_header() {
|
||||
report_header_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
app "broken"
|
||||
provides [main] to
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── WEIRD PROVIDES ──────────────────────────────────────── /code/proj/Main.roc ─
|
||||
|
||||
I am partway through parsing a header, but I got stuck here:
|
||||
|
||||
1│ app "broken"
|
||||
2│ provides [main] to
|
||||
^
|
||||
|
||||
I am expecting the platform name next, like:
|
||||
|
||||
to pf
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn platform_requires_rigids() {
|
||||
report_header_problem_as(
|
||||
|
@ -9744,7 +9798,7 @@ In roc, functions are always written as a lambda, like{}
|
|||
|
||||
Only builtin abilities can be derived.
|
||||
|
||||
Note: The builtin abilities are `Encoding`, `Decoding`, `Hash`, `Eq`
|
||||
Note: The builtin abilities are `Encoding`, `Decoding`, `Hash`, `Eq`, `Inspect`
|
||||
"###
|
||||
);
|
||||
|
||||
|
|
|
@ -4662,7 +4662,9 @@ pub fn add_imports(
|
|||
|
||||
let mut cached_symbol_vars = VecMap::default();
|
||||
|
||||
for &symbol in &exposed_for_module.imported_values {
|
||||
let imported_values = exposed_for_module.imported_values.iter().copied();
|
||||
|
||||
for symbol in imported_values {
|
||||
import_variable_for_symbol(
|
||||
subs,
|
||||
constraints,
|
||||
|
|
|
@ -53,6 +53,10 @@ pub const DERIVABLE_ABILITIES: &[(Symbol, &[Symbol])] = &[
|
|||
(Symbol::DECODE_DECODING, &[Symbol::DECODE_DECODER]),
|
||||
(Symbol::HASH_HASH_ABILITY, &[Symbol::HASH_HASH]),
|
||||
(Symbol::BOOL_EQ, &[Symbol::BOOL_IS_EQ]),
|
||||
(
|
||||
Symbol::INSPECT_INSPECT_ABILITY,
|
||||
&[Symbol::INSPECT_TO_INSPECTOR],
|
||||
),
|
||||
];
|
||||
|
||||
/// In Debug builds only, Symbol has a name() method that lets
|
||||
|
@ -1609,22 +1613,26 @@ define_builtins! {
|
|||
13 INSPECT_BOOL: "bool"
|
||||
14 INSPECT_STR: "str"
|
||||
15 INSPECT_OPAQUE: "opaque"
|
||||
16 INSPECT_U8: "u8"
|
||||
17 INSPECT_I8: "i8"
|
||||
18 INSPECT_U16: "u16"
|
||||
19 INSPECT_I16: "i16"
|
||||
20 INSPECT_U32: "u32"
|
||||
21 INSPECT_I32: "i32"
|
||||
22 INSPECT_U64: "u64"
|
||||
23 INSPECT_I64: "i64"
|
||||
24 INSPECT_U128: "u128"
|
||||
25 INSPECT_I128: "i128"
|
||||
26 INSPECT_F32: "f32"
|
||||
27 INSPECT_F64: "f64"
|
||||
28 INSPECT_DEC: "dec"
|
||||
29 INSPECT_CUSTOM: "custom"
|
||||
30 INSPECT_APPLY: "apply"
|
||||
31 INSPECT_TO_INSPECTOR: "toInspector"
|
||||
16 INSPECT_FUNCTION: "function"
|
||||
17 INSPECT_U8: "u8"
|
||||
18 INSPECT_I8: "i8"
|
||||
19 INSPECT_U16: "u16"
|
||||
20 INSPECT_I16: "i16"
|
||||
21 INSPECT_U32: "u32"
|
||||
22 INSPECT_I32: "i32"
|
||||
23 INSPECT_U64: "u64"
|
||||
24 INSPECT_I64: "i64"
|
||||
25 INSPECT_U128: "u128"
|
||||
26 INSPECT_I128: "i128"
|
||||
27 INSPECT_F32: "f32"
|
||||
28 INSPECT_F64: "f64"
|
||||
29 INSPECT_DEC: "dec"
|
||||
30 INSPECT_CUSTOM: "custom"
|
||||
31 INSPECT_APPLY: "apply"
|
||||
32 INSPECT_TO_INSPECTOR: "toInspector"
|
||||
33 INSPECT_NAT: "nat"
|
||||
34 INSPECT_DBG_FORMATTER: "DbgFormatter" exposed_type=true
|
||||
35 INSPECT_TO_DBG_STR: "toDbgStr"
|
||||
}
|
||||
15 JSON: "TotallyNotJson" => {
|
||||
0 JSON_JSON: "TotallyNotJson"
|
||||
|
|
|
@ -673,7 +673,25 @@ impl<'a> CallerProc<'a> {
|
|||
|
||||
let argument_layouts = match capture_layout {
|
||||
None => passed_function.argument_layouts,
|
||||
Some(_) => &passed_function.argument_layouts[1..],
|
||||
Some(_capture_layout) => {
|
||||
let capture_layout_index = passed_function.argument_layouts.len() - 1;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
let passed_capture_layout =
|
||||
passed_function.argument_layouts[capture_layout_index];
|
||||
let repr = layout_interner.get_repr(passed_capture_layout);
|
||||
|
||||
if let LayoutRepr::LambdaSet(lambda_set) = repr {
|
||||
assert!(layout_interner
|
||||
.equiv(_capture_layout, lambda_set.runtime_representation()));
|
||||
} else {
|
||||
panic!("unexpected layout for capture argument");
|
||||
}
|
||||
}
|
||||
|
||||
&passed_function.argument_layouts[..capture_layout_index]
|
||||
}
|
||||
};
|
||||
|
||||
let capture_symbol = ARG_SYMBOLS[0];
|
||||
|
|
|
@ -4602,7 +4602,7 @@ pub fn with_hole<'a>(
|
|||
Expect { .. } => unreachable!("I think this is unreachable"),
|
||||
ExpectFx { .. } => unreachable!("I think this is unreachable"),
|
||||
Dbg {
|
||||
loc_condition,
|
||||
loc_message,
|
||||
loc_continuation,
|
||||
variable: cond_variable,
|
||||
symbol: dbg_symbol,
|
||||
|
@ -4622,7 +4622,7 @@ pub fn with_hole<'a>(
|
|||
procs,
|
||||
layout_cache,
|
||||
dbg_symbol,
|
||||
*loc_condition,
|
||||
*loc_message,
|
||||
cond_variable,
|
||||
rest,
|
||||
)
|
||||
|
@ -6020,7 +6020,12 @@ fn compile_struct_like<'a, L, UnusedLayout>(
|
|||
match take_elem_expr(index) {
|
||||
Some((var, loc_expr)) => {
|
||||
match can_reuse_symbol(env, layout_cache, procs, &loc_expr.value, var) {
|
||||
Imported(symbol) | LocalFunction(symbol) | UnspecializedExpr(symbol) => {
|
||||
Imported(symbol) => {
|
||||
// we cannot re-use the symbol in this case; it is used as a value, but defined as a thunk
|
||||
elem_symbols.push(env.unique_symbol());
|
||||
can_elems.push(Field::FunctionOrUnspecialized(symbol, variable));
|
||||
}
|
||||
LocalFunction(symbol) | UnspecializedExpr(symbol) => {
|
||||
elem_symbols.push(symbol);
|
||||
can_elems.push(Field::FunctionOrUnspecialized(symbol, variable));
|
||||
}
|
||||
|
@ -6068,15 +6073,15 @@ fn compile_struct_like<'a, L, UnusedLayout>(
|
|||
Field::ValueSymbol => {
|
||||
// this symbol is already defined; nothing to do
|
||||
}
|
||||
Field::FunctionOrUnspecialized(symbol, variable) => {
|
||||
Field::FunctionOrUnspecialized(can_symbol, variable) => {
|
||||
stmt = specialize_symbol(
|
||||
env,
|
||||
procs,
|
||||
layout_cache,
|
||||
Some(variable),
|
||||
symbol,
|
||||
*symbol,
|
||||
env.arena.alloc(stmt),
|
||||
symbol,
|
||||
can_symbol,
|
||||
);
|
||||
}
|
||||
Field::Field(var, loc_expr) => {
|
||||
|
@ -7132,7 +7137,7 @@ pub fn from_can<'a>(
|
|||
}
|
||||
|
||||
Dbg {
|
||||
loc_condition,
|
||||
loc_message,
|
||||
loc_continuation,
|
||||
variable: cond_variable,
|
||||
symbol: dbg_symbol,
|
||||
|
@ -7144,7 +7149,7 @@ pub fn from_can<'a>(
|
|||
procs,
|
||||
layout_cache,
|
||||
dbg_symbol,
|
||||
*loc_condition,
|
||||
*loc_message,
|
||||
cond_variable,
|
||||
rest,
|
||||
)
|
||||
|
|
|
@ -301,6 +301,8 @@ pub enum Expr<'a> {
|
|||
Backpassing(&'a [Loc<Pattern<'a>>], &'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
|
||||
Expect(&'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
|
||||
Dbg(&'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
|
||||
// This form of debug is a desugared call to roc_dbg
|
||||
LowLevelDbg(&'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
|
||||
|
||||
// Application
|
||||
/// To apply by name, do Apply(Var(...), ...)
|
||||
|
@ -1535,6 +1537,7 @@ impl<'a> Malformed for Expr<'a> {
|
|||
Backpassing(args, call, body) => args.iter().any(|arg| arg.is_malformed()) || call.is_malformed() || body.is_malformed(),
|
||||
Expect(condition, continuation) |
|
||||
Dbg(condition, continuation) => condition.is_malformed() || continuation.is_malformed(),
|
||||
LowLevelDbg(condition, continuation) => condition.is_malformed() || continuation.is_malformed(),
|
||||
Apply(func, args, _) => func.is_malformed() || args.iter().any(|arg| arg.is_malformed()),
|
||||
BinOps(firsts, last) => firsts.iter().any(|(expr, _)| expr.is_malformed()) || last.is_malformed(),
|
||||
UnaryOp(expr, _) => expr.is_malformed(),
|
||||
|
|
|
@ -1933,6 +1933,7 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<
|
|||
| Expr::When(_, _)
|
||||
| Expr::Expect(_, _)
|
||||
| Expr::Dbg(_, _)
|
||||
| Expr::LowLevelDbg(_, _)
|
||||
| Expr::MalformedClosure
|
||||
| Expr::PrecedenceConflict { .. }
|
||||
| Expr::MultipleRecordBuilders { .. }
|
||||
|
|
|
@ -304,6 +304,13 @@ impl ObligationCache {
|
|||
|
||||
Symbol::BOOL_EQ => Some(DeriveEq::is_derivable(self, abilities_store, subs, var)),
|
||||
|
||||
Symbol::INSPECT_INSPECT_ABILITY => Some(DeriveInspect::is_derivable(
|
||||
self,
|
||||
abilities_store,
|
||||
subs,
|
||||
var,
|
||||
)),
|
||||
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
@ -373,7 +380,10 @@ impl ObligationCache {
|
|||
|
||||
let ImplKey { opaque, ability } = impl_key;
|
||||
|
||||
let has_declared_impl = abilities_store.has_declared_implementation(opaque, ability);
|
||||
// Every type has the Inspect ability automatically, even opaques with no `implements` declaration.
|
||||
let is_inspect = ability == Symbol::INSPECT_INSPECT_ABILITY;
|
||||
let has_known_impl =
|
||||
is_inspect || abilities_store.has_declared_implementation(opaque, ability);
|
||||
|
||||
// Some builtins, like Float32 and Bool, would have a cyclic dependency on Encode/Decode/etc.
|
||||
// if their Roc implementations explicitly defined some abilities they support.
|
||||
|
@ -382,18 +392,17 @@ impl ObligationCache {
|
|||
DeriveDecoding::ABILITY => DeriveDecoding::is_derivable_builtin_opaque(opaque),
|
||||
DeriveEq::ABILITY => DeriveEq::is_derivable_builtin_opaque(opaque),
|
||||
DeriveHash::ABILITY => DeriveHash::is_derivable_builtin_opaque(opaque),
|
||||
DeriveInspect::ABILITY => DeriveInspect::is_derivable_builtin_opaque(opaque),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let has_declared_impl = has_declared_impl || builtin_opaque_impl_ok();
|
||||
|
||||
let obligation_result = if !has_declared_impl {
|
||||
let obligation_result = if has_known_impl || builtin_opaque_impl_ok() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Unfulfilled::OpaqueDoesNotImplement {
|
||||
typ: opaque,
|
||||
ability,
|
||||
})
|
||||
} else {
|
||||
Ok(())
|
||||
};
|
||||
|
||||
self.impl_cache.insert(impl_key, obligation_result);
|
||||
|
@ -849,6 +858,93 @@ trait DerivableVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
struct DeriveInspect;
|
||||
impl DerivableVisitor for DeriveInspect {
|
||||
const ABILITY: Symbol = Symbol::INSPECT_INSPECT_ABILITY;
|
||||
const ABILITY_SLICE: SubsSlice<Symbol> = Subs::AB_INSPECT;
|
||||
|
||||
#[inline(always)]
|
||||
fn is_derivable_builtin_opaque(_: Symbol) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_recursion(_var: Variable) -> Result<Descend, NotDerivable> {
|
||||
Ok(Descend(true))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_apply(_: Variable, _: Symbol) -> Result<Descend, NotDerivable> {
|
||||
Ok(Descend(true))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_record(
|
||||
_subs: &Subs,
|
||||
_var: Variable,
|
||||
_fields: RecordFields,
|
||||
) -> Result<Descend, NotDerivable> {
|
||||
Ok(Descend(true))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_tuple(
|
||||
_subs: &Subs,
|
||||
_var: Variable,
|
||||
_elems: TupleElems,
|
||||
) -> Result<Descend, NotDerivable> {
|
||||
Ok(Descend(true))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_tag_union(_var: Variable) -> Result<Descend, NotDerivable> {
|
||||
Ok(Descend(true))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_recursive_tag_union(_var: Variable) -> Result<Descend, NotDerivable> {
|
||||
Ok(Descend(true))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_function_or_tag_union(_var: Variable) -> Result<Descend, NotDerivable> {
|
||||
Ok(Descend(true))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_empty_record(_var: Variable) -> Result<(), NotDerivable> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_empty_tag_union(_var: Variable) -> Result<(), NotDerivable> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_alias(_var: Variable, symbol: Symbol) -> Result<Descend, NotDerivable> {
|
||||
if is_builtin_number_alias(symbol) {
|
||||
Ok(Descend(false))
|
||||
} else {
|
||||
Ok(Descend(true))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_ranged_number(_var: Variable, _range: NumericRange) -> Result<(), NotDerivable> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_floating_point_content(
|
||||
_var: Variable,
|
||||
_subs: &mut Subs,
|
||||
_content_var: Variable,
|
||||
) -> Result<Descend, NotDerivable> {
|
||||
Ok(Descend(false))
|
||||
}
|
||||
}
|
||||
|
||||
struct DeriveEncoding;
|
||||
impl DerivableVisitor for DeriveEncoding {
|
||||
const ABILITY: Symbol = Symbol::ENCODE_ENCODING;
|
||||
|
@ -1392,7 +1488,7 @@ impl AbilityResolver for AbilitiesStore {
|
|||
}
|
||||
}
|
||||
|
||||
/// Whether this a module whose types' ability implementations should be checked via derive_key,
|
||||
/// Whether this is a module whose types' ability implementations should be checked via derive_key,
|
||||
/// because they do not explicitly list ability implementations due to circular dependencies.
|
||||
#[inline]
|
||||
pub(crate) fn builtin_module_with_unlisted_ability_impl(module_id: ModuleId) -> bool {
|
||||
|
|
|
@ -628,29 +628,7 @@ fn make_specialization_decision<P: Phase>(
|
|||
} else {
|
||||
// Solving within a module.
|
||||
phase.with_module_abilities_store(opaque.module_id(), |abilities_store| {
|
||||
let impl_key = ImplKey {
|
||||
opaque: *opaque,
|
||||
ability_member,
|
||||
};
|
||||
match abilities_store.get_implementation(impl_key) {
|
||||
None => {
|
||||
// Doesn't specialize; an error will already be reported for this.
|
||||
SpecializeDecision::Drop
|
||||
}
|
||||
Some(MemberImpl::Error) => {
|
||||
// TODO: probably not right, we may want to choose a derive decision!
|
||||
SpecializeDecision::Specialize(Opaque(*opaque))
|
||||
}
|
||||
Some(MemberImpl::Impl(specialization_symbol)) => {
|
||||
match abilities_store.specialization_info(*specialization_symbol) {
|
||||
Some(_) => SpecializeDecision::Specialize(Opaque(*opaque)),
|
||||
|
||||
// If we expect a specialization impl but don't yet know it, we must hold off
|
||||
// compacting the lambda set until the specialization is well-known.
|
||||
None => SpecializeDecision::PendingSpecialization(impl_key),
|
||||
}
|
||||
}
|
||||
}
|
||||
make_ability_specialization_decision(*opaque, ability_member, abilities_store)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -698,6 +676,46 @@ fn make_specialization_decision<P: Phase>(
|
|||
}
|
||||
}
|
||||
|
||||
fn make_ability_specialization_decision(
|
||||
opaque: Symbol,
|
||||
ability_member: Symbol,
|
||||
abilities_store: &AbilitiesStore,
|
||||
) -> SpecializeDecision {
|
||||
use SpecializationTypeKey::*;
|
||||
let impl_key = ImplKey {
|
||||
opaque,
|
||||
ability_member,
|
||||
};
|
||||
match abilities_store.get_implementation(impl_key) {
|
||||
None => {
|
||||
match ability_member {
|
||||
// Inspect is special - if there is no implementation for the
|
||||
// opaque type, we always emit a default implementation.
|
||||
Symbol::INSPECT_TO_INSPECTOR => {
|
||||
SpecializeDecision::Specialize(Immediate(Symbol::INSPECT_OPAQUE))
|
||||
}
|
||||
_ => {
|
||||
// Doesn't specialize; an error will already be reported for this.
|
||||
SpecializeDecision::Drop
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(MemberImpl::Error) => {
|
||||
// TODO: probably not right, we may want to choose a derive decision!
|
||||
SpecializeDecision::Specialize(Opaque(opaque))
|
||||
}
|
||||
Some(MemberImpl::Impl(specialization_symbol)) => {
|
||||
match abilities_store.specialization_info(*specialization_symbol) {
|
||||
Some(_) => SpecializeDecision::Specialize(Opaque(opaque)),
|
||||
|
||||
// If we expect a specialization impl but don't yet know it, we must hold off
|
||||
// compacting the lambda set until the specialization is well-known.
|
||||
None => SpecializeDecision::PendingSpecialization(impl_key),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn get_specialization_lambda_set_ambient_function<P: Phase>(
|
||||
subs: &mut Subs,
|
||||
|
@ -705,23 +723,29 @@ fn get_specialization_lambda_set_ambient_function<P: Phase>(
|
|||
phase: &P,
|
||||
ability_member: Symbol,
|
||||
lset_region: u8,
|
||||
specialization_key: SpecializationTypeKey,
|
||||
mut specialization_key: SpecializationTypeKey,
|
||||
target_rank: Rank,
|
||||
) -> Result<Variable, ()> {
|
||||
loop {
|
||||
match specialization_key {
|
||||
SpecializationTypeKey::Opaque(opaque) => {
|
||||
let opaque_home = opaque.module_id();
|
||||
let external_specialized_lset =
|
||||
phase.with_module_abilities_store(opaque_home, |abilities_store| {
|
||||
let impl_key = roc_can::abilities::ImplKey {
|
||||
let found = phase.with_module_abilities_store(opaque_home, |abilities_store| {
|
||||
find_opaque_specialization_ambient_function(
|
||||
abilities_store,
|
||||
opaque,
|
||||
ability_member,
|
||||
};
|
||||
lset_region,
|
||||
)
|
||||
});
|
||||
|
||||
let opt_specialization =
|
||||
abilities_store.get_implementation(impl_key);
|
||||
match opt_specialization {
|
||||
None => {
|
||||
let external_specialized_lset = match found {
|
||||
FoundOpaqueSpecialization::UpdatedSpecializationKey(key) => {
|
||||
specialization_key = key;
|
||||
continue;
|
||||
}
|
||||
FoundOpaqueSpecialization::AmbientFunction(lset) => lset,
|
||||
FoundOpaqueSpecialization::NotFound => {
|
||||
if P::IS_LATE {
|
||||
internal_error!(
|
||||
"expected to know a specialization for {:?}#{:?}, but it wasn't found",
|
||||
|
@ -729,25 +753,11 @@ fn get_specialization_lambda_set_ambient_function<P: Phase>(
|
|||
ability_member
|
||||
);
|
||||
} else {
|
||||
// doesn't specialize, we'll have reported an error for this
|
||||
Err(())
|
||||
// We'll have reported an error for this.
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
Some(member_impl) => match member_impl {
|
||||
MemberImpl::Impl(spec_symbol) => {
|
||||
let specialization =
|
||||
abilities_store.specialization_info(*spec_symbol).expect("expected custom implementations to always have complete specialization info by this point");
|
||||
|
||||
let specialized_lambda_set = *specialization
|
||||
.specialization_lambda_sets
|
||||
.get(&lset_region)
|
||||
.unwrap_or_else(|| panic!("lambda set region not resolved: {:?}", (spec_symbol, specialization)));
|
||||
Ok(specialized_lambda_set)
|
||||
}
|
||||
MemberImpl::Error => todo_abilities!(),
|
||||
},
|
||||
}
|
||||
})?;
|
||||
};
|
||||
|
||||
let specialized_ambient = phase.copy_lambda_set_ambient_function_to_home_subs(
|
||||
external_specialized_lset,
|
||||
|
@ -755,7 +765,7 @@ fn get_specialization_lambda_set_ambient_function<P: Phase>(
|
|||
subs,
|
||||
);
|
||||
|
||||
Ok(specialized_ambient)
|
||||
return Ok(specialized_ambient);
|
||||
}
|
||||
|
||||
SpecializationTypeKey::Derived(derive_key) => {
|
||||
|
@ -774,7 +784,7 @@ fn get_specialization_lambda_set_ambient_function<P: Phase>(
|
|||
target_rank,
|
||||
);
|
||||
|
||||
Ok(specialized_ambient)
|
||||
return Ok(specialized_ambient);
|
||||
}
|
||||
|
||||
SpecializationTypeKey::Immediate(imm) => {
|
||||
|
@ -790,7 +800,7 @@ fn get_specialization_lambda_set_ambient_function<P: Phase>(
|
|||
let immediate_lambda_set_at_region =
|
||||
phase.get_and_copy_ability_member_ambient_function(imm, lset_region, subs);
|
||||
|
||||
Ok(immediate_lambda_set_at_region)
|
||||
return Ok(immediate_lambda_set_at_region);
|
||||
}
|
||||
|
||||
SpecializationTypeKey::SingleLambdaSetImmediate(imm) => {
|
||||
|
@ -813,7 +823,55 @@ fn get_specialization_lambda_set_ambient_function<P: Phase>(
|
|||
|
||||
roc_types::subs::instantiate_rigids(subs, imported.variable);
|
||||
|
||||
Ok(imported.variable)
|
||||
return Ok(imported.variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum FoundOpaqueSpecialization {
|
||||
UpdatedSpecializationKey(SpecializationTypeKey),
|
||||
AmbientFunction(Variable),
|
||||
NotFound,
|
||||
}
|
||||
|
||||
fn find_opaque_specialization_ambient_function(
|
||||
abilities_store: &AbilitiesStore,
|
||||
opaque: Symbol,
|
||||
ability_member: Symbol,
|
||||
lset_region: u8,
|
||||
) -> FoundOpaqueSpecialization {
|
||||
let impl_key = roc_can::abilities::ImplKey {
|
||||
opaque,
|
||||
ability_member,
|
||||
};
|
||||
|
||||
let opt_specialization = abilities_store.get_implementation(impl_key);
|
||||
match opt_specialization {
|
||||
None => match ability_member {
|
||||
Symbol::INSPECT_TO_INSPECTOR => FoundOpaqueSpecialization::UpdatedSpecializationKey(
|
||||
SpecializationTypeKey::Immediate(Symbol::INSPECT_OPAQUE),
|
||||
),
|
||||
_ => FoundOpaqueSpecialization::NotFound,
|
||||
},
|
||||
Some(member_impl) => match member_impl {
|
||||
MemberImpl::Impl(spec_symbol) => {
|
||||
let specialization =
|
||||
abilities_store.specialization_info(*spec_symbol).expect("expected custom implementations to always have complete specialization info by this point");
|
||||
|
||||
let specialized_lambda_set = *specialization
|
||||
.specialization_lambda_sets
|
||||
.get(&lset_region)
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"lambda set region not resolved: {:?}",
|
||||
(spec_symbol, specialization)
|
||||
)
|
||||
});
|
||||
|
||||
FoundOpaqueSpecialization::AmbientFunction(specialized_lambda_set)
|
||||
}
|
||||
MemberImpl::Error => todo_abilities!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,6 +68,11 @@ fn module_source_and_path(builtin: DeriveBuiltin) -> (ModuleId, &'static str, Pa
|
|||
module_source(ModuleId::BOOL),
|
||||
builtins_path.join("Bool.roc"),
|
||||
),
|
||||
DeriveBuiltin::ToInspector => (
|
||||
ModuleId::INSPECT,
|
||||
module_source(ModuleId::INSPECT),
|
||||
builtins_path.join("Inspect.roc"),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2180,3 +2180,150 @@ fn issue_4772_weakened_monomorphic_destructure() {
|
|||
)
|
||||
})
|
||||
}
|
||||
|
||||
mod inspect {
|
||||
#[cfg(feature = "gen-llvm")]
|
||||
use crate::helpers::llvm::assert_evals_to;
|
||||
|
||||
#[cfg(feature = "gen-wasm")]
|
||||
use crate::helpers::wasm::assert_evals_to;
|
||||
|
||||
#[cfg(all(test, any(feature = "gen-llvm", feature = "gen-wasm")))]
|
||||
use indoc::indoc;
|
||||
|
||||
#[cfg(all(test, any(feature = "gen-llvm", feature = "gen-wasm")))]
|
||||
use roc_std::RocStr;
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn bool() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
main = [
|
||||
Inspect.inspect Bool.true,
|
||||
Inspect.inspect Bool.false,
|
||||
] |> List.map Inspect.toDbgStr |> Str.joinWith ", "
|
||||
"#
|
||||
),
|
||||
RocStr::from("Bool.true, Bool.false"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn num() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
main = [
|
||||
Inspect.inspect 0, # Num a
|
||||
Inspect.inspect 1u8, # U8
|
||||
Inspect.inspect 2i8, # I8
|
||||
Inspect.inspect 3u16, # U16
|
||||
Inspect.inspect 4i16, # I16
|
||||
Inspect.inspect 5u32, # U32
|
||||
Inspect.inspect 6i32, # I32
|
||||
Inspect.inspect 7u64, # U64
|
||||
Inspect.inspect 8i64, # I64
|
||||
Inspect.inspect 9u128, # U128
|
||||
Inspect.inspect 10i128, # I128
|
||||
Inspect.inspect 0.5, # Frac a
|
||||
Inspect.inspect 1.5f32, # F32
|
||||
Inspect.inspect 2.2f64, # F64
|
||||
Inspect.inspect (1.1dec + 2.2), # Dec
|
||||
] |> List.map Inspect.toDbgStr |> Str.joinWith ", "
|
||||
"#
|
||||
),
|
||||
RocStr::from("0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0.5, 1.5, 2.2, 3.3"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn list() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
main = [
|
||||
Inspect.inspect [0, 1, 2], # List (Num *)
|
||||
Inspect.inspect [1, 0x2, 3], # List (Int *)
|
||||
Inspect.inspect [0.1 + 0.2, 0.4], # List (Frac *)
|
||||
Inspect.inspect [1u8, 2u8], # List U8
|
||||
Inspect.inspect ["foo"], # List Str
|
||||
] |> List.map Inspect.toDbgStr |> Str.joinWith ", "
|
||||
"#
|
||||
),
|
||||
RocStr::from("[0, 1, 2], [1, 2, 3], [0.3, 0.4], [1, 2], [\"foo\"]"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn str() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
main = [
|
||||
Inspect.inspect "",
|
||||
Inspect.inspect "a small string",
|
||||
Inspect.inspect "an extraordinarily long string - so long it's on the heap!",
|
||||
] |> List.map Inspect.toDbgStr |> Str.joinWith ", "
|
||||
"#
|
||||
),
|
||||
RocStr::from(
|
||||
r#""", "a small string", "an extraordinarily long string - so long it's on the heap!""#
|
||||
),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn opaque_automatic() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
Op := {}
|
||||
|
||||
main = Inspect.toDbgStr (Inspect.inspect (@Op {}))
|
||||
"#
|
||||
),
|
||||
RocStr::from(r#"<opaque>"#),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn opaque_automatic_with_polymorphic_call() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
Op := {}
|
||||
|
||||
late = \a -> Inspect.toDbgStr (Inspect.inspect a)
|
||||
|
||||
main = late (@Op {})
|
||||
"#
|
||||
),
|
||||
RocStr::from(r#"<opaque>"#),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4630,3 +4630,36 @@ fn many_arguments() {
|
|||
i64
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn multiple_uses_of_bool_true_record() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
(Bool.true, Bool.true).0
|
||||
"#
|
||||
),
|
||||
true,
|
||||
bool
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn multiple_uses_of_bool_true_tag_union() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
x : [ One Bool Bool, Empty ]
|
||||
x = One Bool.true Bool.true
|
||||
|
||||
when x is
|
||||
One a _ -> a
|
||||
Empty -> Bool.false
|
||||
"#
|
||||
),
|
||||
true,
|
||||
bool
|
||||
);
|
||||
}
|
||||
|
|
|
@ -132,6 +132,9 @@ void roc_panic(void* msg, unsigned int panic_tag)
|
|||
exit(101);
|
||||
}
|
||||
|
||||
// TODO: add a way to send dbg to rust.
|
||||
void roc_debug(void* loc, void* msg) {}
|
||||
|
||||
//--------------------------
|
||||
|
||||
void *roc_memset(void *str, int c, size_t n)
|
||||
|
|
|
@ -2,8 +2,48 @@ procedure Bool.2 ():
|
|||
let Bool.23 : Int1 = true;
|
||||
ret Bool.23;
|
||||
|
||||
procedure Inspect.249 (Inspect.250, Inspect.248):
|
||||
let Inspect.323 : Str = "\"";
|
||||
let Inspect.322 : Str = CallByName Inspect.61 Inspect.250 Inspect.323;
|
||||
let Inspect.318 : Str = CallByName Inspect.61 Inspect.322 Inspect.248;
|
||||
let Inspect.319 : Str = "\"";
|
||||
let Inspect.317 : Str = CallByName Inspect.61 Inspect.318 Inspect.319;
|
||||
ret Inspect.317;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.35 (Inspect.300):
|
||||
ret Inspect.300;
|
||||
|
||||
procedure Inspect.36 (Inspect.304):
|
||||
let Inspect.311 : Str = "";
|
||||
ret Inspect.311;
|
||||
|
||||
procedure Inspect.44 (Inspect.248):
|
||||
let Inspect.313 : Str = CallByName Inspect.30 Inspect.248;
|
||||
ret Inspect.313;
|
||||
|
||||
procedure Inspect.5 (Inspect.150):
|
||||
let Inspect.312 : Str = CallByName Inspect.44 Inspect.150;
|
||||
let Inspect.309 : {} = Struct {};
|
||||
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
|
||||
let Inspect.307 : Str = CallByName Inspect.249 Inspect.308 Inspect.312;
|
||||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.61 (Inspect.303, Inspect.298):
|
||||
let Inspect.321 : Str = CallByName Str.3 Inspect.303 Inspect.298;
|
||||
dec Inspect.298;
|
||||
ret Inspect.321;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.292;
|
||||
|
||||
procedure Test.1 ():
|
||||
let Test.0 : Str = "";
|
||||
let Test.5 : Str = "";
|
||||
let Test.4 : Str = CallByName Inspect.5 Test.5;
|
||||
let Test.0 : Str = CallByName Inspect.35 Test.4;
|
||||
dbg Test.0;
|
||||
dec Test.0;
|
||||
let Test.3 : Int1 = CallByName Bool.2;
|
||||
|
|
|
@ -1,5 +1,45 @@
|
|||
procedure Inspect.249 (Inspect.250, Inspect.248):
|
||||
let Inspect.323 : Str = "\"";
|
||||
let Inspect.322 : Str = CallByName Inspect.61 Inspect.250 Inspect.323;
|
||||
let Inspect.318 : Str = CallByName Inspect.61 Inspect.322 Inspect.248;
|
||||
let Inspect.319 : Str = "\"";
|
||||
let Inspect.317 : Str = CallByName Inspect.61 Inspect.318 Inspect.319;
|
||||
ret Inspect.317;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.35 (Inspect.300):
|
||||
ret Inspect.300;
|
||||
|
||||
procedure Inspect.36 (Inspect.304):
|
||||
let Inspect.311 : Str = "";
|
||||
ret Inspect.311;
|
||||
|
||||
procedure Inspect.44 (Inspect.248):
|
||||
let Inspect.313 : Str = CallByName Inspect.30 Inspect.248;
|
||||
ret Inspect.313;
|
||||
|
||||
procedure Inspect.5 (Inspect.150):
|
||||
let Inspect.312 : Str = CallByName Inspect.44 Inspect.150;
|
||||
let Inspect.309 : {} = Struct {};
|
||||
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
|
||||
let Inspect.307 : Str = CallByName Inspect.249 Inspect.308 Inspect.312;
|
||||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.61 (Inspect.303, Inspect.298):
|
||||
let Inspect.321 : Str = CallByName Str.3 Inspect.303 Inspect.298;
|
||||
dec Inspect.298;
|
||||
ret Inspect.321;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.292;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.1 : Str = "";
|
||||
let Test.4 : Str = "";
|
||||
let Test.3 : Str = CallByName Inspect.5 Test.4;
|
||||
let Test.1 : Str = CallByName Inspect.35 Test.3;
|
||||
dbg Test.1;
|
||||
dec Test.1;
|
||||
let Test.2 : I64 = 42i64;
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
procedure Dict.1 (Dict.554):
|
||||
let Dict.563 : List {[], []} = Array [];
|
||||
procedure Dict.1 (Dict.557):
|
||||
let Dict.567 : List {[], []} = Array [];
|
||||
let Dict.574 : U64 = 0i64;
|
||||
let Dict.575 : U64 = 8i64;
|
||||
let Dict.568 : List U64 = CallByName List.11 Dict.574 Dict.575;
|
||||
let Dict.571 : I8 = CallByName Dict.40;
|
||||
let Dict.572 : U64 = 8i64;
|
||||
let Dict.569 : List I8 = CallByName List.11 Dict.571 Dict.572;
|
||||
let Dict.570 : U64 = 0i64;
|
||||
let Dict.571 : U64 = 8i64;
|
||||
let Dict.564 : List U64 = CallByName List.11 Dict.570 Dict.571;
|
||||
let Dict.567 : I8 = CallByName Dict.39;
|
||||
let Dict.568 : U64 = 8i64;
|
||||
let Dict.565 : List I8 = CallByName List.11 Dict.567 Dict.568;
|
||||
let Dict.566 : U64 = 0i64;
|
||||
let Dict.562 : {List {[], []}, List U64, List I8, U64} = Struct {Dict.563, Dict.564, Dict.565, Dict.566};
|
||||
ret Dict.562;
|
||||
let Dict.566 : {List {[], []}, List U64, List I8, U64} = Struct {Dict.567, Dict.568, Dict.569, Dict.570};
|
||||
ret Dict.566;
|
||||
|
||||
procedure Dict.39 ():
|
||||
let Dict.569 : I8 = -128i64;
|
||||
ret Dict.569;
|
||||
|
||||
procedure Dict.4 (Dict.560):
|
||||
let Dict.101 : U64 = StructAtIndex 3 Dict.560;
|
||||
let #Derived_gen.8 : List {[], []} = StructAtIndex 0 Dict.560;
|
||||
procedure Dict.4 (Dict.564):
|
||||
let Dict.105 : U64 = StructAtIndex 3 Dict.564;
|
||||
let #Derived_gen.8 : List {[], []} = StructAtIndex 0 Dict.564;
|
||||
dec #Derived_gen.8;
|
||||
let #Derived_gen.7 : List U64 = StructAtIndex 1 Dict.560;
|
||||
let #Derived_gen.7 : List U64 = StructAtIndex 1 Dict.564;
|
||||
dec #Derived_gen.7;
|
||||
let #Derived_gen.6 : List I8 = StructAtIndex 2 Dict.560;
|
||||
let #Derived_gen.6 : List I8 = StructAtIndex 2 Dict.564;
|
||||
dec #Derived_gen.6;
|
||||
ret Dict.101;
|
||||
ret Dict.105;
|
||||
|
||||
procedure Dict.40 ():
|
||||
let Dict.573 : I8 = -128i64;
|
||||
ret Dict.573;
|
||||
|
||||
procedure List.11 (List.133, List.134):
|
||||
let List.554 : List I8 = CallByName List.68 List.134;
|
||||
|
|
1202
crates/compiler/test_mono/generated/inspect_derived_dict.txt
Normal file
1202
crates/compiler/test_mono/generated/inspect_derived_dict.txt
Normal file
File diff suppressed because it is too large
Load diff
172
crates/compiler/test_mono/generated/inspect_derived_list.txt
Normal file
172
crates/compiler/test_mono/generated/inspect_derived_list.txt
Normal file
|
@ -0,0 +1,172 @@
|
|||
procedure #Derived.0 (#Derived.1):
|
||||
let #Derived_gen.0 : List I64 = CallByName Inspect.30 #Derived.1;
|
||||
ret #Derived_gen.0;
|
||||
|
||||
procedure #Derived.3 (#Derived.2):
|
||||
let #Derived_gen.7 : I64 = CallByName Inspect.54 #Derived.2;
|
||||
ret #Derived_gen.7;
|
||||
|
||||
procedure #Derived.4 (#Derived.5, #Derived.1):
|
||||
let #Derived_gen.5 : {} = Struct {};
|
||||
let #Derived_gen.6 : {} = Struct {};
|
||||
let #Derived_gen.4 : {List I64, {}, {}} = CallByName Inspect.37 #Derived.1 #Derived_gen.5 #Derived_gen.6;
|
||||
let #Derived_gen.3 : Str = CallByName Inspect.31 #Derived_gen.4 #Derived.5;
|
||||
ret #Derived_gen.3;
|
||||
|
||||
procedure Bool.1 ():
|
||||
let Bool.24 : Int1 = false;
|
||||
ret Bool.24;
|
||||
|
||||
procedure Bool.2 ():
|
||||
let Bool.23 : Int1 = true;
|
||||
ret Bool.23;
|
||||
|
||||
procedure Inspect.155 (Inspect.156, #Attr.12):
|
||||
let Inspect.154 : {} = StructAtIndex 2 #Attr.12;
|
||||
let Inspect.153 : {} = StructAtIndex 1 #Attr.12;
|
||||
let Inspect.152 : List I64 = StructAtIndex 0 #Attr.12;
|
||||
let Inspect.347 : Str = "[";
|
||||
let Inspect.328 : Str = CallByName Inspect.61 Inspect.156 Inspect.347;
|
||||
let Inspect.329 : {List I64, {}, {}} = Struct {Inspect.152, Inspect.153, Inspect.154};
|
||||
let Inspect.324 : {Str, Int1} = CallByName Inspect.157 Inspect.328 Inspect.329;
|
||||
let Inspect.325 : {} = Struct {};
|
||||
let Inspect.320 : Str = CallByName Inspect.166 Inspect.324;
|
||||
let Inspect.321 : Str = "]";
|
||||
let Inspect.319 : Str = CallByName Inspect.61 Inspect.320 Inspect.321;
|
||||
ret Inspect.319;
|
||||
|
||||
procedure Inspect.157 (Inspect.158, #Attr.12):
|
||||
let Inspect.154 : {} = StructAtIndex 2 #Attr.12;
|
||||
let Inspect.153 : {} = StructAtIndex 1 #Attr.12;
|
||||
let Inspect.152 : List I64 = StructAtIndex 0 #Attr.12;
|
||||
let Inspect.346 : Int1 = CallByName Bool.1;
|
||||
let Inspect.332 : {Str, Int1} = Struct {Inspect.158, Inspect.346};
|
||||
let Inspect.331 : {Str, Int1} = CallByName List.18 Inspect.152 Inspect.332 Inspect.154;
|
||||
ret Inspect.331;
|
||||
|
||||
procedure Inspect.159 (Inspect.334, Inspect.162, Inspect.154):
|
||||
let Inspect.160 : Str = StructAtIndex 0 Inspect.334;
|
||||
let Inspect.161 : Int1 = StructAtIndex 1 Inspect.334;
|
||||
joinpoint Inspect.344 Inspect.163:
|
||||
let Inspect.341 : I64 = CallByName #Derived.3 Inspect.162;
|
||||
let Inspect.337 : Str = CallByName Inspect.31 Inspect.341 Inspect.163;
|
||||
let Inspect.338 : {} = Struct {};
|
||||
let Inspect.336 : {Str, Int1} = CallByName Inspect.164 Inspect.337;
|
||||
ret Inspect.336;
|
||||
in
|
||||
if Inspect.161 then
|
||||
let Inspect.345 : Str = ", ";
|
||||
let Inspect.343 : Str = CallByName Inspect.61 Inspect.160 Inspect.345;
|
||||
jump Inspect.344 Inspect.343;
|
||||
else
|
||||
jump Inspect.344 Inspect.160;
|
||||
|
||||
procedure Inspect.164 (Inspect.165):
|
||||
let Inspect.340 : Int1 = CallByName Bool.2;
|
||||
let Inspect.339 : {Str, Int1} = Struct {Inspect.165, Inspect.340};
|
||||
ret Inspect.339;
|
||||
|
||||
procedure Inspect.166 (Inspect.326):
|
||||
let Inspect.327 : Str = StructAtIndex 0 Inspect.326;
|
||||
ret Inspect.327;
|
||||
|
||||
procedure Inspect.277 (Inspect.278, Inspect.276):
|
||||
let Inspect.353 : Str = CallByName Num.96 Inspect.276;
|
||||
let Inspect.352 : Str = CallByName Inspect.61 Inspect.278 Inspect.353;
|
||||
ret Inspect.352;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.314 : Str = CallByName Inspect.155 Inspect.149 Inspect.305;
|
||||
ret Inspect.314;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.342 : Str = CallByName Inspect.277 Inspect.149 Inspect.305;
|
||||
ret Inspect.342;
|
||||
|
||||
procedure Inspect.35 (Inspect.300):
|
||||
ret Inspect.300;
|
||||
|
||||
procedure Inspect.36 (Inspect.304):
|
||||
let Inspect.311 : Str = "";
|
||||
ret Inspect.311;
|
||||
|
||||
procedure Inspect.37 (Inspect.152, Inspect.153, Inspect.154):
|
||||
let Inspect.316 : {List I64, {}, {}} = Struct {Inspect.152, Inspect.153, Inspect.154};
|
||||
let Inspect.315 : {List I64, {}, {}} = CallByName Inspect.30 Inspect.316;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.5 (Inspect.150):
|
||||
let Inspect.312 : List I64 = CallByName #Derived.0 Inspect.150;
|
||||
let Inspect.309 : {} = Struct {};
|
||||
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
|
||||
let Inspect.307 : Str = CallByName #Derived.4 Inspect.308 Inspect.312;
|
||||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.54 (Inspect.276):
|
||||
let Inspect.348 : I64 = CallByName Inspect.30 Inspect.276;
|
||||
ret Inspect.348;
|
||||
|
||||
procedure Inspect.61 (Inspect.303, Inspect.298):
|
||||
let Inspect.323 : Str = CallByName Str.3 Inspect.303 Inspect.298;
|
||||
dec Inspect.298;
|
||||
ret Inspect.323;
|
||||
|
||||
procedure List.18 (List.154, List.155, List.156):
|
||||
let List.554 : U64 = 0i64;
|
||||
let List.555 : U64 = CallByName List.6 List.154;
|
||||
let List.553 : {Str, Int1} = CallByName List.88 List.154 List.155 List.156 List.554 List.555;
|
||||
ret List.553;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.564 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.564;
|
||||
|
||||
procedure List.66 (#Attr.2, #Attr.3):
|
||||
let List.563 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.563;
|
||||
|
||||
procedure List.88 (#Derived_gen.17, #Derived_gen.18, #Derived_gen.19, #Derived_gen.20, #Derived_gen.21):
|
||||
joinpoint List.556 List.157 List.158 List.159 List.160 List.161:
|
||||
let List.558 : Int1 = CallByName Num.22 List.160 List.161;
|
||||
if List.558 then
|
||||
let List.562 : I64 = CallByName List.66 List.157 List.160;
|
||||
let List.162 : {Str, Int1} = CallByName Inspect.159 List.158 List.562 List.159;
|
||||
let List.561 : U64 = 1i64;
|
||||
let List.560 : U64 = CallByName Num.51 List.160 List.561;
|
||||
jump List.556 List.157 List.162 List.159 List.560 List.161;
|
||||
else
|
||||
dec List.157;
|
||||
ret List.158;
|
||||
in
|
||||
jump List.556 #Derived_gen.17 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.293 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
ret Num.293;
|
||||
|
||||
procedure Num.51 (#Attr.2, #Attr.3):
|
||||
let Num.292 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
|
||||
ret Num.292;
|
||||
|
||||
procedure Num.96 (#Attr.2):
|
||||
let Num.291 : Str = lowlevel NumToStr #Attr.2;
|
||||
ret Num.291;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.292;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.3 : List I64 = Array [1i64, 2i64, 3i64];
|
||||
let Test.2 : Str = CallByName Inspect.5 Test.3;
|
||||
let Test.1 : Str = CallByName Inspect.35 Test.2;
|
||||
ret Test.1;
|
|
@ -0,0 +1,274 @@
|
|||
procedure #Derived.0 (#Derived.1):
|
||||
let #Derived_gen.0 : Str = CallByName Inspect.30 #Derived.1;
|
||||
ret #Derived_gen.0;
|
||||
|
||||
procedure #Derived.2 (#Derived.3, #Derived.1):
|
||||
let #Derived_gen.7 : Str = "a";
|
||||
let #Derived_gen.8 : Str = CallByName #Derived.4 #Derived.1;
|
||||
let #Derived_gen.6 : {Str, Str} = Struct {#Derived_gen.7, #Derived_gen.8};
|
||||
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6];
|
||||
let #Derived_gen.4 : List {Str, Str} = CallByName Inspect.42 #Derived_gen.5;
|
||||
let #Derived_gen.3 : Str = CallByName Inspect.31 #Derived_gen.4 #Derived.3;
|
||||
ret #Derived_gen.3;
|
||||
|
||||
procedure #Derived.4 (#Derived.5):
|
||||
let #Derived_gen.10 : Str = CallByName Inspect.30 #Derived.5;
|
||||
ret #Derived_gen.10;
|
||||
|
||||
procedure #Derived.6 (#Derived.7, #Derived.5):
|
||||
let #Derived_gen.17 : Str = "b";
|
||||
let #Derived_gen.18 : Str = CallByName Inspect.44 #Derived.5;
|
||||
let #Derived_gen.16 : {Str, Str} = Struct {#Derived_gen.17, #Derived_gen.18};
|
||||
let #Derived_gen.15 : List {Str, Str} = Array [#Derived_gen.16];
|
||||
let #Derived_gen.14 : List {Str, Str} = CallByName Inspect.42 #Derived_gen.15;
|
||||
let #Derived_gen.13 : Str = CallByName Inspect.31 #Derived_gen.14 #Derived.7;
|
||||
ret #Derived_gen.13;
|
||||
|
||||
procedure Bool.1 ():
|
||||
let Bool.26 : Int1 = false;
|
||||
ret Bool.26;
|
||||
|
||||
procedure Bool.2 ():
|
||||
let Bool.25 : Int1 = true;
|
||||
ret Bool.25;
|
||||
|
||||
procedure Inspect.228 (Inspect.229, Inspect.227):
|
||||
let Inspect.352 : Str = "{";
|
||||
let Inspect.328 : Str = CallByName Inspect.61 Inspect.229 Inspect.352;
|
||||
let Inspect.324 : {Str, Int1} = CallByName Inspect.230 Inspect.328 Inspect.227;
|
||||
let Inspect.325 : {} = Struct {};
|
||||
let Inspect.320 : Str = CallByName Inspect.242 Inspect.324;
|
||||
let Inspect.321 : Str = "}";
|
||||
let Inspect.319 : Str = CallByName Inspect.61 Inspect.320 Inspect.321;
|
||||
ret Inspect.319;
|
||||
|
||||
procedure Inspect.228 (Inspect.229, Inspect.227):
|
||||
let Inspect.392 : Str = "{";
|
||||
let Inspect.368 : Str = CallByName Inspect.61 Inspect.229 Inspect.392;
|
||||
let Inspect.364 : {Str, Int1} = CallByName Inspect.230 Inspect.368 Inspect.227;
|
||||
let Inspect.365 : {} = Struct {};
|
||||
let Inspect.360 : Str = CallByName Inspect.242 Inspect.364;
|
||||
let Inspect.361 : Str = "}";
|
||||
let Inspect.359 : Str = CallByName Inspect.61 Inspect.360 Inspect.361;
|
||||
ret Inspect.359;
|
||||
|
||||
procedure Inspect.230 (Inspect.231, Inspect.227):
|
||||
let Inspect.351 : Int1 = CallByName Bool.1;
|
||||
let Inspect.332 : {Str, Int1} = Struct {Inspect.231, Inspect.351};
|
||||
let Inspect.333 : {} = Struct {};
|
||||
let Inspect.331 : {Str, Int1} = CallByName List.18 Inspect.227 Inspect.332 Inspect.333;
|
||||
ret Inspect.331;
|
||||
|
||||
procedure Inspect.230 (Inspect.231, Inspect.227):
|
||||
let Inspect.391 : Int1 = CallByName Bool.1;
|
||||
let Inspect.372 : {Str, Int1} = Struct {Inspect.231, Inspect.391};
|
||||
let Inspect.373 : {} = Struct {};
|
||||
let Inspect.371 : {Str, Int1} = CallByName List.18 Inspect.227 Inspect.372 Inspect.373;
|
||||
ret Inspect.371;
|
||||
|
||||
procedure Inspect.232 (Inspect.334, Inspect.335):
|
||||
let Inspect.235 : Str = StructAtIndex 0 Inspect.335;
|
||||
let Inspect.236 : Str = StructAtIndex 1 Inspect.335;
|
||||
let Inspect.233 : Str = StructAtIndex 0 Inspect.334;
|
||||
let Inspect.234 : Int1 = StructAtIndex 1 Inspect.334;
|
||||
joinpoint Inspect.349 Inspect.237:
|
||||
let Inspect.346 : Str = CallByName Inspect.61 Inspect.237 Inspect.235;
|
||||
let Inspect.347 : Str = ": ";
|
||||
let Inspect.341 : Str = CallByName Inspect.61 Inspect.346 Inspect.347;
|
||||
let Inspect.337 : Str = CallByName Inspect.238 Inspect.341 Inspect.236;
|
||||
let Inspect.338 : {} = Struct {};
|
||||
let Inspect.336 : {Str, Int1} = CallByName Inspect.240 Inspect.337;
|
||||
ret Inspect.336;
|
||||
in
|
||||
if Inspect.234 then
|
||||
let Inspect.350 : Str = ", ";
|
||||
let Inspect.348 : Str = CallByName Inspect.61 Inspect.233 Inspect.350;
|
||||
jump Inspect.349 Inspect.348;
|
||||
else
|
||||
jump Inspect.349 Inspect.233;
|
||||
|
||||
procedure Inspect.232 (Inspect.334, Inspect.335):
|
||||
let Inspect.235 : Str = StructAtIndex 0 Inspect.335;
|
||||
let Inspect.236 : Str = StructAtIndex 1 Inspect.335;
|
||||
let Inspect.233 : Str = StructAtIndex 0 Inspect.334;
|
||||
let Inspect.234 : Int1 = StructAtIndex 1 Inspect.334;
|
||||
joinpoint Inspect.389 Inspect.237:
|
||||
let Inspect.386 : Str = CallByName Inspect.61 Inspect.237 Inspect.235;
|
||||
let Inspect.387 : Str = ": ";
|
||||
let Inspect.381 : Str = CallByName Inspect.61 Inspect.386 Inspect.387;
|
||||
let Inspect.377 : Str = CallByName Inspect.238 Inspect.381 Inspect.236;
|
||||
let Inspect.378 : {} = Struct {};
|
||||
let Inspect.376 : {Str, Int1} = CallByName Inspect.240 Inspect.377;
|
||||
ret Inspect.376;
|
||||
in
|
||||
if Inspect.234 then
|
||||
let Inspect.390 : Str = ", ";
|
||||
let Inspect.388 : Str = CallByName Inspect.61 Inspect.233 Inspect.390;
|
||||
jump Inspect.389 Inspect.388;
|
||||
else
|
||||
jump Inspect.389 Inspect.233;
|
||||
|
||||
procedure Inspect.238 (Inspect.239, Inspect.236):
|
||||
let Inspect.344 : Str = CallByName Inspect.31 Inspect.236 Inspect.239;
|
||||
ret Inspect.344;
|
||||
|
||||
procedure Inspect.238 (Inspect.239, Inspect.236):
|
||||
let Inspect.384 : Str = CallByName Inspect.31 Inspect.236 Inspect.239;
|
||||
ret Inspect.384;
|
||||
|
||||
procedure Inspect.240 (Inspect.241):
|
||||
let Inspect.380 : Int1 = CallByName Bool.2;
|
||||
let Inspect.379 : {Str, Int1} = Struct {Inspect.241, Inspect.380};
|
||||
ret Inspect.379;
|
||||
|
||||
procedure Inspect.242 (Inspect.326):
|
||||
let Inspect.367 : Str = StructAtIndex 0 Inspect.326;
|
||||
ret Inspect.367;
|
||||
|
||||
procedure Inspect.249 (Inspect.250, Inspect.248):
|
||||
let Inspect.401 : Str = "\"";
|
||||
let Inspect.400 : Str = CallByName Inspect.61 Inspect.250 Inspect.401;
|
||||
let Inspect.398 : Str = CallByName Inspect.61 Inspect.400 Inspect.248;
|
||||
let Inspect.399 : Str = "\"";
|
||||
let Inspect.397 : Str = CallByName Inspect.61 Inspect.398 Inspect.399;
|
||||
ret Inspect.397;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.314 : Str = CallByName Inspect.228 Inspect.149 Inspect.305;
|
||||
ret Inspect.314;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.345 : Str = CallByName #Derived.6 Inspect.149 Inspect.305;
|
||||
ret Inspect.345;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.354 : Str = CallByName Inspect.228 Inspect.149 Inspect.305;
|
||||
ret Inspect.354;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.385 : Str = CallByName Inspect.249 Inspect.149 Inspect.305;
|
||||
ret Inspect.385;
|
||||
|
||||
procedure Inspect.35 (Inspect.300):
|
||||
ret Inspect.300;
|
||||
|
||||
procedure Inspect.36 (Inspect.304):
|
||||
let Inspect.311 : Str = "";
|
||||
ret Inspect.311;
|
||||
|
||||
procedure Inspect.42 (Inspect.227):
|
||||
let Inspect.315 : List {Str, Str} = CallByName Inspect.30 Inspect.227;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.42 (Inspect.227):
|
||||
let Inspect.355 : List {Str, Str} = CallByName Inspect.30 Inspect.227;
|
||||
ret Inspect.355;
|
||||
|
||||
procedure Inspect.44 (Inspect.248):
|
||||
let Inspect.393 : Str = CallByName Inspect.30 Inspect.248;
|
||||
ret Inspect.393;
|
||||
|
||||
procedure Inspect.5 (Inspect.150):
|
||||
let Inspect.312 : Str = CallByName #Derived.0 Inspect.150;
|
||||
let Inspect.309 : {} = Struct {};
|
||||
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
|
||||
let Inspect.307 : Str = CallByName #Derived.2 Inspect.308 Inspect.312;
|
||||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.61 (Inspect.303, Inspect.298):
|
||||
let Inspect.363 : Str = CallByName Str.3 Inspect.303 Inspect.298;
|
||||
dec Inspect.298;
|
||||
ret Inspect.363;
|
||||
|
||||
procedure List.18 (List.154, List.155, List.156):
|
||||
let List.554 : U64 = 0i64;
|
||||
let List.555 : U64 = CallByName List.6 List.154;
|
||||
let List.553 : {Str, Int1} = CallByName List.88 List.154 List.155 List.156 List.554 List.555;
|
||||
ret List.553;
|
||||
|
||||
procedure List.18 (List.154, List.155, List.156):
|
||||
let List.566 : U64 = 0i64;
|
||||
let List.567 : U64 = CallByName List.6 List.154;
|
||||
let List.565 : {Str, Int1} = CallByName List.88 List.154 List.155 List.156 List.566 List.567;
|
||||
ret List.565;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.564 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.564;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.576 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.576;
|
||||
|
||||
procedure List.66 (#Attr.2, #Attr.3):
|
||||
let List.563 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.563;
|
||||
|
||||
procedure List.66 (#Attr.2, #Attr.3):
|
||||
let List.575 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.575;
|
||||
|
||||
procedure List.88 (#Derived_gen.30, #Derived_gen.31, #Derived_gen.32, #Derived_gen.33, #Derived_gen.34):
|
||||
joinpoint List.568 List.157 List.158 List.159 List.160 List.161:
|
||||
let List.570 : Int1 = CallByName Num.22 List.160 List.161;
|
||||
if List.570 then
|
||||
let List.574 : {Str, Str} = CallByName List.66 List.157 List.160;
|
||||
inc List.574;
|
||||
let List.162 : {Str, Int1} = CallByName Inspect.232 List.158 List.574;
|
||||
let List.573 : U64 = 1i64;
|
||||
let List.572 : U64 = CallByName Num.51 List.160 List.573;
|
||||
jump List.568 List.157 List.162 List.159 List.572 List.161;
|
||||
else
|
||||
dec List.157;
|
||||
ret List.158;
|
||||
in
|
||||
jump List.568 #Derived_gen.30 #Derived_gen.31 #Derived_gen.32 #Derived_gen.33 #Derived_gen.34;
|
||||
|
||||
procedure List.88 (#Derived_gen.41, #Derived_gen.42, #Derived_gen.43, #Derived_gen.44, #Derived_gen.45):
|
||||
joinpoint List.556 List.157 List.158 List.159 List.160 List.161:
|
||||
let List.558 : Int1 = CallByName Num.22 List.160 List.161;
|
||||
if List.558 then
|
||||
let List.562 : {Str, Str} = CallByName List.66 List.157 List.160;
|
||||
inc List.562;
|
||||
let List.162 : {Str, Int1} = CallByName Inspect.232 List.158 List.562;
|
||||
let List.561 : U64 = 1i64;
|
||||
let List.560 : U64 = CallByName Num.51 List.160 List.561;
|
||||
jump List.556 List.157 List.162 List.159 List.560 List.161;
|
||||
else
|
||||
dec List.157;
|
||||
ret List.158;
|
||||
in
|
||||
jump List.556 #Derived_gen.41 #Derived_gen.42 #Derived_gen.43 #Derived_gen.44 #Derived_gen.45;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.294 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
ret Num.294;
|
||||
|
||||
procedure Num.51 (#Attr.2, #Attr.3):
|
||||
let Num.293 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
|
||||
ret Num.293;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.293 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.293;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.5 : Str = "bar";
|
||||
let Test.2 : Str = CallByName Inspect.5 Test.5;
|
||||
let Test.1 : Str = CallByName Inspect.35 Test.2;
|
||||
ret Test.1;
|
204
crates/compiler/test_mono/generated/inspect_derived_record.txt
Normal file
204
crates/compiler/test_mono/generated/inspect_derived_record.txt
Normal file
|
@ -0,0 +1,204 @@
|
|||
procedure #Derived.0 (#Derived.1):
|
||||
let #Derived_gen.0 : {Decimal, I64} = CallByName Inspect.30 #Derived.1;
|
||||
ret #Derived_gen.0;
|
||||
|
||||
procedure #Derived.2 (#Derived.3, #Derived.1):
|
||||
let #Derived_gen.13 : I64 = StructAtIndex 1 #Derived.1;
|
||||
let #Derived_gen.11 : [C I64, C Decimal] = CallByName Inspect.54 #Derived_gen.13;
|
||||
let #Derived_gen.12 : Str = "a";
|
||||
let #Derived_gen.6 : {[C I64, C Decimal], Str} = Struct {#Derived_gen.11, #Derived_gen.12};
|
||||
let #Derived_gen.10 : Decimal = StructAtIndex 0 #Derived.1;
|
||||
let #Derived_gen.8 : [C I64, C Decimal] = CallByName Inspect.60 #Derived_gen.10;
|
||||
let #Derived_gen.9 : Str = "b";
|
||||
let #Derived_gen.7 : {[C I64, C Decimal], Str} = Struct {#Derived_gen.8, #Derived_gen.9};
|
||||
let #Derived_gen.5 : List {[C I64, C Decimal], Str} = Array [#Derived_gen.6, #Derived_gen.7];
|
||||
let #Derived_gen.4 : List {[C I64, C Decimal], Str} = CallByName Inspect.42 #Derived_gen.5;
|
||||
let #Derived_gen.3 : Str = CallByName Inspect.31 #Derived_gen.4 #Derived.3;
|
||||
ret #Derived_gen.3;
|
||||
|
||||
procedure Bool.1 ():
|
||||
let Bool.24 : Int1 = false;
|
||||
ret Bool.24;
|
||||
|
||||
procedure Bool.2 ():
|
||||
let Bool.23 : Int1 = true;
|
||||
ret Bool.23;
|
||||
|
||||
procedure Inspect.228 (Inspect.229, Inspect.227):
|
||||
let Inspect.353 : Str = "{";
|
||||
let Inspect.328 : Str = CallByName Inspect.61 Inspect.229 Inspect.353;
|
||||
let Inspect.324 : {Str, Int1} = CallByName Inspect.230 Inspect.328 Inspect.227;
|
||||
let Inspect.325 : {} = Struct {};
|
||||
let Inspect.320 : Str = CallByName Inspect.242 Inspect.324;
|
||||
let Inspect.321 : Str = "}";
|
||||
let Inspect.319 : Str = CallByName Inspect.61 Inspect.320 Inspect.321;
|
||||
ret Inspect.319;
|
||||
|
||||
procedure Inspect.230 (Inspect.231, Inspect.227):
|
||||
let Inspect.352 : Int1 = CallByName Bool.1;
|
||||
let Inspect.332 : {Str, Int1} = Struct {Inspect.231, Inspect.352};
|
||||
let Inspect.333 : {} = Struct {};
|
||||
let Inspect.331 : {Str, Int1} = CallByName List.18 Inspect.227 Inspect.332 Inspect.333;
|
||||
ret Inspect.331;
|
||||
|
||||
procedure Inspect.232 (Inspect.334, Inspect.335):
|
||||
let Inspect.236 : [C I64, C Decimal] = StructAtIndex 0 Inspect.335;
|
||||
let Inspect.235 : Str = StructAtIndex 1 Inspect.335;
|
||||
let Inspect.233 : Str = StructAtIndex 0 Inspect.334;
|
||||
let Inspect.234 : Int1 = StructAtIndex 1 Inspect.334;
|
||||
joinpoint Inspect.350 Inspect.237:
|
||||
let Inspect.347 : Str = CallByName Inspect.61 Inspect.237 Inspect.235;
|
||||
let Inspect.348 : Str = ": ";
|
||||
let Inspect.341 : Str = CallByName Inspect.61 Inspect.347 Inspect.348;
|
||||
let Inspect.337 : Str = CallByName Inspect.238 Inspect.341 Inspect.236;
|
||||
let Inspect.338 : {} = Struct {};
|
||||
let Inspect.336 : {Str, Int1} = CallByName Inspect.240 Inspect.337;
|
||||
ret Inspect.336;
|
||||
in
|
||||
if Inspect.234 then
|
||||
let Inspect.351 : Str = ", ";
|
||||
let Inspect.349 : Str = CallByName Inspect.61 Inspect.233 Inspect.351;
|
||||
jump Inspect.350 Inspect.349;
|
||||
else
|
||||
jump Inspect.350 Inspect.233;
|
||||
|
||||
procedure Inspect.238 (Inspect.239, Inspect.236):
|
||||
let Inspect.344 : Str = CallByName Inspect.31 Inspect.236 Inspect.239;
|
||||
ret Inspect.344;
|
||||
|
||||
procedure Inspect.240 (Inspect.241):
|
||||
let Inspect.340 : Int1 = CallByName Bool.2;
|
||||
let Inspect.339 : {Str, Int1} = Struct {Inspect.241, Inspect.340};
|
||||
ret Inspect.339;
|
||||
|
||||
procedure Inspect.242 (Inspect.326):
|
||||
let Inspect.327 : Str = StructAtIndex 0 Inspect.326;
|
||||
ret Inspect.327;
|
||||
|
||||
procedure Inspect.277 (Inspect.278, #Attr.12):
|
||||
let Inspect.366 : I64 = UnionAtIndex (Id 0) (Index 0) #Attr.12;
|
||||
let Inspect.365 : Str = CallByName Num.96 Inspect.366;
|
||||
let Inspect.364 : Str = CallByName Inspect.61 Inspect.278 Inspect.365;
|
||||
ret Inspect.364;
|
||||
|
||||
procedure Inspect.295 (Inspect.296, #Attr.12):
|
||||
let Inspect.360 : Decimal = UnionAtIndex (Id 1) (Index 0) #Attr.12;
|
||||
let Inspect.359 : Str = CallByName Num.96 Inspect.360;
|
||||
let Inspect.358 : Str = CallByName Inspect.61 Inspect.296 Inspect.359;
|
||||
ret Inspect.358;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.314 : Str = CallByName Inspect.228 Inspect.149 Inspect.305;
|
||||
ret Inspect.314;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.346 : U8 = GetTagId Inspect.305;
|
||||
switch Inspect.346:
|
||||
case 0:
|
||||
let Inspect.345 : Str = CallByName Inspect.277 Inspect.149 Inspect.305;
|
||||
ret Inspect.345;
|
||||
|
||||
default:
|
||||
let Inspect.345 : Str = CallByName Inspect.295 Inspect.149 Inspect.305;
|
||||
ret Inspect.345;
|
||||
|
||||
|
||||
procedure Inspect.35 (Inspect.300):
|
||||
ret Inspect.300;
|
||||
|
||||
procedure Inspect.36 (Inspect.304):
|
||||
let Inspect.311 : Str = "";
|
||||
ret Inspect.311;
|
||||
|
||||
procedure Inspect.42 (Inspect.227):
|
||||
let Inspect.315 : List {[C I64, C Decimal], Str} = CallByName Inspect.30 Inspect.227;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.5 (Inspect.150):
|
||||
let Inspect.312 : {Decimal, I64} = CallByName #Derived.0 Inspect.150;
|
||||
let Inspect.309 : {} = Struct {};
|
||||
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
|
||||
let Inspect.307 : Str = CallByName #Derived.2 Inspect.308 Inspect.312;
|
||||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.54 (Inspect.276):
|
||||
let Inspect.362 : [C I64, C Decimal] = TagId(0) Inspect.276;
|
||||
let Inspect.361 : [C I64, C Decimal] = CallByName Inspect.30 Inspect.362;
|
||||
ret Inspect.361;
|
||||
|
||||
procedure Inspect.60 (Inspect.294):
|
||||
let Inspect.355 : [C I64, C Decimal] = TagId(1) Inspect.294;
|
||||
let Inspect.354 : [C I64, C Decimal] = CallByName Inspect.30 Inspect.355;
|
||||
ret Inspect.354;
|
||||
|
||||
procedure Inspect.61 (Inspect.303, Inspect.298):
|
||||
let Inspect.323 : Str = CallByName Str.3 Inspect.303 Inspect.298;
|
||||
dec Inspect.298;
|
||||
ret Inspect.323;
|
||||
|
||||
procedure List.18 (List.154, List.155, List.156):
|
||||
let List.554 : U64 = 0i64;
|
||||
let List.555 : U64 = CallByName List.6 List.154;
|
||||
let List.553 : {Str, Int1} = CallByName List.88 List.154 List.155 List.156 List.554 List.555;
|
||||
ret List.553;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.564 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.564;
|
||||
|
||||
procedure List.66 (#Attr.2, #Attr.3):
|
||||
let List.563 : {[C I64, C Decimal], Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.563;
|
||||
|
||||
procedure List.88 (#Derived_gen.14, #Derived_gen.15, #Derived_gen.16, #Derived_gen.17, #Derived_gen.18):
|
||||
joinpoint List.556 List.157 List.158 List.159 List.160 List.161:
|
||||
let List.558 : Int1 = CallByName Num.22 List.160 List.161;
|
||||
if List.558 then
|
||||
let List.562 : {[C I64, C Decimal], Str} = CallByName List.66 List.157 List.160;
|
||||
inc List.562;
|
||||
let List.162 : {Str, Int1} = CallByName Inspect.232 List.158 List.562;
|
||||
let List.561 : U64 = 1i64;
|
||||
let List.560 : U64 = CallByName Num.51 List.160 List.561;
|
||||
jump List.556 List.157 List.162 List.159 List.560 List.161;
|
||||
else
|
||||
dec List.157;
|
||||
ret List.158;
|
||||
in
|
||||
jump List.556 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17 #Derived_gen.18;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.294 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
ret Num.294;
|
||||
|
||||
procedure Num.51 (#Attr.2, #Attr.3):
|
||||
let Num.293 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
|
||||
ret Num.293;
|
||||
|
||||
procedure Num.96 (#Attr.2):
|
||||
let Num.291 : Str = lowlevel NumToStr #Attr.2;
|
||||
ret Num.291;
|
||||
|
||||
procedure Num.96 (#Attr.2):
|
||||
let Num.292 : Str = lowlevel NumToStr #Attr.2;
|
||||
ret Num.292;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.292;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.4 : Decimal = 3dec;
|
||||
let Test.5 : I64 = 7i64;
|
||||
let Test.3 : {Decimal, I64} = Struct {Test.4, Test.5};
|
||||
let Test.2 : Str = CallByName Inspect.5 Test.3;
|
||||
let Test.1 : Str = CallByName Inspect.35 Test.2;
|
||||
ret Test.1;
|
|
@ -0,0 +1,171 @@
|
|||
procedure #Derived.0 (#Derived.1):
|
||||
let #Derived_gen.0 : Str = CallByName Inspect.30 #Derived.1;
|
||||
ret #Derived_gen.0;
|
||||
|
||||
procedure #Derived.2 (#Derived.3, #Derived.1):
|
||||
let #Derived_gen.7 : Str = "a";
|
||||
let #Derived_gen.8 : Str = CallByName Inspect.44 #Derived.1;
|
||||
let #Derived_gen.6 : {Str, Str} = Struct {#Derived_gen.7, #Derived_gen.8};
|
||||
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6];
|
||||
let #Derived_gen.4 : List {Str, Str} = CallByName Inspect.42 #Derived_gen.5;
|
||||
let #Derived_gen.3 : Str = CallByName Inspect.31 #Derived_gen.4 #Derived.3;
|
||||
ret #Derived_gen.3;
|
||||
|
||||
procedure Bool.1 ():
|
||||
let Bool.24 : Int1 = false;
|
||||
ret Bool.24;
|
||||
|
||||
procedure Bool.2 ():
|
||||
let Bool.23 : Int1 = true;
|
||||
ret Bool.23;
|
||||
|
||||
procedure Inspect.228 (Inspect.229, Inspect.227):
|
||||
let Inspect.352 : Str = "{";
|
||||
let Inspect.328 : Str = CallByName Inspect.61 Inspect.229 Inspect.352;
|
||||
let Inspect.324 : {Str, Int1} = CallByName Inspect.230 Inspect.328 Inspect.227;
|
||||
let Inspect.325 : {} = Struct {};
|
||||
let Inspect.320 : Str = CallByName Inspect.242 Inspect.324;
|
||||
let Inspect.321 : Str = "}";
|
||||
let Inspect.319 : Str = CallByName Inspect.61 Inspect.320 Inspect.321;
|
||||
ret Inspect.319;
|
||||
|
||||
procedure Inspect.230 (Inspect.231, Inspect.227):
|
||||
let Inspect.351 : Int1 = CallByName Bool.1;
|
||||
let Inspect.332 : {Str, Int1} = Struct {Inspect.231, Inspect.351};
|
||||
let Inspect.333 : {} = Struct {};
|
||||
let Inspect.331 : {Str, Int1} = CallByName List.18 Inspect.227 Inspect.332 Inspect.333;
|
||||
ret Inspect.331;
|
||||
|
||||
procedure Inspect.232 (Inspect.334, Inspect.335):
|
||||
let Inspect.235 : Str = StructAtIndex 0 Inspect.335;
|
||||
let Inspect.236 : Str = StructAtIndex 1 Inspect.335;
|
||||
let Inspect.233 : Str = StructAtIndex 0 Inspect.334;
|
||||
let Inspect.234 : Int1 = StructAtIndex 1 Inspect.334;
|
||||
joinpoint Inspect.349 Inspect.237:
|
||||
let Inspect.346 : Str = CallByName Inspect.61 Inspect.237 Inspect.235;
|
||||
let Inspect.347 : Str = ": ";
|
||||
let Inspect.341 : Str = CallByName Inspect.61 Inspect.346 Inspect.347;
|
||||
let Inspect.337 : Str = CallByName Inspect.238 Inspect.341 Inspect.236;
|
||||
let Inspect.338 : {} = Struct {};
|
||||
let Inspect.336 : {Str, Int1} = CallByName Inspect.240 Inspect.337;
|
||||
ret Inspect.336;
|
||||
in
|
||||
if Inspect.234 then
|
||||
let Inspect.350 : Str = ", ";
|
||||
let Inspect.348 : Str = CallByName Inspect.61 Inspect.233 Inspect.350;
|
||||
jump Inspect.349 Inspect.348;
|
||||
else
|
||||
jump Inspect.349 Inspect.233;
|
||||
|
||||
procedure Inspect.238 (Inspect.239, Inspect.236):
|
||||
let Inspect.344 : Str = CallByName Inspect.31 Inspect.236 Inspect.239;
|
||||
ret Inspect.344;
|
||||
|
||||
procedure Inspect.240 (Inspect.241):
|
||||
let Inspect.340 : Int1 = CallByName Bool.2;
|
||||
let Inspect.339 : {Str, Int1} = Struct {Inspect.241, Inspect.340};
|
||||
ret Inspect.339;
|
||||
|
||||
procedure Inspect.242 (Inspect.326):
|
||||
let Inspect.327 : Str = StructAtIndex 0 Inspect.326;
|
||||
ret Inspect.327;
|
||||
|
||||
procedure Inspect.249 (Inspect.250, Inspect.248):
|
||||
let Inspect.361 : Str = "\"";
|
||||
let Inspect.360 : Str = CallByName Inspect.61 Inspect.250 Inspect.361;
|
||||
let Inspect.358 : Str = CallByName Inspect.61 Inspect.360 Inspect.248;
|
||||
let Inspect.359 : Str = "\"";
|
||||
let Inspect.357 : Str = CallByName Inspect.61 Inspect.358 Inspect.359;
|
||||
ret Inspect.357;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.314 : Str = CallByName Inspect.228 Inspect.149 Inspect.305;
|
||||
ret Inspect.314;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.345 : Str = CallByName Inspect.249 Inspect.149 Inspect.305;
|
||||
ret Inspect.345;
|
||||
|
||||
procedure Inspect.35 (Inspect.300):
|
||||
ret Inspect.300;
|
||||
|
||||
procedure Inspect.36 (Inspect.304):
|
||||
let Inspect.311 : Str = "";
|
||||
ret Inspect.311;
|
||||
|
||||
procedure Inspect.42 (Inspect.227):
|
||||
let Inspect.315 : List {Str, Str} = CallByName Inspect.30 Inspect.227;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.44 (Inspect.248):
|
||||
let Inspect.353 : Str = CallByName Inspect.30 Inspect.248;
|
||||
ret Inspect.353;
|
||||
|
||||
procedure Inspect.5 (Inspect.150):
|
||||
let Inspect.312 : Str = CallByName #Derived.0 Inspect.150;
|
||||
let Inspect.309 : {} = Struct {};
|
||||
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
|
||||
let Inspect.307 : Str = CallByName #Derived.2 Inspect.308 Inspect.312;
|
||||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.61 (Inspect.303, Inspect.298):
|
||||
let Inspect.323 : Str = CallByName Str.3 Inspect.303 Inspect.298;
|
||||
dec Inspect.298;
|
||||
ret Inspect.323;
|
||||
|
||||
procedure List.18 (List.154, List.155, List.156):
|
||||
let List.554 : U64 = 0i64;
|
||||
let List.555 : U64 = CallByName List.6 List.154;
|
||||
let List.553 : {Str, Int1} = CallByName List.88 List.154 List.155 List.156 List.554 List.555;
|
||||
ret List.553;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.564 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.564;
|
||||
|
||||
procedure List.66 (#Attr.2, #Attr.3):
|
||||
let List.563 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.563;
|
||||
|
||||
procedure List.88 (#Derived_gen.14, #Derived_gen.15, #Derived_gen.16, #Derived_gen.17, #Derived_gen.18):
|
||||
joinpoint List.556 List.157 List.158 List.159 List.160 List.161:
|
||||
let List.558 : Int1 = CallByName Num.22 List.160 List.161;
|
||||
if List.558 then
|
||||
let List.562 : {Str, Str} = CallByName List.66 List.157 List.160;
|
||||
inc List.562;
|
||||
let List.162 : {Str, Int1} = CallByName Inspect.232 List.158 List.562;
|
||||
let List.561 : U64 = 1i64;
|
||||
let List.560 : U64 = CallByName Num.51 List.160 List.561;
|
||||
jump List.556 List.157 List.162 List.159 List.560 List.161;
|
||||
else
|
||||
dec List.157;
|
||||
ret List.158;
|
||||
in
|
||||
jump List.556 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17 #Derived_gen.18;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.292 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
ret Num.292;
|
||||
|
||||
procedure Num.51 (#Attr.2, #Attr.3):
|
||||
let Num.291 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
|
||||
ret Num.291;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.292;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.4 : Str = "foo";
|
||||
let Test.2 : Str = CallByName Inspect.5 Test.4;
|
||||
let Test.1 : Str = CallByName Inspect.35 Test.2;
|
||||
ret Test.1;
|
|
@ -0,0 +1,180 @@
|
|||
procedure #Derived.0 (#Derived.1):
|
||||
let #Derived_gen.0 : {Str, Str} = CallByName Inspect.30 #Derived.1;
|
||||
ret #Derived_gen.0;
|
||||
|
||||
procedure #Derived.2 (#Derived.3, #Derived.1):
|
||||
let #Derived_gen.11 : Str = "a";
|
||||
let #Derived_gen.13 : Str = StructAtIndex 0 #Derived.1;
|
||||
inc #Derived_gen.13;
|
||||
let #Derived_gen.12 : Str = CallByName Inspect.44 #Derived_gen.13;
|
||||
let #Derived_gen.6 : {Str, Str} = Struct {#Derived_gen.11, #Derived_gen.12};
|
||||
let #Derived_gen.8 : Str = "b";
|
||||
let #Derived_gen.10 : Str = StructAtIndex 1 #Derived.1;
|
||||
dec #Derived_gen.13;
|
||||
let #Derived_gen.9 : Str = CallByName Inspect.44 #Derived_gen.10;
|
||||
let #Derived_gen.7 : {Str, Str} = Struct {#Derived_gen.8, #Derived_gen.9};
|
||||
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6, #Derived_gen.7];
|
||||
let #Derived_gen.4 : List {Str, Str} = CallByName Inspect.42 #Derived_gen.5;
|
||||
let #Derived_gen.3 : Str = CallByName Inspect.31 #Derived_gen.4 #Derived.3;
|
||||
ret #Derived_gen.3;
|
||||
|
||||
procedure Bool.1 ():
|
||||
let Bool.24 : Int1 = false;
|
||||
ret Bool.24;
|
||||
|
||||
procedure Bool.2 ():
|
||||
let Bool.23 : Int1 = true;
|
||||
ret Bool.23;
|
||||
|
||||
procedure Inspect.228 (Inspect.229, Inspect.227):
|
||||
let Inspect.352 : Str = "{";
|
||||
let Inspect.328 : Str = CallByName Inspect.61 Inspect.229 Inspect.352;
|
||||
let Inspect.324 : {Str, Int1} = CallByName Inspect.230 Inspect.328 Inspect.227;
|
||||
let Inspect.325 : {} = Struct {};
|
||||
let Inspect.320 : Str = CallByName Inspect.242 Inspect.324;
|
||||
let Inspect.321 : Str = "}";
|
||||
let Inspect.319 : Str = CallByName Inspect.61 Inspect.320 Inspect.321;
|
||||
ret Inspect.319;
|
||||
|
||||
procedure Inspect.230 (Inspect.231, Inspect.227):
|
||||
let Inspect.351 : Int1 = CallByName Bool.1;
|
||||
let Inspect.332 : {Str, Int1} = Struct {Inspect.231, Inspect.351};
|
||||
let Inspect.333 : {} = Struct {};
|
||||
let Inspect.331 : {Str, Int1} = CallByName List.18 Inspect.227 Inspect.332 Inspect.333;
|
||||
ret Inspect.331;
|
||||
|
||||
procedure Inspect.232 (Inspect.334, Inspect.335):
|
||||
let Inspect.235 : Str = StructAtIndex 0 Inspect.335;
|
||||
let Inspect.236 : Str = StructAtIndex 1 Inspect.335;
|
||||
let Inspect.233 : Str = StructAtIndex 0 Inspect.334;
|
||||
let Inspect.234 : Int1 = StructAtIndex 1 Inspect.334;
|
||||
joinpoint Inspect.349 Inspect.237:
|
||||
let Inspect.346 : Str = CallByName Inspect.61 Inspect.237 Inspect.235;
|
||||
let Inspect.347 : Str = ": ";
|
||||
let Inspect.341 : Str = CallByName Inspect.61 Inspect.346 Inspect.347;
|
||||
let Inspect.337 : Str = CallByName Inspect.238 Inspect.341 Inspect.236;
|
||||
let Inspect.338 : {} = Struct {};
|
||||
let Inspect.336 : {Str, Int1} = CallByName Inspect.240 Inspect.337;
|
||||
ret Inspect.336;
|
||||
in
|
||||
if Inspect.234 then
|
||||
let Inspect.350 : Str = ", ";
|
||||
let Inspect.348 : Str = CallByName Inspect.61 Inspect.233 Inspect.350;
|
||||
jump Inspect.349 Inspect.348;
|
||||
else
|
||||
jump Inspect.349 Inspect.233;
|
||||
|
||||
procedure Inspect.238 (Inspect.239, Inspect.236):
|
||||
let Inspect.344 : Str = CallByName Inspect.31 Inspect.236 Inspect.239;
|
||||
ret Inspect.344;
|
||||
|
||||
procedure Inspect.240 (Inspect.241):
|
||||
let Inspect.340 : Int1 = CallByName Bool.2;
|
||||
let Inspect.339 : {Str, Int1} = Struct {Inspect.241, Inspect.340};
|
||||
ret Inspect.339;
|
||||
|
||||
procedure Inspect.242 (Inspect.326):
|
||||
let Inspect.327 : Str = StructAtIndex 0 Inspect.326;
|
||||
ret Inspect.327;
|
||||
|
||||
procedure Inspect.249 (Inspect.250, Inspect.248):
|
||||
let Inspect.361 : Str = "\"";
|
||||
let Inspect.360 : Str = CallByName Inspect.61 Inspect.250 Inspect.361;
|
||||
let Inspect.358 : Str = CallByName Inspect.61 Inspect.360 Inspect.248;
|
||||
let Inspect.359 : Str = "\"";
|
||||
let Inspect.357 : Str = CallByName Inspect.61 Inspect.358 Inspect.359;
|
||||
ret Inspect.357;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.314 : Str = CallByName Inspect.228 Inspect.149 Inspect.305;
|
||||
ret Inspect.314;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.345 : Str = CallByName Inspect.249 Inspect.149 Inspect.305;
|
||||
ret Inspect.345;
|
||||
|
||||
procedure Inspect.35 (Inspect.300):
|
||||
ret Inspect.300;
|
||||
|
||||
procedure Inspect.36 (Inspect.304):
|
||||
let Inspect.311 : Str = "";
|
||||
ret Inspect.311;
|
||||
|
||||
procedure Inspect.42 (Inspect.227):
|
||||
let Inspect.315 : List {Str, Str} = CallByName Inspect.30 Inspect.227;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.44 (Inspect.248):
|
||||
let Inspect.362 : Str = CallByName Inspect.30 Inspect.248;
|
||||
ret Inspect.362;
|
||||
|
||||
procedure Inspect.5 (Inspect.150):
|
||||
let Inspect.312 : {Str, Str} = CallByName #Derived.0 Inspect.150;
|
||||
let Inspect.309 : {} = Struct {};
|
||||
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
|
||||
let Inspect.307 : Str = CallByName #Derived.2 Inspect.308 Inspect.312;
|
||||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.61 (Inspect.303, Inspect.298):
|
||||
let Inspect.323 : Str = CallByName Str.3 Inspect.303 Inspect.298;
|
||||
dec Inspect.298;
|
||||
ret Inspect.323;
|
||||
|
||||
procedure List.18 (List.154, List.155, List.156):
|
||||
let List.554 : U64 = 0i64;
|
||||
let List.555 : U64 = CallByName List.6 List.154;
|
||||
let List.553 : {Str, Int1} = CallByName List.88 List.154 List.155 List.156 List.554 List.555;
|
||||
ret List.553;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.564 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.564;
|
||||
|
||||
procedure List.66 (#Attr.2, #Attr.3):
|
||||
let List.563 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.563;
|
||||
|
||||
procedure List.88 (#Derived_gen.18, #Derived_gen.19, #Derived_gen.20, #Derived_gen.21, #Derived_gen.22):
|
||||
joinpoint List.556 List.157 List.158 List.159 List.160 List.161:
|
||||
let List.558 : Int1 = CallByName Num.22 List.160 List.161;
|
||||
if List.558 then
|
||||
let List.562 : {Str, Str} = CallByName List.66 List.157 List.160;
|
||||
inc List.562;
|
||||
let List.162 : {Str, Int1} = CallByName Inspect.232 List.158 List.562;
|
||||
let List.561 : U64 = 1i64;
|
||||
let List.560 : U64 = CallByName Num.51 List.160 List.561;
|
||||
jump List.556 List.157 List.162 List.159 List.560 List.161;
|
||||
else
|
||||
dec List.157;
|
||||
ret List.158;
|
||||
in
|
||||
jump List.556 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21 #Derived_gen.22;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.292 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
ret Num.292;
|
||||
|
||||
procedure Num.51 (#Attr.2, #Attr.3):
|
||||
let Num.291 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
|
||||
ret Num.291;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.292;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.4 : Str = "foo";
|
||||
let Test.5 : Str = "bar";
|
||||
let Test.3 : {Str, Str} = Struct {Test.4, Test.5};
|
||||
let Test.2 : Str = CallByName Inspect.5 Test.3;
|
||||
let Test.1 : Str = CallByName Inspect.35 Test.2;
|
||||
ret Test.1;
|
|
@ -0,0 +1,43 @@
|
|||
procedure Inspect.249 (Inspect.250, Inspect.248):
|
||||
let Inspect.323 : Str = "\"";
|
||||
let Inspect.322 : Str = CallByName Inspect.61 Inspect.250 Inspect.323;
|
||||
let Inspect.318 : Str = CallByName Inspect.61 Inspect.322 Inspect.248;
|
||||
let Inspect.319 : Str = "\"";
|
||||
let Inspect.317 : Str = CallByName Inspect.61 Inspect.318 Inspect.319;
|
||||
ret Inspect.317;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.35 (Inspect.300):
|
||||
ret Inspect.300;
|
||||
|
||||
procedure Inspect.36 (Inspect.304):
|
||||
let Inspect.311 : Str = "";
|
||||
ret Inspect.311;
|
||||
|
||||
procedure Inspect.44 (Inspect.248):
|
||||
let Inspect.313 : Str = CallByName Inspect.30 Inspect.248;
|
||||
ret Inspect.313;
|
||||
|
||||
procedure Inspect.5 (Inspect.150):
|
||||
let Inspect.312 : Str = CallByName Inspect.44 Inspect.150;
|
||||
let Inspect.309 : {} = Struct {};
|
||||
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
|
||||
let Inspect.307 : Str = CallByName Inspect.249 Inspect.308 Inspect.312;
|
||||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.61 (Inspect.303, Inspect.298):
|
||||
let Inspect.321 : Str = CallByName Str.3 Inspect.303 Inspect.298;
|
||||
dec Inspect.298;
|
||||
ret Inspect.321;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.292;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.3 : Str = "abc";
|
||||
let Test.2 : Str = CallByName Inspect.5 Test.3;
|
||||
let Test.1 : Str = CallByName Inspect.35 Test.2;
|
||||
ret Test.1;
|
|
@ -0,0 +1,173 @@
|
|||
procedure #Derived.0 (#Derived.1):
|
||||
let #Derived_gen.0 : Str = CallByName Inspect.30 #Derived.1;
|
||||
ret #Derived_gen.0;
|
||||
|
||||
procedure #Derived.3 (#Derived.4, #Derived.1):
|
||||
joinpoint #Derived_gen.5 #Derived_gen.4:
|
||||
let #Derived_gen.3 : Str = CallByName Inspect.31 #Derived_gen.4 #Derived.4;
|
||||
ret #Derived_gen.3;
|
||||
in
|
||||
let #Derived_gen.7 : Str = "A";
|
||||
let #Derived_gen.9 : Str = CallByName Inspect.44 #Derived.1;
|
||||
let #Derived_gen.8 : List Str = Array [#Derived_gen.9];
|
||||
let #Derived_gen.6 : [C Str, C Str List Str] = CallByName Inspect.40 #Derived_gen.7 #Derived_gen.8;
|
||||
jump #Derived_gen.5 #Derived_gen.6;
|
||||
|
||||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.23 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.23;
|
||||
|
||||
procedure Inspect.203 (Inspect.204, #Attr.12):
|
||||
let Inspect.346 : Str = UnionAtIndex (Id 0) (Index 0) #Attr.12;
|
||||
let Inspect.345 : Str = CallByName Inspect.61 Inspect.204 Inspect.346;
|
||||
ret Inspect.345;
|
||||
|
||||
procedure Inspect.205 (Inspect.206, #Attr.12):
|
||||
let Inspect.340 : List Str = UnionAtIndex (Id 1) (Index 1) #Attr.12;
|
||||
let Inspect.339 : Str = UnionAtIndex (Id 1) (Index 0) #Attr.12;
|
||||
let Inspect.338 : Str = "(";
|
||||
let Inspect.337 : Str = CallByName Inspect.61 Inspect.206 Inspect.338;
|
||||
let Inspect.325 : Str = CallByName Inspect.61 Inspect.337 Inspect.339;
|
||||
let Inspect.321 : Str = CallByName Inspect.207 Inspect.325 Inspect.340;
|
||||
let Inspect.322 : Str = ")";
|
||||
let Inspect.320 : Str = CallByName Inspect.61 Inspect.321 Inspect.322;
|
||||
ret Inspect.320;
|
||||
|
||||
procedure Inspect.207 (Inspect.208, Inspect.202):
|
||||
let Inspect.329 : {} = Struct {};
|
||||
let Inspect.328 : Str = CallByName List.18 Inspect.202 Inspect.208 Inspect.329;
|
||||
ret Inspect.328;
|
||||
|
||||
procedure Inspect.209 (Inspect.210, Inspect.211):
|
||||
let Inspect.336 : Str = " ";
|
||||
let Inspect.331 : Str = CallByName Inspect.61 Inspect.210 Inspect.336;
|
||||
let Inspect.330 : Str = CallByName Inspect.212 Inspect.331 Inspect.211;
|
||||
ret Inspect.330;
|
||||
|
||||
procedure Inspect.212 (Inspect.213, Inspect.211):
|
||||
let Inspect.334 : Str = CallByName Inspect.31 Inspect.211 Inspect.213;
|
||||
ret Inspect.334;
|
||||
|
||||
procedure Inspect.249 (Inspect.250, Inspect.248):
|
||||
let Inspect.355 : Str = "\"";
|
||||
let Inspect.354 : Str = CallByName Inspect.61 Inspect.250 Inspect.355;
|
||||
let Inspect.352 : Str = CallByName Inspect.61 Inspect.354 Inspect.248;
|
||||
let Inspect.353 : Str = "\"";
|
||||
let Inspect.351 : Str = CallByName Inspect.61 Inspect.352 Inspect.353;
|
||||
ret Inspect.351;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.315 : U8 = GetTagId Inspect.305;
|
||||
switch Inspect.315:
|
||||
case 0:
|
||||
let Inspect.314 : Str = CallByName Inspect.203 Inspect.149 Inspect.305;
|
||||
ret Inspect.314;
|
||||
|
||||
default:
|
||||
let Inspect.314 : Str = CallByName Inspect.205 Inspect.149 Inspect.305;
|
||||
ret Inspect.314;
|
||||
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.335 : Str = CallByName Inspect.249 Inspect.149 Inspect.305;
|
||||
ret Inspect.335;
|
||||
|
||||
procedure Inspect.35 (Inspect.300):
|
||||
ret Inspect.300;
|
||||
|
||||
procedure Inspect.36 (Inspect.304):
|
||||
let Inspect.311 : Str = "";
|
||||
ret Inspect.311;
|
||||
|
||||
procedure Inspect.40 (Inspect.201, Inspect.202):
|
||||
inc Inspect.202;
|
||||
let Inspect.341 : Int1 = CallByName List.1 Inspect.202;
|
||||
if Inspect.341 then
|
||||
dec Inspect.202;
|
||||
let Inspect.343 : [C Str, C Str List Str] = TagId(0) Inspect.201;
|
||||
let Inspect.342 : [C Str, C Str List Str] = CallByName Inspect.30 Inspect.343;
|
||||
ret Inspect.342;
|
||||
else
|
||||
let Inspect.317 : [C Str, C Str List Str] = TagId(1) Inspect.201 Inspect.202;
|
||||
let Inspect.316 : [C Str, C Str List Str] = CallByName Inspect.30 Inspect.317;
|
||||
ret Inspect.316;
|
||||
|
||||
procedure Inspect.44 (Inspect.248):
|
||||
let Inspect.347 : Str = CallByName Inspect.30 Inspect.248;
|
||||
ret Inspect.347;
|
||||
|
||||
procedure Inspect.5 (Inspect.150):
|
||||
let Inspect.312 : Str = CallByName #Derived.0 Inspect.150;
|
||||
let Inspect.309 : {} = Struct {};
|
||||
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
|
||||
let Inspect.307 : Str = CallByName #Derived.3 Inspect.308 Inspect.312;
|
||||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.61 (Inspect.303, Inspect.298):
|
||||
let Inspect.324 : Str = CallByName Str.3 Inspect.303 Inspect.298;
|
||||
dec Inspect.298;
|
||||
ret Inspect.324;
|
||||
|
||||
procedure List.1 (List.102):
|
||||
let List.566 : U64 = CallByName List.6 List.102;
|
||||
dec List.102;
|
||||
let List.567 : U64 = 0i64;
|
||||
let List.565 : Int1 = CallByName Bool.11 List.566 List.567;
|
||||
ret List.565;
|
||||
|
||||
procedure List.18 (List.154, List.155, List.156):
|
||||
let List.554 : U64 = 0i64;
|
||||
let List.555 : U64 = CallByName List.6 List.154;
|
||||
let List.553 : Str = CallByName List.88 List.154 List.155 List.156 List.554 List.555;
|
||||
ret List.553;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.564 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.564;
|
||||
|
||||
procedure List.66 (#Attr.2, #Attr.3):
|
||||
let List.563 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.563;
|
||||
|
||||
procedure List.88 (#Derived_gen.18, #Derived_gen.19, #Derived_gen.20, #Derived_gen.21, #Derived_gen.22):
|
||||
joinpoint List.556 List.157 List.158 List.159 List.160 List.161:
|
||||
let List.558 : Int1 = CallByName Num.22 List.160 List.161;
|
||||
if List.558 then
|
||||
let List.562 : Str = CallByName List.66 List.157 List.160;
|
||||
inc List.562;
|
||||
let List.162 : Str = CallByName Inspect.209 List.158 List.562;
|
||||
let List.561 : U64 = 1i64;
|
||||
let List.560 : U64 = CallByName Num.51 List.160 List.561;
|
||||
jump List.556 List.157 List.162 List.159 List.560 List.161;
|
||||
else
|
||||
dec List.157;
|
||||
ret List.158;
|
||||
in
|
||||
jump List.556 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21 #Derived_gen.22;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.292 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
ret Num.292;
|
||||
|
||||
procedure Num.51 (#Attr.2, #Attr.3):
|
||||
let Num.291 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
|
||||
ret Num.291;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.292;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.5 : Str = "foo";
|
||||
let Test.4 : Str = CallByName Inspect.5 Test.5;
|
||||
let Test.3 : Str = CallByName Inspect.35 Test.4;
|
||||
ret Test.3;
|
|
@ -0,0 +1,178 @@
|
|||
procedure #Derived.0 (#Derived.1):
|
||||
let #Derived_gen.0 : {Str, Str} = CallByName Inspect.30 #Derived.1;
|
||||
ret #Derived_gen.0;
|
||||
|
||||
procedure #Derived.4 (#Derived.5, #Derived.1):
|
||||
joinpoint #Derived_gen.5 #Derived_gen.4:
|
||||
let #Derived_gen.3 : Str = CallByName Inspect.31 #Derived_gen.4 #Derived.5;
|
||||
ret #Derived_gen.3;
|
||||
in
|
||||
let #Derived.2 : Str = StructAtIndex 0 #Derived.1;
|
||||
let #Derived.3 : Str = StructAtIndex 1 #Derived.1;
|
||||
let #Derived_gen.7 : Str = "A";
|
||||
let #Derived_gen.9 : Str = CallByName Inspect.44 #Derived.2;
|
||||
let #Derived_gen.10 : Str = CallByName Inspect.44 #Derived.3;
|
||||
let #Derived_gen.8 : List Str = Array [#Derived_gen.9, #Derived_gen.10];
|
||||
let #Derived_gen.6 : [C Str, C Str List Str] = CallByName Inspect.40 #Derived_gen.7 #Derived_gen.8;
|
||||
jump #Derived_gen.5 #Derived_gen.6;
|
||||
|
||||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.23 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.23;
|
||||
|
||||
procedure Inspect.203 (Inspect.204, #Attr.12):
|
||||
let Inspect.346 : Str = UnionAtIndex (Id 0) (Index 0) #Attr.12;
|
||||
let Inspect.345 : Str = CallByName Inspect.61 Inspect.204 Inspect.346;
|
||||
ret Inspect.345;
|
||||
|
||||
procedure Inspect.205 (Inspect.206, #Attr.12):
|
||||
let Inspect.340 : List Str = UnionAtIndex (Id 1) (Index 1) #Attr.12;
|
||||
let Inspect.339 : Str = UnionAtIndex (Id 1) (Index 0) #Attr.12;
|
||||
let Inspect.338 : Str = "(";
|
||||
let Inspect.337 : Str = CallByName Inspect.61 Inspect.206 Inspect.338;
|
||||
let Inspect.325 : Str = CallByName Inspect.61 Inspect.337 Inspect.339;
|
||||
let Inspect.321 : Str = CallByName Inspect.207 Inspect.325 Inspect.340;
|
||||
let Inspect.322 : Str = ")";
|
||||
let Inspect.320 : Str = CallByName Inspect.61 Inspect.321 Inspect.322;
|
||||
ret Inspect.320;
|
||||
|
||||
procedure Inspect.207 (Inspect.208, Inspect.202):
|
||||
let Inspect.329 : {} = Struct {};
|
||||
let Inspect.328 : Str = CallByName List.18 Inspect.202 Inspect.208 Inspect.329;
|
||||
ret Inspect.328;
|
||||
|
||||
procedure Inspect.209 (Inspect.210, Inspect.211):
|
||||
let Inspect.336 : Str = " ";
|
||||
let Inspect.331 : Str = CallByName Inspect.61 Inspect.210 Inspect.336;
|
||||
let Inspect.330 : Str = CallByName Inspect.212 Inspect.331 Inspect.211;
|
||||
ret Inspect.330;
|
||||
|
||||
procedure Inspect.212 (Inspect.213, Inspect.211):
|
||||
let Inspect.334 : Str = CallByName Inspect.31 Inspect.211 Inspect.213;
|
||||
ret Inspect.334;
|
||||
|
||||
procedure Inspect.249 (Inspect.250, Inspect.248):
|
||||
let Inspect.355 : Str = "\"";
|
||||
let Inspect.354 : Str = CallByName Inspect.61 Inspect.250 Inspect.355;
|
||||
let Inspect.352 : Str = CallByName Inspect.61 Inspect.354 Inspect.248;
|
||||
let Inspect.353 : Str = "\"";
|
||||
let Inspect.351 : Str = CallByName Inspect.61 Inspect.352 Inspect.353;
|
||||
ret Inspect.351;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.315 : U8 = GetTagId Inspect.305;
|
||||
switch Inspect.315:
|
||||
case 0:
|
||||
let Inspect.314 : Str = CallByName Inspect.203 Inspect.149 Inspect.305;
|
||||
ret Inspect.314;
|
||||
|
||||
default:
|
||||
let Inspect.314 : Str = CallByName Inspect.205 Inspect.149 Inspect.305;
|
||||
ret Inspect.314;
|
||||
|
||||
|
||||
procedure Inspect.31 (Inspect.305, Inspect.149):
|
||||
let Inspect.335 : Str = CallByName Inspect.249 Inspect.149 Inspect.305;
|
||||
ret Inspect.335;
|
||||
|
||||
procedure Inspect.35 (Inspect.300):
|
||||
ret Inspect.300;
|
||||
|
||||
procedure Inspect.36 (Inspect.304):
|
||||
let Inspect.311 : Str = "";
|
||||
ret Inspect.311;
|
||||
|
||||
procedure Inspect.40 (Inspect.201, Inspect.202):
|
||||
inc Inspect.202;
|
||||
let Inspect.341 : Int1 = CallByName List.1 Inspect.202;
|
||||
if Inspect.341 then
|
||||
dec Inspect.202;
|
||||
let Inspect.343 : [C Str, C Str List Str] = TagId(0) Inspect.201;
|
||||
let Inspect.342 : [C Str, C Str List Str] = CallByName Inspect.30 Inspect.343;
|
||||
ret Inspect.342;
|
||||
else
|
||||
let Inspect.317 : [C Str, C Str List Str] = TagId(1) Inspect.201 Inspect.202;
|
||||
let Inspect.316 : [C Str, C Str List Str] = CallByName Inspect.30 Inspect.317;
|
||||
ret Inspect.316;
|
||||
|
||||
procedure Inspect.44 (Inspect.248):
|
||||
let Inspect.356 : Str = CallByName Inspect.30 Inspect.248;
|
||||
ret Inspect.356;
|
||||
|
||||
procedure Inspect.5 (Inspect.150):
|
||||
let Inspect.312 : {Str, Str} = CallByName #Derived.0 Inspect.150;
|
||||
let Inspect.309 : {} = Struct {};
|
||||
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
|
||||
let Inspect.307 : Str = CallByName #Derived.4 Inspect.308 Inspect.312;
|
||||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.61 (Inspect.303, Inspect.298):
|
||||
let Inspect.324 : Str = CallByName Str.3 Inspect.303 Inspect.298;
|
||||
dec Inspect.298;
|
||||
ret Inspect.324;
|
||||
|
||||
procedure List.1 (List.102):
|
||||
let List.566 : U64 = CallByName List.6 List.102;
|
||||
dec List.102;
|
||||
let List.567 : U64 = 0i64;
|
||||
let List.565 : Int1 = CallByName Bool.11 List.566 List.567;
|
||||
ret List.565;
|
||||
|
||||
procedure List.18 (List.154, List.155, List.156):
|
||||
let List.554 : U64 = 0i64;
|
||||
let List.555 : U64 = CallByName List.6 List.154;
|
||||
let List.553 : Str = CallByName List.88 List.154 List.155 List.156 List.554 List.555;
|
||||
ret List.553;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.564 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.564;
|
||||
|
||||
procedure List.66 (#Attr.2, #Attr.3):
|
||||
let List.563 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.563;
|
||||
|
||||
procedure List.88 (#Derived_gen.19, #Derived_gen.20, #Derived_gen.21, #Derived_gen.22, #Derived_gen.23):
|
||||
joinpoint List.556 List.157 List.158 List.159 List.160 List.161:
|
||||
let List.558 : Int1 = CallByName Num.22 List.160 List.161;
|
||||
if List.558 then
|
||||
let List.562 : Str = CallByName List.66 List.157 List.160;
|
||||
inc List.562;
|
||||
let List.162 : Str = CallByName Inspect.209 List.158 List.562;
|
||||
let List.561 : U64 = 1i64;
|
||||
let List.560 : U64 = CallByName Num.51 List.160 List.561;
|
||||
jump List.556 List.157 List.162 List.159 List.560 List.161;
|
||||
else
|
||||
dec List.157;
|
||||
ret List.158;
|
||||
in
|
||||
jump List.556 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21 #Derived_gen.22 #Derived_gen.23;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.292 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
ret Num.292;
|
||||
|
||||
procedure Num.51 (#Attr.2, #Attr.3):
|
||||
let Num.291 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
|
||||
ret Num.291;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.292;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.6 : Str = "foo";
|
||||
let Test.5 : Str = "foo";
|
||||
let Test.1 : {Str, Str} = Struct {Test.5, Test.6};
|
||||
let Test.4 : Str = CallByName Inspect.5 Test.1;
|
||||
let Test.3 : Str = CallByName Inspect.35 Test.4;
|
||||
ret Test.3;
|
|
@ -0,0 +1,15 @@
|
|||
procedure Num.19 (#Attr.2, #Attr.3):
|
||||
let Num.292 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||
ret Num.292;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.7 : I64 = 1i64;
|
||||
let Test.8 : I64 = 2i64;
|
||||
let Test.9 : I64 = 3i64;
|
||||
let Test.1 : {I64, I64, I64} = Struct {Test.7, Test.8, Test.9};
|
||||
let Test.2 : I64 = StructAtIndex 0 Test.1;
|
||||
let Test.3 : I64 = StructAtIndex 1 Test.1;
|
||||
let Test.4 : I64 = StructAtIndex 2 Test.1;
|
||||
let Test.6 : I64 = CallByName Num.19 Test.2 Test.3;
|
||||
let Test.5 : I64 = CallByName Num.19 Test.6 Test.4;
|
||||
ret Test.5;
|
|
@ -0,0 +1,23 @@
|
|||
procedure Num.19 (#Attr.2, #Attr.3):
|
||||
let Num.291 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||
ret Num.291;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.17 : {} = Struct {};
|
||||
let Test.15 : List {} = Array [Test.17];
|
||||
let Test.16 : Str = "foo";
|
||||
let Test.14 : {List {}, Str} = Struct {Test.15, Test.16};
|
||||
let Test.10 : List {} = StructAtIndex 0 Test.14;
|
||||
dec Test.16;
|
||||
let Test.11 : U64 = lowlevel ListLen Test.10;
|
||||
dec Test.10;
|
||||
let Test.12 : U64 = 1i64;
|
||||
let Test.13 : Int1 = lowlevel Eq Test.11 Test.12;
|
||||
if Test.13 then
|
||||
let Test.5 : I64 = 1i64;
|
||||
let Test.6 : I64 = 1i64;
|
||||
let Test.2 : I64 = CallByName Num.19 Test.5 Test.6;
|
||||
ret Test.2;
|
||||
else
|
||||
let Test.7 : I64 = 0i64;
|
||||
ret Test.7;
|
|
@ -0,0 +1,10 @@
|
|||
procedure Num.19 (#Attr.2, #Attr.3):
|
||||
let Num.291 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||
ret Num.291;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.5 : {} = Struct {};
|
||||
let Test.3 : I64 = 1i64;
|
||||
let Test.4 : I64 = 1i64;
|
||||
let Test.1 : I64 = CallByName Num.19 Test.3 Test.4;
|
||||
ret Test.1;
|
|
@ -893,6 +893,37 @@ fn optional_when() {
|
|||
"#
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
fn optional_field_with_binary_op() {
|
||||
r#"
|
||||
{ bar ? 1 + 1 } = {}
|
||||
bar
|
||||
"#
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
fn nested_optional_field_with_binary_op() {
|
||||
r#"
|
||||
when { x: ([{}], "foo") } is
|
||||
{ x: ([{ bar ? 1 + 1 }], _) } -> bar
|
||||
_ -> 0
|
||||
"#
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
fn multiline_record_pattern() {
|
||||
r#"
|
||||
x = { a: 1, b: 2, c: 3 }
|
||||
{
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
} = x
|
||||
|
||||
a + b + c
|
||||
"#
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
fn nested_pattern_match() {
|
||||
r#"
|
||||
|
@ -3258,3 +3289,150 @@ fn non_nullable_unwrapped_instead_of_nullable_wrapped() {
|
|||
"#
|
||||
)
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
#[ignore = "Hits an unimplemented for abilities, not sure why..."]
|
||||
fn inspect_custom_type() {
|
||||
indoc!(
|
||||
r#"
|
||||
app "test"
|
||||
imports []
|
||||
provides [main] to "./platform"
|
||||
|
||||
HelloWorld := {} implements [Inspect { toInspector: myToInspector }]
|
||||
|
||||
myToInspector : HelloWorld -> Inspector f where f implements InspectFormatter
|
||||
myToInspector = \@HellowWorld {} ->
|
||||
fmt <- Inspect.custom
|
||||
Inspect.apply (Inspect.str "Hello, World!\n") fmt
|
||||
|
||||
main =
|
||||
Inspect.inspect (@HelloWorld {})
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
fn inspect_derived_string() {
|
||||
indoc!(
|
||||
r#"
|
||||
app "test"
|
||||
imports []
|
||||
provides [main] to "./platform"
|
||||
|
||||
main = Inspect.inspect "abc" |> Inspect.toDbgStr
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
fn inspect_derived_record() {
|
||||
indoc!(
|
||||
r#"
|
||||
app "test"
|
||||
imports []
|
||||
provides [main] to "./platform"
|
||||
|
||||
main = Inspect.inspect {a: 7, b: 3dec} |> Inspect.toDbgStr
|
||||
"#
|
||||
)
|
||||
}
|
||||
#[mono_test]
|
||||
fn inspect_derived_record_one_field_string() {
|
||||
indoc!(
|
||||
r#"
|
||||
app "test"
|
||||
imports []
|
||||
provides [main] to "./platform"
|
||||
|
||||
main = Inspect.inspect {a: "foo"} |> Inspect.toDbgStr
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
fn inspect_derived_record_two_field_strings() {
|
||||
indoc!(
|
||||
r#"
|
||||
app "test"
|
||||
imports []
|
||||
provides [main] to "./platform"
|
||||
|
||||
main = Inspect.inspect {a: "foo", b: "bar"} |> Inspect.toDbgStr
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
fn inspect_derived_nested_record_string() {
|
||||
indoc!(
|
||||
r#"
|
||||
app "test"
|
||||
imports []
|
||||
provides [main] to "./platform"
|
||||
|
||||
main = Inspect.inspect {a: {b: "bar"}} |> Inspect.toDbgStr
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
fn inspect_derived_tag_one_field_string() {
|
||||
indoc!(
|
||||
r#"
|
||||
app "test"
|
||||
imports []
|
||||
provides [main] to "./platform"
|
||||
|
||||
main =
|
||||
x : [A Str]
|
||||
x = A "foo"
|
||||
Inspect.inspect x |> Inspect.toDbgStr
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
fn inspect_derived_tag_two_payloads_string() {
|
||||
indoc!(
|
||||
r#"
|
||||
app "test"
|
||||
imports []
|
||||
provides [main] to "./platform"
|
||||
|
||||
main =
|
||||
x : [A Str Str]
|
||||
x = A "foo" "foo"
|
||||
Inspect.inspect x |> Inspect.toDbgStr
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
||||
#[mono_test]
|
||||
fn inspect_derived_list() {
|
||||
indoc!(
|
||||
r#"
|
||||
app "test"
|
||||
imports []
|
||||
provides [main] to "./platform"
|
||||
|
||||
main = Inspect.inspect [1, 2, 3] |> Inspect.toDbgStr
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
||||
#[mono_test(large_stack = "true")]
|
||||
fn inspect_derived_dict() {
|
||||
indoc!(
|
||||
r#"
|
||||
app "test"
|
||||
imports []
|
||||
provides [main] to "./platform"
|
||||
|
||||
main =
|
||||
Dict.fromList [("a", 1), ("b", 2)]
|
||||
|> Inspect.inspect
|
||||
|> Inspect.toDbgStr
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
app "hello"
|
||||
packages {
|
||||
pf:
|
||||
"https://github.com/roc-lang/basic-cli/releases/download/0.5.0/Cufzl36_SnJ4QbOoEmiJ5dIpUxBvdB3NEySvuH82Wio.tar.br",
|
||||
"https://github.com/roc-lang/basic-cli/releases/download/0.7.0/bkGby8jb0tmZYsy2hg1E_B2QrCgcSTxdUlHtETwm5m4.tar.br",
|
||||
}
|
||||
imports [pf.Stdout]
|
||||
provides [main] to pf
|
||||
|
|
|
@ -24,7 +24,7 @@ Full {
|
|||
Newline,
|
||||
],
|
||||
package_name: @31-145 PackageName(
|
||||
"https://github.com/roc-lang/basic-cli/releases/download/0.5.0/Cufzl36_SnJ4QbOoEmiJ5dIpUxBvdB3NEySvuH82Wio.tar.br",
|
||||
"https://github.com/roc-lang/basic-cli/releases/download/0.7.0/bkGby8jb0tmZYsy2hg1E_B2QrCgcSTxdUlHtETwm5m4.tar.br",
|
||||
),
|
||||
},
|
||||
[
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
app "hello"
|
||||
packages { pf:
|
||||
"https://github.com/roc-lang/basic-cli/releases/download/0.5.0/Cufzl36_SnJ4QbOoEmiJ5dIpUxBvdB3NEySvuH82Wio.tar.br"
|
||||
"https://github.com/roc-lang/basic-cli/releases/download/0.7.0/bkGby8jb0tmZYsy2hg1E_B2QrCgcSTxdUlHtETwm5m4.tar.br"
|
||||
}
|
||||
imports [pf.Stdout]
|
||||
provides [main] to pf
|
||||
|
|
|
@ -1726,6 +1726,8 @@ impl Subs {
|
|||
pub const AB_HASH: SubsSlice<Symbol> = SubsSlice::new(3, 1);
|
||||
#[rustfmt::skip]
|
||||
pub const AB_EQ: SubsSlice<Symbol> = SubsSlice::new(4, 1);
|
||||
#[rustfmt::skip]
|
||||
pub const AB_INSPECT: SubsSlice<Symbol> = SubsSlice::new(5, 1);
|
||||
// END INIT-SymbolSubsSlice
|
||||
|
||||
pub fn new() -> Self {
|
||||
|
@ -1746,7 +1748,7 @@ impl Subs {
|
|||
tag_names.push(TagName("OutOfBounds".into()));
|
||||
// END INIT-TagNames
|
||||
|
||||
// IFTTT INIT-SymbolNames
|
||||
// IFTTT INIT-SymbolSubsSlice
|
||||
let mut symbol_names = Vec::with_capacity(32);
|
||||
|
||||
symbol_names.push(Symbol::ENCODE_ENCODING);
|
||||
|
@ -1754,7 +1756,8 @@ impl Subs {
|
|||
symbol_names.push(Symbol::HASH_HASHER);
|
||||
symbol_names.push(Symbol::HASH_HASH_ABILITY);
|
||||
symbol_names.push(Symbol::BOOL_EQ);
|
||||
// END INIT-SymbolNames
|
||||
symbol_names.push(Symbol::INSPECT_INSPECT_ABILITY);
|
||||
// END INIT-SymbolSubsSlice
|
||||
|
||||
// IFTTT INIT-VariableSubsSlice
|
||||
let variables = vec![Variable::STR];
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
app "test" provides [main] to "./platform"
|
||||
|
||||
main = Inspect.toInspector Bool.true |> Inspect.apply (Inspect.init {}) |> Inspect.toDbgStr
|
||||
# ^^^^^^^^^^^^^^^^^^^ Inspect#Inspect.toInspector(32): Bool -[[Inspect.dbgBool(43)]]-> Inspector DbgFormatter
|
|
@ -0,0 +1,4 @@
|
|||
app "test" provides [main] to "./platform"
|
||||
|
||||
main = Inspect.toInspector 7dec |> Inspect.apply (Inspect.init {}) |> Inspect.toDbgStr
|
||||
# ^^^^^^^^^^^^^^^^^^^ Inspect#Inspect.toInspector(32): Dec -[[Inspect.dbgDec(60)]]-> Inspector DbgFormatter
|
|
@ -0,0 +1,6 @@
|
|||
app "test" provides [main] to "./platform"
|
||||
|
||||
Op := {}
|
||||
|
||||
main = Inspect.toInspector (@Op {}) |> Inspect.apply (Inspect.init {}) |> Inspect.toDbgStr
|
||||
# ^^^^^^^^^^^^^^^^^^^ Inspect#Inspect.toInspector(32): Op -[[Inspect.dbgOpaque(45)]]-> Inspector DbgFormatter
|
|
@ -0,0 +1,54 @@
|
|||
# +emit:mono
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
Op := {}
|
||||
|
||||
main =
|
||||
dbg (@Op {})
|
||||
1
|
||||
|
||||
# -emit:mono
|
||||
procedure Inspect.251 (Inspect.252):
|
||||
let Inspect.317 : Str = "<opaque>";
|
||||
let Inspect.316 : Str = CallByName Inspect.61 Inspect.252 Inspect.317;
|
||||
ret Inspect.316;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.35 (Inspect.300):
|
||||
ret Inspect.300;
|
||||
|
||||
procedure Inspect.36 (Inspect.304):
|
||||
let Inspect.311 : Str = "";
|
||||
ret Inspect.311;
|
||||
|
||||
procedure Inspect.45 (Inspect.302):
|
||||
let Inspect.314 : {} = Struct {};
|
||||
let Inspect.313 : {} = CallByName Inspect.30 Inspect.314;
|
||||
ret Inspect.313;
|
||||
|
||||
procedure Inspect.5 (Inspect.150):
|
||||
let Inspect.312 : {} = CallByName Inspect.45 Inspect.150;
|
||||
let Inspect.309 : {} = Struct {};
|
||||
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
|
||||
let Inspect.307 : Str = CallByName Inspect.251 Inspect.308;
|
||||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.61 (Inspect.303, Inspect.298):
|
||||
let Inspect.319 : Str = CallByName Str.3 Inspect.303 Inspect.298;
|
||||
dec Inspect.298;
|
||||
ret Inspect.319;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.292;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.5 : {} = Struct {};
|
||||
let Test.4 : Str = CallByName Inspect.5 Test.5;
|
||||
let Test.2 : Str = CallByName Inspect.35 Test.4;
|
||||
dbg Test.2;
|
||||
dec Test.2;
|
||||
let Test.3 : I64 = 1i64;
|
||||
ret Test.3;
|
|
@ -0,0 +1,61 @@
|
|||
# +emit:mono
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
Op := {}
|
||||
|
||||
late = \a ->
|
||||
dbg a
|
||||
1
|
||||
|
||||
main =
|
||||
late (@Op {})
|
||||
|
||||
# -emit:mono
|
||||
procedure Inspect.251 (Inspect.252):
|
||||
let Inspect.317 : Str = "<opaque>";
|
||||
let Inspect.316 : Str = CallByName Inspect.61 Inspect.252 Inspect.317;
|
||||
ret Inspect.316;
|
||||
|
||||
procedure Inspect.30 (Inspect.147):
|
||||
ret Inspect.147;
|
||||
|
||||
procedure Inspect.35 (Inspect.300):
|
||||
ret Inspect.300;
|
||||
|
||||
procedure Inspect.36 (Inspect.304):
|
||||
let Inspect.311 : Str = "";
|
||||
ret Inspect.311;
|
||||
|
||||
procedure Inspect.45 (Inspect.302):
|
||||
let Inspect.314 : {} = Struct {};
|
||||
let Inspect.313 : {} = CallByName Inspect.30 Inspect.314;
|
||||
ret Inspect.313;
|
||||
|
||||
procedure Inspect.5 (Inspect.150):
|
||||
let Inspect.312 : {} = CallByName Inspect.45 Inspect.150;
|
||||
let Inspect.309 : {} = Struct {};
|
||||
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
|
||||
let Inspect.307 : Str = CallByName Inspect.251 Inspect.308;
|
||||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.61 (Inspect.303, Inspect.298):
|
||||
let Inspect.319 : Str = CallByName Str.3 Inspect.303 Inspect.298;
|
||||
dec Inspect.298;
|
||||
ret Inspect.319;
|
||||
|
||||
procedure Str.3 (#Attr.2, #Attr.3):
|
||||
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
|
||||
ret Str.292;
|
||||
|
||||
procedure Test.2 (Test.3):
|
||||
let Test.8 : Str = CallByName Inspect.5 Test.3;
|
||||
let Test.4 : Str = CallByName Inspect.35 Test.8;
|
||||
dbg Test.4;
|
||||
dec Test.4;
|
||||
let Test.7 : I64 = 1i64;
|
||||
ret Test.7;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.6 : {} = Struct {};
|
||||
let Test.5 : I64 = CallByName Test.2 Test.6;
|
||||
ret Test.5;
|
|
@ -0,0 +1,9 @@
|
|||
app "test" provides [main] to "./platform"
|
||||
|
||||
Op := U8 implements [Inspect { toInspector: myToInspector }]
|
||||
|
||||
myToInspector : Op -> Inspector f where f implements InspectFormatter
|
||||
myToInspector = \@Op num -> Inspect.u8 num
|
||||
|
||||
main = Inspect.toInspector (@Op 1u8) |> Inspect.apply (Inspect.init {}) |> Inspect.toDbgStr
|
||||
# ^^^^^^^^^^^^^^^^^^^ Op#Inspect.toInspector(2): Op -[[myToInspector(2)]]-> Inspector DbgFormatter
|
|
@ -0,0 +1,6 @@
|
|||
app "test" provides [main] to "./platform"
|
||||
|
||||
Op := U8 implements [Inspect]
|
||||
|
||||
main = Inspect.toInspector (@Op 1u8) |> Inspect.apply (Inspect.init {}) |> Inspect.toDbgStr
|
||||
# ^^^^^^^^^^^^^^^^^^^ Op#Inspect.toInspector(3): Op -[[#Op_toInspector(3)]]-> Inspector DbgFormatter
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue