mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 12:18:19 +00:00
Merge branch 'main' into new-builder-syntax
This commit is contained in:
commit
618b713ecd
70 changed files with 1654 additions and 256 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -941,6 +941,13 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"widestring",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_at"
|
||||
version = "0.1.10"
|
||||
|
@ -4551,6 +4558,12 @@ version = "0.25.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc"
|
||||
|
||||
[[package]]
|
||||
name = "widestring"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
|
102
Cargo.toml
102
Cargo.toml
|
@ -1,40 +1,41 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"crates/compiler/*",
|
||||
"crates/vendor/*",
|
||||
"crates/glue",
|
||||
"crates/cli",
|
||||
"crates/cli_utils",
|
||||
"crates/highlight",
|
||||
"crates/error_macros",
|
||||
"crates/reporting",
|
||||
"crates/packaging",
|
||||
"crates/repl_cli",
|
||||
"crates/repl_eval",
|
||||
"crates/repl_test",
|
||||
"crates/repl_ui",
|
||||
"crates/repl_wasm",
|
||||
"crates/repl_expect",
|
||||
"crates/roc_std",
|
||||
"crates/test_utils",
|
||||
"crates/test_utils_dir",
|
||||
"crates/valgrind",
|
||||
"crates/tracing",
|
||||
"crates/utils/*",
|
||||
"crates/docs",
|
||||
"crates/docs_cli",
|
||||
"crates/linker",
|
||||
"crates/wasi-libc-sys",
|
||||
"crates/wasm_module",
|
||||
"crates/wasm_interp",
|
||||
"crates/language_server",
|
||||
"crates/compiler/*",
|
||||
"crates/vendor/*",
|
||||
"crates/fs",
|
||||
"crates/glue",
|
||||
"crates/cli",
|
||||
"crates/cli_utils",
|
||||
"crates/highlight",
|
||||
"crates/error_macros",
|
||||
"crates/reporting",
|
||||
"crates/packaging",
|
||||
"crates/repl_cli",
|
||||
"crates/repl_eval",
|
||||
"crates/repl_test",
|
||||
"crates/repl_ui",
|
||||
"crates/repl_wasm",
|
||||
"crates/repl_expect",
|
||||
"crates/roc_std",
|
||||
"crates/test_utils",
|
||||
"crates/test_utils_dir",
|
||||
"crates/valgrind",
|
||||
"crates/tracing",
|
||||
"crates/utils/*",
|
||||
"crates/docs",
|
||||
"crates/docs_cli",
|
||||
"crates/linker",
|
||||
"crates/wasi-libc-sys",
|
||||
"crates/wasm_module",
|
||||
"crates/wasm_interp",
|
||||
"crates/language_server",
|
||||
]
|
||||
|
||||
exclude = [
|
||||
"ci/benchmarks/bench-runner",
|
||||
"ci/repl_basic_test",
|
||||
# Examples sometimes have Rust hosts in their platforms. The compiler should ignore those.
|
||||
"examples",
|
||||
"ci/benchmarks/bench-runner",
|
||||
"ci/repl_basic_test",
|
||||
# Examples sometimes have Rust hosts in their platforms. The compiler should ignore those.
|
||||
"examples",
|
||||
]
|
||||
# Needed to be able to run `cargo run -p roc_cli --no-default-features` -
|
||||
# see www/build.sh for more.
|
||||
|
@ -69,7 +70,9 @@ version = "0.0.1"
|
|||
# change the tag value in this Cargo.toml to point to that tag, and `cargo update`.
|
||||
# This way, GitHub Actions works and nobody's builds get broken.
|
||||
# TODO: Switch this back to roc-lang/inkwell once it is updated
|
||||
inkwell = { git = "https://github.com/roc-lang/inkwell", branch = "inkwell-llvm-16", features = ["llvm16-0"] }
|
||||
inkwell = { git = "https://github.com/roc-lang/inkwell", branch = "inkwell-llvm-16", features = [
|
||||
"llvm16-0",
|
||||
] }
|
||||
|
||||
arrayvec = "0.7.2" # update roc_std/Cargo.toml on change
|
||||
backtrace = "0.3.67"
|
||||
|
@ -78,18 +81,27 @@ bincode = "1.3.3"
|
|||
bitflags = "1.3.2"
|
||||
bitvec = "1.0.1"
|
||||
blake3 = "1.3.3"
|
||||
brotli = "3.3.4" # used for decompressing tarballs over HTTPS, if the server supports brotli
|
||||
brotli = "3.3.4" # used for decompressing tarballs over HTTPS, if the server supports brotli
|
||||
bumpalo = { version = "3.12.0", features = ["collections"] }
|
||||
bytemuck = { version = "1.13.1", features = ["derive"] }
|
||||
capstone = { version = "0.11.0", default-features = false }
|
||||
cgmath = "0.18.0"
|
||||
chrono = "0.4.26"
|
||||
clap = { version = "4.2.7", default-features = false, features = ["std", "color", "suggestions", "help", "usage", "error-context"] }
|
||||
clap = { version = "4.2.7", default-features = false, features = [
|
||||
"std",
|
||||
"color",
|
||||
"suggestions",
|
||||
"help",
|
||||
"usage",
|
||||
"error-context",
|
||||
] }
|
||||
colored = "2.0.0"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
const_format = { version = "0.2.30", features = ["const_generics"] }
|
||||
copypasta = "0.8.2"
|
||||
criterion = { git = "https://github.com/Anton-4/criterion.rs", features = ["html_reports"], rev = "30ea0c5" }
|
||||
criterion = { git = "https://github.com/Anton-4/criterion.rs", features = [
|
||||
"html_reports",
|
||||
], rev = "30ea0c5" }
|
||||
criterion-perf-events = { git = "https://github.com/Anton-4/criterion-perf-events", rev = "0f38c3e" }
|
||||
crossbeam = "0.8.2"
|
||||
dircpy = "0.3.14"
|
||||
|
@ -102,7 +114,12 @@ fs_extra = "1.3.0"
|
|||
futures = "0.3.26"
|
||||
glyph_brush = "0.7.7"
|
||||
hashbrown = { version = "0.14.3" }
|
||||
iced-x86 = { version = "1.18.0", default-features = false, features = ["std", "decoder", "op_code_info", "instr_info"] }
|
||||
iced-x86 = { version = "1.18.0", default-features = false, features = [
|
||||
"std",
|
||||
"decoder",
|
||||
"op_code_info",
|
||||
"instr_info",
|
||||
] }
|
||||
im = "15.1.0"
|
||||
im-rc = "15.1.0"
|
||||
indexmap = "2.1.0"
|
||||
|
@ -138,12 +155,17 @@ quote = "1.0.23"
|
|||
rand = "0.8.5"
|
||||
regex = "1.7.1"
|
||||
remove_dir_all = "0.8.1"
|
||||
reqwest = { version = "0.11.23", default-features = false, features = ["blocking", "rustls-tls"] } # default-features=false removes libopenssl as a dependency on Linux, which might not be available!
|
||||
reqwest = { version = "0.11.23", default-features = false, features = [
|
||||
"blocking",
|
||||
"rustls-tls",
|
||||
] } # default-features=false removes libopenssl as a dependency on Linux, which might not be available!
|
||||
rlimit = "0.9.1"
|
||||
rustyline = { git = "https://github.com/roc-lang/rustyline", rev = "e74333c" }
|
||||
rustyline-derive = { git = "https://github.com/roc-lang/rustyline", rev = "e74333c" }
|
||||
schemars = "0.8.12"
|
||||
serde = { version = "1.0.153", features = ["derive"] } # update roc_std/Cargo.toml on change
|
||||
serde = { version = "1.0.153", features = [
|
||||
"derive",
|
||||
] } # update roc_std/Cargo.toml on change
|
||||
serde-xml-rs = "0.6.0"
|
||||
serde_json = "1.0.94" # update roc_std/Cargo.toml on change
|
||||
serial_test = "1.0.0"
|
||||
|
@ -191,7 +213,7 @@ debug = true
|
|||
|
||||
[profile.release-with-lto]
|
||||
inherits = "release"
|
||||
lto = "thin" # TODO: We could consider full here since this is only used for packaged release on github.
|
||||
lto = "thin" # TODO: We could consider full here since this is only used for packaged release on github.
|
||||
|
||||
[profile.debug-full]
|
||||
inherits = "dev"
|
||||
|
|
|
@ -13,15 +13,18 @@ use roc_build::program::{
|
|||
handle_error_module, handle_loading_problem, standard_load_config, BuildFileError,
|
||||
BuildOrdering, BuiltFile, CodeGenBackend, CodeGenOptions, DEFAULT_ROC_FILENAME,
|
||||
};
|
||||
#[cfg(not(windows))]
|
||||
use roc_collections::MutMap;
|
||||
use roc_error_macros::{internal_error, user_error};
|
||||
use roc_gen_dev::AssemblyBackendMode;
|
||||
use roc_gen_llvm::llvm::build::LlvmBackendMode;
|
||||
use roc_load::{ExpectMetadata, Threading};
|
||||
#[cfg(not(windows))]
|
||||
use roc_module::symbol::ModuleId;
|
||||
use roc_mono::ir::OptLevel;
|
||||
use roc_packaging::cache::RocCacheDir;
|
||||
use roc_packaging::tarball::Compression;
|
||||
#[cfg(not(windows))]
|
||||
use roc_reporting::report::ANSI_STYLE_CODES;
|
||||
use roc_target::{Architecture, Target};
|
||||
use std::env;
|
||||
|
@ -31,7 +34,9 @@ use std::mem::ManuallyDrop;
|
|||
use std::os::raw::{c_char, c_int};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
use std::time::{Duration, Instant};
|
||||
#[cfg(not(windows))]
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
use strum::IntoEnumIterator;
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use tempfile::TempDir;
|
||||
|
@ -468,6 +473,7 @@ pub fn test(_matches: &ArgMatches, _target: Target) -> io::Result<i32> {
|
|||
todo!("running tests does not work on windows right now")
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
struct ModuleTestResults {
|
||||
module_id: ModuleId,
|
||||
failed_count: usize,
|
||||
|
@ -516,8 +522,7 @@ pub fn test(matches: &ArgMatches, target: Target) -> io::Result<i32> {
|
|||
}
|
||||
|
||||
let arena = &arena;
|
||||
// TODO may need to determine this dynamically based on dev builds.
|
||||
let function_kind = FunctionKind::LambdaSet;
|
||||
let function_kind = FunctionKind::from_env();
|
||||
|
||||
let opt_main_path = matches.get_one::<PathBuf>(FLAG_MAIN);
|
||||
|
||||
|
@ -647,6 +652,7 @@ pub fn test(matches: &ArgMatches, target: Target) -> io::Result<i32> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn print_test_results(
|
||||
module_test_results: ModuleTestResults,
|
||||
sources: &MutMap<ModuleId, (PathBuf, Box<str>)>,
|
||||
|
@ -666,6 +672,7 @@ fn print_test_results(
|
|||
println!("\n{module_name}:\n {test_summary_str}",);
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn test_summary(failed_count: usize, passed_count: usize, tests_duration: Duration) -> String {
|
||||
let failed_color = if failed_count == 0 {
|
||||
ANSI_STYLE_CODES.green
|
||||
|
|
|
@ -126,7 +126,7 @@ fn main() -> io::Result<()> {
|
|||
.get_one::<String>(FLAG_TARGET)
|
||||
.and_then(|s| Target::from_str(s).ok())
|
||||
.unwrap_or_default();
|
||||
let function_kind = FunctionKind::LambdaSet;
|
||||
let function_kind = FunctionKind::from_env();
|
||||
roc_linker::generate_stub_lib(
|
||||
input_path,
|
||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||
|
|
|
@ -695,20 +695,9 @@ pub fn standard_load_config(
|
|||
BuildOrdering::AlwaysBuild => ExecutionMode::Executable,
|
||||
};
|
||||
|
||||
// UNSTABLE(lambda-erasure)
|
||||
let function_kind = if cfg!(debug_assertions) {
|
||||
if std::env::var("EXPERIMENTAL_ROC_ERASE").is_ok() {
|
||||
FunctionKind::Erased
|
||||
} else {
|
||||
FunctionKind::LambdaSet
|
||||
}
|
||||
} else {
|
||||
FunctionKind::LambdaSet
|
||||
};
|
||||
|
||||
LoadConfig {
|
||||
target,
|
||||
function_kind,
|
||||
function_kind: FunctionKind::from_env(),
|
||||
render: RenderTarget::ColorTerminal,
|
||||
palette: DEFAULT_PALETTE,
|
||||
threading,
|
||||
|
@ -1202,8 +1191,7 @@ pub fn check_file<'a>(
|
|||
|
||||
let load_config = LoadConfig {
|
||||
target,
|
||||
// TODO: we may not want this for just checking.
|
||||
function_kind: FunctionKind::LambdaSet,
|
||||
function_kind: FunctionKind::from_env(),
|
||||
// TODO: expose this from CLI?
|
||||
render: RenderTarget::ColorTerminal,
|
||||
palette: DEFAULT_PALETTE,
|
||||
|
|
|
@ -1,28 +1,223 @@
|
|||
use bumpalo::{collections::Vec, Bump};
|
||||
use bumpalo::{
|
||||
collections::{CollectIn, Vec},
|
||||
Bump,
|
||||
};
|
||||
use roc_collections::{MutMap, ReferenceMatrix};
|
||||
use roc_module::symbol::Symbol;
|
||||
|
||||
use crate::{
|
||||
inc_dec::Ownership,
|
||||
ir::{Call, CallType, Expr, Proc, Stmt},
|
||||
layout::{Builtin, InLayout, LayoutInterner, LayoutRepr},
|
||||
ir::{Call, CallType, Expr, JoinPointId, Param, Proc, ProcLayout, Stmt},
|
||||
layout::{Builtin, InLayout, LayoutInterner, LayoutRepr, Niche},
|
||||
};
|
||||
|
||||
#[allow(unused)]
|
||||
pub(crate) fn infer_borrow_signature<'a>(
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub(crate) struct BorrowSignature(u64);
|
||||
|
||||
impl std::fmt::Debug for BorrowSignature {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let mut f = &mut f.debug_struct("BorrowSignature");
|
||||
|
||||
for (i, ownership) in self.iter().enumerate() {
|
||||
f = f.field(&format!("_{i}"), &ownership);
|
||||
}
|
||||
|
||||
f.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl BorrowSignature {
|
||||
fn new(len: usize) -> Self {
|
||||
assert!(len < 64 - 8);
|
||||
|
||||
Self(len as _)
|
||||
}
|
||||
|
||||
fn from_layouts<'a>(
|
||||
interner: &impl LayoutInterner<'a>,
|
||||
layouts: impl ExactSizeIterator<Item = &'a InLayout<'a>>,
|
||||
) -> Self {
|
||||
let mut signature = BorrowSignature::new(layouts.len());
|
||||
|
||||
for (i, layout) in layouts.enumerate() {
|
||||
signature.set(i, layout_to_ownership(*layout, interner));
|
||||
}
|
||||
|
||||
signature
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
(self.0 & 0xFF) as usize
|
||||
}
|
||||
|
||||
fn get(&self, index: usize) -> Option<&Ownership> {
|
||||
if index >= self.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
match self.0 & (1 << (index + 8)) {
|
||||
0 => Some(&Ownership::Borrowed),
|
||||
_ => Some(&Ownership::Owned),
|
||||
}
|
||||
}
|
||||
|
||||
fn set(&mut self, index: usize, ownership: Ownership) -> bool {
|
||||
assert!(index < self.len());
|
||||
|
||||
let modified = self.get(index) != Some(&ownership);
|
||||
|
||||
let mask = 1 << (index + 8);
|
||||
|
||||
match ownership {
|
||||
Ownership::Owned => self.0 |= mask,
|
||||
Ownership::Borrowed => self.0 &= !mask,
|
||||
}
|
||||
|
||||
modified
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = Ownership> + '_ {
|
||||
let mut i = 0;
|
||||
|
||||
std::iter::from_fn(move || {
|
||||
let value = self.get(i)?;
|
||||
i += 1;
|
||||
Some(*value)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Index<usize> for BorrowSignature {
|
||||
type Output = Ownership;
|
||||
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
self.get(index).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct BorrowSignatures<'a> {
|
||||
pub(crate) procs: MutMap<(Symbol, ProcLayout<'a>), BorrowSignature>,
|
||||
}
|
||||
|
||||
pub(crate) fn infer_borrow_signatures<'a>(
|
||||
arena: &'a Bump,
|
||||
interner: &impl LayoutInterner<'a>,
|
||||
proc: &'a Proc<'a>,
|
||||
) -> &'a [Ownership] {
|
||||
let mut state = State::new(arena, interner, proc);
|
||||
state.inspect_stmt(&proc.body);
|
||||
procs: &MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||
) -> BorrowSignatures<'a> {
|
||||
let mut borrow_signatures: BorrowSignatures = BorrowSignatures {
|
||||
procs: procs
|
||||
.iter()
|
||||
.map(|(_key, proc)| {
|
||||
let key = (proc.name.name(), proc.proc_layout(arena));
|
||||
let signature = BorrowSignature::from_layouts(interner, key.1.arguments.iter());
|
||||
(key, signature)
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
// for every proc (by index) a collection of its join points
|
||||
let mut join_points: Vec<_> = std::iter::repeat_with(MutMap::default)
|
||||
.take(procs.len())
|
||||
.collect_in(arena);
|
||||
|
||||
// next we first partition the functions into strongly connected components, then do a
|
||||
// topological sort on these components, finally run the fix-point borrow analysis on each
|
||||
// component (in top-sorted order, from primitives (std-lib) to main)
|
||||
|
||||
let matrix = construct_reference_matrix(arena, procs);
|
||||
let sccs = matrix.strongly_connected_components_all();
|
||||
|
||||
let mut join_point_stack = Vec::new_in(arena);
|
||||
let mut proc_join_points = MutMap::default();
|
||||
|
||||
for (group, _) in sccs.groups() {
|
||||
// This is a fixed-point analysis
|
||||
//
|
||||
// all functions initially own all their parameters
|
||||
// through a series of checks and heuristics, some arguments are set to borrowed
|
||||
// when that doesn't lead to conflicts the change is kept, otherwise it may be reverted
|
||||
//
|
||||
// when the signatures no longer change, the analysis stops and returns the signatures
|
||||
|
||||
loop {
|
||||
let mut modified = false;
|
||||
|
||||
for index in group.iter_ones() {
|
||||
let (_, proc) = procs.iter().nth(index).unwrap();
|
||||
let key = (proc.name.name(), proc.proc_layout(arena));
|
||||
|
||||
if proc.args.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::mem::swap(&mut proc_join_points, &mut join_points[index]);
|
||||
|
||||
let mut state = State {
|
||||
args: proc.args,
|
||||
borrow_signature: *borrow_signatures.procs.get(&key).unwrap(),
|
||||
join_point_stack,
|
||||
join_points: proc_join_points,
|
||||
modified: false,
|
||||
};
|
||||
|
||||
state.inspect_stmt(interner, &mut borrow_signatures, &proc.body);
|
||||
|
||||
// did any proc signature get modified?
|
||||
//
|
||||
// NOTE: this does not directly include updates to join point signatures. The
|
||||
// assumption is that a relevant change in join point signature is immediately
|
||||
// (i.e. no fixpoint is required) reflected in the proc signature.
|
||||
//
|
||||
// TODO: this is a load-bearing assert! There must be UB somewhere, removing this
|
||||
// assert causes the code to run into an infinite loop that terminates when the
|
||||
// memory on the system is exhausted.
|
||||
assert_eq!(
|
||||
state.modified,
|
||||
borrow_signatures
|
||||
.procs
|
||||
.insert(key, state.borrow_signature)
|
||||
.unwrap()
|
||||
!= state.borrow_signature
|
||||
);
|
||||
modified |= state.modified;
|
||||
|
||||
proc_join_points = state.join_points;
|
||||
|
||||
std::mem::swap(&mut proc_join_points, &mut join_points[index]);
|
||||
|
||||
join_point_stack = state.join_point_stack;
|
||||
join_point_stack.clear();
|
||||
}
|
||||
|
||||
if !modified {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
borrow_signatures
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn infer_borrow_signature<'a>(
|
||||
arena: &'a Bump,
|
||||
interner: &impl LayoutInterner<'a>,
|
||||
borrow_signatures: &'a mut BorrowSignatures<'a>,
|
||||
proc: &Proc<'a>,
|
||||
) -> BorrowSignature {
|
||||
let mut state = State::new(arena, interner, borrow_signatures, proc);
|
||||
state.inspect_stmt(interner, borrow_signatures, &proc.body);
|
||||
state.borrow_signature
|
||||
}
|
||||
|
||||
struct State<'a> {
|
||||
struct State<'state, 'arena> {
|
||||
/// Argument symbols with a layout of `List *` or `Str`, i.e. the layouts
|
||||
/// for which borrow inference might decide to pass as borrowed
|
||||
args: &'a [(InLayout<'a>, Symbol)],
|
||||
borrow_signature: &'a mut [Ownership],
|
||||
args: &'state [(InLayout<'arena>, Symbol)],
|
||||
borrow_signature: BorrowSignature,
|
||||
join_point_stack: Vec<'arena, (JoinPointId, &'state [Param<'arena>])>,
|
||||
join_points: MutMap<JoinPointId, BorrowSignature>,
|
||||
modified: bool,
|
||||
}
|
||||
|
||||
fn layout_to_ownership<'a>(
|
||||
|
@ -30,7 +225,8 @@ fn layout_to_ownership<'a>(
|
|||
interner: &impl LayoutInterner<'a>,
|
||||
) -> Ownership {
|
||||
match interner.get_repr(in_layout) {
|
||||
LayoutRepr::Builtin(Builtin::Str | Builtin::List(_)) => Ownership::Borrowed,
|
||||
LayoutRepr::Builtin(Builtin::Str) => Ownership::Borrowed,
|
||||
LayoutRepr::Builtin(Builtin::List(_)) => Ownership::Borrowed,
|
||||
LayoutRepr::LambdaSet(inner) => {
|
||||
layout_to_ownership(inner.runtime_representation(), interner)
|
||||
}
|
||||
|
@ -38,33 +234,61 @@ fn layout_to_ownership<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> State<'a> {
|
||||
fn new(arena: &'a Bump, interner: &impl LayoutInterner<'a>, proc: &'a Proc<'a>) -> Self {
|
||||
let borrow_signature = Vec::from_iter_in(
|
||||
proc.args
|
||||
.iter()
|
||||
.map(|(in_layout, _)| layout_to_ownership(*in_layout, interner)),
|
||||
arena,
|
||||
)
|
||||
.into_bump_slice_mut();
|
||||
impl<'state, 'a> State<'state, 'a> {
|
||||
fn new(
|
||||
arena: &'a Bump,
|
||||
interner: &impl LayoutInterner<'a>,
|
||||
borrow_signatures: &mut BorrowSignatures<'a>,
|
||||
proc: &Proc<'a>,
|
||||
) -> Self {
|
||||
let key = (proc.name.name(), proc.proc_layout(arena));
|
||||
|
||||
// initialize the borrow signature based on the layout if first time
|
||||
let borrow_signature = borrow_signatures
|
||||
.procs
|
||||
.entry(key)
|
||||
.or_insert_with(|| BorrowSignature::from_layouts(interner, key.1.arguments.iter()));
|
||||
|
||||
Self {
|
||||
args: proc.args,
|
||||
borrow_signature,
|
||||
borrow_signature: *borrow_signature,
|
||||
join_point_stack: Vec::new_in(arena),
|
||||
join_points: MutMap::default(),
|
||||
modified: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Mark the given argument symbol as Owned if the symbol participates in borrow inference
|
||||
///
|
||||
/// Currently argument symbols participate if `layout_to_ownership` returns `Borrowed` for their layout.
|
||||
fn mark_owned(&mut self, symbol: Symbol) {
|
||||
if let Some(index) = self.args.iter().position(|(_, s)| *s == symbol) {
|
||||
self.borrow_signature[index] = Ownership::Owned;
|
||||
self.modified |= self.borrow_signature.set(index, Ownership::Owned);
|
||||
}
|
||||
|
||||
// theory: relevant modification to a join point borrow signature is always immediately
|
||||
// reflected in the borrow signature of its surrounding function. Therefore we don't need
|
||||
// to include changes to join point signatures in the `modified` flag.
|
||||
for (id, params) in &self.join_point_stack {
|
||||
if let Some(index) = params.iter().position(|p| p.symbol == symbol) {
|
||||
self.join_points
|
||||
.get_mut(id)
|
||||
.unwrap()
|
||||
.set(index, Ownership::Owned);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn inspect_stmt(&mut self, stmt: &'a Stmt<'a>) {
|
||||
fn inspect_stmt(
|
||||
&mut self,
|
||||
interner: &impl LayoutInterner<'a>,
|
||||
borrow_signatures: &mut BorrowSignatures<'a>,
|
||||
stmt: &Stmt<'a>,
|
||||
) {
|
||||
match stmt {
|
||||
Stmt::Let(_, expr, _, stmt) => {
|
||||
self.inspect_expr(expr);
|
||||
self.inspect_stmt(stmt);
|
||||
self.inspect_expr(borrow_signatures, expr);
|
||||
self.inspect_stmt(interner, borrow_signatures, stmt);
|
||||
}
|
||||
Stmt::Switch {
|
||||
branches,
|
||||
|
@ -72,48 +296,110 @@ impl<'a> State<'a> {
|
|||
..
|
||||
} => {
|
||||
for (_, _, stmt) in branches.iter() {
|
||||
self.inspect_stmt(stmt);
|
||||
self.inspect_stmt(interner, borrow_signatures, stmt);
|
||||
}
|
||||
self.inspect_stmt(default_branch.1);
|
||||
self.inspect_stmt(interner, borrow_signatures, default_branch.1);
|
||||
}
|
||||
Stmt::Ret(_) => todo!(),
|
||||
Stmt::Refcounting(_, _) => todo!(),
|
||||
Stmt::Expect { .. } | Stmt::ExpectFx { .. } => {
|
||||
// TODO do we rely on values being passed by-value here?
|
||||
// it would be better to pass by-reference in general
|
||||
Stmt::Ret(s) => {
|
||||
// to return a value we must own it
|
||||
// (with the current implementation anyway)
|
||||
self.mark_owned(*s);
|
||||
}
|
||||
Stmt::Dbg { .. } => {
|
||||
// TODO do we rely on values being passed by-value here?
|
||||
// it would be better to pass by-reference in general
|
||||
Stmt::Refcounting(_, _) => unreachable!("not inserted yet"),
|
||||
Stmt::Expect { remainder, .. } | Stmt::ExpectFx { remainder, .. } => {
|
||||
// based on my reading of inc_dec.rs, expect borrows the symbols
|
||||
self.inspect_stmt(interner, borrow_signatures, remainder);
|
||||
}
|
||||
Stmt::Dbg { remainder, .. } => {
|
||||
// based on my reading of inc_dec.rs, expect borrows the symbol
|
||||
self.inspect_stmt(interner, borrow_signatures, remainder);
|
||||
}
|
||||
Stmt::Join {
|
||||
body, remainder, ..
|
||||
id,
|
||||
parameters,
|
||||
body,
|
||||
remainder,
|
||||
} => {
|
||||
self.inspect_stmt(body);
|
||||
self.inspect_stmt(remainder);
|
||||
// insert the default borrow signature if we're seeing this JP for the first time
|
||||
self.join_points.entry(*id).or_insert_with(|| {
|
||||
BorrowSignature::from_layouts(interner, parameters.iter().map(|p| &p.layout))
|
||||
});
|
||||
|
||||
// within the body, changes to ownership for symbols introduced by this join point
|
||||
// must be propagated. An example is
|
||||
//
|
||||
// ```roc
|
||||
// writeIndents = \buf, indents ->
|
||||
// if indents <= 0 then
|
||||
// buf
|
||||
// else
|
||||
// buf
|
||||
// |> Str.concat " "
|
||||
// |> writeIndents (indents - 1)
|
||||
// ```
|
||||
//
|
||||
// where the mono will jump immediately to a (recursive) join point. The fact that
|
||||
// the `buf` value is owned within the join point for efficient concatentation must
|
||||
// be propagated to `writeIndents`' function argument
|
||||
self.join_point_stack.push((*id, parameters));
|
||||
self.inspect_stmt(interner, borrow_signatures, body);
|
||||
self.join_point_stack.pop().unwrap();
|
||||
|
||||
self.inspect_stmt(interner, borrow_signatures, remainder);
|
||||
}
|
||||
|
||||
Stmt::Jump(_, _) | Stmt::Crash(_, _) => { /* not relevant for ownership */ }
|
||||
Stmt::Jump(id, arguments) => {
|
||||
let borrow_signature = match self.join_points.get(id) {
|
||||
Some(s) => *s,
|
||||
None => unreachable!("no borrow signature for join point {id:?} layout"),
|
||||
};
|
||||
|
||||
for (argument, ownership) in arguments.iter().zip(borrow_signature.iter()) {
|
||||
if let Ownership::Owned = ownership {
|
||||
self.mark_owned(*argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Stmt::Crash(_, _) => { /* not relevant for ownership */ }
|
||||
}
|
||||
}
|
||||
|
||||
fn inspect_expr(&mut self, expr: &'a Expr<'a>) {
|
||||
fn inspect_expr(&mut self, borrow_signatures: &mut BorrowSignatures<'a>, expr: &Expr<'a>) {
|
||||
if let Expr::Call(call) = expr {
|
||||
self.inspect_call(call)
|
||||
self.inspect_call(borrow_signatures, call)
|
||||
}
|
||||
}
|
||||
|
||||
fn inspect_call(&mut self, call: &'a Call<'a>) {
|
||||
fn inspect_call(&mut self, borrow_signatures: &mut BorrowSignatures<'a>, call: &Call<'a>) {
|
||||
let Call {
|
||||
call_type,
|
||||
arguments,
|
||||
} = call;
|
||||
|
||||
match call_type {
|
||||
CallType::ByName { name: _, .. } => {
|
||||
// TODO ownership should depend on the borrow signature of the called function
|
||||
for argument in arguments.iter() {
|
||||
self.mark_owned(*argument)
|
||||
CallType::ByName {
|
||||
name,
|
||||
arg_layouts,
|
||||
ret_layout,
|
||||
..
|
||||
} => {
|
||||
let proc_layout = ProcLayout {
|
||||
arguments: arg_layouts,
|
||||
result: *ret_layout,
|
||||
niche: Niche::NONE,
|
||||
};
|
||||
|
||||
let borrow_signature =
|
||||
match borrow_signatures.procs.get(&(name.name(), proc_layout)) {
|
||||
Some(s) => s,
|
||||
None => unreachable!("no borrow signature for {name:?} layout"),
|
||||
};
|
||||
|
||||
for (argument, ownership) in arguments.iter().zip(borrow_signature.iter()) {
|
||||
if let Ownership::Owned = ownership {
|
||||
self.mark_owned(*argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
CallType::LowLevel { op, .. } => {
|
||||
|
@ -134,3 +420,110 @@ impl<'a> State<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn construct_reference_matrix<'a>(
|
||||
arena: &'a Bump,
|
||||
procs: &MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||
) -> ReferenceMatrix {
|
||||
let mut matrix = ReferenceMatrix::new(procs.len());
|
||||
|
||||
let mut call_info = CallInfo::new(arena);
|
||||
|
||||
for (row, proc) in procs.values().enumerate() {
|
||||
call_info.clear();
|
||||
call_info.stmt(arena, &proc.body);
|
||||
|
||||
for key in call_info.keys.iter() {
|
||||
// the same symbol can be in `keys` multiple times (with different layouts)
|
||||
for (col, (k, _)) in procs.keys().enumerate() {
|
||||
if k == key {
|
||||
matrix.set_row_col(row, col, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matrix
|
||||
}
|
||||
|
||||
struct CallInfo<'a> {
|
||||
keys: Vec<'a, Symbol>,
|
||||
}
|
||||
|
||||
impl<'a> CallInfo<'a> {
|
||||
fn new(arena: &'a Bump) -> Self {
|
||||
CallInfo {
|
||||
keys: Vec::new_in(arena),
|
||||
}
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
self.keys.clear()
|
||||
}
|
||||
|
||||
fn call(&mut self, call: &crate::ir::Call<'a>) {
|
||||
use crate::ir::CallType::*;
|
||||
use crate::ir::HigherOrderLowLevel;
|
||||
use crate::ir::PassedFunction;
|
||||
|
||||
match call.call_type {
|
||||
ByName { name, .. } => {
|
||||
self.keys.push(name.name());
|
||||
}
|
||||
ByPointer { .. } => {
|
||||
// nothing to be done
|
||||
}
|
||||
Foreign { .. } => {}
|
||||
LowLevel { .. } => {}
|
||||
HigherOrder(HigherOrderLowLevel {
|
||||
passed_function: PassedFunction { name, .. },
|
||||
..
|
||||
}) => {
|
||||
self.keys.push(name.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn stmt(&mut self, arena: &'a Bump, stmt: &Stmt<'a>) {
|
||||
use Stmt::*;
|
||||
|
||||
let mut stack = bumpalo::vec![in arena; stmt];
|
||||
|
||||
while let Some(stmt) = stack.pop() {
|
||||
match stmt {
|
||||
Join {
|
||||
remainder: v,
|
||||
body: b,
|
||||
..
|
||||
} => {
|
||||
stack.push(v);
|
||||
stack.push(b);
|
||||
}
|
||||
Let(_, expr, _, cont) => {
|
||||
if let Expr::Call(call) = expr {
|
||||
self.call(call);
|
||||
}
|
||||
stack.push(cont);
|
||||
}
|
||||
Switch {
|
||||
branches,
|
||||
default_branch,
|
||||
..
|
||||
} => {
|
||||
stack.extend(branches.iter().map(|b| &b.2));
|
||||
stack.push(default_branch.1);
|
||||
}
|
||||
|
||||
Dbg { remainder, .. } => stack.push(remainder),
|
||||
Expect { remainder, .. } => stack.push(remainder),
|
||||
ExpectFx { remainder, .. } => stack.push(remainder),
|
||||
|
||||
Refcounting(_, _) => unreachable!("these have not been introduced yet"),
|
||||
|
||||
Ret(_) | Jump(_, _) | Crash(..) => {
|
||||
// these are terminal, do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::{
|
|||
BranchInfo, Call, CallType, Expr, HigherOrderLowLevel, JoinPointId, ListLiteralElement,
|
||||
ModifyRc, Param, Proc, ProcLayout, Stmt,
|
||||
},
|
||||
layout::{InLayout, LayoutInterner, STLayoutInterner},
|
||||
layout::{InLayout, LayoutInterner, Niche, STLayoutInterner},
|
||||
low_level::HigherOrder,
|
||||
};
|
||||
|
||||
|
@ -30,8 +30,12 @@ Insert the reference count operations for procedures.
|
|||
pub fn insert_inc_dec_operations<'a>(
|
||||
arena: &'a Bump,
|
||||
layout_interner: &STLayoutInterner<'a>,
|
||||
procedures: &mut HashMap<(Symbol, ProcLayout), Proc<'a>, BuildHasherDefault<WyHash>>,
|
||||
procedures: &mut HashMap<(Symbol, ProcLayout<'a>), Proc<'a>, BuildHasherDefault<WyHash>>,
|
||||
) {
|
||||
let borrow_signatures =
|
||||
crate::borrow::infer_borrow_signatures(arena, layout_interner, procedures);
|
||||
let borrow_signatures = arena.alloc(borrow_signatures);
|
||||
|
||||
// All calls to lowlevels are wrapped in another function to help with type inference and return/parameter layouts.
|
||||
// But this lowlevel might get inlined into the caller of the wrapper and thus removing any reference counting operations.
|
||||
// Thus, these rc operations are performed on the caller of the wrapper instead, and we skip rc on the lowlevel.
|
||||
|
@ -43,15 +47,13 @@ pub fn insert_inc_dec_operations<'a>(
|
|||
LowLevelWrapperType::NotALowLevelWrapper
|
||||
) {
|
||||
let symbol_rc_types_env = SymbolRcTypesEnv::from_layout_interner(layout_interner);
|
||||
insert_inc_dec_operations_proc(arena, symbol_rc_types_env, proc);
|
||||
insert_inc_dec_operations_proc(arena, symbol_rc_types_env, borrow_signatures, proc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Enum indicating whether a symbol should be reference counted or not.
|
||||
This includes layouts that themselves can be stack allocated but that contain a heap allocated item.
|
||||
*/
|
||||
/// Enum indicating whether a symbol should be reference counted or not.
|
||||
/// This includes layouts that themselves can be stack allocated but that contain a heap allocated item.
|
||||
#[derive(Copy, Clone)]
|
||||
enum VarRcType {
|
||||
ReferenceCounted,
|
||||
|
@ -256,6 +258,8 @@ struct RefcountEnvironment<'v> {
|
|||
// The Koka implementation assumes everything that is not owned to be borrowed.
|
||||
symbols_ownership: SymbolsOwnership,
|
||||
jointpoint_closures: MutMap<JoinPointId, JoinPointConsumption>,
|
||||
// inferred borrow signatures of roc functions
|
||||
borrow_signatures: &'v crate::borrow::BorrowSignatures<'v>,
|
||||
}
|
||||
|
||||
impl<'v> RefcountEnvironment<'v> {
|
||||
|
@ -306,9 +310,13 @@ impl<'v> RefcountEnvironment<'v> {
|
|||
Add a symbol to the environment if it is reference counted.
|
||||
*/
|
||||
fn add_symbol(&mut self, symbol: Symbol) {
|
||||
self.add_symbol_with(symbol, Ownership::Owned)
|
||||
}
|
||||
|
||||
fn add_symbol_with(&mut self, symbol: Symbol, ownership: Ownership) {
|
||||
match self.get_symbol_rc_type(&symbol) {
|
||||
VarRcType::ReferenceCounted => {
|
||||
self.symbols_ownership.insert(symbol, Ownership::Owned);
|
||||
self.symbols_ownership.insert(symbol, ownership);
|
||||
}
|
||||
VarRcType::NotReferenceCounted => {
|
||||
// If this symbol is not reference counted, we don't need to do anything.
|
||||
|
@ -403,6 +411,7 @@ impl<'v> RefcountEnvironment<'v> {
|
|||
fn insert_inc_dec_operations_proc<'a>(
|
||||
arena: &'a Bump,
|
||||
mut symbol_rc_types_env: SymbolRcTypesEnv<'a, '_>,
|
||||
borrow_signatures: &'a crate::borrow::BorrowSignatures<'a>,
|
||||
proc: &mut Proc<'a>,
|
||||
) {
|
||||
// Clone the symbol_rc_types_env and insert the symbols in the current procedure.
|
||||
|
@ -413,19 +422,26 @@ fn insert_inc_dec_operations_proc<'a>(
|
|||
symbols_rc_types: &symbol_rc_types_env.symbols_rc_type,
|
||||
symbols_ownership: MutMap::default(),
|
||||
jointpoint_closures: MutMap::default(),
|
||||
borrow_signatures,
|
||||
};
|
||||
|
||||
// Add all arguments to the environment (if they are reference counted)
|
||||
let proc_symbols = proc.args.iter().map(|(_layout, symbol)| symbol);
|
||||
for symbol in proc_symbols.clone() {
|
||||
environment.add_symbol(*symbol);
|
||||
let borrow_signature = borrow_signatures
|
||||
.procs
|
||||
.get(&(proc.name.name(), proc.proc_layout(arena)))
|
||||
.unwrap();
|
||||
for ((_, symbol), ownership) in proc.args.iter().zip(borrow_signature.iter()) {
|
||||
environment.add_symbol_with(*symbol, ownership);
|
||||
}
|
||||
|
||||
// Update the body with reference count statements.
|
||||
let new_body = insert_refcount_operations_stmt(arena, &mut environment, &proc.body);
|
||||
|
||||
// Insert decrement statements for unused parameters (which are still marked as owned).
|
||||
let rc_proc_symbols = proc_symbols
|
||||
let rc_proc_symbols = proc
|
||||
.args
|
||||
.iter()
|
||||
.map(|(_layout, symbol)| symbol)
|
||||
.filter(|symbol| environment.symbols_ownership.contains_key(symbol))
|
||||
.copied()
|
||||
.collect_in::<Vec<_>>(arena);
|
||||
|
@ -718,12 +734,11 @@ fn insert_refcount_operations_stmt<'v, 'a>(
|
|||
body,
|
||||
remainder,
|
||||
} => {
|
||||
// Assuming that the values in the closure of the body of this jointpoint are already bound.
|
||||
// Assuming that all symbols are still owned. (So that we can determine what symbols got consumed in the join point.)
|
||||
debug_assert!(environment
|
||||
.symbols_ownership
|
||||
.iter()
|
||||
.all(|(_, ownership)| ownership.is_owned()));
|
||||
// NOTE: Assuming that the values in the closure of the body of this jointpoint are already bound.
|
||||
|
||||
// NOTE: this code previously assumed that all symbols bound by the join point are owned.
|
||||
// With borrow inference, that is no longer true but the analysis here _should_ mirror
|
||||
// borrow inference and yield the same result.
|
||||
|
||||
let mut body_env = environment.clone();
|
||||
|
||||
|
@ -978,12 +993,42 @@ fn insert_refcount_operations_binding<'a>(
|
|||
call_type,
|
||||
}) => {
|
||||
match call_type.clone().replace_lowlevel_wrapper() {
|
||||
// A by name call refers to a normal function call.
|
||||
// Normal functions take all their parameters as owned, so we can mark them all as such.
|
||||
CallType::ByName { .. } => {
|
||||
let new_let = new_let!(stmt);
|
||||
CallType::ByName {
|
||||
name,
|
||||
arg_layouts,
|
||||
ret_layout,
|
||||
..
|
||||
} => {
|
||||
let proc_layout = ProcLayout {
|
||||
arguments: arg_layouts,
|
||||
result: ret_layout,
|
||||
niche: Niche::NONE,
|
||||
};
|
||||
|
||||
inc_owned!(arguments.iter().copied(), new_let)
|
||||
let borrow_signature = match environment
|
||||
.borrow_signatures
|
||||
.procs
|
||||
.get(&(name.name(), proc_layout))
|
||||
{
|
||||
Some(s) => s,
|
||||
None => unreachable!("no borrow signature for {name:?} layout"),
|
||||
};
|
||||
|
||||
let owned_arguments = arguments
|
||||
.iter()
|
||||
.copied()
|
||||
.zip(borrow_signature.iter())
|
||||
.filter_map(|(symbol, ownership)| ownership.is_owned().then_some(symbol));
|
||||
let borrowed_arguments = arguments
|
||||
.iter()
|
||||
.copied()
|
||||
.zip(borrow_signature.iter())
|
||||
.filter_map(|(symbol, ownership)| {
|
||||
ownership.is_borrowed().then_some(symbol)
|
||||
});
|
||||
let new_stmt = dec_borrowed!(borrowed_arguments, stmt);
|
||||
let new_let = new_let!(new_stmt);
|
||||
inc_owned!(owned_arguments, new_let)
|
||||
}
|
||||
// A normal Roc function call, but we don't actually know where its target is.
|
||||
// As such, we assume that it takes all parameters as owned, as will the function
|
||||
|
|
|
@ -396,6 +396,16 @@ impl<'a> Proc<'a> {
|
|||
w.push(b'\n');
|
||||
String::from_utf8(w).unwrap()
|
||||
}
|
||||
|
||||
pub fn proc_layout(&self, arena: &'a Bump) -> ProcLayout<'a> {
|
||||
let args = Vec::from_iter_in(self.args.iter().map(|(a, _)| *a), arena);
|
||||
|
||||
ProcLayout {
|
||||
arguments: args.into_bump_slice(),
|
||||
result: self.ret_layout,
|
||||
niche: Niche::NONE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A host-exposed function must be specialized; it's a seed for subsequent specializations
|
||||
|
|
|
@ -3362,32 +3362,36 @@ fn layout_from_flat_type<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
sortables.sort_by(|(label1, layout1), (label2, layout2)| {
|
||||
cmp_fields(&env.cache.interner, label1, *layout1, label2, *layout2)
|
||||
});
|
||||
|
||||
let ordered_field_names = Vec::from_iter_in(
|
||||
sortables
|
||||
.iter()
|
||||
.map(|(label, _)| &*arena.alloc_str(label.as_str())),
|
||||
arena,
|
||||
)
|
||||
.into_bump_slice();
|
||||
let semantic = SemanticRepr::record(ordered_field_names);
|
||||
|
||||
let repr = if sortables.len() == 1 {
|
||||
// If the record has only one field that isn't zero-sized,
|
||||
// unwrap it.
|
||||
let inner_repr = sortables.pop().unwrap().1;
|
||||
inner_repr.newtype()
|
||||
if sortables.is_empty() {
|
||||
Cacheable(Ok(Layout::UNIT), criteria)
|
||||
} else {
|
||||
let layouts = Vec::from_iter_in(sortables.into_iter().map(|t| t.1), arena);
|
||||
LayoutRepr::Struct(layouts.into_bump_slice()).direct()
|
||||
};
|
||||
sortables.sort_by(|(label1, layout1), (label2, layout2)| {
|
||||
cmp_fields(&env.cache.interner, label1, *layout1, label2, *layout2)
|
||||
});
|
||||
|
||||
let result = Ok(env.cache.put_in(Layout { repr, semantic }));
|
||||
let ordered_field_names = Vec::from_iter_in(
|
||||
sortables
|
||||
.iter()
|
||||
.map(|(label, _)| &*arena.alloc_str(label.as_str())),
|
||||
arena,
|
||||
)
|
||||
.into_bump_slice();
|
||||
let semantic = SemanticRepr::record(ordered_field_names);
|
||||
|
||||
Cacheable(result, criteria)
|
||||
let repr = if sortables.len() == 1 {
|
||||
// If the record has only one field that isn't zero-sized,
|
||||
// unwrap it.
|
||||
let inner_repr = sortables.pop().unwrap().1;
|
||||
inner_repr.newtype()
|
||||
} else {
|
||||
let layouts = Vec::from_iter_in(sortables.into_iter().map(|t| t.1), arena);
|
||||
LayoutRepr::struct_(layouts.into_bump_slice()).direct()
|
||||
};
|
||||
|
||||
let result = Ok(env.cache.put_in(Layout { repr, semantic }));
|
||||
|
||||
Cacheable(result, criteria)
|
||||
}
|
||||
}
|
||||
Tuple(elems, ext_var) => {
|
||||
let mut criteria = CACHEABLE;
|
||||
|
|
|
@ -63,9 +63,14 @@ pub fn loc_pattern_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>>
|
|||
},
|
||||
Ok((_, pattern_as, state)) => {
|
||||
let region = Region::span_across(&pattern.region, &pattern_as.identifier.region);
|
||||
let pattern = arena
|
||||
.alloc(pattern.value)
|
||||
.with_spaces_after(pattern_spaces, pattern.region);
|
||||
|
||||
let mut pattern = pattern;
|
||||
if !pattern_spaces.is_empty() {
|
||||
pattern = arena
|
||||
.alloc(pattern.value)
|
||||
.with_spaces_after(pattern_spaces, pattern.region)
|
||||
}
|
||||
|
||||
let as_pattern = Pattern::As(arena.alloc(pattern), pattern_as);
|
||||
|
||||
Ok((MadeProgress, Loc::at(region, as_pattern), state))
|
||||
|
|
|
@ -6,3 +6,17 @@ pub enum FunctionKind {
|
|||
/// Function values are erased, no kind is introduced.
|
||||
Erased,
|
||||
}
|
||||
|
||||
impl FunctionKind {
|
||||
pub fn from_env() -> Self {
|
||||
if cfg!(debug_assertions) {
|
||||
if std::env::var("EXPERIMENTAL_ROC_ERASE").is_ok() {
|
||||
FunctionKind::Erased
|
||||
} else {
|
||||
FunctionKind::LambdaSet
|
||||
}
|
||||
} else {
|
||||
FunctionKind::LambdaSet
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
|
|||
let List.595 : [C U64, C U64] = TagId(1) List.492;
|
||||
ret List.595;
|
||||
in
|
||||
inc #Derived_gen.0;
|
||||
jump List.594 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
@ -92,7 +93,6 @@ procedure Num.77 (#Attr.2, #Attr.3):
|
|||
procedure Test.1 (Test.2):
|
||||
let Test.13 : U64 = 0i64;
|
||||
let Test.14 : {} = Struct {};
|
||||
inc Test.2;
|
||||
let Test.3 : U64 = CallByName List.26 Test.2 Test.13 Test.14;
|
||||
let Test.12 : U64 = 0i64;
|
||||
let Test.10 : Int1 = CallByName Bool.11 Test.3 Test.12;
|
||||
|
|
|
@ -25,6 +25,7 @@ procedure List.92 (#Derived_gen.11, #Derived_gen.12, #Derived_gen.13, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.11;
|
||||
jump List.577 #Derived_gen.11 #Derived_gen.12 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
@ -163,4 +164,5 @@ procedure Test.0 ():
|
|||
let Test.35 : List [] = Array [];
|
||||
let Test.36 : {} = Struct {};
|
||||
let Test.34 : [<r>C {}, C *self {{}, []}] = CallByName Test.6 Test.35 Test.36;
|
||||
dec Test.35;
|
||||
ret Test.34;
|
||||
|
|
|
@ -8,11 +8,9 @@ procedure List.2 (List.108, List.109):
|
|||
if List.584 then
|
||||
let List.586 : Str = CallByName List.66 List.108 List.109;
|
||||
inc List.586;
|
||||
dec List.108;
|
||||
let List.585 : [C {}, C Str] = TagId(1) List.586;
|
||||
ret List.585;
|
||||
else
|
||||
dec List.108;
|
||||
let List.583 : {} = Struct {};
|
||||
let List.582 : [C {}, C Str] = TagId(0) List.583;
|
||||
ret List.582;
|
||||
|
@ -102,6 +100,7 @@ procedure Test.2 (Test.6):
|
|||
let Test.24 : {} = Struct {};
|
||||
let Test.23 : List Str = CallByName List.5 Test.9 Test.24;
|
||||
let Test.21 : [C {}, C Str] = CallByName List.9 Test.23;
|
||||
dec Test.23;
|
||||
let Test.22 : Str = "foo";
|
||||
let Test.20 : Str = CallByName Result.5 Test.21 Test.22;
|
||||
ret Test.20;
|
||||
|
|
|
@ -29,6 +29,7 @@ procedure List.92 (#Derived_gen.5, #Derived_gen.6, #Derived_gen.7, #Derived_gen.
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.5;
|
||||
jump List.577 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7 #Derived_gen.8 #Derived_gen.9;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
@ -162,6 +163,7 @@ procedure Test.0 ():
|
|||
let Test.23 : Int1 = CallByName Bool.2;
|
||||
let Test.22 : Int1 = CallByName Test.1 Test.23;
|
||||
let Test.16 : [<rnw><null>, C *self Int1, C *self Int1] = CallByName List.18 Test.20 Test.21 Test.22;
|
||||
dec Test.20;
|
||||
let Test.18 : Str = "hello";
|
||||
let Test.19 : U8 = GetTagId Test.16;
|
||||
switch Test.19:
|
||||
|
|
|
@ -5,9 +5,11 @@ procedure Bool.2 ():
|
|||
procedure Inspect.246 (Inspect.247, Inspect.245):
|
||||
let Inspect.319 : Str = "\"";
|
||||
let Inspect.318 : Str = CallByName Inspect.59 Inspect.247 Inspect.319;
|
||||
dec Inspect.319;
|
||||
let Inspect.314 : Str = CallByName Inspect.59 Inspect.318 Inspect.245;
|
||||
let Inspect.315 : Str = "\"";
|
||||
let Inspect.313 : Str = CallByName Inspect.59 Inspect.314 Inspect.315;
|
||||
dec Inspect.315;
|
||||
ret Inspect.313;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -31,11 +33,11 @@ procedure Inspect.5 (Inspect.146):
|
|||
let Inspect.305 : {} = Struct {};
|
||||
let Inspect.304 : Str = CallByName Inspect.35 Inspect.305;
|
||||
let Inspect.303 : Str = CallByName Inspect.246 Inspect.304 Inspect.308;
|
||||
dec Inspect.308;
|
||||
ret Inspect.303;
|
||||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.317 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.317;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
procedure Inspect.246 (Inspect.247, Inspect.245):
|
||||
let Inspect.319 : Str = "\"";
|
||||
let Inspect.318 : Str = CallByName Inspect.59 Inspect.247 Inspect.319;
|
||||
dec Inspect.319;
|
||||
let Inspect.314 : Str = CallByName Inspect.59 Inspect.318 Inspect.245;
|
||||
let Inspect.315 : Str = "\"";
|
||||
let Inspect.313 : Str = CallByName Inspect.59 Inspect.314 Inspect.315;
|
||||
dec Inspect.315;
|
||||
ret Inspect.313;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -27,11 +29,11 @@ procedure Inspect.5 (Inspect.146):
|
|||
let Inspect.305 : {} = Struct {};
|
||||
let Inspect.304 : Str = CallByName Inspect.35 Inspect.305;
|
||||
let Inspect.303 : Str = CallByName Inspect.246 Inspect.304 Inspect.308;
|
||||
dec Inspect.308;
|
||||
ret Inspect.303;
|
||||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.317 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.317;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
|
|
@ -7,11 +7,9 @@ procedure List.2 (List.108, List.109):
|
|||
let List.576 : Int1 = CallByName Num.22 List.109 List.580;
|
||||
if List.576 then
|
||||
let List.578 : {} = CallByName List.66 List.108 List.109;
|
||||
dec List.108;
|
||||
let List.577 : [C {}, C {}] = TagId(1) List.578;
|
||||
ret List.577;
|
||||
else
|
||||
dec List.108;
|
||||
let List.575 : {} = Struct {};
|
||||
let List.574 : [C {}, C {}] = TagId(0) List.575;
|
||||
ret List.574;
|
||||
|
@ -29,7 +27,6 @@ procedure Num.22 (#Attr.2, #Attr.3):
|
|||
ret Num.279;
|
||||
|
||||
procedure Test.2 (Test.5):
|
||||
dec Test.5;
|
||||
let Test.17 : Str = "bar";
|
||||
ret Test.17;
|
||||
|
||||
|
@ -38,6 +35,7 @@ procedure Test.0 ():
|
|||
joinpoint Test.15 Test.3:
|
||||
let Test.13 : U64 = 0i64;
|
||||
let Test.6 : [C {}, C {}] = CallByName List.2 Test.3 Test.13;
|
||||
dec Test.3;
|
||||
let Test.10 : U8 = 1i64;
|
||||
let Test.11 : U8 = GetTagId Test.6;
|
||||
let Test.12 : Int1 = lowlevel Eq Test.10 Test.11;
|
||||
|
@ -45,6 +43,7 @@ procedure Test.0 ():
|
|||
let Test.4 : {} = UnionAtIndex (Id 1) (Index 0) Test.6;
|
||||
let Test.8 : Str = "foo";
|
||||
let Test.7 : Str = CallByName Test.2 Test.8;
|
||||
dec Test.8;
|
||||
ret Test.7;
|
||||
else
|
||||
let Test.9 : Str = "bad!";
|
||||
|
|
|
@ -9,6 +9,7 @@ procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
|
|||
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6];
|
||||
let #Derived_gen.4 : List {Str, Str} = CallByName Test.21 #Derived_gen.5;
|
||||
let #Derived_gen.3 : List U8 = CallByName Encode.24 #Derived.3 #Derived_gen.4 #Derived.4;
|
||||
dec #Derived_gen.4;
|
||||
ret #Derived_gen.3;
|
||||
|
||||
procedure #Derived.5 (#Derived.6):
|
||||
|
@ -22,6 +23,7 @@ procedure #Derived.7 (#Derived.8, #Derived.9, #Derived.6):
|
|||
let #Derived_gen.15 : List {Str, Str} = Array [#Derived_gen.16];
|
||||
let #Derived_gen.14 : List {Str, Str} = CallByName Test.21 #Derived_gen.15;
|
||||
let #Derived_gen.13 : List U8 = CallByName Encode.24 #Derived.8 #Derived_gen.14 #Derived.9;
|
||||
dec #Derived_gen.14;
|
||||
ret #Derived_gen.13;
|
||||
|
||||
procedure Encode.23 (Encode.98):
|
||||
|
@ -125,6 +127,7 @@ procedure List.92 (#Derived_gen.29, #Derived_gen.30, #Derived_gen.31, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.29;
|
||||
jump List.603 #Derived_gen.29 #Derived_gen.30 #Derived_gen.31 #Derived_gen.32 #Derived_gen.33;
|
||||
|
||||
procedure List.92 (#Derived_gen.37, #Derived_gen.38, #Derived_gen.39, #Derived_gen.40, #Derived_gen.41):
|
||||
|
@ -141,6 +144,7 @@ procedure List.92 (#Derived_gen.37, #Derived_gen.38, #Derived_gen.39, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.37;
|
||||
jump List.577 #Derived_gen.37 #Derived_gen.38 #Derived_gen.39 #Derived_gen.40 #Derived_gen.41;
|
||||
|
||||
procedure Num.127 (#Attr.2):
|
||||
|
|
|
@ -9,6 +9,7 @@ procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
|
|||
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6];
|
||||
let #Derived_gen.4 : List {Str, Str} = CallByName Test.21 #Derived_gen.5;
|
||||
let #Derived_gen.3 : List U8 = CallByName Encode.24 #Derived.3 #Derived_gen.4 #Derived.4;
|
||||
dec #Derived_gen.4;
|
||||
ret #Derived_gen.3;
|
||||
|
||||
procedure Encode.23 (Encode.98):
|
||||
|
@ -84,6 +85,7 @@ procedure List.92 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.13;
|
||||
jump List.577 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17;
|
||||
|
||||
procedure Num.127 (#Attr.2):
|
||||
|
|
|
@ -16,6 +16,7 @@ procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
|
|||
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6, #Derived_gen.7];
|
||||
let #Derived_gen.4 : List {Str, Str} = CallByName Test.21 #Derived_gen.5;
|
||||
let #Derived_gen.3 : List U8 = CallByName Encode.24 #Derived.3 #Derived_gen.4 #Derived.4;
|
||||
dec #Derived_gen.4;
|
||||
ret #Derived_gen.3;
|
||||
|
||||
procedure Encode.23 (Encode.98):
|
||||
|
@ -91,6 +92,7 @@ procedure List.92 (#Derived_gen.17, #Derived_gen.18, #Derived_gen.19, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.17;
|
||||
jump List.577 #Derived_gen.17 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21;
|
||||
|
||||
procedure Num.127 (#Attr.2):
|
||||
|
|
|
@ -90,6 +90,7 @@ procedure List.92 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.13;
|
||||
jump List.577 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17;
|
||||
|
||||
procedure Num.127 (#Attr.2):
|
||||
|
@ -145,6 +146,7 @@ procedure Test.2 ():
|
|||
ret Test.258;
|
||||
|
||||
procedure Test.20 (Test.58, Test.59):
|
||||
inc Test.58;
|
||||
let Test.265 : {List Str, {}} = Struct {Test.58, Test.59};
|
||||
let Test.264 : {List Str, {}} = CallByName Encode.23 Test.265;
|
||||
ret Test.264;
|
||||
|
@ -158,6 +160,7 @@ procedure Test.23 (Test.77, Test.78):
|
|||
let Test.284 : Str = CallByName Test.19 Test.77;
|
||||
let Test.261 : List Str = CallByName List.13 Test.78 Test.284;
|
||||
let Test.260 : {List Str, {}} = CallByName Test.22 Test.261;
|
||||
dec Test.261;
|
||||
ret Test.260;
|
||||
|
||||
procedure Test.3 (Test.48, Test.49, Test.50):
|
||||
|
@ -187,6 +190,7 @@ procedure Test.60 (Test.61, Test.266, #Attr.12):
|
|||
let Test.275 : U64 = CallByName List.6 Test.58;
|
||||
let Test.62 : List U8 = CallByName Test.3 Test.61 Test.274 Test.275;
|
||||
let Test.268 : List U8 = CallByName List.18 Test.58 Test.62 Test.59;
|
||||
dec Test.58;
|
||||
ret Test.268;
|
||||
|
||||
procedure Test.63 (Test.64, Test.65, Test.59):
|
||||
|
|
|
@ -93,6 +93,7 @@ procedure List.92 (#Derived_gen.14, #Derived_gen.15, #Derived_gen.16, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.14;
|
||||
jump List.577 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17 #Derived_gen.18;
|
||||
|
||||
procedure Num.127 (#Attr.2):
|
||||
|
@ -148,6 +149,7 @@ procedure Test.2 ():
|
|||
ret Test.258;
|
||||
|
||||
procedure Test.20 (Test.58, Test.59):
|
||||
inc Test.58;
|
||||
let Test.266 : {List Str, {}} = Struct {Test.58, Test.59};
|
||||
let Test.265 : {List Str, {}} = CallByName Encode.23 Test.266;
|
||||
ret Test.265;
|
||||
|
@ -161,6 +163,7 @@ procedure Test.23 (Test.77, Test.78):
|
|||
let Test.285 : Str = CallByName Test.19 Test.77;
|
||||
let Test.262 : List Str = CallByName List.13 Test.78 Test.285;
|
||||
let Test.261 : {List Str, {}} = CallByName Test.22 Test.262;
|
||||
dec Test.262;
|
||||
ret Test.261;
|
||||
|
||||
procedure Test.3 (Test.48, Test.49, Test.50):
|
||||
|
@ -190,6 +193,7 @@ procedure Test.60 (Test.61, Test.267, #Attr.12):
|
|||
let Test.276 : U64 = CallByName List.6 Test.58;
|
||||
let Test.62 : List U8 = CallByName Test.3 Test.61 Test.275 Test.276;
|
||||
let Test.269 : List U8 = CallByName List.18 Test.58 Test.62 Test.59;
|
||||
dec Test.58;
|
||||
ret Test.269;
|
||||
|
||||
procedure Test.63 (Test.64, Test.65, Test.59):
|
||||
|
|
2
crates/compiler/test_mono/generated/fst.txt
generated
2
crates/compiler/test_mono/generated/fst.txt
generated
|
@ -1,9 +1,9 @@
|
|||
procedure Test.1 (Test.2, Test.3):
|
||||
dec Test.3;
|
||||
ret Test.2;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.5 : List I64 = Array [1i64, 2i64, 3i64];
|
||||
let Test.6 : List I64 = Array [3i64, 2i64, 1i64];
|
||||
let Test.4 : List I64 = CallByName Test.1 Test.5 Test.6;
|
||||
dec Test.6;
|
||||
ret Test.4;
|
||||
|
|
|
@ -48,6 +48,7 @@ procedure Dict.10 (Dict.724, Dict.179, Dict.180):
|
|||
let #Derived_gen.68 : List {U32, U32} = StructAtIndex 0 Dict.724;
|
||||
dec #Derived_gen.68;
|
||||
let Dict.1101 : {Str, Int1} = CallByName List.18 Dict.178 Dict.179 Dict.180;
|
||||
dec Dict.178;
|
||||
ret Dict.1101;
|
||||
|
||||
procedure Dict.12 (Dict.151):
|
||||
|
@ -148,11 +149,11 @@ procedure Dict.38 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
|
|||
let Dict.239 : U32 = CallByName Dict.48 Dict.224;
|
||||
jump Dict.736 Dict.221 Dict.222 Dict.238 Dict.239 Dict.225 Dict.226 Dict.227 Dict.228 Dict.229;
|
||||
in
|
||||
inc #Derived_gen.4;
|
||||
jump Dict.736 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7 #Derived_gen.8;
|
||||
|
||||
procedure Dict.398 (Dict.399, Dict.840, Dict.401, Dict.397):
|
||||
let Dict.400 : Str = StructAtIndex 0 Dict.840;
|
||||
inc Dict.399;
|
||||
let Dict.845 : {U64, U32} = CallByName Dict.65 Dict.399 Dict.400 Dict.397;
|
||||
let Dict.402 : U64 = StructAtIndex 0 Dict.845;
|
||||
let Dict.403 : U32 = StructAtIndex 1 Dict.845;
|
||||
|
@ -222,7 +223,6 @@ procedure Dict.59 (Dict.719):
|
|||
let Dict.877 : U64 = CallByName Dict.47;
|
||||
let Dict.836 : Int1 = CallByName Bool.7 Dict.377 Dict.877;
|
||||
if Dict.836 then
|
||||
inc Dict.376;
|
||||
let Dict.876 : U8 = 1i64;
|
||||
let Dict.380 : U8 = CallByName Num.75 Dict.379 Dict.876;
|
||||
let Dict.855 : {List {U32, U32}, U64} = CallByName Dict.60 Dict.380 Dict.378;
|
||||
|
@ -298,6 +298,7 @@ procedure Dict.66 (#Derived_gen.40, #Derived_gen.41, #Derived_gen.42):
|
|||
let Dict.848 : {U64, U32} = Struct {Dict.411, Dict.412};
|
||||
ret Dict.848;
|
||||
in
|
||||
inc #Derived_gen.40;
|
||||
jump Dict.847 #Derived_gen.40 #Derived_gen.41 #Derived_gen.42;
|
||||
|
||||
procedure Dict.67 (#Derived_gen.28, #Derived_gen.29, #Derived_gen.30):
|
||||
|
@ -416,6 +417,7 @@ procedure Dict.8 (Dict.210, Dict.211, Dict.212):
|
|||
let Dict.219 : U32 = CallByName Dict.70 Dict.218;
|
||||
let Dict.220 : U64 = CallByName Dict.71 Dict.218 Dict.217;
|
||||
let Dict.735 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = CallByName Dict.38 Dict.213 Dict.214 Dict.220 Dict.219 Dict.211 Dict.212 Dict.215 Dict.216 Dict.217;
|
||||
dec Dict.211;
|
||||
ret Dict.735;
|
||||
in
|
||||
inc 2 Dict.210;
|
||||
|
@ -455,7 +457,6 @@ procedure Dict.82 (Dict.702, Dict.480):
|
|||
let Dict.1089 : U8 = 2i64;
|
||||
let Dict.483 : U64 = CallByName Num.72 Dict.1088 Dict.1089;
|
||||
let Dict.1087 : U64 = 0i64;
|
||||
inc 3 Dict.480;
|
||||
let Dict.1085 : U64 = CallByName Dict.92 Dict.480 Dict.1087;
|
||||
let Dict.1086 : U8 = 32i64;
|
||||
let Dict.1083 : U64 = CallByName Num.72 Dict.1085 Dict.1086;
|
||||
|
@ -483,7 +484,6 @@ procedure Dict.82 (Dict.702, Dict.480):
|
|||
let Dict.1033 : {U64, U64, U64} = Struct {Dict.1038, Dict.1039, Dict.478};
|
||||
jump Dict.1034 Dict.1033;
|
||||
else
|
||||
dec Dict.480;
|
||||
let Dict.1035 : U64 = 0i64;
|
||||
let Dict.1036 : U64 = 0i64;
|
||||
let Dict.1033 : {U64, U64, U64} = Struct {Dict.1035, Dict.1036, Dict.478};
|
||||
|
@ -502,7 +502,6 @@ procedure Dict.82 (Dict.702, Dict.480):
|
|||
|
||||
procedure Dict.83 (#Derived_gen.9, #Derived_gen.10, #Derived_gen.11, #Derived_gen.12, #Derived_gen.13, #Derived_gen.14):
|
||||
joinpoint Dict.920 Dict.486 Dict.487 Dict.488 Dict.489 Dict.490 Dict.491:
|
||||
inc 6 Dict.489;
|
||||
let Dict.1027 : U64 = CallByName Dict.91 Dict.489 Dict.490;
|
||||
let Dict.1028 : U64 = CallByName Dict.86;
|
||||
let Dict.1022 : U64 = CallByName Num.70 Dict.1027 Dict.1028;
|
||||
|
@ -546,9 +545,9 @@ procedure Dict.83 (#Derived_gen.9, #Derived_gen.10, #Derived_gen.11, #Derived_ge
|
|||
let Dict.995 : U64 = CallByName Num.70 Dict.493 Dict.492;
|
||||
let Dict.497 : U64 = CallByName Num.70 Dict.494 Dict.995;
|
||||
let Dict.972 : {U64, U64, U64} = CallByName Dict.84 Dict.497 Dict.489 Dict.496 Dict.495;
|
||||
dec Dict.489;
|
||||
ret Dict.972;
|
||||
else
|
||||
inc Dict.489;
|
||||
let Dict.970 : U64 = CallByName Num.70 Dict.493 Dict.492;
|
||||
let Dict.498 : U64 = CallByName Num.70 Dict.494 Dict.970;
|
||||
let Dict.969 : U64 = 16i64;
|
||||
|
@ -559,14 +558,15 @@ procedure Dict.83 (#Derived_gen.9, #Derived_gen.10, #Derived_gen.11, #Derived_ge
|
|||
let Dict.965 : U64 = CallByName Num.75 Dict.495 Dict.966;
|
||||
let Dict.924 : U64 = CallByName Num.51 Dict.965 Dict.496;
|
||||
let Dict.923 : U64 = CallByName Dict.91 Dict.489 Dict.924;
|
||||
dec Dict.489;
|
||||
let Dict.921 : {U64, U64, U64} = Struct {Dict.922, Dict.923, Dict.498};
|
||||
ret Dict.921;
|
||||
in
|
||||
inc #Derived_gen.12;
|
||||
jump Dict.920 #Derived_gen.9 #Derived_gen.10 #Derived_gen.11 #Derived_gen.12 #Derived_gen.13 #Derived_gen.14;
|
||||
|
||||
procedure Dict.84 (#Derived_gen.43, #Derived_gen.44, #Derived_gen.45, #Derived_gen.46):
|
||||
joinpoint Dict.973 Dict.499 Dict.500 Dict.501 Dict.502:
|
||||
inc 2 Dict.500;
|
||||
let Dict.993 : U64 = CallByName Dict.91 Dict.500 Dict.501;
|
||||
let Dict.994 : U64 = CallByName Dict.86;
|
||||
let Dict.988 : U64 = CallByName Num.70 Dict.993 Dict.994;
|
||||
|
@ -582,7 +582,6 @@ procedure Dict.84 (#Derived_gen.43, #Derived_gen.44, #Derived_gen.45, #Derived_g
|
|||
let Dict.985 : U64 = 16i64;
|
||||
let Dict.975 : Int1 = CallByName Num.23 Dict.504 Dict.985;
|
||||
if Dict.975 then
|
||||
inc Dict.500;
|
||||
let Dict.984 : U64 = 16i64;
|
||||
let Dict.983 : U64 = CallByName Num.75 Dict.504 Dict.984;
|
||||
let Dict.982 : U64 = CallByName Num.51 Dict.983 Dict.505;
|
||||
|
@ -591,11 +590,13 @@ procedure Dict.84 (#Derived_gen.43, #Derived_gen.44, #Derived_gen.45, #Derived_g
|
|||
let Dict.980 : U64 = CallByName Num.75 Dict.504 Dict.981;
|
||||
let Dict.979 : U64 = CallByName Num.51 Dict.980 Dict.505;
|
||||
let Dict.978 : U64 = CallByName Dict.91 Dict.500 Dict.979;
|
||||
dec Dict.500;
|
||||
let Dict.976 : {U64, U64, U64} = Struct {Dict.977, Dict.978, Dict.503};
|
||||
ret Dict.976;
|
||||
else
|
||||
jump Dict.973 Dict.503 Dict.500 Dict.505 Dict.504;
|
||||
in
|
||||
inc #Derived_gen.44;
|
||||
jump Dict.973 #Derived_gen.43 #Derived_gen.44 #Derived_gen.45 #Derived_gen.46;
|
||||
|
||||
procedure Dict.85 ():
|
||||
|
@ -662,7 +663,6 @@ procedure Dict.91 (Dict.515, Dict.516):
|
|||
let Dict.945 : U64 = 7i64;
|
||||
let Dict.943 : U64 = CallByName Num.51 Dict.516 Dict.945;
|
||||
let Dict.942 : U8 = CallByName Dict.22 Dict.515 Dict.943;
|
||||
dec Dict.515;
|
||||
let Dict.524 : U64 = CallByName Num.133 Dict.942;
|
||||
let Dict.941 : U8 = 8i64;
|
||||
let Dict.940 : U64 = CallByName Num.72 Dict.518 Dict.941;
|
||||
|
@ -701,7 +701,6 @@ procedure Dict.92 (Dict.529, Dict.530):
|
|||
let Dict.1069 : U64 = 3i64;
|
||||
let Dict.1068 : U64 = CallByName Num.51 Dict.530 Dict.1069;
|
||||
let Dict.1067 : U8 = CallByName Dict.22 Dict.529 Dict.1068;
|
||||
dec Dict.529;
|
||||
let Dict.534 : U64 = CallByName Num.133 Dict.1067;
|
||||
let Dict.1066 : U8 = 8i64;
|
||||
let Dict.1065 : U64 = CallByName Num.72 Dict.532 Dict.1066;
|
||||
|
@ -726,7 +725,6 @@ procedure Dict.93 (Dict.537, Dict.538, Dict.539):
|
|||
let Dict.1048 : U64 = CallByName Num.75 Dict.539 Dict.1049;
|
||||
let Dict.1047 : U64 = CallByName Num.51 Dict.1048 Dict.538;
|
||||
let Dict.1046 : U8 = CallByName Dict.22 Dict.537 Dict.1047;
|
||||
dec Dict.537;
|
||||
let Dict.542 : U64 = CallByName Num.133 Dict.1046;
|
||||
let Dict.1045 : U8 = 16i64;
|
||||
let Dict.1042 : U64 = CallByName Num.72 Dict.540 Dict.1045;
|
||||
|
@ -739,6 +737,7 @@ procedure Dict.93 (Dict.537, Dict.538, Dict.539):
|
|||
procedure Hash.19 (Hash.38, Hash.39):
|
||||
let Hash.71 : List U8 = CallByName Str.12 Hash.39;
|
||||
let Hash.70 : {U64, U64} = CallByName Dict.82 Hash.38 Hash.71;
|
||||
dec Hash.71;
|
||||
ret Hash.70;
|
||||
|
||||
procedure Inspect.183 (Inspect.184, #Attr.12):
|
||||
|
@ -748,12 +747,15 @@ procedure Inspect.183 (Inspect.184, #Attr.12):
|
|||
let Inspect.179 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = StructAtIndex 0 #Attr.12;
|
||||
let Inspect.351 : Str = "{";
|
||||
let Inspect.324 : Str = CallByName Inspect.59 Inspect.184 Inspect.351;
|
||||
dec Inspect.351;
|
||||
let Inspect.325 : {{List {U32, U32}, List {Str, I64}, U64, Float32, U8}, {}, {}, {}} = Struct {Inspect.179, Inspect.180, Inspect.181, Inspect.182};
|
||||
let Inspect.320 : {Str, Int1} = CallByName Inspect.185 Inspect.324 Inspect.325;
|
||||
dec Inspect.324;
|
||||
let Inspect.321 : {} = Struct {};
|
||||
let Inspect.316 : Str = CallByName Inspect.197 Inspect.320;
|
||||
let Inspect.317 : Str = "}";
|
||||
let Inspect.315 : Str = CallByName Inspect.59 Inspect.316 Inspect.317;
|
||||
dec Inspect.317;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.185 (Inspect.186, #Attr.12):
|
||||
|
@ -762,6 +764,7 @@ procedure Inspect.185 (Inspect.186, #Attr.12):
|
|||
let Inspect.180 : {} = StructAtIndex 1 #Attr.12;
|
||||
let Inspect.179 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = StructAtIndex 0 #Attr.12;
|
||||
let Inspect.350 : Int1 = CallByName Bool.1;
|
||||
inc Inspect.186;
|
||||
let Inspect.328 : {Str, Int1} = Struct {Inspect.186, Inspect.350};
|
||||
let Inspect.329 : {{}, {}} = Struct {Inspect.181, Inspect.182};
|
||||
let Inspect.327 : {Str, Int1} = CallByName Dict.10 Inspect.179 Inspect.328 Inspect.329;
|
||||
|
@ -775,17 +778,21 @@ procedure Inspect.187 (Inspect.330, Inspect.190, Inspect.191, #Attr.12):
|
|||
joinpoint Inspect.348 Inspect.192:
|
||||
let Inspect.345 : Str = CallByName Inspect.43 Inspect.190;
|
||||
let Inspect.343 : Str = CallByName Inspect.31 Inspect.345 Inspect.192;
|
||||
dec Inspect.345;
|
||||
let Inspect.344 : Str = ": ";
|
||||
let Inspect.337 : Str = CallByName Inspect.59 Inspect.343 Inspect.344;
|
||||
dec Inspect.344;
|
||||
let Inspect.338 : {I64, {}} = Struct {Inspect.191, Inspect.182};
|
||||
let Inspect.333 : Str = CallByName Inspect.193 Inspect.337 Inspect.338;
|
||||
let Inspect.334 : {} = Struct {};
|
||||
let Inspect.332 : {Str, Int1} = CallByName Inspect.195 Inspect.333;
|
||||
dec Inspect.333;
|
||||
ret Inspect.332;
|
||||
in
|
||||
if Inspect.189 then
|
||||
let Inspect.349 : Str = ", ";
|
||||
let Inspect.347 : Str = CallByName Inspect.59 Inspect.188 Inspect.349;
|
||||
dec Inspect.349;
|
||||
jump Inspect.348 Inspect.347;
|
||||
else
|
||||
jump Inspect.348 Inspect.188;
|
||||
|
@ -799,6 +806,7 @@ procedure Inspect.193 (Inspect.194, #Attr.12):
|
|||
|
||||
procedure Inspect.195 (Inspect.196):
|
||||
let Inspect.336 : Int1 = CallByName Bool.2;
|
||||
inc Inspect.196;
|
||||
let Inspect.335 : {Str, Int1} = Struct {Inspect.196, Inspect.336};
|
||||
ret Inspect.335;
|
||||
|
||||
|
@ -809,14 +817,17 @@ procedure Inspect.197 (Inspect.322):
|
|||
procedure Inspect.246 (Inspect.247, Inspect.245):
|
||||
let Inspect.366 : Str = "\"";
|
||||
let Inspect.365 : Str = CallByName Inspect.59 Inspect.247 Inspect.366;
|
||||
dec Inspect.366;
|
||||
let Inspect.363 : Str = CallByName Inspect.59 Inspect.365 Inspect.245;
|
||||
let Inspect.364 : Str = "\"";
|
||||
let Inspect.362 : Str = CallByName Inspect.59 Inspect.363 Inspect.364;
|
||||
dec Inspect.364;
|
||||
ret Inspect.362;
|
||||
|
||||
procedure Inspect.274 (Inspect.275, Inspect.273):
|
||||
let Inspect.357 : Str = CallByName Num.96 Inspect.273;
|
||||
let Inspect.356 : Str = CallByName Inspect.59 Inspect.275 Inspect.357;
|
||||
dec Inspect.357;
|
||||
ret Inspect.356;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -874,7 +885,6 @@ procedure Inspect.53 (Inspect.273):
|
|||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.319 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.319;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
@ -1009,6 +1019,7 @@ procedure List.92 (#Derived_gen.50, #Derived_gen.51, #Derived_gen.52, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.50;
|
||||
jump List.577 #Derived_gen.50 #Derived_gen.51 #Derived_gen.52 #Derived_gen.53 #Derived_gen.54;
|
||||
|
||||
procedure List.92 (#Derived_gen.59, #Derived_gen.60, #Derived_gen.61, #Derived_gen.62, #Derived_gen.63):
|
||||
|
@ -1025,6 +1036,7 @@ procedure List.92 (#Derived_gen.59, #Derived_gen.60, #Derived_gen.61, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.59;
|
||||
jump List.641 #Derived_gen.59 #Derived_gen.60 #Derived_gen.61 #Derived_gen.62 #Derived_gen.63;
|
||||
|
||||
procedure List.93 (#Derived_gen.23, #Derived_gen.24, #Derived_gen.25, #Derived_gen.26, #Derived_gen.27):
|
||||
|
@ -1041,6 +1053,7 @@ procedure List.93 (#Derived_gen.23, #Derived_gen.24, #Derived_gen.25, #Derived_g
|
|||
dec List.172;
|
||||
ret List.173;
|
||||
in
|
||||
inc #Derived_gen.23;
|
||||
jump List.616 #Derived_gen.23 #Derived_gen.24 #Derived_gen.25 #Derived_gen.26 #Derived_gen.27;
|
||||
|
||||
procedure Num.131 (#Attr.2):
|
||||
|
@ -1187,5 +1200,6 @@ procedure Test.0 ():
|
|||
let Test.5 : {Str, I64} = Struct {Test.6, Test.7};
|
||||
let Test.3 : List {Str, I64} = Array [Test.4, Test.5];
|
||||
let Test.2 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = CallByName Dict.12 Test.3;
|
||||
dec Test.3;
|
||||
let Test.1 : Str = CallByName Inspect.33 Test.2;
|
||||
ret Test.1;
|
||||
|
|
|
@ -27,12 +27,15 @@ procedure Inspect.152 (Inspect.153, #Attr.12):
|
|||
let Inspect.149 : List I64 = StructAtIndex 0 #Attr.12;
|
||||
let Inspect.343 : Str = "[";
|
||||
let Inspect.324 : Str = CallByName Inspect.59 Inspect.153 Inspect.343;
|
||||
dec Inspect.343;
|
||||
let Inspect.325 : {List I64, {}, {}} = Struct {Inspect.149, Inspect.150, Inspect.151};
|
||||
let Inspect.320 : {Str, Int1} = CallByName Inspect.154 Inspect.324 Inspect.325;
|
||||
dec Inspect.324;
|
||||
let Inspect.321 : {} = Struct {};
|
||||
let Inspect.316 : Str = CallByName Inspect.163 Inspect.320;
|
||||
let Inspect.317 : Str = "]";
|
||||
let Inspect.315 : Str = CallByName Inspect.59 Inspect.316 Inspect.317;
|
||||
dec Inspect.317;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.154 (Inspect.155, #Attr.12):
|
||||
|
@ -40,8 +43,10 @@ procedure Inspect.154 (Inspect.155, #Attr.12):
|
|||
let Inspect.150 : {} = StructAtIndex 1 #Attr.12;
|
||||
let Inspect.149 : List I64 = StructAtIndex 0 #Attr.12;
|
||||
let Inspect.342 : Int1 = CallByName Bool.1;
|
||||
inc Inspect.155;
|
||||
let Inspect.328 : {Str, Int1} = Struct {Inspect.155, Inspect.342};
|
||||
let Inspect.327 : {Str, Int1} = CallByName List.18 Inspect.149 Inspect.328 Inspect.151;
|
||||
dec Inspect.149;
|
||||
ret Inspect.327;
|
||||
|
||||
procedure Inspect.156 (Inspect.330, Inspect.159, Inspect.151):
|
||||
|
@ -52,17 +57,20 @@ procedure Inspect.156 (Inspect.330, Inspect.159, Inspect.151):
|
|||
let Inspect.333 : Str = CallByName Inspect.31 Inspect.337 Inspect.160;
|
||||
let Inspect.334 : {} = Struct {};
|
||||
let Inspect.332 : {Str, Int1} = CallByName Inspect.161 Inspect.333;
|
||||
dec Inspect.333;
|
||||
ret Inspect.332;
|
||||
in
|
||||
if Inspect.158 then
|
||||
let Inspect.341 : Str = ", ";
|
||||
let Inspect.339 : Str = CallByName Inspect.59 Inspect.157 Inspect.341;
|
||||
dec Inspect.341;
|
||||
jump Inspect.340 Inspect.339;
|
||||
else
|
||||
jump Inspect.340 Inspect.157;
|
||||
|
||||
procedure Inspect.161 (Inspect.162):
|
||||
let Inspect.336 : Int1 = CallByName Bool.2;
|
||||
inc Inspect.162;
|
||||
let Inspect.335 : {Str, Int1} = Struct {Inspect.162, Inspect.336};
|
||||
ret Inspect.335;
|
||||
|
||||
|
@ -73,6 +81,7 @@ procedure Inspect.163 (Inspect.322):
|
|||
procedure Inspect.274 (Inspect.275, Inspect.273):
|
||||
let Inspect.349 : Str = CallByName Num.96 Inspect.273;
|
||||
let Inspect.348 : Str = CallByName Inspect.59 Inspect.275 Inspect.349;
|
||||
dec Inspect.349;
|
||||
ret Inspect.348;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -102,6 +111,7 @@ procedure Inspect.35 (Inspect.297):
|
|||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.36 (Inspect.149, Inspect.150, Inspect.151):
|
||||
inc Inspect.149;
|
||||
let Inspect.312 : {List I64, {}, {}} = Struct {Inspect.149, Inspect.150, Inspect.151};
|
||||
let Inspect.311 : {List I64, {}, {}} = CallByName Inspect.30 Inspect.312;
|
||||
ret Inspect.311;
|
||||
|
@ -111,6 +121,7 @@ procedure Inspect.5 (Inspect.146):
|
|||
let Inspect.305 : {} = Struct {};
|
||||
let Inspect.304 : Str = CallByName Inspect.35 Inspect.305;
|
||||
let Inspect.303 : Str = CallByName #Derived.4 Inspect.304 Inspect.308;
|
||||
dec Inspect.308;
|
||||
ret Inspect.303;
|
||||
|
||||
procedure Inspect.53 (Inspect.273):
|
||||
|
@ -119,7 +130,6 @@ procedure Inspect.53 (Inspect.273):
|
|||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.319 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.319;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
@ -152,6 +162,7 @@ procedure List.92 (#Derived_gen.19, #Derived_gen.20, #Derived_gen.21, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.19;
|
||||
jump List.577 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21 #Derived_gen.22 #Derived_gen.23;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
|
|
@ -9,6 +9,7 @@ procedure #Derived.2 (#Derived.3, #Derived.1):
|
|||
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6];
|
||||
let #Derived_gen.4 : List {Str, Str} = CallByName Inspect.41 #Derived_gen.5;
|
||||
let #Derived_gen.3 : Str = CallByName Inspect.31 #Derived_gen.4 #Derived.3;
|
||||
dec #Derived_gen.4;
|
||||
ret #Derived_gen.3;
|
||||
|
||||
procedure #Derived.4 (#Derived.5):
|
||||
|
@ -22,6 +23,7 @@ procedure #Derived.6 (#Derived.7, #Derived.5):
|
|||
let #Derived_gen.15 : List {Str, Str} = Array [#Derived_gen.16];
|
||||
let #Derived_gen.14 : List {Str, Str} = CallByName Inspect.41 #Derived_gen.15;
|
||||
let #Derived_gen.13 : Str = CallByName Inspect.31 #Derived_gen.14 #Derived.7;
|
||||
dec #Derived_gen.14;
|
||||
ret #Derived_gen.13;
|
||||
|
||||
procedure Bool.1 ():
|
||||
|
@ -35,25 +37,32 @@ procedure Bool.2 ():
|
|||
procedure Inspect.225 (Inspect.226, Inspect.224):
|
||||
let Inspect.348 : Str = "{";
|
||||
let Inspect.324 : Str = CallByName Inspect.59 Inspect.226 Inspect.348;
|
||||
dec Inspect.348;
|
||||
let Inspect.320 : {Str, Int1} = CallByName Inspect.227 Inspect.324 Inspect.224;
|
||||
dec Inspect.324;
|
||||
let Inspect.321 : {} = Struct {};
|
||||
let Inspect.316 : Str = CallByName Inspect.239 Inspect.320;
|
||||
let Inspect.317 : Str = "}";
|
||||
let Inspect.315 : Str = CallByName Inspect.59 Inspect.316 Inspect.317;
|
||||
dec Inspect.317;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.225 (Inspect.226, Inspect.224):
|
||||
let Inspect.388 : Str = "{";
|
||||
let Inspect.364 : Str = CallByName Inspect.59 Inspect.226 Inspect.388;
|
||||
dec Inspect.388;
|
||||
let Inspect.360 : {Str, Int1} = CallByName Inspect.227 Inspect.364 Inspect.224;
|
||||
dec Inspect.364;
|
||||
let Inspect.361 : {} = Struct {};
|
||||
let Inspect.356 : Str = CallByName Inspect.239 Inspect.360;
|
||||
let Inspect.357 : Str = "}";
|
||||
let Inspect.355 : Str = CallByName Inspect.59 Inspect.356 Inspect.357;
|
||||
dec Inspect.357;
|
||||
ret Inspect.355;
|
||||
|
||||
procedure Inspect.227 (Inspect.228, Inspect.224):
|
||||
let Inspect.347 : Int1 = CallByName Bool.1;
|
||||
inc Inspect.228;
|
||||
let Inspect.328 : {Str, Int1} = Struct {Inspect.228, Inspect.347};
|
||||
let Inspect.329 : {} = Struct {};
|
||||
let Inspect.327 : {Str, Int1} = CallByName List.18 Inspect.224 Inspect.328 Inspect.329;
|
||||
|
@ -61,6 +70,7 @@ procedure Inspect.227 (Inspect.228, Inspect.224):
|
|||
|
||||
procedure Inspect.227 (Inspect.228, Inspect.224):
|
||||
let Inspect.387 : Int1 = CallByName Bool.1;
|
||||
inc Inspect.228;
|
||||
let Inspect.368 : {Str, Int1} = Struct {Inspect.228, Inspect.387};
|
||||
let Inspect.369 : {} = Struct {};
|
||||
let Inspect.367 : {Str, Int1} = CallByName List.18 Inspect.224 Inspect.368 Inspect.369;
|
||||
|
@ -73,16 +83,20 @@ procedure Inspect.229 (Inspect.330, Inspect.331):
|
|||
let Inspect.231 : Int1 = StructAtIndex 1 Inspect.330;
|
||||
joinpoint Inspect.345 Inspect.234:
|
||||
let Inspect.342 : Str = CallByName Inspect.59 Inspect.234 Inspect.232;
|
||||
dec Inspect.232;
|
||||
let Inspect.343 : Str = ": ";
|
||||
let Inspect.337 : Str = CallByName Inspect.59 Inspect.342 Inspect.343;
|
||||
dec Inspect.343;
|
||||
let Inspect.333 : Str = CallByName Inspect.235 Inspect.337 Inspect.233;
|
||||
let Inspect.334 : {} = Struct {};
|
||||
let Inspect.332 : {Str, Int1} = CallByName Inspect.237 Inspect.333;
|
||||
dec Inspect.333;
|
||||
ret Inspect.332;
|
||||
in
|
||||
if Inspect.231 then
|
||||
let Inspect.346 : Str = ", ";
|
||||
let Inspect.344 : Str = CallByName Inspect.59 Inspect.230 Inspect.346;
|
||||
dec Inspect.346;
|
||||
jump Inspect.345 Inspect.344;
|
||||
else
|
||||
jump Inspect.345 Inspect.230;
|
||||
|
@ -94,16 +108,21 @@ procedure Inspect.229 (Inspect.330, Inspect.331):
|
|||
let Inspect.231 : Int1 = StructAtIndex 1 Inspect.330;
|
||||
joinpoint Inspect.385 Inspect.234:
|
||||
let Inspect.382 : Str = CallByName Inspect.59 Inspect.234 Inspect.232;
|
||||
dec Inspect.232;
|
||||
let Inspect.383 : Str = ": ";
|
||||
let Inspect.377 : Str = CallByName Inspect.59 Inspect.382 Inspect.383;
|
||||
dec Inspect.383;
|
||||
let Inspect.373 : Str = CallByName Inspect.235 Inspect.377 Inspect.233;
|
||||
dec Inspect.233;
|
||||
let Inspect.374 : {} = Struct {};
|
||||
let Inspect.372 : {Str, Int1} = CallByName Inspect.237 Inspect.373;
|
||||
dec Inspect.373;
|
||||
ret Inspect.372;
|
||||
in
|
||||
if Inspect.231 then
|
||||
let Inspect.386 : Str = ", ";
|
||||
let Inspect.384 : Str = CallByName Inspect.59 Inspect.230 Inspect.386;
|
||||
dec Inspect.386;
|
||||
jump Inspect.385 Inspect.384;
|
||||
else
|
||||
jump Inspect.385 Inspect.230;
|
||||
|
@ -118,6 +137,7 @@ procedure Inspect.235 (Inspect.236, Inspect.233):
|
|||
|
||||
procedure Inspect.237 (Inspect.238):
|
||||
let Inspect.376 : Int1 = CallByName Bool.2;
|
||||
inc Inspect.238;
|
||||
let Inspect.375 : {Str, Int1} = Struct {Inspect.238, Inspect.376};
|
||||
ret Inspect.375;
|
||||
|
||||
|
@ -128,9 +148,11 @@ procedure Inspect.239 (Inspect.322):
|
|||
procedure Inspect.246 (Inspect.247, Inspect.245):
|
||||
let Inspect.397 : Str = "\"";
|
||||
let Inspect.396 : Str = CallByName Inspect.59 Inspect.247 Inspect.397;
|
||||
dec Inspect.397;
|
||||
let Inspect.394 : Str = CallByName Inspect.59 Inspect.396 Inspect.245;
|
||||
let Inspect.395 : Str = "\"";
|
||||
let Inspect.393 : Str = CallByName Inspect.59 Inspect.394 Inspect.395;
|
||||
dec Inspect.395;
|
||||
ret Inspect.393;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -194,7 +216,6 @@ procedure Inspect.5 (Inspect.146):
|
|||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.359 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.359;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
@ -242,6 +263,7 @@ procedure List.92 (#Derived_gen.26, #Derived_gen.27, #Derived_gen.28, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.26;
|
||||
jump List.589 #Derived_gen.26 #Derived_gen.27 #Derived_gen.28 #Derived_gen.29 #Derived_gen.30;
|
||||
|
||||
procedure List.92 (#Derived_gen.39, #Derived_gen.40, #Derived_gen.41, #Derived_gen.42, #Derived_gen.43):
|
||||
|
@ -258,6 +280,7 @@ procedure List.92 (#Derived_gen.39, #Derived_gen.40, #Derived_gen.41, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.39;
|
||||
jump List.577 #Derived_gen.39 #Derived_gen.40 #Derived_gen.41 #Derived_gen.42 #Derived_gen.43;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
|
|
@ -14,6 +14,7 @@ procedure #Derived.2 (#Derived.3, #Derived.1):
|
|||
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.41 #Derived_gen.5;
|
||||
let #Derived_gen.3 : Str = CallByName Inspect.31 #Derived_gen.4 #Derived.3;
|
||||
dec #Derived_gen.4;
|
||||
ret #Derived_gen.3;
|
||||
|
||||
procedure Bool.1 ():
|
||||
|
@ -27,15 +28,19 @@ procedure Bool.2 ():
|
|||
procedure Inspect.225 (Inspect.226, Inspect.224):
|
||||
let Inspect.349 : Str = "{";
|
||||
let Inspect.324 : Str = CallByName Inspect.59 Inspect.226 Inspect.349;
|
||||
dec Inspect.349;
|
||||
let Inspect.320 : {Str, Int1} = CallByName Inspect.227 Inspect.324 Inspect.224;
|
||||
dec Inspect.324;
|
||||
let Inspect.321 : {} = Struct {};
|
||||
let Inspect.316 : Str = CallByName Inspect.239 Inspect.320;
|
||||
let Inspect.317 : Str = "}";
|
||||
let Inspect.315 : Str = CallByName Inspect.59 Inspect.316 Inspect.317;
|
||||
dec Inspect.317;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.227 (Inspect.228, Inspect.224):
|
||||
let Inspect.348 : Int1 = CallByName Bool.1;
|
||||
inc Inspect.228;
|
||||
let Inspect.328 : {Str, Int1} = Struct {Inspect.228, Inspect.348};
|
||||
let Inspect.329 : {} = Struct {};
|
||||
let Inspect.327 : {Str, Int1} = CallByName List.18 Inspect.224 Inspect.328 Inspect.329;
|
||||
|
@ -48,16 +53,20 @@ procedure Inspect.229 (Inspect.330, Inspect.331):
|
|||
let Inspect.231 : Int1 = StructAtIndex 1 Inspect.330;
|
||||
joinpoint Inspect.346 Inspect.234:
|
||||
let Inspect.343 : Str = CallByName Inspect.59 Inspect.234 Inspect.232;
|
||||
dec Inspect.232;
|
||||
let Inspect.344 : Str = ": ";
|
||||
let Inspect.337 : Str = CallByName Inspect.59 Inspect.343 Inspect.344;
|
||||
dec Inspect.344;
|
||||
let Inspect.333 : Str = CallByName Inspect.235 Inspect.337 Inspect.233;
|
||||
let Inspect.334 : {} = Struct {};
|
||||
let Inspect.332 : {Str, Int1} = CallByName Inspect.237 Inspect.333;
|
||||
dec Inspect.333;
|
||||
ret Inspect.332;
|
||||
in
|
||||
if Inspect.231 then
|
||||
let Inspect.347 : Str = ", ";
|
||||
let Inspect.345 : Str = CallByName Inspect.59 Inspect.230 Inspect.347;
|
||||
dec Inspect.347;
|
||||
jump Inspect.346 Inspect.345;
|
||||
else
|
||||
jump Inspect.346 Inspect.230;
|
||||
|
@ -68,6 +77,7 @@ procedure Inspect.235 (Inspect.236, Inspect.233):
|
|||
|
||||
procedure Inspect.237 (Inspect.238):
|
||||
let Inspect.336 : Int1 = CallByName Bool.2;
|
||||
inc Inspect.238;
|
||||
let Inspect.335 : {Str, Int1} = Struct {Inspect.238, Inspect.336};
|
||||
ret Inspect.335;
|
||||
|
||||
|
@ -79,12 +89,14 @@ procedure Inspect.274 (Inspect.275, #Attr.12):
|
|||
let Inspect.362 : I64 = UnionAtIndex (Id 0) (Index 0) #Attr.12;
|
||||
let Inspect.361 : Str = CallByName Num.96 Inspect.362;
|
||||
let Inspect.360 : Str = CallByName Inspect.59 Inspect.275 Inspect.361;
|
||||
dec Inspect.361;
|
||||
ret Inspect.360;
|
||||
|
||||
procedure Inspect.289 (Inspect.290, #Attr.12):
|
||||
let Inspect.356 : Decimal = UnionAtIndex (Id 1) (Index 0) #Attr.12;
|
||||
let Inspect.355 : Str = CallByName Num.96 Inspect.356;
|
||||
let Inspect.354 : Str = CallByName Inspect.59 Inspect.290 Inspect.355;
|
||||
dec Inspect.355;
|
||||
ret Inspect.354;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -144,7 +156,6 @@ procedure Inspect.58 (Inspect.288):
|
|||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.319 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.319;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
@ -178,6 +189,7 @@ procedure List.92 (#Derived_gen.26, #Derived_gen.27, #Derived_gen.28, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.26;
|
||||
jump List.577 #Derived_gen.26 #Derived_gen.27 #Derived_gen.28 #Derived_gen.29 #Derived_gen.30;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
|
|
@ -9,6 +9,7 @@ procedure #Derived.2 (#Derived.3, #Derived.1):
|
|||
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6];
|
||||
let #Derived_gen.4 : List {Str, Str} = CallByName Inspect.41 #Derived_gen.5;
|
||||
let #Derived_gen.3 : Str = CallByName Inspect.31 #Derived_gen.4 #Derived.3;
|
||||
dec #Derived_gen.4;
|
||||
ret #Derived_gen.3;
|
||||
|
||||
procedure Bool.1 ():
|
||||
|
@ -22,15 +23,19 @@ procedure Bool.2 ():
|
|||
procedure Inspect.225 (Inspect.226, Inspect.224):
|
||||
let Inspect.348 : Str = "{";
|
||||
let Inspect.324 : Str = CallByName Inspect.59 Inspect.226 Inspect.348;
|
||||
dec Inspect.348;
|
||||
let Inspect.320 : {Str, Int1} = CallByName Inspect.227 Inspect.324 Inspect.224;
|
||||
dec Inspect.324;
|
||||
let Inspect.321 : {} = Struct {};
|
||||
let Inspect.316 : Str = CallByName Inspect.239 Inspect.320;
|
||||
let Inspect.317 : Str = "}";
|
||||
let Inspect.315 : Str = CallByName Inspect.59 Inspect.316 Inspect.317;
|
||||
dec Inspect.317;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.227 (Inspect.228, Inspect.224):
|
||||
let Inspect.347 : Int1 = CallByName Bool.1;
|
||||
inc Inspect.228;
|
||||
let Inspect.328 : {Str, Int1} = Struct {Inspect.228, Inspect.347};
|
||||
let Inspect.329 : {} = Struct {};
|
||||
let Inspect.327 : {Str, Int1} = CallByName List.18 Inspect.224 Inspect.328 Inspect.329;
|
||||
|
@ -43,16 +48,21 @@ procedure Inspect.229 (Inspect.330, Inspect.331):
|
|||
let Inspect.231 : Int1 = StructAtIndex 1 Inspect.330;
|
||||
joinpoint Inspect.345 Inspect.234:
|
||||
let Inspect.342 : Str = CallByName Inspect.59 Inspect.234 Inspect.232;
|
||||
dec Inspect.232;
|
||||
let Inspect.343 : Str = ": ";
|
||||
let Inspect.337 : Str = CallByName Inspect.59 Inspect.342 Inspect.343;
|
||||
dec Inspect.343;
|
||||
let Inspect.333 : Str = CallByName Inspect.235 Inspect.337 Inspect.233;
|
||||
dec Inspect.233;
|
||||
let Inspect.334 : {} = Struct {};
|
||||
let Inspect.332 : {Str, Int1} = CallByName Inspect.237 Inspect.333;
|
||||
dec Inspect.333;
|
||||
ret Inspect.332;
|
||||
in
|
||||
if Inspect.231 then
|
||||
let Inspect.346 : Str = ", ";
|
||||
let Inspect.344 : Str = CallByName Inspect.59 Inspect.230 Inspect.346;
|
||||
dec Inspect.346;
|
||||
jump Inspect.345 Inspect.344;
|
||||
else
|
||||
jump Inspect.345 Inspect.230;
|
||||
|
@ -63,6 +73,7 @@ procedure Inspect.235 (Inspect.236, Inspect.233):
|
|||
|
||||
procedure Inspect.237 (Inspect.238):
|
||||
let Inspect.336 : Int1 = CallByName Bool.2;
|
||||
inc Inspect.238;
|
||||
let Inspect.335 : {Str, Int1} = Struct {Inspect.238, Inspect.336};
|
||||
ret Inspect.335;
|
||||
|
||||
|
@ -73,9 +84,11 @@ procedure Inspect.239 (Inspect.322):
|
|||
procedure Inspect.246 (Inspect.247, Inspect.245):
|
||||
let Inspect.357 : Str = "\"";
|
||||
let Inspect.356 : Str = CallByName Inspect.59 Inspect.247 Inspect.357;
|
||||
dec Inspect.357;
|
||||
let Inspect.354 : Str = CallByName Inspect.59 Inspect.356 Inspect.245;
|
||||
let Inspect.355 : Str = "\"";
|
||||
let Inspect.353 : Str = CallByName Inspect.59 Inspect.354 Inspect.355;
|
||||
dec Inspect.355;
|
||||
ret Inspect.353;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -121,7 +134,6 @@ procedure Inspect.5 (Inspect.146):
|
|||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.319 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.319;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
@ -155,6 +167,7 @@ procedure List.92 (#Derived_gen.10, #Derived_gen.11, #Derived_gen.12, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.10;
|
||||
jump List.577 #Derived_gen.10 #Derived_gen.11 #Derived_gen.12 #Derived_gen.13 #Derived_gen.14;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
|
|
@ -16,6 +16,7 @@ procedure #Derived.2 (#Derived.3, #Derived.1):
|
|||
let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6, #Derived_gen.7];
|
||||
let #Derived_gen.4 : List {Str, Str} = CallByName Inspect.41 #Derived_gen.5;
|
||||
let #Derived_gen.3 : Str = CallByName Inspect.31 #Derived_gen.4 #Derived.3;
|
||||
dec #Derived_gen.4;
|
||||
ret #Derived_gen.3;
|
||||
|
||||
procedure Bool.1 ():
|
||||
|
@ -29,15 +30,19 @@ procedure Bool.2 ():
|
|||
procedure Inspect.225 (Inspect.226, Inspect.224):
|
||||
let Inspect.348 : Str = "{";
|
||||
let Inspect.324 : Str = CallByName Inspect.59 Inspect.226 Inspect.348;
|
||||
dec Inspect.348;
|
||||
let Inspect.320 : {Str, Int1} = CallByName Inspect.227 Inspect.324 Inspect.224;
|
||||
dec Inspect.324;
|
||||
let Inspect.321 : {} = Struct {};
|
||||
let Inspect.316 : Str = CallByName Inspect.239 Inspect.320;
|
||||
let Inspect.317 : Str = "}";
|
||||
let Inspect.315 : Str = CallByName Inspect.59 Inspect.316 Inspect.317;
|
||||
dec Inspect.317;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.227 (Inspect.228, Inspect.224):
|
||||
let Inspect.347 : Int1 = CallByName Bool.1;
|
||||
inc Inspect.228;
|
||||
let Inspect.328 : {Str, Int1} = Struct {Inspect.228, Inspect.347};
|
||||
let Inspect.329 : {} = Struct {};
|
||||
let Inspect.327 : {Str, Int1} = CallByName List.18 Inspect.224 Inspect.328 Inspect.329;
|
||||
|
@ -50,16 +55,21 @@ procedure Inspect.229 (Inspect.330, Inspect.331):
|
|||
let Inspect.231 : Int1 = StructAtIndex 1 Inspect.330;
|
||||
joinpoint Inspect.345 Inspect.234:
|
||||
let Inspect.342 : Str = CallByName Inspect.59 Inspect.234 Inspect.232;
|
||||
dec Inspect.232;
|
||||
let Inspect.343 : Str = ": ";
|
||||
let Inspect.337 : Str = CallByName Inspect.59 Inspect.342 Inspect.343;
|
||||
dec Inspect.343;
|
||||
let Inspect.333 : Str = CallByName Inspect.235 Inspect.337 Inspect.233;
|
||||
dec Inspect.233;
|
||||
let Inspect.334 : {} = Struct {};
|
||||
let Inspect.332 : {Str, Int1} = CallByName Inspect.237 Inspect.333;
|
||||
dec Inspect.333;
|
||||
ret Inspect.332;
|
||||
in
|
||||
if Inspect.231 then
|
||||
let Inspect.346 : Str = ", ";
|
||||
let Inspect.344 : Str = CallByName Inspect.59 Inspect.230 Inspect.346;
|
||||
dec Inspect.346;
|
||||
jump Inspect.345 Inspect.344;
|
||||
else
|
||||
jump Inspect.345 Inspect.230;
|
||||
|
@ -70,6 +80,7 @@ procedure Inspect.235 (Inspect.236, Inspect.233):
|
|||
|
||||
procedure Inspect.237 (Inspect.238):
|
||||
let Inspect.336 : Int1 = CallByName Bool.2;
|
||||
inc Inspect.238;
|
||||
let Inspect.335 : {Str, Int1} = Struct {Inspect.238, Inspect.336};
|
||||
ret Inspect.335;
|
||||
|
||||
|
@ -80,9 +91,11 @@ procedure Inspect.239 (Inspect.322):
|
|||
procedure Inspect.246 (Inspect.247, Inspect.245):
|
||||
let Inspect.357 : Str = "\"";
|
||||
let Inspect.356 : Str = CallByName Inspect.59 Inspect.247 Inspect.357;
|
||||
dec Inspect.357;
|
||||
let Inspect.354 : Str = CallByName Inspect.59 Inspect.356 Inspect.245;
|
||||
let Inspect.355 : Str = "\"";
|
||||
let Inspect.353 : Str = CallByName Inspect.59 Inspect.354 Inspect.355;
|
||||
dec Inspect.355;
|
||||
ret Inspect.353;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -128,7 +141,6 @@ procedure Inspect.5 (Inspect.146):
|
|||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.319 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.319;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
@ -162,6 +174,7 @@ procedure List.92 (#Derived_gen.14, #Derived_gen.15, #Derived_gen.16, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.14;
|
||||
jump List.577 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17 #Derived_gen.18;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
procedure Inspect.246 (Inspect.247, Inspect.245):
|
||||
let Inspect.319 : Str = "\"";
|
||||
let Inspect.318 : Str = CallByName Inspect.59 Inspect.247 Inspect.319;
|
||||
dec Inspect.319;
|
||||
let Inspect.314 : Str = CallByName Inspect.59 Inspect.318 Inspect.245;
|
||||
let Inspect.315 : Str = "\"";
|
||||
let Inspect.313 : Str = CallByName Inspect.59 Inspect.314 Inspect.315;
|
||||
dec Inspect.315;
|
||||
ret Inspect.313;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -27,11 +29,11 @@ procedure Inspect.5 (Inspect.146):
|
|||
let Inspect.305 : {} = Struct {};
|
||||
let Inspect.304 : Str = CallByName Inspect.35 Inspect.305;
|
||||
let Inspect.303 : Str = CallByName Inspect.246 Inspect.304 Inspect.308;
|
||||
dec Inspect.308;
|
||||
ret Inspect.303;
|
||||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.317 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.317;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
|
|
@ -11,6 +11,8 @@ procedure #Derived.3 (#Derived.4, #Derived.1):
|
|||
let #Derived_gen.9 : Str = CallByName Inspect.43 #Derived.1;
|
||||
let #Derived_gen.8 : List Str = Array [#Derived_gen.9];
|
||||
let #Derived_gen.6 : [C Str, C Str List Str] = CallByName Inspect.39 #Derived_gen.7 #Derived_gen.8;
|
||||
dec #Derived_gen.8;
|
||||
dec #Derived_gen.7;
|
||||
jump #Derived_gen.5 #Derived_gen.6;
|
||||
|
||||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
|
@ -20,6 +22,7 @@ procedure Bool.11 (#Attr.2, #Attr.3):
|
|||
procedure Inspect.200 (Inspect.201, #Attr.12):
|
||||
let Inspect.342 : Str = UnionAtIndex (Id 0) (Index 0) #Attr.12;
|
||||
let Inspect.341 : Str = CallByName Inspect.59 Inspect.201 Inspect.342;
|
||||
dec Inspect.342;
|
||||
ret Inspect.341;
|
||||
|
||||
procedure Inspect.202 (Inspect.203, #Attr.12):
|
||||
|
@ -27,10 +30,14 @@ procedure Inspect.202 (Inspect.203, #Attr.12):
|
|||
let Inspect.335 : Str = UnionAtIndex (Id 1) (Index 0) #Attr.12;
|
||||
let Inspect.334 : Str = "(";
|
||||
let Inspect.333 : Str = CallByName Inspect.59 Inspect.203 Inspect.334;
|
||||
dec Inspect.334;
|
||||
let Inspect.321 : Str = CallByName Inspect.59 Inspect.333 Inspect.335;
|
||||
dec Inspect.335;
|
||||
let Inspect.317 : Str = CallByName Inspect.204 Inspect.321 Inspect.336;
|
||||
dec Inspect.336;
|
||||
let Inspect.318 : Str = ")";
|
||||
let Inspect.316 : Str = CallByName Inspect.59 Inspect.317 Inspect.318;
|
||||
dec Inspect.318;
|
||||
ret Inspect.316;
|
||||
|
||||
procedure Inspect.204 (Inspect.205, Inspect.199):
|
||||
|
@ -41,6 +48,7 @@ procedure Inspect.204 (Inspect.205, Inspect.199):
|
|||
procedure Inspect.206 (Inspect.207, Inspect.208):
|
||||
let Inspect.332 : Str = " ";
|
||||
let Inspect.327 : Str = CallByName Inspect.59 Inspect.207 Inspect.332;
|
||||
dec Inspect.332;
|
||||
let Inspect.326 : Str = CallByName Inspect.209 Inspect.327 Inspect.208;
|
||||
ret Inspect.326;
|
||||
|
||||
|
@ -51,9 +59,11 @@ procedure Inspect.209 (Inspect.210, Inspect.208):
|
|||
procedure Inspect.246 (Inspect.247, Inspect.245):
|
||||
let Inspect.351 : Str = "\"";
|
||||
let Inspect.350 : Str = CallByName Inspect.59 Inspect.247 Inspect.351;
|
||||
dec Inspect.351;
|
||||
let Inspect.348 : Str = CallByName Inspect.59 Inspect.350 Inspect.245;
|
||||
let Inspect.349 : Str = "\"";
|
||||
let Inspect.347 : Str = CallByName Inspect.59 Inspect.348 Inspect.349;
|
||||
dec Inspect.349;
|
||||
ret Inspect.347;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -91,14 +101,15 @@ procedure Inspect.35 (Inspect.297):
|
|||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.39 (Inspect.198, Inspect.199):
|
||||
inc Inspect.199;
|
||||
let Inspect.337 : Int1 = CallByName List.1 Inspect.199;
|
||||
if Inspect.337 then
|
||||
dec Inspect.199;
|
||||
inc Inspect.198;
|
||||
let Inspect.339 : [C Str, C Str List Str] = TagId(0) Inspect.198;
|
||||
let Inspect.338 : [C Str, C Str List Str] = CallByName Inspect.30 Inspect.339;
|
||||
ret Inspect.338;
|
||||
else
|
||||
inc Inspect.199;
|
||||
inc Inspect.198;
|
||||
let Inspect.313 : [C Str, C Str List Str] = TagId(1) Inspect.198 Inspect.199;
|
||||
let Inspect.312 : [C Str, C Str List Str] = CallByName Inspect.30 Inspect.313;
|
||||
ret Inspect.312;
|
||||
|
@ -116,7 +127,6 @@ procedure Inspect.5 (Inspect.146):
|
|||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.320 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.320;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
@ -124,7 +134,6 @@ procedure Inspect.60 (Inspect.298):
|
|||
|
||||
procedure List.1 (List.107):
|
||||
let List.587 : U64 = CallByName List.6 List.107;
|
||||
dec List.107;
|
||||
let List.588 : U64 = 0i64;
|
||||
let List.586 : Int1 = CallByName Bool.11 List.587 List.588;
|
||||
ret List.586;
|
||||
|
@ -150,6 +159,7 @@ procedure List.92 (#Derived_gen.10, #Derived_gen.11, #Derived_gen.12, #Derived_g
|
|||
let List.583 : Str = CallByName List.66 List.163 List.166;
|
||||
inc List.583;
|
||||
let List.168 : Str = CallByName Inspect.206 List.164 List.583;
|
||||
dec List.583;
|
||||
let List.582 : U64 = 1i64;
|
||||
let List.581 : U64 = CallByName Num.51 List.166 List.582;
|
||||
jump List.577 List.163 List.168 List.165 List.581 List.167;
|
||||
|
@ -157,6 +167,7 @@ procedure List.92 (#Derived_gen.10, #Derived_gen.11, #Derived_gen.12, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.10;
|
||||
jump List.577 #Derived_gen.10 #Derived_gen.11 #Derived_gen.12 #Derived_gen.13 #Derived_gen.14;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
|
|
@ -14,6 +14,8 @@ procedure #Derived.4 (#Derived.5, #Derived.1):
|
|||
let #Derived_gen.10 : Str = CallByName Inspect.43 #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.39 #Derived_gen.7 #Derived_gen.8;
|
||||
dec #Derived_gen.8;
|
||||
dec #Derived_gen.7;
|
||||
jump #Derived_gen.5 #Derived_gen.6;
|
||||
|
||||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
|
@ -23,6 +25,7 @@ procedure Bool.11 (#Attr.2, #Attr.3):
|
|||
procedure Inspect.200 (Inspect.201, #Attr.12):
|
||||
let Inspect.342 : Str = UnionAtIndex (Id 0) (Index 0) #Attr.12;
|
||||
let Inspect.341 : Str = CallByName Inspect.59 Inspect.201 Inspect.342;
|
||||
dec Inspect.342;
|
||||
ret Inspect.341;
|
||||
|
||||
procedure Inspect.202 (Inspect.203, #Attr.12):
|
||||
|
@ -30,10 +33,14 @@ procedure Inspect.202 (Inspect.203, #Attr.12):
|
|||
let Inspect.335 : Str = UnionAtIndex (Id 1) (Index 0) #Attr.12;
|
||||
let Inspect.334 : Str = "(";
|
||||
let Inspect.333 : Str = CallByName Inspect.59 Inspect.203 Inspect.334;
|
||||
dec Inspect.334;
|
||||
let Inspect.321 : Str = CallByName Inspect.59 Inspect.333 Inspect.335;
|
||||
dec Inspect.335;
|
||||
let Inspect.317 : Str = CallByName Inspect.204 Inspect.321 Inspect.336;
|
||||
dec Inspect.336;
|
||||
let Inspect.318 : Str = ")";
|
||||
let Inspect.316 : Str = CallByName Inspect.59 Inspect.317 Inspect.318;
|
||||
dec Inspect.318;
|
||||
ret Inspect.316;
|
||||
|
||||
procedure Inspect.204 (Inspect.205, Inspect.199):
|
||||
|
@ -44,6 +51,7 @@ procedure Inspect.204 (Inspect.205, Inspect.199):
|
|||
procedure Inspect.206 (Inspect.207, Inspect.208):
|
||||
let Inspect.332 : Str = " ";
|
||||
let Inspect.327 : Str = CallByName Inspect.59 Inspect.207 Inspect.332;
|
||||
dec Inspect.332;
|
||||
let Inspect.326 : Str = CallByName Inspect.209 Inspect.327 Inspect.208;
|
||||
ret Inspect.326;
|
||||
|
||||
|
@ -54,9 +62,11 @@ procedure Inspect.209 (Inspect.210, Inspect.208):
|
|||
procedure Inspect.246 (Inspect.247, Inspect.245):
|
||||
let Inspect.351 : Str = "\"";
|
||||
let Inspect.350 : Str = CallByName Inspect.59 Inspect.247 Inspect.351;
|
||||
dec Inspect.351;
|
||||
let Inspect.348 : Str = CallByName Inspect.59 Inspect.350 Inspect.245;
|
||||
let Inspect.349 : Str = "\"";
|
||||
let Inspect.347 : Str = CallByName Inspect.59 Inspect.348 Inspect.349;
|
||||
dec Inspect.349;
|
||||
ret Inspect.347;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -94,14 +104,15 @@ procedure Inspect.35 (Inspect.297):
|
|||
ret Inspect.307;
|
||||
|
||||
procedure Inspect.39 (Inspect.198, Inspect.199):
|
||||
inc Inspect.199;
|
||||
let Inspect.337 : Int1 = CallByName List.1 Inspect.199;
|
||||
if Inspect.337 then
|
||||
dec Inspect.199;
|
||||
inc Inspect.198;
|
||||
let Inspect.339 : [C Str, C Str List Str] = TagId(0) Inspect.198;
|
||||
let Inspect.338 : [C Str, C Str List Str] = CallByName Inspect.30 Inspect.339;
|
||||
ret Inspect.338;
|
||||
else
|
||||
inc Inspect.199;
|
||||
inc Inspect.198;
|
||||
let Inspect.313 : [C Str, C Str List Str] = TagId(1) Inspect.198 Inspect.199;
|
||||
let Inspect.312 : [C Str, C Str List Str] = CallByName Inspect.30 Inspect.313;
|
||||
ret Inspect.312;
|
||||
|
@ -119,7 +130,6 @@ procedure Inspect.5 (Inspect.146):
|
|||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.320 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.320;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
@ -127,7 +137,6 @@ procedure Inspect.60 (Inspect.298):
|
|||
|
||||
procedure List.1 (List.107):
|
||||
let List.587 : U64 = CallByName List.6 List.107;
|
||||
dec List.107;
|
||||
let List.588 : U64 = 0i64;
|
||||
let List.586 : Int1 = CallByName Bool.11 List.587 List.588;
|
||||
ret List.586;
|
||||
|
@ -153,6 +162,7 @@ procedure List.92 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_g
|
|||
let List.583 : Str = CallByName List.66 List.163 List.166;
|
||||
inc List.583;
|
||||
let List.168 : Str = CallByName Inspect.206 List.164 List.583;
|
||||
dec List.583;
|
||||
let List.582 : U64 = 1i64;
|
||||
let List.581 : U64 = CallByName Num.51 List.166 List.582;
|
||||
jump List.577 List.163 List.168 List.165 List.581 List.167;
|
||||
|
@ -160,6 +170,7 @@ procedure List.92 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.13;
|
||||
jump List.577 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
|
|
@ -11,11 +11,9 @@ procedure List.2 (List.108, List.109):
|
|||
let List.584 : Int1 = CallByName Num.22 List.109 List.588;
|
||||
if List.584 then
|
||||
let List.586 : I64 = CallByName List.66 List.108 List.109;
|
||||
dec List.108;
|
||||
let List.585 : [C {}, C I64] = TagId(1) List.586;
|
||||
ret List.585;
|
||||
else
|
||||
dec List.108;
|
||||
let List.583 : {} = Struct {};
|
||||
let List.582 : [C {}, C I64] = TagId(0) List.583;
|
||||
ret List.582;
|
||||
|
@ -57,7 +55,6 @@ procedure Str.42 (#Attr.2):
|
|||
|
||||
procedure Str.60 (Str.185):
|
||||
let Str.186 : {I64, U8} = CallByName Str.42 Str.185;
|
||||
dec Str.185;
|
||||
let Str.238 : U8 = StructAtIndex 1 Str.186;
|
||||
let Str.239 : U8 = 0i64;
|
||||
let Str.235 : Int1 = CallByName Bool.11 Str.238 Str.239;
|
||||
|
@ -75,8 +72,10 @@ procedure Test.0 ():
|
|||
if Test.3 then
|
||||
let Test.5 : List I64 = Array [];
|
||||
let Test.4 : [C Int1, C I64] = CallByName List.9 Test.5;
|
||||
dec Test.5;
|
||||
ret Test.4;
|
||||
else
|
||||
let Test.2 : Str = "";
|
||||
let Test.1 : [C Int1, C I64] = CallByName Str.27 Test.2;
|
||||
dec Test.2;
|
||||
ret Test.1;
|
||||
|
|
|
@ -79,6 +79,7 @@ procedure List.80 (#Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.
|
|||
let List.591 : [C {}, C {}] = TagId(1) List.492;
|
||||
ret List.591;
|
||||
in
|
||||
inc #Derived_gen.1;
|
||||
jump List.590 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4 #Derived_gen.5;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
@ -146,6 +147,7 @@ procedure Test.1 (#Derived_gen.0):
|
|||
let Test.33 : List {[<r>C I64, C List *self], [<r>C I64, C List *self]} = CallByName List.23 Test.12 Test.14 Test.35;
|
||||
let Test.34 : {} = Struct {};
|
||||
let Test.29 : Int1 = CallByName List.56 Test.33 Test.34;
|
||||
dec Test.33;
|
||||
if Test.29 then
|
||||
let Test.31 : U64 = CallByName List.6 Test.12;
|
||||
dec Test.12;
|
||||
|
|
|
@ -32,7 +32,6 @@ procedure Str.42 (#Attr.2):
|
|||
|
||||
procedure Str.60 (Str.185):
|
||||
let Str.186 : {I64, U8} = CallByName Str.42 Str.185;
|
||||
dec Str.185;
|
||||
let Str.238 : U8 = StructAtIndex 1 Str.186;
|
||||
let Str.239 : U8 = 0i64;
|
||||
let Str.235 : Int1 = CallByName Bool.11 Str.238 Str.239;
|
||||
|
@ -68,6 +67,7 @@ procedure Test.19 ():
|
|||
let Test.133 : List U8 = CallByName Str.12 Test.135;
|
||||
let Test.134 : {} = Struct {};
|
||||
let Test.132 : {List U8, [C {}, C Str]} = CallByName Decode.26 Test.133 Test.134;
|
||||
dec Test.133;
|
||||
let Test.93 : List U8 = StructAtIndex 0 Test.132;
|
||||
let Test.92 : [C {}, C Str] = StructAtIndex 1 Test.132;
|
||||
let Test.129 : U8 = 1i64;
|
||||
|
@ -76,6 +76,7 @@ procedure Test.19 ():
|
|||
if Test.131 then
|
||||
let Test.94 : Str = UnionAtIndex (Id 1) (Index 0) Test.92;
|
||||
let Test.117 : [C {}, C I64] = CallByName Str.27 Test.94;
|
||||
dec Test.94;
|
||||
let Test.123 : U8 = 1i64;
|
||||
let Test.124 : U8 = GetTagId Test.117;
|
||||
let Test.125 : Int1 = lowlevel Eq Test.123 Test.124;
|
||||
|
@ -99,5 +100,6 @@ procedure Test.19 ():
|
|||
procedure Test.76 (Test.77, Test.138):
|
||||
let Test.141 : {} = Struct {};
|
||||
let Test.140 : [C {}, C Str] = TagId(0) Test.141;
|
||||
inc Test.77;
|
||||
let Test.139 : {List U8, [C {}, C Str]} = Struct {Test.77, Test.140};
|
||||
ret Test.139;
|
||||
|
|
|
@ -37,6 +37,7 @@ procedure Test.1 (#Derived_gen.0, #Derived_gen.1):
|
|||
let Test.14 : [C {}, C Str] = TagId(0) Test.15;
|
||||
ret Test.14;
|
||||
in
|
||||
inc #Derived_gen.0;
|
||||
jump Test.12 #Derived_gen.0 #Derived_gen.1;
|
||||
|
||||
procedure Test.0 ():
|
||||
|
@ -44,4 +45,5 @@ procedure Test.0 ():
|
|||
let Test.10 : List Str = Array [Test.35];
|
||||
let Test.11 : U64 = 0i64;
|
||||
let Test.9 : [C {}, C Str] = CallByName Test.1 Test.10 Test.11;
|
||||
dec Test.10;
|
||||
ret Test.9;
|
||||
|
|
|
@ -3,7 +3,6 @@ procedure Bool.1 ():
|
|||
ret Bool.24;
|
||||
|
||||
procedure Test.1 (Test.4):
|
||||
dec Test.4;
|
||||
let Test.9 : I64 = 0i64;
|
||||
ret Test.9;
|
||||
|
||||
|
@ -18,6 +17,7 @@ procedure Test.0 ():
|
|||
in
|
||||
joinpoint Test.13 Test.12:
|
||||
let Test.8 : I64 = CallByName Test.1 Test.12;
|
||||
dec Test.12;
|
||||
jump Test.7 Test.8;
|
||||
in
|
||||
let Test.32 : U64 = lowlevel ListLenUsize Test.6;
|
||||
|
|
|
@ -3,7 +3,6 @@ procedure Bool.1 ():
|
|||
ret Bool.24;
|
||||
|
||||
procedure Test.1 (Test.4):
|
||||
dec Test.4;
|
||||
let Test.9 : I64 = 0i64;
|
||||
ret Test.9;
|
||||
|
||||
|
@ -18,6 +17,7 @@ procedure Test.0 ():
|
|||
in
|
||||
joinpoint Test.13 Test.12:
|
||||
let Test.8 : I64 = CallByName Test.1 Test.12;
|
||||
dec Test.12;
|
||||
jump Test.7 Test.8;
|
||||
in
|
||||
let Test.44 : U64 = lowlevel ListLenUsize Test.6;
|
||||
|
|
|
@ -22,7 +22,6 @@ procedure Test.2 (Test.7, Test.8):
|
|||
ret Test.43;
|
||||
|
||||
procedure Test.3 (Test.17):
|
||||
dec Test.17;
|
||||
let Test.35 : {} = Struct {};
|
||||
ret Test.35;
|
||||
|
||||
|
@ -35,6 +34,7 @@ procedure Test.9 (Test.26, #Attr.12):
|
|||
let Test.32 : {} = Struct {};
|
||||
let Test.31 : Str = CallByName Test.15 Test.32;
|
||||
let Test.28 : {} = CallByName Test.3 Test.31;
|
||||
dec Test.31;
|
||||
let Test.30 : {} = Struct {};
|
||||
let Test.29 : Str = CallByName Test.11 Test.30;
|
||||
ret Test.29;
|
||||
|
|
|
@ -11,6 +11,7 @@ procedure Test.1 (Test.5):
|
|||
ret Test.31;
|
||||
|
||||
procedure Test.2 (Test.7):
|
||||
inc Test.7;
|
||||
let Test.23 : [C {}, C U64, C Str] = TagId(2) Test.7;
|
||||
ret Test.23;
|
||||
|
||||
|
@ -59,6 +60,7 @@ procedure Test.0 ():
|
|||
case 1:
|
||||
let Test.22 : Str = "foo";
|
||||
let Test.21 : [C {}, C U64, C Str] = CallByName Test.2 Test.22;
|
||||
dec Test.22;
|
||||
jump Test.13 Test.21;
|
||||
|
||||
default:
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
procedure Test.1 (Test.4):
|
||||
inc Test.4;
|
||||
let Test.13 : [C Str, C Str] = TagId(0) Test.4;
|
||||
ret Test.13;
|
||||
|
||||
procedure Test.1 (Test.4):
|
||||
inc Test.4;
|
||||
let Test.19 : [C Str, C Str] = TagId(0) Test.4;
|
||||
ret Test.19;
|
||||
|
||||
|
@ -22,8 +24,10 @@ procedure Test.0 ():
|
|||
if Test.22 then
|
||||
let Test.16 : Str = "";
|
||||
let Test.10 : [C Str, C Str] = CallByName Test.1 Test.16;
|
||||
dec Test.16;
|
||||
jump Test.9 Test.10;
|
||||
else
|
||||
let Test.20 : Str = "";
|
||||
let Test.17 : [C Str, C Str] = CallByName Test.1 Test.20;
|
||||
dec Test.20;
|
||||
jump Test.9 Test.17;
|
||||
|
|
|
@ -26,6 +26,7 @@ procedure List.92 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.0;
|
||||
jump List.577 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
@ -46,4 +47,5 @@ procedure Test.0 ():
|
|||
let Test.8 : List [<rnu>C *self, <null>] = Array [];
|
||||
let Test.15 : {} = Struct {};
|
||||
let Test.9 : [<rnu><null>, C {[<rnu>C *self, <null>], *self}] = CallByName List.18 Test.8 Test.6 Test.15;
|
||||
dec Test.8;
|
||||
ret Test.9;
|
||||
|
|
3
crates/compiler/test_mono/generated/list_get.txt
generated
3
crates/compiler/test_mono/generated/list_get.txt
generated
|
@ -3,11 +3,9 @@ procedure List.2 (List.108, List.109):
|
|||
let List.576 : Int1 = CallByName Num.22 List.109 List.580;
|
||||
if List.576 then
|
||||
let List.578 : I64 = CallByName List.66 List.108 List.109;
|
||||
dec List.108;
|
||||
let List.577 : [C {}, C I64] = TagId(1) List.578;
|
||||
ret List.577;
|
||||
else
|
||||
dec List.108;
|
||||
let List.575 : {} = Struct {};
|
||||
let List.574 : [C {}, C I64] = TagId(0) List.575;
|
||||
ret List.574;
|
||||
|
@ -28,6 +26,7 @@ procedure Test.1 (Test.2):
|
|||
let Test.6 : List I64 = Array [1i64, 2i64, 3i64];
|
||||
let Test.7 : U64 = 0i64;
|
||||
let Test.5 : [C {}, C I64] = CallByName List.2 Test.6 Test.7;
|
||||
dec Test.6;
|
||||
ret Test.5;
|
||||
|
||||
procedure Test.0 ():
|
||||
|
|
|
@ -4,11 +4,9 @@ procedure List.2 (List.108, List.109):
|
|||
if List.576 then
|
||||
let List.578 : Str = CallByName List.66 List.108 List.109;
|
||||
inc List.578;
|
||||
dec List.108;
|
||||
let List.577 : [C {}, C Str] = TagId(1) List.578;
|
||||
ret List.577;
|
||||
else
|
||||
dec List.108;
|
||||
let List.575 : {} = Struct {};
|
||||
let List.574 : [C {}, C Str] = TagId(0) List.575;
|
||||
ret List.574;
|
||||
|
@ -55,13 +53,13 @@ procedure Test.2 ():
|
|||
procedure Test.3 (Test.4):
|
||||
let Test.18 : U64 = 2i64;
|
||||
let Test.17 : Str = CallByName Str.16 Test.4 Test.18;
|
||||
dec Test.4;
|
||||
ret Test.17;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.12 : List Str = CallByName Test.2;
|
||||
let Test.13 : U64 = 0i64;
|
||||
let Test.6 : [C {}, C Str] = CallByName List.2 Test.12 Test.13;
|
||||
dec Test.12;
|
||||
let Test.9 : U8 = 1i64;
|
||||
let Test.10 : U8 = GetTagId Test.6;
|
||||
let Test.11 : Int1 = lowlevel Eq Test.9 Test.10;
|
||||
|
|
|
@ -4,11 +4,9 @@ procedure List.2 (List.108, List.109):
|
|||
if List.576 then
|
||||
let List.578 : Str = CallByName List.66 List.108 List.109;
|
||||
inc List.578;
|
||||
dec List.108;
|
||||
let List.577 : [C {}, C Str] = TagId(1) List.578;
|
||||
ret List.577;
|
||||
else
|
||||
dec List.108;
|
||||
let List.575 : {} = Struct {};
|
||||
let List.574 : [C {}, C Str] = TagId(0) List.575;
|
||||
ret List.574;
|
||||
|
@ -58,6 +56,7 @@ procedure Test.0 ():
|
|||
let Test.12 : List Str = CallByName Test.2;
|
||||
let Test.13 : U64 = 0i64;
|
||||
let Test.6 : [C {}, C Str] = CallByName List.2 Test.12 Test.13;
|
||||
dec Test.12;
|
||||
let Test.9 : U8 = 1i64;
|
||||
let Test.10 : U8 = GetTagId Test.6;
|
||||
let Test.11 : Int1 = lowlevel Eq Test.9 Test.10;
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
procedure Test.1 (Test.2):
|
||||
inc Test.2;
|
||||
inc 2 Test.2;
|
||||
let Test.6 : {List I64, List I64} = Struct {Test.2, Test.2};
|
||||
ret Test.6;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.5 : List I64 = Array [1i64, 2i64, 3i64];
|
||||
let Test.4 : {List I64, List I64} = CallByName Test.1 Test.5;
|
||||
dec Test.5;
|
||||
ret Test.4;
|
||||
|
|
|
@ -7,8 +7,6 @@ procedure Test.1 (Test.3):
|
|||
ret Test.13;
|
||||
|
||||
procedure Test.2 (Test.4, Test.5):
|
||||
dec Test.5;
|
||||
dec Test.4;
|
||||
let Test.9 : U64 = 18i64;
|
||||
ret Test.9;
|
||||
|
||||
|
@ -18,4 +16,6 @@ procedure Test.0 ():
|
|||
let Test.10 : {} = Struct {};
|
||||
let Test.8 : List U16 = CallByName Test.1 Test.10;
|
||||
let Test.6 : U64 = CallByName Test.2 Test.7 Test.8;
|
||||
dec Test.8;
|
||||
dec Test.7;
|
||||
ret Test.6;
|
||||
|
|
|
@ -3,11 +3,9 @@ procedure List.2 (List.108, List.109):
|
|||
let List.593 : Int1 = CallByName Num.22 List.109 List.596;
|
||||
if List.593 then
|
||||
let List.595 : I64 = CallByName List.66 List.108 List.109;
|
||||
dec List.108;
|
||||
let List.594 : [C {}, C I64] = TagId(1) List.595;
|
||||
ret List.594;
|
||||
else
|
||||
dec List.108;
|
||||
let List.592 : {} = Struct {};
|
||||
let List.591 : [C {}, C I64] = TagId(0) List.592;
|
||||
ret List.591;
|
||||
|
@ -45,7 +43,6 @@ procedure Num.22 (#Attr.2, #Attr.3):
|
|||
|
||||
procedure Test.1 (Test.2):
|
||||
let Test.28 : U64 = 0i64;
|
||||
inc 2 Test.2;
|
||||
let Test.26 : [C {}, C I64] = CallByName List.2 Test.2 Test.28;
|
||||
let Test.27 : U64 = 0i64;
|
||||
let Test.25 : [C {}, C I64] = CallByName List.2 Test.2 Test.27;
|
||||
|
|
|
@ -3,7 +3,6 @@ procedure Bool.2 ():
|
|||
ret Bool.23;
|
||||
|
||||
procedure Test.10 (Test.26):
|
||||
dec Test.26;
|
||||
let Test.30 : Int1 = CallByName Bool.2;
|
||||
if Test.30 then
|
||||
let Test.31 : [<rnu><null>, C {}] = CallByName Test.0;
|
||||
|
@ -30,6 +29,7 @@ procedure Test.6 (Test.16, #Attr.12):
|
|||
let Test.19 : {} = Struct {};
|
||||
let Test.22 : Str = "foobar";
|
||||
let Test.20 : [<rnu><null>, C {}] = CallByName Test.8 Test.22 Test.23;
|
||||
dec Test.22;
|
||||
let Test.21 : U8 = GetTagId Test.20;
|
||||
switch Test.21:
|
||||
case 0:
|
||||
|
|
3
crates/compiler/test_mono/generated/rigids.txt
generated
3
crates/compiler/test_mono/generated/rigids.txt
generated
|
@ -3,11 +3,9 @@ procedure List.2 (List.108, List.109):
|
|||
let List.593 : Int1 = CallByName Num.22 List.109 List.596;
|
||||
if List.593 then
|
||||
let List.595 : I64 = CallByName List.66 List.108 List.109;
|
||||
dec List.108;
|
||||
let List.594 : [C {}, C I64] = TagId(1) List.595;
|
||||
ret List.594;
|
||||
else
|
||||
dec List.108;
|
||||
let List.592 : {} = Struct {};
|
||||
let List.591 : [C {}, C I64] = TagId(0) List.592;
|
||||
ret List.591;
|
||||
|
@ -44,7 +42,6 @@ procedure Num.22 (#Attr.2, #Attr.3):
|
|||
ret Num.281;
|
||||
|
||||
procedure Test.1 (Test.2, Test.3, Test.4):
|
||||
inc 2 Test.4;
|
||||
let Test.29 : [C {}, C I64] = CallByName List.2 Test.4 Test.3;
|
||||
let Test.28 : [C {}, C I64] = CallByName List.2 Test.4 Test.2;
|
||||
let Test.13 : {[C {}, C I64], [C {}, C I64]} = Struct {Test.28, Test.29};
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
procedure Test.1 (Test.2):
|
||||
dec Test.2;
|
||||
let Test.11 : Int1 = false;
|
||||
ret Test.11;
|
||||
|
||||
|
@ -14,6 +13,7 @@ procedure Test.4 (Test.13):
|
|||
procedure Test.0 ():
|
||||
let Test.16 : Str = "abc";
|
||||
let Test.6 : Int1 = CallByName Test.1 Test.16;
|
||||
dec Test.16;
|
||||
let Test.9 : {} = Struct {};
|
||||
switch Test.6:
|
||||
case 0:
|
||||
|
|
|
@ -79,6 +79,7 @@ procedure List.92 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.0;
|
||||
jump List.577 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
|
||||
|
||||
procedure Num.127 (#Attr.2):
|
||||
|
@ -110,6 +111,7 @@ procedure Test.20 (Test.58):
|
|||
ret Test.295;
|
||||
|
||||
procedure Test.21 (Test.61, Test.62):
|
||||
inc Test.61;
|
||||
let Test.275 : {List Str, {}} = Struct {Test.61, Test.62};
|
||||
let Test.274 : {List Str, {}} = CallByName Encode.23 Test.275;
|
||||
ret Test.274;
|
||||
|
@ -148,6 +150,7 @@ procedure Test.24 (Test.80, Test.81):
|
|||
let Test.294 : Str = CallByName Test.20 Test.80;
|
||||
let Test.271 : List Str = CallByName List.13 Test.81 Test.294;
|
||||
let Test.270 : {List Str, {}} = CallByName Test.23 Test.271;
|
||||
dec Test.271;
|
||||
ret Test.270;
|
||||
|
||||
procedure Test.3 ():
|
||||
|
@ -191,6 +194,7 @@ procedure Test.63 (Test.64, Test.276, #Attr.12):
|
|||
let Test.285 : U64 = CallByName List.6 Test.61;
|
||||
let Test.65 : List U8 = CallByName Test.4 Test.64 Test.284 Test.285;
|
||||
let Test.278 : List U8 = CallByName List.18 Test.61 Test.65 Test.62;
|
||||
dec Test.61;
|
||||
ret Test.278;
|
||||
|
||||
procedure Test.66 (Test.67, Test.68, Test.62):
|
||||
|
|
|
@ -19,7 +19,6 @@ procedure Test.15 (Test.49):
|
|||
ret Test.70;
|
||||
|
||||
procedure Test.16 (Test.48):
|
||||
dec Test.48;
|
||||
let Test.79 : {} = Struct {};
|
||||
let Test.78 : Int1 = CallByName Test.13 Test.79;
|
||||
ret Test.78;
|
||||
|
@ -55,6 +54,7 @@ procedure Test.43 (Test.44, Test.42):
|
|||
if Test.75 then
|
||||
let Test.77 : Str = StructAtIndex 0 Test.42;
|
||||
let Test.76 : Int1 = CallByName Test.16 Test.77;
|
||||
dec Test.77;
|
||||
let Test.61 : Int1 = CallByName Test.14 Test.76;
|
||||
jump Test.62 Test.61;
|
||||
else
|
||||
|
|
|
@ -155,6 +155,7 @@ procedure List.92 (#Derived_gen.29, #Derived_gen.30, #Derived_gen.31, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.29;
|
||||
jump List.577 #Derived_gen.29 #Derived_gen.30 #Derived_gen.31 #Derived_gen.32 #Derived_gen.33;
|
||||
|
||||
procedure List.92 (#Derived_gen.52, #Derived_gen.53, #Derived_gen.54, #Derived_gen.55, #Derived_gen.56):
|
||||
|
@ -171,6 +172,7 @@ procedure List.92 (#Derived_gen.52, #Derived_gen.53, #Derived_gen.54, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.52;
|
||||
jump List.604 #Derived_gen.52 #Derived_gen.53 #Derived_gen.54 #Derived_gen.55 #Derived_gen.56;
|
||||
|
||||
procedure Num.127 (#Attr.2):
|
||||
|
@ -198,6 +200,7 @@ procedure Str.36 (#Attr.2):
|
|||
ret Str.237;
|
||||
|
||||
procedure Test.20 (Test.58):
|
||||
inc Test.58;
|
||||
let Test.299 : [C {}, C {}, C Str] = TagId(2) Test.58;
|
||||
let Test.298 : [C {}, C {}, C Str] = CallByName Encode.23 Test.299;
|
||||
ret Test.298;
|
||||
|
@ -207,11 +210,13 @@ procedure Test.20 (Test.58):
|
|||
ret Test.342;
|
||||
|
||||
procedure Test.21 (Test.61, Test.62):
|
||||
inc Test.61;
|
||||
let Test.278 : {List [C {}, C {}, C Str], {}} = Struct {Test.61, Test.62};
|
||||
let Test.277 : {List [C {}, C {}, C Str], {}} = CallByName Encode.23 Test.278;
|
||||
ret Test.277;
|
||||
|
||||
procedure Test.21 (Test.61, Test.62):
|
||||
inc Test.61;
|
||||
let Test.322 : {List Str, {}} = Struct {Test.61, Test.62};
|
||||
let Test.321 : {List Str, {}} = CallByName Encode.23 Test.322;
|
||||
ret Test.321;
|
||||
|
@ -228,6 +233,7 @@ procedure Test.213 (Test.214, Test.215, Test.212):
|
|||
let Test.315 : [C {}, C {}, C Str] = CallByName #Derived.0 Test.316;
|
||||
let Test.314 : List [C {}, C {}, C Str] = Array [Test.315];
|
||||
let Test.269 : {List [C {}, C {}, C Str], {}} = CallByName Test.24 Test.313 Test.314;
|
||||
dec Test.313;
|
||||
jump Test.270 Test.269;
|
||||
else
|
||||
let Test.271 : Str = "B";
|
||||
|
@ -235,6 +241,7 @@ procedure Test.213 (Test.214, Test.215, Test.212):
|
|||
let Test.310 : [C {}, C {}, C Str] = CallByName #Derived.5 Test.311;
|
||||
let Test.272 : List [C {}, C {}, C Str] = Array [Test.310];
|
||||
let Test.269 : {List [C {}, C {}, C Str], {}} = CallByName Test.24 Test.271 Test.272;
|
||||
dec Test.271;
|
||||
jump Test.270 Test.269;
|
||||
|
||||
procedure Test.23 (Test.77):
|
||||
|
@ -251,12 +258,14 @@ procedure Test.24 (Test.80, Test.81):
|
|||
let Test.297 : [C {}, C {}, C Str] = CallByName Test.20 Test.80;
|
||||
let Test.274 : List [C {}, C {}, C Str] = CallByName List.13 Test.81 Test.297;
|
||||
let Test.273 : {List [C {}, C {}, C Str], {}} = CallByName Test.23 Test.274;
|
||||
dec Test.274;
|
||||
ret Test.273;
|
||||
|
||||
procedure Test.24 (Test.80, Test.81):
|
||||
let Test.355 : Str = CallByName Test.20 Test.80;
|
||||
let Test.354 : List Str = CallByName List.13 Test.81 Test.355;
|
||||
let Test.353 : {List Str, {}} = CallByName Test.23 Test.354;
|
||||
dec Test.354;
|
||||
ret Test.353;
|
||||
|
||||
procedure Test.3 ():
|
||||
|
@ -311,6 +320,7 @@ procedure Test.63 (Test.64, Test.279, #Attr.12):
|
|||
let Test.332 : U64 = CallByName List.6 Test.61;
|
||||
let Test.65 : List U8 = CallByName Test.4 Test.64 Test.331 Test.332;
|
||||
let Test.325 : List U8 = CallByName List.18 Test.61 Test.65 Test.62;
|
||||
dec Test.61;
|
||||
ret Test.325;
|
||||
|
||||
procedure Test.63 (Test.64, Test.279, #Attr.12):
|
||||
|
@ -320,6 +330,7 @@ procedure Test.63 (Test.64, Test.279, #Attr.12):
|
|||
let Test.288 : U64 = CallByName List.6 Test.61;
|
||||
let Test.65 : List U8 = CallByName Test.4 Test.64 Test.287 Test.288;
|
||||
let Test.281 : List U8 = CallByName List.18 Test.61 Test.65 Test.62;
|
||||
dec Test.61;
|
||||
ret Test.281;
|
||||
|
||||
procedure Test.66 (Test.67, Test.68, Test.62):
|
||||
|
|
|
@ -75,6 +75,7 @@ procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
|
|||
let List.595 : [C U64, C U64] = TagId(1) List.492;
|
||||
ret List.595;
|
||||
in
|
||||
inc #Derived_gen.0;
|
||||
jump List.594 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
|
@ -96,7 +97,6 @@ procedure Test.3 (Test.4, Test.12):
|
|||
procedure Test.0 (Test.1):
|
||||
let Test.10 : U64 = 0i64;
|
||||
let Test.11 : {} = Struct {};
|
||||
inc Test.1;
|
||||
let Test.2 : U64 = CallByName List.26 Test.1 Test.10 Test.11;
|
||||
let Test.9 : U64 = 0i64;
|
||||
let Test.7 : Int1 = CallByName Bool.11 Test.2 Test.9;
|
||||
|
|
|
@ -7,11 +7,8 @@ When(
|
|||
patterns: [
|
||||
@14-20 SpaceBefore(
|
||||
As(
|
||||
@14-15 SpaceAfter(
|
||||
Underscore(
|
||||
"",
|
||||
),
|
||||
[],
|
||||
@14-15 Underscore(
|
||||
"",
|
||||
),
|
||||
PatternAs {
|
||||
spaces_before: [],
|
||||
|
|
|
@ -6205,6 +6205,31 @@ mod test_fmt {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_6215() {
|
||||
expr_formats_to(
|
||||
indoc!(
|
||||
r"
|
||||
when list is
|
||||
[first as last]
|
||||
| [first, last] ->
|
||||
first
|
||||
_->Not
|
||||
"
|
||||
),
|
||||
indoc!(
|
||||
r"
|
||||
when list is
|
||||
[first as last]
|
||||
| [first, last] ->
|
||||
first
|
||||
|
||||
_ -> Not
|
||||
"
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// this is a parse error atm
|
||||
// #[test]
|
||||
// fn multiline_apply() {
|
||||
|
|
|
@ -11,6 +11,7 @@ main =
|
|||
procedure Inspect.248 (Inspect.249):
|
||||
let Inspect.313 : Str = "<opaque>";
|
||||
let Inspect.312 : Str = CallByName Inspect.59 Inspect.249 Inspect.313;
|
||||
dec Inspect.313;
|
||||
ret Inspect.312;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -39,7 +40,6 @@ procedure Inspect.5 (Inspect.146):
|
|||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.315 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
|
|
@ -14,6 +14,7 @@ main =
|
|||
procedure Inspect.248 (Inspect.249):
|
||||
let Inspect.313 : Str = "<opaque>";
|
||||
let Inspect.312 : Str = CallByName Inspect.59 Inspect.249 Inspect.313;
|
||||
dec Inspect.313;
|
||||
ret Inspect.312;
|
||||
|
||||
procedure Inspect.30 (Inspect.143):
|
||||
|
@ -42,7 +43,6 @@ procedure Inspect.5 (Inspect.146):
|
|||
|
||||
procedure Inspect.59 (Inspect.296, Inspect.292):
|
||||
let Inspect.315 : Str = CallByName Str.3 Inspect.296 Inspect.292;
|
||||
dec Inspect.292;
|
||||
ret Inspect.315;
|
||||
|
||||
procedure Inspect.60 (Inspect.298):
|
||||
|
|
|
@ -20,11 +20,11 @@ procedure Bool.2 ():
|
|||
procedure Test.1 (Test.2):
|
||||
let Test.34 : Int1 = CallByName Bool.2;
|
||||
if Test.34 then
|
||||
dec Test.2;
|
||||
let Test.38 : FunPtr(({}) -> Str) = FunctionPointer Test.3;
|
||||
let Test.35 : ?Erased = ErasedMake { value: <null>, callee: Test.38 };
|
||||
ret Test.35;
|
||||
else
|
||||
inc Test.2;
|
||||
let Test.33 : {Str} = Struct {Test.2};
|
||||
let Test.31 : [<rnu><null>, C {Str}] = TagId(0) Test.33;
|
||||
let Test.32 : FunPtr(({}, ?Erased) -> Str) = FunctionPointer Test.4;
|
||||
|
|
|
@ -109,13 +109,16 @@ pub const INTERNAL_ERROR_MESSAGE: &str = concat!(
|
|||
#[macro_export]
|
||||
macro_rules! internal_error {
|
||||
() => ({
|
||||
$crate::error_and_exit(format_args!("{}", $crate::INTERNAL_ERROR_MESSAGE))
|
||||
$crate::error_and_exit(format_args!("{}\nLocation: {}:{}:{}", $crate::INTERNAL_ERROR_MESSAGE, file!(), line!(), column!()))
|
||||
});
|
||||
($($arg:tt)*) => ({
|
||||
$crate::error_and_exit(format_args!(
|
||||
"{}{}",
|
||||
"{}{}\nLocation: {}:{}:{}",
|
||||
$crate::INTERNAL_ERROR_MESSAGE,
|
||||
format_args!($($arg)*)
|
||||
format_args!($($arg)*),
|
||||
file!(),
|
||||
line!(),
|
||||
column!(),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
@ -132,13 +135,16 @@ pub const USER_ERROR_MESSAGE: &str = concat!(
|
|||
#[macro_export]
|
||||
macro_rules! user_error {
|
||||
() => ({
|
||||
$crate::error_and_exit(format_args!("{}", $crate::USER_ERROR_MESSAGE))
|
||||
$crate::error_and_exit(format_args!("{}\nLocation: {}:{}:{}", $crate::USER_ERROR_MESSAGE, file!(), line!(), column!()))
|
||||
});
|
||||
($($arg:tt)*) => ({
|
||||
$crate::error_and_exit(format_args!(
|
||||
"{}{}",
|
||||
"{}{}\nLocation: {}:{}:{}",
|
||||
$crate::USER_ERROR_MESSAGE,
|
||||
format_args!($($arg)*)
|
||||
format_args!($($arg)*),
|
||||
file!(),
|
||||
line!(),
|
||||
column!(),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
|
11
crates/fs/Cargo.toml
Normal file
11
crates/fs/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "fs"
|
||||
description = "no_std filesystem access. These operations all use native OS strings and do not allocate."
|
||||
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
widestring = { version = "1.1.0", default-features = false }
|
607
crates/fs/src/file.rs
Normal file
607
crates/fs/src/file.rs
Normal file
|
@ -0,0 +1,607 @@
|
|||
use crate::native_path::NativePath;
|
||||
use core::{fmt, mem::MaybeUninit};
|
||||
|
||||
#[cfg(windows)]
|
||||
use widestring::U16CStr;
|
||||
|
||||
#[cfg(unix)]
|
||||
use core::ffi::{c_char, c_int, CStr};
|
||||
|
||||
#[cfg(unix)]
|
||||
pub struct File {
|
||||
fd: i32,
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub struct File {
|
||||
handle: isize,
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
extern "C" {
|
||||
fn open(pathname: *const c_char, flags: c_int, ...) -> c_int;
|
||||
fn close(fd: c_int) -> c_int;
|
||||
fn read(fd: c_int, buf: *mut MaybeUninit<u8>, count: usize) -> isize;
|
||||
fn write(fd: c_int, buf: *const u8, count: usize) -> isize;
|
||||
fn mkstemp(template: *mut c_char) -> c_int;
|
||||
fn unlink(pathname: *const c_char) -> c_int;
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl Drop for File {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
close(self.fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
extern "system" {
|
||||
fn CreateFileW(
|
||||
lpFileName: *const u16,
|
||||
dwDesiredAccess: u32,
|
||||
dwShareMode: u32,
|
||||
lpSecurityAttributes: *mut core::ffi::c_void,
|
||||
dwCreationDisposition: u32,
|
||||
dwFlagsAndAttributes: u32,
|
||||
hTemplateFile: isize,
|
||||
) -> isize;
|
||||
fn CloseHandle(hObject: isize) -> i32;
|
||||
fn ReadFile(
|
||||
hFile: isize,
|
||||
lpBuffer: *mut MaybeUninit<u8>,
|
||||
nNumberOfBytesToRead: u32,
|
||||
lpNumberOfBytesRead: *mut u32,
|
||||
lpOverlapped: *mut core::ffi::c_void,
|
||||
) -> i32;
|
||||
fn WriteFile(
|
||||
hFile: isize,
|
||||
lpBuffer: *const u8,
|
||||
nNumberOfBytesToWrite: u32,
|
||||
lpNumberOfBytesWritten: *mut u32,
|
||||
lpOverlapped: *mut core::ffi::c_void,
|
||||
) -> i32;
|
||||
fn DeleteFileW(lpFileName: *const u16) -> i32;
|
||||
fn GetTempPath2W(nBufferLength: u32, lpBuffer: *mut u16) -> u32;
|
||||
fn GetTempFileNameW(
|
||||
lpPathName: *const u16,
|
||||
lpPrefixString: *const u16,
|
||||
uUnique: u32,
|
||||
lpTempFileName: *mut u16,
|
||||
) -> u32;
|
||||
fn CreateDirectoryW(
|
||||
lpPathName: *const u16,
|
||||
lpSecurityAttributes: *mut core::ffi::c_void,
|
||||
) -> i32;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl Drop for File {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
CloseHandle(self.handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(unix, repr(i32))]
|
||||
#[cfg_attr(windows, repr(u32))]
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
#[non_exhaustive] // There are tons of other error numbers that functions which return this might return!
|
||||
pub enum FileIoErr {
|
||||
/// "File not found" is the same code (namely, 2) on both UNIX and Windows:
|
||||
/// ENOENT on UNIX: https://www.man7.org/linux/man-pages/man3/errno.3.html
|
||||
/// ERROR_FILE_NOT_FOUND on Windows: // https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
|
||||
NotFound = 2,
|
||||
|
||||
#[cfg(unix)]
|
||||
/// EACCES: https://www.man7.org/linux/man-pages/man3/errno.3.html
|
||||
AccessDenied = 13,
|
||||
|
||||
#[cfg(windows)]
|
||||
/// ERROR_ACCESS_DENIED: https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
|
||||
AccessDenied = 5,
|
||||
|
||||
#[cfg(unix)]
|
||||
/// EEXIST: https://www.man7.org/linux/man-pages/man3/errno.3.html
|
||||
AlreadyExists = 17,
|
||||
|
||||
#[cfg(windows)]
|
||||
/// ERROR_FILE_EXISTS: https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
|
||||
AlreadyExists = 80,
|
||||
}
|
||||
|
||||
impl fmt::Debug for FileIoErr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
FileIoErr::NotFound => write!(f, "NotFound ({})", *self as i32),
|
||||
#[cfg(unix)]
|
||||
FileIoErr::AccessDenied => write!(f, "AccessDenied ({})", *self as i32),
|
||||
#[cfg(windows)]
|
||||
FileIoErr::AccessDenied => write!(f, "AccessDenied ({})", *self as i32),
|
||||
FileIoErr::AlreadyExists => write!(f, "AlreadyExists ({})", *self as i32),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FileIoErr {
|
||||
#[cfg(target_os = "macos")]
|
||||
fn most_recent() -> FileIoErr {
|
||||
extern "C" {
|
||||
fn __error() -> *mut FileIoErr;
|
||||
}
|
||||
|
||||
unsafe { *__error() }
|
||||
}
|
||||
|
||||
#[cfg(all(target_family = "unix", not(target_os = "macos")))]
|
||||
fn most_recent() -> FileIoErr {
|
||||
extern "C" {
|
||||
fn __errno_location() -> *mut FileIoErr;
|
||||
}
|
||||
|
||||
unsafe { *__errno_location() }
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn most_recent() -> FileIoErr {
|
||||
extern "system" {
|
||||
fn GetLastError() -> FileIoErr;
|
||||
}
|
||||
|
||||
unsafe { GetLastError() }
|
||||
}
|
||||
}
|
||||
|
||||
// OPEN FILE //
|
||||
|
||||
#[cfg(unix)]
|
||||
impl File {
|
||||
const O_WRONLY: c_int = 1;
|
||||
const O_RDWR: c_int = 2;
|
||||
|
||||
/// source: https://github.com/apple-open-source/macos/blob/8038f956fee603c486e75adbf93cac7a66064f02/Libc/exclave/sys/fcntl.h#L104
|
||||
#[cfg(target_os = "macos")]
|
||||
const O_CREAT: c_int = 512;
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
const O_CREAT: c_int = 64;
|
||||
|
||||
/// source: https://github.com/apple-open-source/macos/blob/8038f956fee603c486e75adbf93cac7a66064f02/Libc/exclave/sys/fcntl.h#L106
|
||||
#[cfg(target_os = "macos")]
|
||||
const O_EXCL: c_int = 2048;
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
const O_EXCL: c_int = 128;
|
||||
|
||||
pub fn open(path: &NativePath) -> Result<Self, FileIoErr> {
|
||||
let fd = unsafe { open(path.inner.as_ptr(), Self::O_RDWR) };
|
||||
|
||||
if fd != -1 {
|
||||
Ok(File { fd })
|
||||
} else {
|
||||
Err(FileIoErr::most_recent())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create(path: &NativePath) -> Result<Self, FileIoErr> {
|
||||
let fd = unsafe {
|
||||
open(
|
||||
path.inner.as_ptr(),
|
||||
Self::O_CREAT | Self::O_WRONLY | Self::O_EXCL, // O_EXCL means fail if it already exists
|
||||
// read/write mode
|
||||
0o644,
|
||||
)
|
||||
};
|
||||
|
||||
if fd != -1 {
|
||||
Ok(File { fd })
|
||||
} else {
|
||||
Err(FileIoErr::most_recent())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl File {
|
||||
const GENERIC_READ: u32 = 0x80000000;
|
||||
const GENERIC_WRITE: u32 = 0x40000000;
|
||||
const FILE_SHARE_READ: u32 = 1;
|
||||
const FILE_SHARE_WRITE: u32 = 2;
|
||||
const CREATE_NEW: u32 = 1;
|
||||
const CREATE_ALWAYS: u32 = 2;
|
||||
const OPEN_EXISTING: u32 = 3;
|
||||
|
||||
pub fn open(path: &NativePath) -> Result<Self, FileIoErr> {
|
||||
let handle = unsafe {
|
||||
CreateFileW(
|
||||
path.inner.as_ptr(),
|
||||
Self::GENERIC_READ | Self::GENERIC_WRITE,
|
||||
Self::FILE_SHARE_READ | Self::FILE_SHARE_WRITE,
|
||||
core::ptr::null_mut(),
|
||||
Self::OPEN_EXISTING,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
};
|
||||
|
||||
if handle != -1 {
|
||||
Ok(File { handle })
|
||||
} else {
|
||||
Err(FileIoErr::most_recent())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create(path: &NativePath) -> Result<Self, FileIoErr> {
|
||||
let handle = unsafe {
|
||||
CreateFileW(
|
||||
path.inner.as_ptr(),
|
||||
Self::GENERIC_READ | Self::GENERIC_WRITE,
|
||||
Self::FILE_SHARE_READ | Self::FILE_SHARE_WRITE,
|
||||
core::ptr::null_mut(),
|
||||
Self::CREATE_ALWAYS,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
};
|
||||
|
||||
if handle != -1 {
|
||||
Ok(File { handle })
|
||||
} else {
|
||||
Err(FileIoErr::most_recent())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// REMOVE //
|
||||
|
||||
#[cfg(unix)]
|
||||
impl File {
|
||||
/// Returns whether it succeeded.
|
||||
pub fn remove(path: &NativePath) -> bool {
|
||||
unsafe { unlink(path.inner.as_ptr()) == 0 }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl File {
|
||||
/// Source: https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Foundation/constant.MAX_PATH.html
|
||||
const MAX_PATH: u32 = 260;
|
||||
|
||||
/// Returns whether it succeeded.
|
||||
pub fn remove(path: &NativePath) -> bool {
|
||||
unsafe { DeleteFileW(path.inner.as_ptr()) != 0 }
|
||||
}
|
||||
}
|
||||
|
||||
// TEMPFILE //
|
||||
|
||||
#[cfg(unix)]
|
||||
impl File {
|
||||
/// Create a tempfile, open it as a File, pass that File and its generated path
|
||||
/// to the given function, and then delete it after the function returns.
|
||||
pub fn with_tempfile<T>(
|
||||
run: impl FnOnce(Result<(&NativePath, &mut Self), FileIoErr>) -> T,
|
||||
) -> T {
|
||||
const TEMPLATE: &[u8] = b"/tmp/roc_tempfile_XXXXXX\0";
|
||||
|
||||
let mut template = [0; TEMPLATE.len()];
|
||||
template.copy_from_slice(TEMPLATE);
|
||||
|
||||
// mkstemp replaces the Xs in the template with chars that result in a unique path.
|
||||
let fd = unsafe { mkstemp(template.as_mut_ptr().cast()) };
|
||||
|
||||
if fd != -1 {
|
||||
let path_cstr = unsafe { CStr::from_bytes_with_nul_unchecked(&template) };
|
||||
let native_path: &NativePath = path_cstr.into();
|
||||
let mut file = File { fd };
|
||||
|
||||
// Since we pass an owned File, it will get closed automatically once dropped.
|
||||
// This in turn will result in the file getting deleted, since we already unlinked it.
|
||||
let answer = run(Ok((native_path, &mut file)));
|
||||
|
||||
// Unlink the file now that we're done with it.
|
||||
unsafe {
|
||||
unlink(template.as_ptr().cast());
|
||||
}
|
||||
|
||||
answer
|
||||
} else {
|
||||
// Here we assume that since mkstemp errored out, the file was not created
|
||||
// and we shouldn't attempt to unlink it.
|
||||
run(Err(FileIoErr::most_recent()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl File {
|
||||
/// Create a tempfile, open it as a File, pass that File and its generated path
|
||||
/// to the given function, and then delete it after the function returns.
|
||||
pub fn with_tempfile<T>(
|
||||
run: impl FnOnce(Result<(&NativePath, &mut Self), FileIoErr>) -> T,
|
||||
) -> T {
|
||||
let tempdir_path: &mut [MaybeUninit<u16>] =
|
||||
&mut [MaybeUninit::uninit(); Self::MAX_PATH as usize + 1];
|
||||
|
||||
let tempdir_path_len =
|
||||
unsafe { GetTempPath2W(tempdir_path.len() as u32, tempdir_path.as_mut_ptr().cast()) };
|
||||
|
||||
if tempdir_path_len == 0 {
|
||||
return run(Err(FileIoErr::most_recent()));
|
||||
}
|
||||
|
||||
let suffix =
|
||||
// Note: only up to the first 3 chars of this string will be used,
|
||||
// so we only give it 3.
|
||||
//
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamew
|
||||
widestring::u16cstr!("roc").as_slice_with_nul();
|
||||
|
||||
let tempfile_path: &mut [MaybeUninit<u16>] =
|
||||
&mut [MaybeUninit::uninit(); Self::MAX_PATH as usize + 1];
|
||||
|
||||
let result = unsafe {
|
||||
GetTempFileNameW(
|
||||
tempdir_path.as_ptr().cast(),
|
||||
suffix.as_ptr(),
|
||||
0,
|
||||
tempfile_path.as_mut_ptr().cast(),
|
||||
)
|
||||
};
|
||||
|
||||
if result == 0 {
|
||||
return run(Err(FileIoErr::most_recent()));
|
||||
}
|
||||
|
||||
let handle = unsafe {
|
||||
CreateFileW(
|
||||
tempfile_path.as_mut_ptr().cast(),
|
||||
Self::GENERIC_WRITE,
|
||||
Self::FILE_SHARE_READ | Self::FILE_SHARE_WRITE,
|
||||
core::ptr::null_mut(),
|
||||
Self::CREATE_ALWAYS,
|
||||
0x80, // FILE_ATTRIBUTE_TEMPORARY
|
||||
0,
|
||||
)
|
||||
};
|
||||
|
||||
if handle != -1 {
|
||||
let mut file = File { handle };
|
||||
let native_path = unsafe { U16CStr::from_ptr_str(tempfile_path.as_ptr().cast()) };
|
||||
|
||||
// Windows automatically deletes tempfiles when the last handle
|
||||
// to them is closed, so we don't need to delete this explicitly.
|
||||
run(Ok((native_path.into(), &mut file)))
|
||||
} else {
|
||||
run(Err(FileIoErr::most_recent()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// READ FILE //
|
||||
|
||||
impl File {
|
||||
#[cfg(unix)]
|
||||
pub fn read_into<'buf>(
|
||||
&mut self,
|
||||
buf: &'buf mut [MaybeUninit<u8>],
|
||||
) -> Result<&'buf mut [u8], FileIoErr> {
|
||||
let bytes_read = unsafe { read(self.fd, buf.as_mut_ptr(), buf.len()) };
|
||||
|
||||
if bytes_read >= 0 {
|
||||
// Return the subset of the buf that we actually initialized.
|
||||
let buf_ptr = buf.as_mut_ptr();
|
||||
let len = bytes_read as usize;
|
||||
|
||||
Ok(unsafe { core::slice::from_raw_parts_mut(buf_ptr.cast(), len) })
|
||||
} else {
|
||||
Err(FileIoErr::most_recent())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn read_into<'buf>(
|
||||
&mut self,
|
||||
buf: &'buf mut [MaybeUninit<u8>],
|
||||
) -> Result<&'buf mut [u8], FileIoErr> {
|
||||
let mut bytes_read: u32 = 0;
|
||||
|
||||
let result = unsafe {
|
||||
ReadFile(
|
||||
self.handle,
|
||||
buf.as_mut_ptr(),
|
||||
buf.len() as u32,
|
||||
&mut bytes_read,
|
||||
core::ptr::null_mut(),
|
||||
)
|
||||
};
|
||||
|
||||
if result >= 0 {
|
||||
let buf_ptr = buf.as_mut_ptr();
|
||||
let len = bytes_read as usize;
|
||||
|
||||
Ok(unsafe { core::slice::from_raw_parts_mut(buf_ptr.cast(), len) })
|
||||
} else {
|
||||
Err(FileIoErr::most_recent())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WRITE FILE //
|
||||
|
||||
impl File {
|
||||
#[cfg(unix)]
|
||||
pub fn write(&mut self, buf: &[u8]) -> Result<usize, FileIoErr> {
|
||||
let bytes_written = unsafe { write(self.fd, buf.as_ptr(), buf.len()) };
|
||||
|
||||
if bytes_written >= 0 {
|
||||
Ok(bytes_written as usize)
|
||||
} else {
|
||||
Err(FileIoErr::most_recent())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn write(&mut self, buf: &[u8]) -> Result<usize, FileIoErr> {
|
||||
let mut bytes_written: u32 = 0;
|
||||
|
||||
let result = unsafe {
|
||||
WriteFile(
|
||||
self.handle,
|
||||
buf.as_ptr(),
|
||||
buf.len() as u32,
|
||||
&mut bytes_written,
|
||||
core::ptr::null_mut(),
|
||||
)
|
||||
};
|
||||
|
||||
if result != 0 {
|
||||
Ok(bytes_written as usize)
|
||||
} else {
|
||||
Err(FileIoErr::most_recent())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{File, FileIoErr};
|
||||
use crate::native_path::NativePath;
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
#[cfg(unix)]
|
||||
use core::ffi::CStr;
|
||||
|
||||
#[cfg(windows)]
|
||||
use widestring::U16CStr;
|
||||
|
||||
#[cfg(unix)]
|
||||
fn str_to_cstr(s: &str) -> &CStr {
|
||||
CStr::from_bytes_with_nul(s.as_bytes()).expect("CStr conversion failed")
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn str_to_u16cstr(s: &str) -> &widestring::U16CStr {
|
||||
let wide_str: Vec<u16> = s.encode_utf16().collect::<Vec<_>>();
|
||||
unsafe { U16CStr::from_ptr_str(wide_str.as_ptr()) }
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn mock_path(path: &str) -> &NativePath {
|
||||
str_to_cstr(path).into()
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn mock_path(path: &str) -> &NativePath {
|
||||
str_to_u16cstr(path).into()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn file_not_found() {
|
||||
let file_result = File::open(mock_path("test_file_that_should_not_exist\0"));
|
||||
|
||||
assert_eq!(
|
||||
file_result.map(|_| ()),
|
||||
Err(FileIoErr::NotFound),
|
||||
"File should not exist: test_file_that_should_not_exist"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_write_read_delete() {
|
||||
let path = mock_path("roc_test_read_file\0");
|
||||
let mut file = File::create(path).unwrap();
|
||||
|
||||
// Write some data to the file
|
||||
let write_data: &[u8] = &[42u8; 10];
|
||||
let write_result = file.write(write_data);
|
||||
assert_eq!(
|
||||
write_result,
|
||||
Ok(write_data.len()),
|
||||
"Failed to write all data to the file: roc_test_read_file"
|
||||
);
|
||||
|
||||
// Close the file by dropping the file descriptor
|
||||
drop(file);
|
||||
|
||||
// Reopen the file
|
||||
let mut file = File::open(path).unwrap();
|
||||
let mut input_buf = [MaybeUninit::uninit(); 10];
|
||||
let result = file.read_into(&mut input_buf);
|
||||
assert_eq!(
|
||||
result.map(|mut_slice| &*mut_slice),
|
||||
Ok(write_data),
|
||||
"Failed to read all the data from the file: roc_test_read_file"
|
||||
);
|
||||
|
||||
// Close the file by dropping the file descriptor
|
||||
drop(file);
|
||||
|
||||
// Remove the file
|
||||
let result = File::remove(path);
|
||||
assert!(result, "Failed to remove the file: roc_test_read_file");
|
||||
|
||||
// Verify that the file no longer exists
|
||||
let file_result = File::open(path);
|
||||
|
||||
assert_eq!(
|
||||
file_result.map(|_| ()),
|
||||
Err(FileIoErr::NotFound),
|
||||
"File should not exist after removal: roc_test_read_file"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tempfile() {
|
||||
const DATA: &[u8] = &[42; 10];
|
||||
let buf = &mut [MaybeUninit::uninit(); DATA.len()];
|
||||
|
||||
let answer = File::with_tempfile(|result| {
|
||||
let (native_path, file) = result.unwrap();
|
||||
|
||||
// Write some data to the tempfile
|
||||
assert_eq!(
|
||||
Ok(DATA.len()),
|
||||
file.write(DATA),
|
||||
"Failed to write all the bytes to the tempfile"
|
||||
);
|
||||
|
||||
// Reopen the tempfile with a fresh file descriptor, and read the data back in from it
|
||||
File::open(native_path).unwrap().read_into(buf)
|
||||
});
|
||||
|
||||
// The data read should match the data written
|
||||
assert_eq!(
|
||||
Ok(DATA),
|
||||
answer.map(|mut_slice| &*mut_slice),
|
||||
"Data read from the file does not match data written to the file"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_file_that_already_exists() {
|
||||
let path = mock_path("roc_test_already_exists\0");
|
||||
|
||||
let first = File::create(path); // Create the file for the first time
|
||||
let second = File::create(path); // Attempt to create the same file again
|
||||
let removed = File::remove(path); // Remove the file now that we're done with it (before we do any assertions!)
|
||||
|
||||
assert!(
|
||||
first.is_ok(),
|
||||
"Failed to create the file: roc_test_already_exists"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
second.map(|_| ()),
|
||||
Err(FileIoErr::AlreadyExists),
|
||||
"File should already exist: roc_test_already_exists"
|
||||
);
|
||||
|
||||
assert!(
|
||||
removed,
|
||||
"Failed to remove the file: roc_test_already_exists"
|
||||
);
|
||||
}
|
||||
}
|
7
crates/fs/src/lib.rs
Normal file
7
crates/fs/src/lib.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
#![cfg_attr(not(any(debug_assertions, test)), no_std)]
|
||||
|
||||
mod file;
|
||||
mod native_path;
|
||||
|
||||
pub use file::*;
|
||||
pub use native_path::*;
|
41
crates/fs/src/native_path.rs
Normal file
41
crates/fs/src/native_path.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
use core::{fmt, mem};
|
||||
|
||||
#[cfg(unix)]
|
||||
use core::ffi::CStr;
|
||||
|
||||
#[cfg(windows)]
|
||||
use widestring::U16CStr;
|
||||
|
||||
#[cfg(unix)]
|
||||
#[repr(transparent)]
|
||||
pub struct NativePath {
|
||||
pub(crate) inner: CStr,
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[repr(transparent)]
|
||||
pub struct NativePath {
|
||||
pub(crate) inner: U16CStr,
|
||||
}
|
||||
|
||||
impl fmt::Debug for NativePath {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.inner.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl<'a> From<&'a CStr> for &'a NativePath {
|
||||
fn from(c_str: &'a CStr) -> Self {
|
||||
// Safety: Self is repr(transparent)
|
||||
unsafe { mem::transmute(c_str) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl<'a> From<&'a U16CStr> for &'a NativePath {
|
||||
fn from(u16_c_str: &'a U16CStr) -> Self {
|
||||
// Safety: Self is repr(transparent)
|
||||
unsafe { mem::transmute(u16_c_str) }
|
||||
}
|
||||
}
|
|
@ -1,21 +1,18 @@
|
|||
app "rust-glue"
|
||||
packages { pf: "../platform/main.roc" }
|
||||
imports [
|
||||
pf.Types.{ Types },
|
||||
pf.Shape.{ Shape, RocFn },
|
||||
pf.File.{ File },
|
||||
pf.TypeId.{ TypeId },
|
||||
"../static/Cargo.toml" as rocAppCargoToml : Str,
|
||||
"../../roc_std/Cargo.toml" as rocStdCargoToml : Str,
|
||||
"../../roc_std/src/lib.rs" as rocStdLib : Str,
|
||||
"../../roc_std/src/roc_box.rs" as rocStdBox : Str,
|
||||
"../../roc_std/src/roc_list.rs" as rocStdList : Str,
|
||||
"../../roc_std/src/roc_dict.rs" as rocStdDict : Str,
|
||||
"../../roc_std/src/roc_set.rs" as rocStdSet : Str,
|
||||
"../../roc_std/src/roc_str.rs" as rocStdStr : Str,
|
||||
"../../roc_std/src/storage.rs" as rocStdStorage : Str,
|
||||
]
|
||||
provides [makeGlue] to pf
|
||||
app [makeGlue] { pf: platform "../platform/main.roc" }
|
||||
|
||||
import pf.Types exposing [Types]
|
||||
import pf.Shape exposing [Shape, RocFn]
|
||||
import pf.File exposing [File]
|
||||
import pf.TypeId exposing [TypeId]
|
||||
import "../static/Cargo.toml" as rocAppCargoToml : Str
|
||||
import "../../roc_std/Cargo.toml" as rocStdCargoToml : Str
|
||||
import "../../roc_std/src/lib.rs" as rocStdLib : Str
|
||||
import "../../roc_std/src/roc_box.rs" as rocStdBox : Str
|
||||
import "../../roc_std/src/roc_list.rs" as rocStdList : Str
|
||||
import "../../roc_std/src/roc_dict.rs" as rocStdDict : Str
|
||||
import "../../roc_std/src/roc_set.rs" as rocStdSet : Str
|
||||
import "../../roc_std/src/roc_str.rs" as rocStdStr : Str
|
||||
import "../../roc_std/src/storage.rs" as rocStdStorage : Str
|
||||
|
||||
makeGlue : List Types -> Result (List File) Str
|
||||
makeGlue = \typesByArch ->
|
||||
|
@ -167,6 +164,7 @@ generateEntryPoint = \buf, types, name, id ->
|
|||
when Types.shape types rocFn.ret is
|
||||
Function _ ->
|
||||
("(_: *mut u8, $(arguments))", ret, Bool.true)
|
||||
|
||||
_ ->
|
||||
("(_: *mut $(ret), $(arguments))", ret, Bool.false)
|
||||
|
||||
|
@ -646,6 +644,30 @@ generateDestructorFunction = \buf, types, tagUnionType, name, optPayload ->
|
|||
else
|
||||
"unsafe { core::mem::ManuallyDrop::take(&mut self.payload.$(name)) }"
|
||||
|
||||
(borrow, borrowType) =
|
||||
if canDeriveCopy types shape then
|
||||
("unsafe { self.payload.$(name) }", payloadType)
|
||||
else
|
||||
(
|
||||
"""
|
||||
use core::borrow::Borrow;
|
||||
unsafe { self.payload.$(name).borrow() }
|
||||
""",
|
||||
"&$(payloadType)",
|
||||
)
|
||||
|
||||
(borrowMut, borrowMutType) =
|
||||
if canDeriveCopy types shape then
|
||||
("unsafe { &mut self.payload.$(name) }", "&mut $(payloadType)")
|
||||
else
|
||||
(
|
||||
"""
|
||||
use core::borrow::BorrowMut;
|
||||
unsafe { self.payload.$(name).borrow_mut() }
|
||||
""",
|
||||
"&mut $(payloadType)",
|
||||
)
|
||||
|
||||
"""
|
||||
$(buf)
|
||||
|
||||
|
@ -654,6 +676,16 @@ generateDestructorFunction = \buf, types, tagUnionType, name, optPayload ->
|
|||
$(take)
|
||||
}
|
||||
|
||||
pub fn borrow_$(name)(&self) -> $(borrowType) {
|
||||
debug_assert_eq!(self.discriminant, discriminant_$(tagUnionType)::$(name));
|
||||
$(borrow)
|
||||
}
|
||||
|
||||
pub fn borrow_mut_$(name)(&mut self) -> $(borrowMutType) {
|
||||
debug_assert_eq!(self.discriminant, discriminant_$(tagUnionType)::$(name));
|
||||
$(borrowMut)
|
||||
}
|
||||
|
||||
pub fn is_$(name)(&self) -> bool {
|
||||
matches!(self.discriminant, discriminant_$(tagUnionType)::$(name))
|
||||
}
|
||||
|
@ -1286,6 +1318,7 @@ writeIndents = \buf, indents ->
|
|||
|> Str.concat indent
|
||||
|> writeIndents (indents - 1)
|
||||
|
||||
writeTagImpls : Str, List { name : Str, payload : [Some TypeId, None] }, Str, U64, (Str, [Some TypeId, None] -> Str) -> Str
|
||||
writeTagImpls = \buf, tags, discriminantName, indents, f ->
|
||||
buf
|
||||
|> writeIndents indents
|
||||
|
|
|
@ -399,8 +399,7 @@ pub fn load_types(
|
|||
ignore_errors: IgnoreErrors,
|
||||
target: Target,
|
||||
) -> Result<Vec<Types>, io::Error> {
|
||||
// TODO the function kind may need to be parameterizable.
|
||||
let function_kind = FunctionKind::LambdaSet;
|
||||
let function_kind = FunctionKind::from_env();
|
||||
let arena = &Bump::new();
|
||||
let LoadedModule {
|
||||
module_id: home,
|
||||
|
|
|
@ -117,7 +117,7 @@ mod glue_cli_run {
|
|||
`Bar 123` is: NonRecursive::Bar(123)
|
||||
`Baz` is: NonRecursive::Baz(())
|
||||
`Blah 456` is: NonRecursive::Blah(456)
|
||||
"#),
|
||||
"#),
|
||||
nullable_wrapped:"nullable-wrapped" => indoc!(r#"
|
||||
tag_union was: StrFingerTree::More("foo", StrFingerTree::More("bar", StrFingerTree::Empty))
|
||||
`More "small str" (Single "other str")` is: StrFingerTree::More("small str", StrFingerTree::Single("other str"))
|
||||
|
@ -232,7 +232,7 @@ mod glue_cli_run {
|
|||
.join("RustGlue.roc");
|
||||
|
||||
// Generate a fresh test_glue for this platform
|
||||
let glue_out = run_glue(
|
||||
let parts : Vec<_> =
|
||||
// converting these all to String avoids lifetime issues
|
||||
std::iter::once("glue".to_string()).chain(
|
||||
args.into_iter().map(|arg| arg.to_string()).chain([
|
||||
|
@ -240,12 +240,13 @@ mod glue_cli_run {
|
|||
glue_dir.to_str().unwrap().to_string(),
|
||||
platform_module_path.to_str().unwrap().to_string(),
|
||||
]),
|
||||
),
|
||||
);
|
||||
).collect();
|
||||
let glue_out = run_glue(parts.iter());
|
||||
|
||||
if has_error(&glue_out.stderr) {
|
||||
panic!(
|
||||
"`roc glue` command had unexpected stderr: {}",
|
||||
"`roc {}` command had unexpected stderr: {}",
|
||||
parts.join(" "),
|
||||
glue_out.stderr
|
||||
);
|
||||
}
|
||||
|
|
|
@ -566,3 +566,22 @@ fn freeing_boxes() {
|
|||
"#
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn joinpoint_that_owns() {
|
||||
valgrind_test(indoc!(
|
||||
r#"
|
||||
(
|
||||
writeIndents = \buf, indents ->
|
||||
if indents <= 0 then
|
||||
buf
|
||||
else
|
||||
buf
|
||||
|> Str.concat " "
|
||||
|> writeIndents (indents - 1)
|
||||
|
||||
List.walk [{}, {}] "" \accum, {} -> accum |> writeIndents 4
|
||||
)
|
||||
"#
|
||||
));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue