Merge branch 'trunk' of github.com:rtfeldman/roc into wasm-stack-size-control-i2490

This commit is contained in:
Brian Carroll 2022-08-08 22:39:26 +01:00
commit 86b5db10d5
No known key found for this signature in database
GPG key ID: 9CF4E3BF9C4722C7
42 changed files with 1202 additions and 704 deletions

View file

@ -89,6 +89,9 @@ test-rust:
# gen-wasm has some multithreading problems to do with the wasmer runtime. Run it single-threaded as a separate job
RUN --mount=type=cache,target=$SCCACHE_DIR \
cargo test --locked --release --package test_gen --no-default-features --features gen-wasm -- --test-threads=1 && sccache --show-stats
# run `roc test` on Str builtins
RUN --mount=type=cache,target=$SCCACHE_DIR \
cargo run --release -- test crates/compiler/builtins/roc/Str.roc && sccache --show-stats
# repl_test: build the compiler for wasm target, then run the tests on native target
RUN --mount=type=cache,target=$SCCACHE_DIR \
crates/repl_test/test_wasm.sh && sccache --show-stats

View file

@ -25,7 +25,7 @@ roc_gen_wasm = { path = "../gen_wasm" }
roc_gen_dev = { path = "../gen_dev", default-features = false }
roc_reporting = { path = "../../reporting" }
roc_error_macros = { path = "../../error_macros" }
roc_std = { path = "../../roc_std", default-features = false }
roc_std = { path = "../../roc_std" }
roc_utils = { path = "../../utils" }
bumpalo = { version = "3.8.0", features = ["collections"] }
libloading = "0.7.1"

View file

@ -102,7 +102,7 @@ fn find_wasi_libc_path() -> PathBuf {
panic!("cannot find `wasi-libc.a`")
}
#[cfg(not(target_os = "macos"))]
#[cfg(all(unix, not(target_os = "macos")))]
#[allow(clippy::too_many_arguments)]
pub fn build_zig_host_native(
env_path: &str,
@ -166,6 +166,62 @@ pub fn build_zig_host_native(
command.output().unwrap()
}
#[cfg(windows)]
#[allow(clippy::too_many_arguments)]
pub fn build_zig_host_native(
env_path: &str,
env_home: &str,
emit_bin: &str,
zig_host_src: &str,
zig_str_path: &str,
target: &str,
opt_level: OptLevel,
shared_lib_path: Option<&Path>,
_target_valgrind: bool,
) -> Output {
let mut command = Command::new(&zig_executable());
command
.env_clear()
.env("PATH", env_path)
.env("HOME", env_home);
if let Some(shared_lib_path) = shared_lib_path {
command.args(&[
"build-exe",
"-fPIE",
shared_lib_path.to_str().unwrap(),
&bitcode::get_builtins_host_obj_path(),
]);
} else {
command.args(&["build-obj", "-fPIC"]);
}
command.args(&[
zig_host_src,
emit_bin,
"--pkg-begin",
"str",
zig_str_path,
"--pkg-end",
// include the zig runtime
// "-fcompiler-rt", compiler-rt causes segfaults on windows; investigate why
// include libc
"--library",
"c",
// cross-compile?
"-target",
target,
]);
if matches!(opt_level, OptLevel::Optimize) {
command.args(&["-O", "ReleaseSafe"]);
} else if matches!(opt_level, OptLevel::Size) {
command.args(&["-O", "ReleaseSmall"]);
}
command.output().unwrap()
}
#[cfg(target_os = "macos")]
#[allow(clippy::too_many_arguments)]
pub fn build_zig_host_native(

View file

@ -330,6 +330,15 @@ splitLast = \haystack, needle ->
None ->
Err NotFound
# splitLast when needle isn't in haystack
expect Str.splitLast "foo" "z" == Err NotFound
# splitLast when haystack ends with needle repeated
expect Str.splitLast "foo" "o" == Ok { before: "fo", after: "" }
# splitLast with multi-byte needle
expect Str.splitLast "hullabaloo" "ab" == Ok { before: "hull", after: "aloo" }
lastMatch : Str, Str -> [Some Nat, None]
lastMatch = \haystack, needle ->
haystackLength = Str.countUtf8Bytes haystack

View file

@ -30,7 +30,7 @@ packed_struct = "0.10.0"
[dev-dependencies]
roc_can = { path = "../can" }
roc_parse = { path = "../parse" }
roc_std = { path = "../../roc_std", default-features = false }
roc_std = { path = "../../roc_std" }
bumpalo = { version = "3.8.0", features = ["collections"] }
capstone = "0.11.0"

View file

@ -14,7 +14,7 @@ roc_builtins = { path = "../builtins" }
roc_error_macros = { path = "../../error_macros" }
roc_mono = { path = "../mono" }
roc_target = { path = "../roc_target" }
roc_std = { path = "../../roc_std", default-features = false }
roc_std = { path = "../../roc_std" }
roc_debug_flags = { path = "../debug_flags" }
roc_region = { path = "../region" }
morphic_lib = { path = "../../vendor/morphic_lib" }

View file

@ -4243,7 +4243,7 @@ pub fn build_wasm_test_wrapper<'a, 'ctx, 'env>(
opt_level,
procedures,
Some(entry_point),
Some(Path::new("/tmp/test.ll")),
Some(&std::env::temp_dir().join("test.ll")),
);
promote_to_wasm_test_wrapper(env, mod_solutions, entry_point.symbol, entry_point.layout)
@ -4260,7 +4260,7 @@ pub fn build_procedures_return_main<'a, 'ctx, 'env>(
opt_level,
procedures,
Some(entry_point),
Some(Path::new("/tmp/test.ll")),
Some(&std::env::temp_dir().join("test.ll")),
);
promote_to_main_function(env, mod_solutions, entry_point.symbol, entry_point.layout)
@ -4278,7 +4278,7 @@ pub fn build_procedures_expose_expects<'a, 'ctx, 'env>(
opt_level,
procedures,
opt_entry_point,
Some(Path::new("/tmp/test.ll")),
Some(&std::env::temp_dir().join("test.ll")),
);
let captures_niche = CapturesNiche::no_niche();

View file

@ -13,5 +13,5 @@ roc_collections = { path = "../collections" }
roc_module = { path = "../module" }
roc_mono = { path = "../mono" }
roc_target = { path = "../roc_target" }
roc_std = { path = "../../roc_std", default-features = false }
roc_std = { path = "../../roc_std" }
roc_error_macros = { path = "../../error_macros" }

View file

@ -269,3 +269,51 @@ pub const DEBUG_SETTINGS: WasmDebugSettings = WasmDebugSettings {
keep_test_binary: false && cfg!(debug_assertions),
skip_dead_code_elim: false && cfg!(debug_assertions),
};
#[cfg(test)]
mod dummy_platform_functions {
// `cargo test` produces an executable. At least on Windows, this means that extern symbols must be defined. This crate imports roc_std which
// defines a bunch of externs, and uses the three below. We provide dummy implementations because these functions are not called.
use core::ffi::c_void;
/// # Safety
/// This is only marked unsafe to typecheck without warnings in the rest of the code here.
#[no_mangle]
pub unsafe extern "C" fn roc_alloc(_size: usize, _alignment: u32) -> *mut c_void {
unimplemented!("It is not valid to call roc alloc from within the compiler. Please use the \"platform\" feature if this is a platform.")
}
/// # Safety
/// This is only marked unsafe to typecheck without warnings in the rest of the code here.
#[no_mangle]
pub unsafe extern "C" fn roc_realloc(
_ptr: *mut c_void,
_new_size: usize,
_old_size: usize,
_alignment: u32,
) -> *mut c_void {
unimplemented!("It is not valid to call roc realloc from within the compiler. Please use the \"platform\" feature if this is a platform.")
}
/// # Safety
/// This is only marked unsafe to typecheck without warnings in the rest of the code here.
#[no_mangle]
pub unsafe extern "C" fn roc_dealloc(_ptr: *mut c_void, _alignment: u32) {
unimplemented!("It is not valid to call roc dealloc from within the compiler. Please use the \"platform\" feature if this is a platform.")
}
#[no_mangle]
pub unsafe extern "C" fn roc_panic(_c_ptr: *mut c_void, _tag_id: u32) {
unimplemented!("It is not valid to call roc panic from within the compiler. Please use the \"platform\" feature if this is a platform.")
}
#[no_mangle]
pub fn roc_memcpy(_dst: *mut c_void, _src: *mut c_void, _n: usize) -> *mut c_void {
unimplemented!("It is not valid to call roc memcpy from within the compiler. Please use the \"platform\" feature if this is a platform.")
}
#[no_mangle]
pub fn roc_memset(_dst: *mut c_void, _c: i32, _n: usize) -> *mut c_void {
unimplemented!("It is not valid to call roc memset from within the compiler. Please use the \"platform\" feature if this is a platform.")
}
}

View file

@ -445,6 +445,7 @@ fn start_phase<'a>(
BuildTask::BuildPendingSpecializations {
layout_cache,
execution_mode: state.exec_mode,
module_id,
module_timing,
solved_subs,
@ -1090,6 +1091,7 @@ enum BuildTask<'a> {
},
BuildPendingSpecializations {
module_timing: ModuleTiming,
execution_mode: ExecutionMode,
layout_cache: LayoutCache<'a>,
solved_subs: Solved<Subs>,
imported_module_thunks: &'a [Symbol],
@ -4736,6 +4738,7 @@ fn make_specializations<'a>(
#[allow(clippy::too_many_arguments)]
fn build_pending_specializations<'a>(
arena: &'a Bump,
execution_mode: ExecutionMode,
solved_subs: Solved<Subs>,
imported_module_thunks: &'a [Symbol],
home: ModuleId,
@ -4993,6 +4996,12 @@ fn build_pending_specializations<'a>(
// the declarations of this group will be treaded individually by later iterations
}
Expectation => {
// skip expectations if we're not going to run them
match execution_mode {
ExecutionMode::Test => { /* fall through */ }
ExecutionMode::Check | ExecutionMode::Executable => continue,
}
// mark this symbol as a top-level thunk before any other work on the procs
module_thunks.push(symbol);
@ -5265,6 +5274,7 @@ fn run_task<'a>(
)),
BuildPendingSpecializations {
module_id,
execution_mode,
ident_ids,
decls,
module_timing,
@ -5277,6 +5287,7 @@ fn run_task<'a>(
derived_module,
} => Ok(build_pending_specializations(
arena,
execution_mode,
solved_subs,
imported_module_thunks,
module_id,

View file

@ -15,7 +15,7 @@ roc_can = { path = "../can" }
roc_derive_key = { path = "../derive_key" }
roc_derive = { path = "../derive" }
roc_late_solve = { path = "../late_solve" }
roc_std = { path = "../../roc_std", default-features = false }
roc_std = { path = "../../roc_std" }
roc_problem = { path = "../problem" }
roc_builtins = { path = "../builtins" }
roc_target = { path = "../roc_target" }

View file

@ -34,7 +34,7 @@ roc_parse = { path = "../parse" }
roc_build = { path = "../build", features = ["target-aarch64", "target-x86_64", "target-wasm32"] }
roc_target = { path = "../roc_target" }
roc_error_macros = { path = "../../error_macros" }
roc_std = { path = "../../roc_std" }
roc_std = { path = "../../roc_std" }
roc_debug_flags = {path="../debug_flags"}
bumpalo = { version = "3.8.0", features = ["collections"] }
either = "1.6.1"

View file

@ -17,6 +17,14 @@ fn main() {
}
}
const fn object_file_extension() -> &'static str {
if cfg!(windows) {
"obj"
} else {
"o"
}
}
fn build_wasm_linking_test_host() {
let host_source_path = PathBuf::from("src")
.join("helpers")
@ -53,15 +61,8 @@ fn build_wasm_linking_test_host() {
&format!("-femit-bin={}", host_wasm),
]);
let host_obj_path = PathBuf::from("build").join("wasm_linking_test_host.o");
let host_obj = host_obj_path.to_str().unwrap();
run_zig(&[
"build-obj",
host_source,
&format!("-femit-bin={}", &host_obj),
]);
let import_obj_path = PathBuf::from("build").join("wasm_linking_host_imports.o");
let mut import_obj_path = PathBuf::from("build").join("wasm_linking_host_imports");
import_obj_path.set_extension(object_file_extension());
let import_obj = import_obj_path.to_str().unwrap();
run_zig(&[
"build-obj",
@ -71,9 +72,15 @@ fn build_wasm_linking_test_host() {
run_zig(&[
"build-exe",
host_obj,
host_source,
import_obj,
&format!("-femit-bin={}", host_native),
#[cfg(windows)]
"--subsystem",
#[cfg(windows)]
"console",
#[cfg(windows)]
"-lc",
]);
}
@ -143,7 +150,12 @@ fn run_zig(args: &[&str]) {
println!("{} {}", zig, args.join(" "));
let output = Command::new(&zig).args(args).output().unwrap();
assert!(output.status.success(), "{:#?}", output);
if !output.status.success() {
eprintln!("stdout:\n{}", String::from_utf8_lossy(&output.stdout));
eprintln!("stderr:\n{}", String::from_utf8_lossy(&output.stderr));
panic!("zig call failed with status {:?}", output.status);
}
assert!(output.stdout.is_empty(), "{:#?}", output);
assert!(output.stderr.is_empty(), "{:#?}", output);
}

View file

@ -273,11 +273,12 @@ fn create_llvm_module<'a>(
// Verify the module
if let Err(errors) = env.module.verify() {
let path = "/tmp/test.ll";
env.module.print_to_file(path).unwrap();
let path = std::env::temp_dir().join("test.ll");
env.module.print_to_file(&path).unwrap();
panic!(
"Errors defining module:\n\n{}\n\nI have written the full module to `{path}`",
errors.to_string()
"Errors defining module:\n\n{}\n\nI have written the full module to `{:?}`",
errors.to_string(),
path
);
}

View file

@ -11,7 +11,7 @@ procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12):
let #Derived_gen.8 : {Str} = CallByName #Derived.5 #Derived.1;
let #Derived_gen.6 : {Str, {Str}} = Struct {#Derived_gen.7, #Derived_gen.8};
let #Derived_gen.5 : List {Str, {Str}} = Array [#Derived_gen.6];
let #Derived_gen.4 : {List {Str, {Str}}} = CallByName Json.19 #Derived_gen.5;
let #Derived_gen.4 : {List {Str, {Str}}} = CallByName Json.20 #Derived_gen.5;
let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4;
ret #Derived_gen.3;
@ -25,10 +25,10 @@ procedure #Derived.7 (#Derived.8, #Derived.9, #Attr.12):
inc #Derived.6;
dec #Attr.12;
let #Derived_gen.21 : Str = "b";
let #Derived_gen.22 : {Str} = CallByName Json.17 #Derived.6;
let #Derived_gen.22 : {Str} = CallByName Json.18 #Derived.6;
let #Derived_gen.20 : {Str, {Str}} = Struct {#Derived_gen.21, #Derived_gen.22};
let #Derived_gen.19 : List {Str, {Str}} = Array [#Derived_gen.20];
let #Derived_gen.18 : {List {Str, {Str}}} = CallByName Json.19 #Derived_gen.19;
let #Derived_gen.18 : {List {Str, {Str}}} = CallByName Json.20 #Derived_gen.19;
let #Derived_gen.17 : List U8 = CallByName Encode.23 #Derived.8 #Derived_gen.18 #Derived.9;
ret #Derived_gen.17;
@ -52,7 +52,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96):
ret Encode.106;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
let Encode.113 : List U8 = CallByName Json.81 Encode.94 Encode.96 Encode.102;
let Encode.113 : List U8 = CallByName Json.103 Encode.94 Encode.96 Encode.102;
ret Encode.113;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
@ -60,11 +60,11 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96):
ret Encode.115;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
let Encode.125 : List U8 = CallByName Json.81 Encode.94 Encode.96 Encode.102;
let Encode.125 : List U8 = CallByName Json.103 Encode.94 Encode.96 Encode.102;
ret Encode.125;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
let Encode.128 : List U8 = CallByName Json.65 Encode.94 Encode.96 Encode.102;
let Encode.128 : List U8 = CallByName Json.87 Encode.94 Encode.96 Encode.102;
ret Encode.128;
procedure Encode.25 (Encode.100, Encode.101):
@ -74,165 +74,165 @@ procedure Encode.25 (Encode.100, Encode.101):
ret Encode.103;
procedure Json.1 ():
let Json.106 : {} = Struct {};
ret Json.106;
let Json.318 : {} = Struct {};
ret Json.318;
procedure Json.17 (Json.64):
let Json.153 : {Str} = Struct {Json.64};
let Json.152 : {Str} = CallByName Encode.22 Json.153;
ret Json.152;
procedure Json.19 (Json.80):
let Json.108 : {List {Str, {Str}}} = Struct {Json.80};
let Json.107 : {List {Str, {Str}}} = CallByName Encode.22 Json.108;
ret Json.107;
procedure Json.19 (Json.80):
let Json.150 : {List {Str, {Str}}} = Struct {Json.80};
let Json.149 : {List {Str, {Str}}} = CallByName Encode.22 Json.150;
ret Json.149;
procedure Json.65 (Json.66, Json.154, #Attr.12):
let Json.64 : Str = StructAtIndex 0 #Attr.12;
inc Json.64;
procedure Json.103 (Json.104, Json.321, #Attr.12):
let Json.102 : List {Str, {Str}} = StructAtIndex 0 #Attr.12;
inc Json.102;
dec #Attr.12;
let Json.194 : I32 = 34i64;
let Json.193 : U8 = CallByName Num.123 Json.194;
let Json.191 : List U8 = CallByName List.4 Json.66 Json.193;
let Json.192 : List U8 = CallByName Str.12 Json.64;
let Json.188 : List U8 = CallByName List.8 Json.191 Json.192;
let Json.190 : I32 = 34i64;
let Json.189 : U8 = CallByName Num.123 Json.190;
let Json.187 : List U8 = CallByName List.4 Json.188 Json.189;
ret Json.187;
let Json.354 : I32 = 123i64;
let Json.353 : U8 = CallByName Num.123 Json.354;
let Json.106 : List U8 = CallByName List.4 Json.104 Json.353;
let Json.352 : U64 = CallByName List.6 Json.102;
let Json.329 : {List U8, U64} = Struct {Json.106, Json.352};
let Json.330 : {} = Struct {};
let Json.328 : {List U8, U64} = CallByName List.18 Json.102 Json.329 Json.330;
dec Json.102;
let Json.108 : List U8 = StructAtIndex 0 Json.328;
inc Json.108;
dec Json.328;
let Json.327 : I32 = 125i64;
let Json.326 : U8 = CallByName Num.123 Json.327;
let Json.325 : List U8 = CallByName List.4 Json.108 Json.326;
ret Json.325;
procedure Json.81 (Json.82, Json.109, #Attr.12):
let Json.80 : List {Str, {Str}} = StructAtIndex 0 #Attr.12;
inc Json.80;
procedure Json.103 (Json.104, Json.321, #Attr.12):
let Json.102 : List {Str, {Str}} = StructAtIndex 0 #Attr.12;
inc Json.102;
dec #Attr.12;
let Json.142 : I32 = 123i64;
let Json.141 : U8 = CallByName Num.123 Json.142;
let Json.84 : List U8 = CallByName List.4 Json.82 Json.141;
let Json.140 : U64 = CallByName List.6 Json.80;
let Json.117 : {List U8, U64} = Struct {Json.84, Json.140};
let Json.118 : {} = Struct {};
let Json.116 : {List U8, U64} = CallByName List.18 Json.80 Json.117 Json.118;
dec Json.80;
let Json.86 : List U8 = StructAtIndex 0 Json.116;
inc Json.86;
dec Json.116;
let Json.115 : I32 = 125i64;
let Json.114 : U8 = CallByName Num.123 Json.115;
let Json.113 : List U8 = CallByName List.4 Json.86 Json.114;
ret Json.113;
let Json.397 : I32 = 123i64;
let Json.396 : U8 = CallByName Num.123 Json.397;
let Json.106 : List U8 = CallByName List.4 Json.104 Json.396;
let Json.395 : U64 = CallByName List.6 Json.102;
let Json.372 : {List U8, U64} = Struct {Json.106, Json.395};
let Json.373 : {} = Struct {};
let Json.371 : {List U8, U64} = CallByName List.18 Json.102 Json.372 Json.373;
dec Json.102;
let Json.108 : List U8 = StructAtIndex 0 Json.371;
inc Json.108;
dec Json.371;
let Json.370 : I32 = 125i64;
let Json.369 : U8 = CallByName Num.123 Json.370;
let Json.368 : List U8 = CallByName List.4 Json.108 Json.369;
ret Json.368;
procedure Json.81 (Json.82, Json.109, #Attr.12):
let Json.80 : List {Str, {Str}} = StructAtIndex 0 #Attr.12;
inc Json.80;
dec #Attr.12;
let Json.185 : I32 = 123i64;
let Json.184 : U8 = CallByName Num.123 Json.185;
let Json.84 : List U8 = CallByName List.4 Json.82 Json.184;
let Json.183 : U64 = CallByName List.6 Json.80;
let Json.160 : {List U8, U64} = Struct {Json.84, Json.183};
let Json.161 : {} = Struct {};
let Json.159 : {List U8, U64} = CallByName List.18 Json.80 Json.160 Json.161;
dec Json.80;
let Json.86 : List U8 = StructAtIndex 0 Json.159;
inc Json.86;
dec Json.159;
let Json.158 : I32 = 125i64;
let Json.157 : U8 = CallByName Num.123 Json.158;
let Json.156 : List U8 = CallByName List.4 Json.86 Json.157;
ret Json.156;
procedure Json.83 (Json.111, Json.112):
let Json.89 : Str = StructAtIndex 0 Json.112;
inc Json.89;
let Json.90 : {Str} = StructAtIndex 1 Json.112;
inc Json.90;
dec Json.112;
let Json.87 : List U8 = StructAtIndex 0 Json.111;
inc Json.87;
let Json.88 : U64 = StructAtIndex 1 Json.111;
dec Json.111;
let Json.139 : I32 = 34i64;
let Json.138 : U8 = CallByName Num.123 Json.139;
let Json.136 : List U8 = CallByName List.4 Json.87 Json.138;
let Json.137 : List U8 = CallByName Str.12 Json.89;
let Json.133 : List U8 = CallByName List.8 Json.136 Json.137;
let Json.135 : I32 = 34i64;
let Json.134 : U8 = CallByName Num.123 Json.135;
let Json.130 : List U8 = CallByName List.4 Json.133 Json.134;
let Json.132 : I32 = 58i64;
let Json.131 : U8 = CallByName Num.123 Json.132;
let Json.128 : List U8 = CallByName List.4 Json.130 Json.131;
let Json.129 : {} = Struct {};
let Json.91 : List U8 = CallByName Encode.23 Json.128 Json.90 Json.129;
joinpoint Json.123 Json.92:
let Json.121 : U64 = 1i64;
let Json.120 : U64 = CallByName Num.20 Json.88 Json.121;
let Json.119 : {List U8, U64} = Struct {Json.92, Json.120};
ret Json.119;
procedure Json.105 (Json.323, Json.324):
let Json.111 : Str = StructAtIndex 0 Json.324;
inc Json.111;
let Json.112 : {Str} = StructAtIndex 1 Json.324;
inc Json.112;
dec Json.324;
let Json.109 : List U8 = StructAtIndex 0 Json.323;
inc Json.109;
let Json.110 : U64 = StructAtIndex 1 Json.323;
dec Json.323;
let Json.351 : I32 = 34i64;
let Json.350 : U8 = CallByName Num.123 Json.351;
let Json.348 : List U8 = CallByName List.4 Json.109 Json.350;
let Json.349 : List U8 = CallByName Str.12 Json.111;
let Json.345 : List U8 = CallByName List.8 Json.348 Json.349;
let Json.347 : I32 = 34i64;
let Json.346 : U8 = CallByName Num.123 Json.347;
let Json.342 : List U8 = CallByName List.4 Json.345 Json.346;
let Json.344 : I32 = 58i64;
let Json.343 : U8 = CallByName Num.123 Json.344;
let Json.340 : List U8 = CallByName List.4 Json.342 Json.343;
let Json.341 : {} = Struct {};
let Json.113 : List U8 = CallByName Encode.23 Json.340 Json.112 Json.341;
joinpoint Json.335 Json.114:
let Json.333 : U64 = 1i64;
let Json.332 : U64 = CallByName Num.20 Json.110 Json.333;
let Json.331 : {List U8, U64} = Struct {Json.114, Json.332};
ret Json.331;
in
let Json.127 : U64 = 1i64;
let Json.124 : Int1 = CallByName Num.24 Json.88 Json.127;
if Json.124 then
let Json.126 : I32 = 44i64;
let Json.125 : U8 = CallByName Num.123 Json.126;
let Json.122 : List U8 = CallByName List.4 Json.91 Json.125;
jump Json.123 Json.122;
let Json.339 : U64 = 1i64;
let Json.336 : Int1 = CallByName Num.24 Json.110 Json.339;
if Json.336 then
let Json.338 : I32 = 44i64;
let Json.337 : U8 = CallByName Num.123 Json.338;
let Json.334 : List U8 = CallByName List.4 Json.113 Json.337;
jump Json.335 Json.334;
else
jump Json.123 Json.91;
jump Json.335 Json.113;
procedure Json.83 (Json.111, Json.112):
let Json.89 : Str = StructAtIndex 0 Json.112;
inc Json.89;
let Json.90 : {Str} = StructAtIndex 1 Json.112;
inc Json.90;
dec Json.112;
let Json.87 : List U8 = StructAtIndex 0 Json.111;
inc Json.87;
let Json.88 : U64 = StructAtIndex 1 Json.111;
dec Json.111;
let Json.182 : I32 = 34i64;
let Json.181 : U8 = CallByName Num.123 Json.182;
let Json.179 : List U8 = CallByName List.4 Json.87 Json.181;
let Json.180 : List U8 = CallByName Str.12 Json.89;
let Json.176 : List U8 = CallByName List.8 Json.179 Json.180;
let Json.178 : I32 = 34i64;
let Json.177 : U8 = CallByName Num.123 Json.178;
let Json.173 : List U8 = CallByName List.4 Json.176 Json.177;
let Json.175 : I32 = 58i64;
let Json.174 : U8 = CallByName Num.123 Json.175;
let Json.171 : List U8 = CallByName List.4 Json.173 Json.174;
let Json.172 : {} = Struct {};
let Json.91 : List U8 = CallByName Encode.23 Json.171 Json.90 Json.172;
joinpoint Json.166 Json.92:
let Json.164 : U64 = 1i64;
let Json.163 : U64 = CallByName Num.20 Json.88 Json.164;
let Json.162 : {List U8, U64} = Struct {Json.92, Json.163};
ret Json.162;
procedure Json.105 (Json.323, Json.324):
let Json.111 : Str = StructAtIndex 0 Json.324;
inc Json.111;
let Json.112 : {Str} = StructAtIndex 1 Json.324;
inc Json.112;
dec Json.324;
let Json.109 : List U8 = StructAtIndex 0 Json.323;
inc Json.109;
let Json.110 : U64 = StructAtIndex 1 Json.323;
dec Json.323;
let Json.394 : I32 = 34i64;
let Json.393 : U8 = CallByName Num.123 Json.394;
let Json.391 : List U8 = CallByName List.4 Json.109 Json.393;
let Json.392 : List U8 = CallByName Str.12 Json.111;
let Json.388 : List U8 = CallByName List.8 Json.391 Json.392;
let Json.390 : I32 = 34i64;
let Json.389 : U8 = CallByName Num.123 Json.390;
let Json.385 : List U8 = CallByName List.4 Json.388 Json.389;
let Json.387 : I32 = 58i64;
let Json.386 : U8 = CallByName Num.123 Json.387;
let Json.383 : List U8 = CallByName List.4 Json.385 Json.386;
let Json.384 : {} = Struct {};
let Json.113 : List U8 = CallByName Encode.23 Json.383 Json.112 Json.384;
joinpoint Json.378 Json.114:
let Json.376 : U64 = 1i64;
let Json.375 : U64 = CallByName Num.20 Json.110 Json.376;
let Json.374 : {List U8, U64} = Struct {Json.114, Json.375};
ret Json.374;
in
let Json.170 : U64 = 1i64;
let Json.167 : Int1 = CallByName Num.24 Json.88 Json.170;
if Json.167 then
let Json.169 : I32 = 44i64;
let Json.168 : U8 = CallByName Num.123 Json.169;
let Json.165 : List U8 = CallByName List.4 Json.91 Json.168;
jump Json.166 Json.165;
let Json.382 : U64 = 1i64;
let Json.379 : Int1 = CallByName Num.24 Json.110 Json.382;
if Json.379 then
let Json.381 : I32 = 44i64;
let Json.380 : U8 = CallByName Num.123 Json.381;
let Json.377 : List U8 = CallByName List.4 Json.113 Json.380;
jump Json.378 Json.377;
else
jump Json.166 Json.91;
jump Json.378 Json.113;
procedure Json.18 (Json.86):
let Json.365 : {Str} = Struct {Json.86};
let Json.364 : {Str} = CallByName Encode.22 Json.365;
ret Json.364;
procedure Json.20 (Json.102):
let Json.320 : {List {Str, {Str}}} = Struct {Json.102};
let Json.319 : {List {Str, {Str}}} = CallByName Encode.22 Json.320;
ret Json.319;
procedure Json.20 (Json.102):
let Json.362 : {List {Str, {Str}}} = Struct {Json.102};
let Json.361 : {List {Str, {Str}}} = CallByName Encode.22 Json.362;
ret Json.361;
procedure Json.87 (Json.88, Json.366, #Attr.12):
let Json.86 : Str = StructAtIndex 0 #Attr.12;
inc Json.86;
dec #Attr.12;
let Json.406 : I32 = 34i64;
let Json.405 : U8 = CallByName Num.123 Json.406;
let Json.403 : List U8 = CallByName List.4 Json.88 Json.405;
let Json.404 : List U8 = CallByName Str.12 Json.86;
let Json.400 : List U8 = CallByName List.8 Json.403 Json.404;
let Json.402 : I32 = 34i64;
let Json.401 : U8 = CallByName Num.123 Json.402;
let Json.399 : List U8 = CallByName List.4 Json.400 Json.401;
ret Json.399;
procedure List.133 (List.134, List.135, #Attr.12):
let List.132 : {} = StructAtIndex 0 #Attr.12;
let List.434 : {List U8, U64} = CallByName Json.83 List.134 List.135;
let List.434 : {List U8, U64} = CallByName Json.105 List.134 List.135;
let List.433 : [C [], C {List U8, U64}] = TagId(1) List.434;
ret List.433;
procedure List.133 (List.134, List.135, #Attr.12):
let List.132 : {} = StructAtIndex 0 #Attr.12;
let List.515 : {List U8, U64} = CallByName Json.83 List.134 List.135;
let List.515 : {List U8, U64} = CallByName Json.105 List.134 List.135;
let List.514 : [C [], C {List U8, U64}] = TagId(1) List.515;
ret List.514;

View file

@ -8,10 +8,10 @@ procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12):
inc #Derived.1;
dec #Attr.12;
let #Derived_gen.7 : Str = "a";
let #Derived_gen.8 : {Str} = CallByName Json.17 #Derived.1;
let #Derived_gen.8 : {Str} = CallByName Json.18 #Derived.1;
let #Derived_gen.6 : {Str, {Str}} = Struct {#Derived_gen.7, #Derived_gen.8};
let #Derived_gen.5 : List {Str, {Str}} = Array [#Derived_gen.6];
let #Derived_gen.4 : {List {Str, {Str}}} = CallByName Json.19 #Derived_gen.5;
let #Derived_gen.4 : {List {Str, {Str}}} = CallByName Json.20 #Derived_gen.5;
let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4;
ret #Derived_gen.3;
@ -29,11 +29,11 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96):
ret Encode.106;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
let Encode.113 : List U8 = CallByName Json.81 Encode.94 Encode.96 Encode.102;
let Encode.113 : List U8 = CallByName Json.103 Encode.94 Encode.96 Encode.102;
ret Encode.113;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
let Encode.116 : List U8 = CallByName Json.65 Encode.94 Encode.96 Encode.102;
let Encode.116 : List U8 = CallByName Json.87 Encode.94 Encode.96 Encode.102;
ret Encode.116;
procedure Encode.25 (Encode.100, Encode.101):
@ -43,95 +43,95 @@ procedure Encode.25 (Encode.100, Encode.101):
ret Encode.103;
procedure Json.1 ():
let Json.106 : {} = Struct {};
ret Json.106;
let Json.318 : {} = Struct {};
ret Json.318;
procedure Json.17 (Json.64):
let Json.111 : {Str} = Struct {Json.64};
let Json.110 : {Str} = CallByName Encode.22 Json.111;
ret Json.110;
procedure Json.19 (Json.80):
let Json.108 : {List {Str, {Str}}} = Struct {Json.80};
let Json.107 : {List {Str, {Str}}} = CallByName Encode.22 Json.108;
ret Json.107;
procedure Json.65 (Json.66, Json.112, #Attr.12):
let Json.64 : Str = StructAtIndex 0 #Attr.12;
inc Json.64;
procedure Json.103 (Json.104, Json.321, #Attr.12):
let Json.102 : List {Str, {Str}} = StructAtIndex 0 #Attr.12;
inc Json.102;
dec #Attr.12;
let Json.154 : I32 = 34i64;
let Json.153 : U8 = CallByName Num.123 Json.154;
let Json.151 : List U8 = CallByName List.4 Json.66 Json.153;
let Json.152 : List U8 = CallByName Str.12 Json.64;
let Json.148 : List U8 = CallByName List.8 Json.151 Json.152;
let Json.150 : I32 = 34i64;
let Json.149 : U8 = CallByName Num.123 Json.150;
let Json.147 : List U8 = CallByName List.4 Json.148 Json.149;
ret Json.147;
let Json.357 : I32 = 123i64;
let Json.356 : U8 = CallByName Num.123 Json.357;
let Json.106 : List U8 = CallByName List.4 Json.104 Json.356;
let Json.355 : U64 = CallByName List.6 Json.102;
let Json.332 : {List U8, U64} = Struct {Json.106, Json.355};
let Json.333 : {} = Struct {};
let Json.331 : {List U8, U64} = CallByName List.18 Json.102 Json.332 Json.333;
dec Json.102;
let Json.108 : List U8 = StructAtIndex 0 Json.331;
inc Json.108;
dec Json.331;
let Json.330 : I32 = 125i64;
let Json.329 : U8 = CallByName Num.123 Json.330;
let Json.328 : List U8 = CallByName List.4 Json.108 Json.329;
ret Json.328;
procedure Json.81 (Json.82, Json.109, #Attr.12):
let Json.80 : List {Str, {Str}} = StructAtIndex 0 #Attr.12;
inc Json.80;
dec #Attr.12;
let Json.145 : I32 = 123i64;
let Json.144 : U8 = CallByName Num.123 Json.145;
let Json.84 : List U8 = CallByName List.4 Json.82 Json.144;
let Json.143 : U64 = CallByName List.6 Json.80;
let Json.120 : {List U8, U64} = Struct {Json.84, Json.143};
let Json.121 : {} = Struct {};
let Json.119 : {List U8, U64} = CallByName List.18 Json.80 Json.120 Json.121;
dec Json.80;
let Json.86 : List U8 = StructAtIndex 0 Json.119;
inc Json.86;
dec Json.119;
let Json.118 : I32 = 125i64;
let Json.117 : U8 = CallByName Num.123 Json.118;
let Json.116 : List U8 = CallByName List.4 Json.86 Json.117;
ret Json.116;
procedure Json.83 (Json.114, Json.115):
let Json.89 : Str = StructAtIndex 0 Json.115;
inc Json.89;
let Json.90 : {Str} = StructAtIndex 1 Json.115;
inc Json.90;
dec Json.115;
let Json.87 : List U8 = StructAtIndex 0 Json.114;
inc Json.87;
let Json.88 : U64 = StructAtIndex 1 Json.114;
dec Json.114;
let Json.142 : I32 = 34i64;
let Json.141 : U8 = CallByName Num.123 Json.142;
let Json.139 : List U8 = CallByName List.4 Json.87 Json.141;
let Json.140 : List U8 = CallByName Str.12 Json.89;
let Json.136 : List U8 = CallByName List.8 Json.139 Json.140;
let Json.138 : I32 = 34i64;
let Json.137 : U8 = CallByName Num.123 Json.138;
let Json.133 : List U8 = CallByName List.4 Json.136 Json.137;
let Json.135 : I32 = 58i64;
let Json.134 : U8 = CallByName Num.123 Json.135;
let Json.131 : List U8 = CallByName List.4 Json.133 Json.134;
let Json.132 : {} = Struct {};
let Json.91 : List U8 = CallByName Encode.23 Json.131 Json.90 Json.132;
joinpoint Json.126 Json.92:
let Json.124 : U64 = 1i64;
let Json.123 : U64 = CallByName Num.20 Json.88 Json.124;
let Json.122 : {List U8, U64} = Struct {Json.92, Json.123};
ret Json.122;
procedure Json.105 (Json.326, Json.327):
let Json.111 : Str = StructAtIndex 0 Json.327;
inc Json.111;
let Json.112 : {Str} = StructAtIndex 1 Json.327;
inc Json.112;
dec Json.327;
let Json.109 : List U8 = StructAtIndex 0 Json.326;
inc Json.109;
let Json.110 : U64 = StructAtIndex 1 Json.326;
dec Json.326;
let Json.354 : I32 = 34i64;
let Json.353 : U8 = CallByName Num.123 Json.354;
let Json.351 : List U8 = CallByName List.4 Json.109 Json.353;
let Json.352 : List U8 = CallByName Str.12 Json.111;
let Json.348 : List U8 = CallByName List.8 Json.351 Json.352;
let Json.350 : I32 = 34i64;
let Json.349 : U8 = CallByName Num.123 Json.350;
let Json.345 : List U8 = CallByName List.4 Json.348 Json.349;
let Json.347 : I32 = 58i64;
let Json.346 : U8 = CallByName Num.123 Json.347;
let Json.343 : List U8 = CallByName List.4 Json.345 Json.346;
let Json.344 : {} = Struct {};
let Json.113 : List U8 = CallByName Encode.23 Json.343 Json.112 Json.344;
joinpoint Json.338 Json.114:
let Json.336 : U64 = 1i64;
let Json.335 : U64 = CallByName Num.20 Json.110 Json.336;
let Json.334 : {List U8, U64} = Struct {Json.114, Json.335};
ret Json.334;
in
let Json.130 : U64 = 1i64;
let Json.127 : Int1 = CallByName Num.24 Json.88 Json.130;
if Json.127 then
let Json.129 : I32 = 44i64;
let Json.128 : U8 = CallByName Num.123 Json.129;
let Json.125 : List U8 = CallByName List.4 Json.91 Json.128;
jump Json.126 Json.125;
let Json.342 : U64 = 1i64;
let Json.339 : Int1 = CallByName Num.24 Json.110 Json.342;
if Json.339 then
let Json.341 : I32 = 44i64;
let Json.340 : U8 = CallByName Num.123 Json.341;
let Json.337 : List U8 = CallByName List.4 Json.113 Json.340;
jump Json.338 Json.337;
else
jump Json.126 Json.91;
jump Json.338 Json.113;
procedure Json.18 (Json.86):
let Json.323 : {Str} = Struct {Json.86};
let Json.322 : {Str} = CallByName Encode.22 Json.323;
ret Json.322;
procedure Json.20 (Json.102):
let Json.320 : {List {Str, {Str}}} = Struct {Json.102};
let Json.319 : {List {Str, {Str}}} = CallByName Encode.22 Json.320;
ret Json.319;
procedure Json.87 (Json.88, Json.324, #Attr.12):
let Json.86 : Str = StructAtIndex 0 #Attr.12;
inc Json.86;
dec #Attr.12;
let Json.366 : I32 = 34i64;
let Json.365 : U8 = CallByName Num.123 Json.366;
let Json.363 : List U8 = CallByName List.4 Json.88 Json.365;
let Json.364 : List U8 = CallByName Str.12 Json.86;
let Json.360 : List U8 = CallByName List.8 Json.363 Json.364;
let Json.362 : I32 = 34i64;
let Json.361 : U8 = CallByName Num.123 Json.362;
let Json.359 : List U8 = CallByName List.4 Json.360 Json.361;
ret Json.359;
procedure List.133 (List.134, List.135, #Attr.12):
let List.132 : {} = StructAtIndex 0 #Attr.12;
let List.441 : {List U8, U64} = CallByName Json.83 List.134 List.135;
let List.441 : {List U8, U64} = CallByName Json.105 List.134 List.135;
let List.440 : [C [], C {List U8, U64}] = TagId(1) List.441;
ret List.440;

View file

@ -10,16 +10,16 @@ procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12):
let #Derived_gen.11 : Str = "a";
let #Derived_gen.13 : Str = StructAtIndex 0 #Derived.1;
inc #Derived_gen.13;
let #Derived_gen.12 : {Str} = CallByName Json.17 #Derived_gen.13;
let #Derived_gen.12 : {Str} = CallByName Json.18 #Derived_gen.13;
let #Derived_gen.6 : {Str, {Str}} = Struct {#Derived_gen.11, #Derived_gen.12};
let #Derived_gen.8 : Str = "b";
let #Derived_gen.10 : Str = StructAtIndex 1 #Derived.1;
inc #Derived_gen.10;
dec #Derived.1;
let #Derived_gen.9 : {Str} = CallByName Json.17 #Derived_gen.10;
let #Derived_gen.9 : {Str} = CallByName Json.18 #Derived_gen.10;
let #Derived_gen.7 : {Str, {Str}} = Struct {#Derived_gen.8, #Derived_gen.9};
let #Derived_gen.5 : List {Str, {Str}} = Array [#Derived_gen.6, #Derived_gen.7];
let #Derived_gen.4 : {List {Str, {Str}}} = CallByName Json.19 #Derived_gen.5;
let #Derived_gen.4 : {List {Str, {Str}}} = CallByName Json.20 #Derived_gen.5;
let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4;
ret #Derived_gen.3;
@ -37,11 +37,11 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96):
ret Encode.106;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
let Encode.113 : List U8 = CallByName Json.81 Encode.94 Encode.96 Encode.102;
let Encode.113 : List U8 = CallByName Json.103 Encode.94 Encode.96 Encode.102;
ret Encode.113;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
let Encode.117 : List U8 = CallByName Json.65 Encode.94 Encode.96 Encode.102;
let Encode.117 : List U8 = CallByName Json.87 Encode.94 Encode.96 Encode.102;
ret Encode.117;
procedure Encode.25 (Encode.100, Encode.101):
@ -51,95 +51,95 @@ procedure Encode.25 (Encode.100, Encode.101):
ret Encode.103;
procedure Json.1 ():
let Json.106 : {} = Struct {};
ret Json.106;
let Json.318 : {} = Struct {};
ret Json.318;
procedure Json.17 (Json.64):
let Json.114 : {Str} = Struct {Json.64};
let Json.113 : {Str} = CallByName Encode.22 Json.114;
ret Json.113;
procedure Json.19 (Json.80):
let Json.108 : {List {Str, {Str}}} = Struct {Json.80};
let Json.107 : {List {Str, {Str}}} = CallByName Encode.22 Json.108;
ret Json.107;
procedure Json.65 (Json.66, Json.112, #Attr.12):
let Json.64 : Str = StructAtIndex 0 #Attr.12;
inc Json.64;
procedure Json.103 (Json.104, Json.321, #Attr.12):
let Json.102 : List {Str, {Str}} = StructAtIndex 0 #Attr.12;
inc Json.102;
dec #Attr.12;
let Json.157 : I32 = 34i64;
let Json.156 : U8 = CallByName Num.123 Json.157;
let Json.154 : List U8 = CallByName List.4 Json.66 Json.156;
let Json.155 : List U8 = CallByName Str.12 Json.64;
let Json.151 : List U8 = CallByName List.8 Json.154 Json.155;
let Json.153 : I32 = 34i64;
let Json.152 : U8 = CallByName Num.123 Json.153;
let Json.150 : List U8 = CallByName List.4 Json.151 Json.152;
ret Json.150;
let Json.360 : I32 = 123i64;
let Json.359 : U8 = CallByName Num.123 Json.360;
let Json.106 : List U8 = CallByName List.4 Json.104 Json.359;
let Json.358 : U64 = CallByName List.6 Json.102;
let Json.335 : {List U8, U64} = Struct {Json.106, Json.358};
let Json.336 : {} = Struct {};
let Json.334 : {List U8, U64} = CallByName List.18 Json.102 Json.335 Json.336;
dec Json.102;
let Json.108 : List U8 = StructAtIndex 0 Json.334;
inc Json.108;
dec Json.334;
let Json.333 : I32 = 125i64;
let Json.332 : U8 = CallByName Num.123 Json.333;
let Json.331 : List U8 = CallByName List.4 Json.108 Json.332;
ret Json.331;
procedure Json.81 (Json.82, Json.109, #Attr.12):
let Json.80 : List {Str, {Str}} = StructAtIndex 0 #Attr.12;
inc Json.80;
dec #Attr.12;
let Json.148 : I32 = 123i64;
let Json.147 : U8 = CallByName Num.123 Json.148;
let Json.84 : List U8 = CallByName List.4 Json.82 Json.147;
let Json.146 : U64 = CallByName List.6 Json.80;
let Json.123 : {List U8, U64} = Struct {Json.84, Json.146};
let Json.124 : {} = Struct {};
let Json.122 : {List U8, U64} = CallByName List.18 Json.80 Json.123 Json.124;
dec Json.80;
let Json.86 : List U8 = StructAtIndex 0 Json.122;
inc Json.86;
dec Json.122;
let Json.121 : I32 = 125i64;
let Json.120 : U8 = CallByName Num.123 Json.121;
let Json.119 : List U8 = CallByName List.4 Json.86 Json.120;
ret Json.119;
procedure Json.83 (Json.117, Json.118):
let Json.89 : Str = StructAtIndex 0 Json.118;
inc Json.89;
let Json.90 : {Str} = StructAtIndex 1 Json.118;
inc Json.90;
dec Json.118;
let Json.87 : List U8 = StructAtIndex 0 Json.117;
inc Json.87;
let Json.88 : U64 = StructAtIndex 1 Json.117;
dec Json.117;
let Json.145 : I32 = 34i64;
let Json.144 : U8 = CallByName Num.123 Json.145;
let Json.142 : List U8 = CallByName List.4 Json.87 Json.144;
let Json.143 : List U8 = CallByName Str.12 Json.89;
let Json.139 : List U8 = CallByName List.8 Json.142 Json.143;
let Json.141 : I32 = 34i64;
let Json.140 : U8 = CallByName Num.123 Json.141;
let Json.136 : List U8 = CallByName List.4 Json.139 Json.140;
let Json.138 : I32 = 58i64;
let Json.137 : U8 = CallByName Num.123 Json.138;
let Json.134 : List U8 = CallByName List.4 Json.136 Json.137;
let Json.135 : {} = Struct {};
let Json.91 : List U8 = CallByName Encode.23 Json.134 Json.90 Json.135;
joinpoint Json.129 Json.92:
let Json.127 : U64 = 1i64;
let Json.126 : U64 = CallByName Num.20 Json.88 Json.127;
let Json.125 : {List U8, U64} = Struct {Json.92, Json.126};
ret Json.125;
procedure Json.105 (Json.329, Json.330):
let Json.111 : Str = StructAtIndex 0 Json.330;
inc Json.111;
let Json.112 : {Str} = StructAtIndex 1 Json.330;
inc Json.112;
dec Json.330;
let Json.109 : List U8 = StructAtIndex 0 Json.329;
inc Json.109;
let Json.110 : U64 = StructAtIndex 1 Json.329;
dec Json.329;
let Json.357 : I32 = 34i64;
let Json.356 : U8 = CallByName Num.123 Json.357;
let Json.354 : List U8 = CallByName List.4 Json.109 Json.356;
let Json.355 : List U8 = CallByName Str.12 Json.111;
let Json.351 : List U8 = CallByName List.8 Json.354 Json.355;
let Json.353 : I32 = 34i64;
let Json.352 : U8 = CallByName Num.123 Json.353;
let Json.348 : List U8 = CallByName List.4 Json.351 Json.352;
let Json.350 : I32 = 58i64;
let Json.349 : U8 = CallByName Num.123 Json.350;
let Json.346 : List U8 = CallByName List.4 Json.348 Json.349;
let Json.347 : {} = Struct {};
let Json.113 : List U8 = CallByName Encode.23 Json.346 Json.112 Json.347;
joinpoint Json.341 Json.114:
let Json.339 : U64 = 1i64;
let Json.338 : U64 = CallByName Num.20 Json.110 Json.339;
let Json.337 : {List U8, U64} = Struct {Json.114, Json.338};
ret Json.337;
in
let Json.133 : U64 = 1i64;
let Json.130 : Int1 = CallByName Num.24 Json.88 Json.133;
if Json.130 then
let Json.132 : I32 = 44i64;
let Json.131 : U8 = CallByName Num.123 Json.132;
let Json.128 : List U8 = CallByName List.4 Json.91 Json.131;
jump Json.129 Json.128;
let Json.345 : U64 = 1i64;
let Json.342 : Int1 = CallByName Num.24 Json.110 Json.345;
if Json.342 then
let Json.344 : I32 = 44i64;
let Json.343 : U8 = CallByName Num.123 Json.344;
let Json.340 : List U8 = CallByName List.4 Json.113 Json.343;
jump Json.341 Json.340;
else
jump Json.129 Json.91;
jump Json.341 Json.113;
procedure Json.18 (Json.86):
let Json.326 : {Str} = Struct {Json.86};
let Json.325 : {Str} = CallByName Encode.22 Json.326;
ret Json.325;
procedure Json.20 (Json.102):
let Json.320 : {List {Str, {Str}}} = Struct {Json.102};
let Json.319 : {List {Str, {Str}}} = CallByName Encode.22 Json.320;
ret Json.319;
procedure Json.87 (Json.88, Json.324, #Attr.12):
let Json.86 : Str = StructAtIndex 0 #Attr.12;
inc Json.86;
dec #Attr.12;
let Json.369 : I32 = 34i64;
let Json.368 : U8 = CallByName Num.123 Json.369;
let Json.366 : List U8 = CallByName List.4 Json.88 Json.368;
let Json.367 : List U8 = CallByName Str.12 Json.86;
let Json.363 : List U8 = CallByName List.8 Json.366 Json.367;
let Json.365 : I32 = 34i64;
let Json.364 : U8 = CallByName Num.123 Json.365;
let Json.362 : List U8 = CallByName List.4 Json.363 Json.364;
ret Json.362;
procedure List.133 (List.134, List.135, #Attr.12):
let List.132 : {} = StructAtIndex 0 #Attr.12;
let List.441 : {List U8, U64} = CallByName Json.83 List.134 List.135;
let List.441 : {List U8, U64} = CallByName Json.105 List.134 List.135;
let List.440 : [C [], C {List U8, U64}] = TagId(1) List.441;
ret List.440;

View file

@ -2,37 +2,37 @@ procedure Encode.22 (Encode.93):
ret Encode.93;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
let Encode.106 : List U8 = CallByName Json.65 Encode.94 Encode.96 Encode.102;
let Encode.106 : List U8 = CallByName Json.87 Encode.94 Encode.96 Encode.102;
ret Encode.106;
procedure Encode.25 (Encode.100, Encode.101):
let Encode.104 : List U8 = Array [];
let Encode.105 : {Str} = CallByName Json.17 Encode.100;
let Encode.105 : {Str} = CallByName Json.18 Encode.100;
let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
ret Encode.103;
procedure Json.1 ():
let Json.106 : {} = Struct {};
ret Json.106;
let Json.318 : {} = Struct {};
ret Json.318;
procedure Json.17 (Json.64):
let Json.108 : {Str} = Struct {Json.64};
let Json.107 : {Str} = CallByName Encode.22 Json.108;
ret Json.107;
procedure Json.18 (Json.86):
let Json.320 : {Str} = Struct {Json.86};
let Json.319 : {Str} = CallByName Encode.22 Json.320;
ret Json.319;
procedure Json.65 (Json.66, Json.109, #Attr.12):
let Json.64 : Str = StructAtIndex 0 #Attr.12;
inc Json.64;
procedure Json.87 (Json.88, Json.321, #Attr.12):
let Json.86 : Str = StructAtIndex 0 #Attr.12;
inc Json.86;
dec #Attr.12;
let Json.118 : I32 = 34i64;
let Json.117 : U8 = CallByName Num.123 Json.118;
let Json.115 : List U8 = CallByName List.4 Json.66 Json.117;
let Json.116 : List U8 = CallByName Str.12 Json.64;
let Json.112 : List U8 = CallByName List.8 Json.115 Json.116;
let Json.114 : I32 = 34i64;
let Json.113 : U8 = CallByName Num.123 Json.114;
let Json.111 : List U8 = CallByName List.4 Json.112 Json.113;
ret Json.111;
let Json.330 : I32 = 34i64;
let Json.329 : U8 = CallByName Num.123 Json.330;
let Json.327 : List U8 = CallByName List.4 Json.88 Json.329;
let Json.328 : List U8 = CallByName Str.12 Json.86;
let Json.324 : List U8 = CallByName List.8 Json.327 Json.328;
let Json.326 : I32 = 34i64;
let Json.325 : U8 = CallByName Num.123 Json.326;
let Json.323 : List U8 = CallByName List.4 Json.324 Json.325;
ret Json.323;
procedure List.4 (List.101, List.102):
let List.392 : U64 = 1i64;

View file

@ -12,9 +12,9 @@ procedure #Derived.3 (#Derived.4, #Derived.5, #Attr.12):
ret #Derived_gen.3;
in
let #Derived_gen.7 : Str = "A";
let #Derived_gen.9 : {Str} = CallByName Json.17 #Derived.1;
let #Derived_gen.9 : {Str} = CallByName Json.18 #Derived.1;
let #Derived_gen.8 : List {Str} = Array [#Derived_gen.9];
let #Derived_gen.6 : {Str, List {Str}} = CallByName Json.20 #Derived_gen.7 #Derived_gen.8;
let #Derived_gen.6 : {Str, List {Str}} = CallByName Json.21 #Derived_gen.7 #Derived_gen.8;
jump #Derived_gen.5 #Derived_gen.6;
procedure Encode.22 (Encode.93):
@ -31,11 +31,11 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96):
ret Encode.106;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
let Encode.113 : List U8 = CallByName Json.95 Encode.94 Encode.96 Encode.102;
let Encode.113 : List U8 = CallByName Json.117 Encode.94 Encode.96 Encode.102;
ret Encode.113;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
let Encode.116 : List U8 = CallByName Json.65 Encode.94 Encode.96 Encode.102;
let Encode.116 : List U8 = CallByName Json.87 Encode.94 Encode.96 Encode.102;
ret Encode.116;
procedure Encode.25 (Encode.100, Encode.101):
@ -45,98 +45,98 @@ procedure Encode.25 (Encode.100, Encode.101):
ret Encode.103;
procedure Json.1 ():
let Json.106 : {} = Struct {};
ret Json.106;
let Json.318 : {} = Struct {};
ret Json.318;
procedure Json.17 (Json.64):
let Json.111 : {Str} = Struct {Json.64};
let Json.110 : {Str} = CallByName Encode.22 Json.111;
ret Json.110;
procedure Json.20 (Json.93, Json.94):
let Json.108 : {Str, List {Str}} = Struct {Json.93, Json.94};
let Json.107 : {Str, List {Str}} = CallByName Encode.22 Json.108;
ret Json.107;
procedure Json.65 (Json.66, Json.112, #Attr.12):
let Json.64 : Str = StructAtIndex 0 #Attr.12;
inc Json.64;
procedure Json.117 (Json.118, Json.321, #Attr.12):
let Json.116 : List {Str} = StructAtIndex 1 #Attr.12;
inc Json.116;
let Json.115 : Str = StructAtIndex 0 #Attr.12;
inc Json.115;
dec #Attr.12;
let Json.159 : I32 = 34i64;
let Json.158 : U8 = CallByName Num.123 Json.159;
let Json.156 : List U8 = CallByName List.4 Json.66 Json.158;
let Json.157 : List U8 = CallByName Str.12 Json.64;
let Json.153 : List U8 = CallByName List.8 Json.156 Json.157;
let Json.155 : I32 = 34i64;
let Json.154 : U8 = CallByName Num.123 Json.155;
let Json.152 : List U8 = CallByName List.4 Json.153 Json.154;
ret Json.152;
let Json.362 : I32 = 123i64;
let Json.361 : U8 = CallByName Num.123 Json.362;
let Json.358 : List U8 = CallByName List.4 Json.118 Json.361;
let Json.360 : I32 = 34i64;
let Json.359 : U8 = CallByName Num.123 Json.360;
let Json.356 : List U8 = CallByName List.4 Json.358 Json.359;
let Json.357 : List U8 = CallByName Str.12 Json.115;
let Json.353 : List U8 = CallByName List.8 Json.356 Json.357;
let Json.355 : I32 = 34i64;
let Json.354 : U8 = CallByName Num.123 Json.355;
let Json.350 : List U8 = CallByName List.4 Json.353 Json.354;
let Json.352 : I32 = 58i64;
let Json.351 : U8 = CallByName Num.123 Json.352;
let Json.347 : List U8 = CallByName List.4 Json.350 Json.351;
let Json.349 : I32 = 91i64;
let Json.348 : U8 = CallByName Num.123 Json.349;
let Json.120 : List U8 = CallByName List.4 Json.347 Json.348;
let Json.346 : U64 = CallByName List.6 Json.116;
let Json.334 : {List U8, U64} = Struct {Json.120, Json.346};
let Json.335 : {} = Struct {};
let Json.333 : {List U8, U64} = CallByName List.18 Json.116 Json.334 Json.335;
dec Json.116;
let Json.122 : List U8 = StructAtIndex 0 Json.333;
inc Json.122;
dec Json.333;
let Json.332 : I32 = 93i64;
let Json.331 : U8 = CallByName Num.123 Json.332;
let Json.328 : List U8 = CallByName List.4 Json.122 Json.331;
let Json.330 : I32 = 125i64;
let Json.329 : U8 = CallByName Num.123 Json.330;
let Json.327 : List U8 = CallByName List.4 Json.328 Json.329;
ret Json.327;
procedure Json.95 (Json.96, Json.109, #Attr.12):
let Json.94 : List {Str} = StructAtIndex 1 #Attr.12;
inc Json.94;
let Json.93 : Str = StructAtIndex 0 #Attr.12;
inc Json.93;
dec #Attr.12;
let Json.150 : I32 = 123i64;
let Json.149 : U8 = CallByName Num.123 Json.150;
let Json.146 : List U8 = CallByName List.4 Json.96 Json.149;
let Json.148 : I32 = 34i64;
let Json.147 : U8 = CallByName Num.123 Json.148;
let Json.144 : List U8 = CallByName List.4 Json.146 Json.147;
let Json.145 : List U8 = CallByName Str.12 Json.93;
let Json.141 : List U8 = CallByName List.8 Json.144 Json.145;
let Json.143 : I32 = 34i64;
let Json.142 : U8 = CallByName Num.123 Json.143;
let Json.138 : List U8 = CallByName List.4 Json.141 Json.142;
let Json.140 : I32 = 58i64;
let Json.139 : U8 = CallByName Num.123 Json.140;
let Json.135 : List U8 = CallByName List.4 Json.138 Json.139;
let Json.137 : I32 = 91i64;
let Json.136 : U8 = CallByName Num.123 Json.137;
let Json.98 : List U8 = CallByName List.4 Json.135 Json.136;
let Json.134 : U64 = CallByName List.6 Json.94;
let Json.122 : {List U8, U64} = Struct {Json.98, Json.134};
let Json.123 : {} = Struct {};
let Json.121 : {List U8, U64} = CallByName List.18 Json.94 Json.122 Json.123;
dec Json.94;
let Json.100 : List U8 = StructAtIndex 0 Json.121;
inc Json.100;
dec Json.121;
let Json.120 : I32 = 93i64;
let Json.119 : U8 = CallByName Num.123 Json.120;
let Json.116 : List U8 = CallByName List.4 Json.100 Json.119;
let Json.118 : I32 = 125i64;
let Json.117 : U8 = CallByName Num.123 Json.118;
let Json.115 : List U8 = CallByName List.4 Json.116 Json.117;
ret Json.115;
procedure Json.97 (Json.114, Json.103):
let Json.101 : List U8 = StructAtIndex 0 Json.114;
inc Json.101;
let Json.102 : U64 = StructAtIndex 1 Json.114;
dec Json.114;
let Json.133 : {} = Struct {};
let Json.104 : List U8 = CallByName Encode.23 Json.101 Json.103 Json.133;
joinpoint Json.128 Json.105:
let Json.126 : U64 = 1i64;
let Json.125 : U64 = CallByName Num.20 Json.102 Json.126;
let Json.124 : {List U8, U64} = Struct {Json.105, Json.125};
ret Json.124;
procedure Json.119 (Json.326, Json.125):
let Json.123 : List U8 = StructAtIndex 0 Json.326;
inc Json.123;
let Json.124 : U64 = StructAtIndex 1 Json.326;
dec Json.326;
let Json.345 : {} = Struct {};
let Json.126 : List U8 = CallByName Encode.23 Json.123 Json.125 Json.345;
joinpoint Json.340 Json.127:
let Json.338 : U64 = 1i64;
let Json.337 : U64 = CallByName Num.20 Json.124 Json.338;
let Json.336 : {List U8, U64} = Struct {Json.127, Json.337};
ret Json.336;
in
let Json.132 : U64 = 1i64;
let Json.129 : Int1 = CallByName Num.24 Json.102 Json.132;
if Json.129 then
let Json.131 : I32 = 44i64;
let Json.130 : U8 = CallByName Num.123 Json.131;
let Json.127 : List U8 = CallByName List.4 Json.104 Json.130;
jump Json.128 Json.127;
let Json.344 : U64 = 1i64;
let Json.341 : Int1 = CallByName Num.24 Json.124 Json.344;
if Json.341 then
let Json.343 : I32 = 44i64;
let Json.342 : U8 = CallByName Num.123 Json.343;
let Json.339 : List U8 = CallByName List.4 Json.126 Json.342;
jump Json.340 Json.339;
else
jump Json.128 Json.104;
jump Json.340 Json.126;
procedure Json.18 (Json.86):
let Json.323 : {Str} = Struct {Json.86};
let Json.322 : {Str} = CallByName Encode.22 Json.323;
ret Json.322;
procedure Json.21 (Json.115, Json.116):
let Json.320 : {Str, List {Str}} = Struct {Json.115, Json.116};
let Json.319 : {Str, List {Str}} = CallByName Encode.22 Json.320;
ret Json.319;
procedure Json.87 (Json.88, Json.324, #Attr.12):
let Json.86 : Str = StructAtIndex 0 #Attr.12;
inc Json.86;
dec #Attr.12;
let Json.371 : I32 = 34i64;
let Json.370 : U8 = CallByName Num.123 Json.371;
let Json.368 : List U8 = CallByName List.4 Json.88 Json.370;
let Json.369 : List U8 = CallByName Str.12 Json.86;
let Json.365 : List U8 = CallByName List.8 Json.368 Json.369;
let Json.367 : I32 = 34i64;
let Json.366 : U8 = CallByName Num.123 Json.367;
let Json.364 : List U8 = CallByName List.4 Json.365 Json.366;
ret Json.364;
procedure List.133 (List.134, List.135, #Attr.12):
let List.132 : {} = StructAtIndex 0 #Attr.12;
let List.447 : {List U8, U64} = CallByName Json.97 List.134 List.135;
let List.447 : {List U8, U64} = CallByName Json.119 List.134 List.135;
let List.446 : [C [], C {List U8, U64}] = TagId(1) List.447;
ret List.446;

View file

@ -17,10 +17,10 @@ procedure #Derived.4 (#Derived.5, #Derived.6, #Attr.12):
inc #Derived.3;
dec #Derived.1;
let #Derived_gen.7 : Str = "A";
let #Derived_gen.9 : {Str} = CallByName Json.17 #Derived.2;
let #Derived_gen.10 : {Str} = CallByName Json.17 #Derived.3;
let #Derived_gen.9 : {Str} = CallByName Json.18 #Derived.2;
let #Derived_gen.10 : {Str} = CallByName Json.18 #Derived.3;
let #Derived_gen.8 : List {Str} = Array [#Derived_gen.9, #Derived_gen.10];
let #Derived_gen.6 : {Str, List {Str}} = CallByName Json.20 #Derived_gen.7 #Derived_gen.8;
let #Derived_gen.6 : {Str, List {Str}} = CallByName Json.21 #Derived_gen.7 #Derived_gen.8;
jump #Derived_gen.5 #Derived_gen.6;
procedure Encode.22 (Encode.93):
@ -37,11 +37,11 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96):
ret Encode.106;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
let Encode.113 : List U8 = CallByName Json.95 Encode.94 Encode.96 Encode.102;
let Encode.113 : List U8 = CallByName Json.117 Encode.94 Encode.96 Encode.102;
ret Encode.113;
procedure Encode.23 (Encode.94, Encode.102, Encode.96):
let Encode.117 : List U8 = CallByName Json.65 Encode.94 Encode.96 Encode.102;
let Encode.117 : List U8 = CallByName Json.87 Encode.94 Encode.96 Encode.102;
ret Encode.117;
procedure Encode.25 (Encode.100, Encode.101):
@ -51,98 +51,98 @@ procedure Encode.25 (Encode.100, Encode.101):
ret Encode.103;
procedure Json.1 ():
let Json.106 : {} = Struct {};
ret Json.106;
let Json.318 : {} = Struct {};
ret Json.318;
procedure Json.17 (Json.64):
let Json.114 : {Str} = Struct {Json.64};
let Json.113 : {Str} = CallByName Encode.22 Json.114;
ret Json.113;
procedure Json.20 (Json.93, Json.94):
let Json.108 : {Str, List {Str}} = Struct {Json.93, Json.94};
let Json.107 : {Str, List {Str}} = CallByName Encode.22 Json.108;
ret Json.107;
procedure Json.65 (Json.66, Json.112, #Attr.12):
let Json.64 : Str = StructAtIndex 0 #Attr.12;
inc Json.64;
procedure Json.117 (Json.118, Json.321, #Attr.12):
let Json.116 : List {Str} = StructAtIndex 1 #Attr.12;
inc Json.116;
let Json.115 : Str = StructAtIndex 0 #Attr.12;
inc Json.115;
dec #Attr.12;
let Json.162 : I32 = 34i64;
let Json.161 : U8 = CallByName Num.123 Json.162;
let Json.159 : List U8 = CallByName List.4 Json.66 Json.161;
let Json.160 : List U8 = CallByName Str.12 Json.64;
let Json.156 : List U8 = CallByName List.8 Json.159 Json.160;
let Json.158 : I32 = 34i64;
let Json.157 : U8 = CallByName Num.123 Json.158;
let Json.155 : List U8 = CallByName List.4 Json.156 Json.157;
ret Json.155;
let Json.365 : I32 = 123i64;
let Json.364 : U8 = CallByName Num.123 Json.365;
let Json.361 : List U8 = CallByName List.4 Json.118 Json.364;
let Json.363 : I32 = 34i64;
let Json.362 : U8 = CallByName Num.123 Json.363;
let Json.359 : List U8 = CallByName List.4 Json.361 Json.362;
let Json.360 : List U8 = CallByName Str.12 Json.115;
let Json.356 : List U8 = CallByName List.8 Json.359 Json.360;
let Json.358 : I32 = 34i64;
let Json.357 : U8 = CallByName Num.123 Json.358;
let Json.353 : List U8 = CallByName List.4 Json.356 Json.357;
let Json.355 : I32 = 58i64;
let Json.354 : U8 = CallByName Num.123 Json.355;
let Json.350 : List U8 = CallByName List.4 Json.353 Json.354;
let Json.352 : I32 = 91i64;
let Json.351 : U8 = CallByName Num.123 Json.352;
let Json.120 : List U8 = CallByName List.4 Json.350 Json.351;
let Json.349 : U64 = CallByName List.6 Json.116;
let Json.337 : {List U8, U64} = Struct {Json.120, Json.349};
let Json.338 : {} = Struct {};
let Json.336 : {List U8, U64} = CallByName List.18 Json.116 Json.337 Json.338;
dec Json.116;
let Json.122 : List U8 = StructAtIndex 0 Json.336;
inc Json.122;
dec Json.336;
let Json.335 : I32 = 93i64;
let Json.334 : U8 = CallByName Num.123 Json.335;
let Json.331 : List U8 = CallByName List.4 Json.122 Json.334;
let Json.333 : I32 = 125i64;
let Json.332 : U8 = CallByName Num.123 Json.333;
let Json.330 : List U8 = CallByName List.4 Json.331 Json.332;
ret Json.330;
procedure Json.95 (Json.96, Json.109, #Attr.12):
let Json.94 : List {Str} = StructAtIndex 1 #Attr.12;
inc Json.94;
let Json.93 : Str = StructAtIndex 0 #Attr.12;
inc Json.93;
dec #Attr.12;
let Json.153 : I32 = 123i64;
let Json.152 : U8 = CallByName Num.123 Json.153;
let Json.149 : List U8 = CallByName List.4 Json.96 Json.152;
let Json.151 : I32 = 34i64;
let Json.150 : U8 = CallByName Num.123 Json.151;
let Json.147 : List U8 = CallByName List.4 Json.149 Json.150;
let Json.148 : List U8 = CallByName Str.12 Json.93;
let Json.144 : List U8 = CallByName List.8 Json.147 Json.148;
let Json.146 : I32 = 34i64;
let Json.145 : U8 = CallByName Num.123 Json.146;
let Json.141 : List U8 = CallByName List.4 Json.144 Json.145;
let Json.143 : I32 = 58i64;
let Json.142 : U8 = CallByName Num.123 Json.143;
let Json.138 : List U8 = CallByName List.4 Json.141 Json.142;
let Json.140 : I32 = 91i64;
let Json.139 : U8 = CallByName Num.123 Json.140;
let Json.98 : List U8 = CallByName List.4 Json.138 Json.139;
let Json.137 : U64 = CallByName List.6 Json.94;
let Json.125 : {List U8, U64} = Struct {Json.98, Json.137};
let Json.126 : {} = Struct {};
let Json.124 : {List U8, U64} = CallByName List.18 Json.94 Json.125 Json.126;
dec Json.94;
let Json.100 : List U8 = StructAtIndex 0 Json.124;
inc Json.100;
dec Json.124;
let Json.123 : I32 = 93i64;
let Json.122 : U8 = CallByName Num.123 Json.123;
let Json.119 : List U8 = CallByName List.4 Json.100 Json.122;
let Json.121 : I32 = 125i64;
let Json.120 : U8 = CallByName Num.123 Json.121;
let Json.118 : List U8 = CallByName List.4 Json.119 Json.120;
ret Json.118;
procedure Json.97 (Json.117, Json.103):
let Json.101 : List U8 = StructAtIndex 0 Json.117;
inc Json.101;
let Json.102 : U64 = StructAtIndex 1 Json.117;
dec Json.117;
let Json.136 : {} = Struct {};
let Json.104 : List U8 = CallByName Encode.23 Json.101 Json.103 Json.136;
joinpoint Json.131 Json.105:
let Json.129 : U64 = 1i64;
let Json.128 : U64 = CallByName Num.20 Json.102 Json.129;
let Json.127 : {List U8, U64} = Struct {Json.105, Json.128};
ret Json.127;
procedure Json.119 (Json.329, Json.125):
let Json.123 : List U8 = StructAtIndex 0 Json.329;
inc Json.123;
let Json.124 : U64 = StructAtIndex 1 Json.329;
dec Json.329;
let Json.348 : {} = Struct {};
let Json.126 : List U8 = CallByName Encode.23 Json.123 Json.125 Json.348;
joinpoint Json.343 Json.127:
let Json.341 : U64 = 1i64;
let Json.340 : U64 = CallByName Num.20 Json.124 Json.341;
let Json.339 : {List U8, U64} = Struct {Json.127, Json.340};
ret Json.339;
in
let Json.135 : U64 = 1i64;
let Json.132 : Int1 = CallByName Num.24 Json.102 Json.135;
if Json.132 then
let Json.134 : I32 = 44i64;
let Json.133 : U8 = CallByName Num.123 Json.134;
let Json.130 : List U8 = CallByName List.4 Json.104 Json.133;
jump Json.131 Json.130;
let Json.347 : U64 = 1i64;
let Json.344 : Int1 = CallByName Num.24 Json.124 Json.347;
if Json.344 then
let Json.346 : I32 = 44i64;
let Json.345 : U8 = CallByName Num.123 Json.346;
let Json.342 : List U8 = CallByName List.4 Json.126 Json.345;
jump Json.343 Json.342;
else
jump Json.131 Json.104;
jump Json.343 Json.126;
procedure Json.18 (Json.86):
let Json.326 : {Str} = Struct {Json.86};
let Json.325 : {Str} = CallByName Encode.22 Json.326;
ret Json.325;
procedure Json.21 (Json.115, Json.116):
let Json.320 : {Str, List {Str}} = Struct {Json.115, Json.116};
let Json.319 : {Str, List {Str}} = CallByName Encode.22 Json.320;
ret Json.319;
procedure Json.87 (Json.88, Json.324, #Attr.12):
let Json.86 : Str = StructAtIndex 0 #Attr.12;
inc Json.86;
dec #Attr.12;
let Json.374 : I32 = 34i64;
let Json.373 : U8 = CallByName Num.123 Json.374;
let Json.371 : List U8 = CallByName List.4 Json.88 Json.373;
let Json.372 : List U8 = CallByName Str.12 Json.86;
let Json.368 : List U8 = CallByName List.8 Json.371 Json.372;
let Json.370 : I32 = 34i64;
let Json.369 : U8 = CallByName Num.123 Json.370;
let Json.367 : List U8 = CallByName List.4 Json.368 Json.369;
ret Json.367;
procedure List.133 (List.134, List.135, #Attr.12):
let List.132 : {} = StructAtIndex 0 #Attr.12;
let List.447 : {List U8, U64} = CallByName Json.97 List.134 List.135;
let List.447 : {List U8, U64} = CallByName Json.119 List.134 List.135;
let List.446 : [C [], C {List U8, U64}] = TagId(1) List.447;
ret List.446;

View file

@ -6,7 +6,7 @@ license = "UPL-1.0"
edition = "2021"
[dependencies]
roc_std = { path = "../roc_std" }
roc_std = { path = "../roc_std"}
roc_can = { path = "../compiler/can" }
roc_mono = { path = "../compiler/mono" }
roc_load = { path = "../compiler/load" }

View file

@ -148,27 +148,15 @@ fn add_type(target_info: TargetInfo, id: TypeId, types: &Types, impls: &mut Impl
}
RocType::TagUnion(tag_union) => {
match tag_union {
RocTagUnion::Enumeration { tags, name, size } => {
if tags.len() == 1 {
// An enumeration with one tag is a zero-sized unit type, so
// represent it as a zero-sized struct (e.g. "struct Foo()").
let derive = derive_str(types.get_type(id), types, true);
let struct_name = type_name(id, types);
let body = format!("{derive}\nstruct {struct_name}();");
add_decl(impls, None, target_info, body);
} else {
add_enumeration(
name,
target_info,
types.get_type(id),
tags.iter(),
*size,
types,
impls,
)
}
}
RocTagUnion::Enumeration { tags, name, size } => add_enumeration(
name,
target_info,
types.get_type(id),
tags.iter(),
*size,
types,
impls,
),
RocTagUnion::NonRecursive {
tags,
name,
@ -184,6 +172,7 @@ fn add_type(target_info: TargetInfo, id: TypeId, types: &Types, impls: &mut Impl
target_info,
id,
tags,
None,
*discriminant_size,
*discriminant_offset,
types,
@ -206,6 +195,7 @@ fn add_type(target_info: TargetInfo, id: TypeId, types: &Types, impls: &mut Impl
target_info,
id,
tags,
None,
*discriminant_size,
*discriminant_offset,
types,
@ -213,8 +203,30 @@ fn add_type(target_info: TargetInfo, id: TypeId, types: &Types, impls: &mut Impl
);
}
}
RocTagUnion::NullableWrapped { .. } => {
todo!();
RocTagUnion::NullableWrapped {
name,
index_of_null_tag,
tags,
discriminant_size,
discriminant_offset,
} => {
// index_of_null_tag refers to the index of the tag that is represented at runtime as NULL.
// For example, in `FingerTree a : [Empty, Single a, More (Some a) (FingerTree (Tuple a)) (Some a)]`,
// the ids would be Empty = 0, More = 1, Single = 2, because that's how those tags are
// ordered alphabetically. Since the Empty tag will be represented at runtime as NULL,
// and since Empty's tag id is 0, here nullable_id would be 0.
add_tag_union(
Recursiveness::Recursive,
name,
target_info,
id,
tags,
Some(*index_of_null_tag as usize),
*discriminant_size,
*discriminant_offset,
types,
impls,
)
}
RocTagUnion::NullableUnwrapped {
name,
@ -236,6 +248,75 @@ fn add_type(target_info: TargetInfo, id: TypeId, types: &Types, impls: &mut Impl
RocTagUnion::NonNullableUnwrapped { .. } => {
todo!();
}
RocTagUnion::SingleTagUnion { name, tag_name } => {
// An enumeration with one tag is a zero-sized unit type, so
// represent it as a zero-sized struct (e.g. "struct Foo()").
let derive = derive_str(
&RocType::Struct {
// Deriving doesn't depend on the struct's name,
// so no need to clone name here.
name: String::new(),
fields: Vec::new(),
},
types,
false,
);
let body = format!("{derive}\npub struct {name}();");
add_decl(impls, None, target_info, body);
let opt_impl = Some(format!("impl {name}"));
add_decl(
impls,
opt_impl.clone(),
target_info,
format!(
r#"/// A tag named {tag_name}, which has no payload.
pub const {tag_name}: Self = Self();"#,
),
);
add_decl(
impls,
opt_impl.clone(),
target_info,
format!(
r#"/// Other `into_` methods return a payload, but since the {tag_name} tag
/// has no payload, this does nothing and is only here for completeness.
pub fn into_{tag_name}(self) {{
()
}}"#,
),
);
add_decl(
impls,
opt_impl,
target_info,
format!(
r#"/// Other `as` methods return a payload, but since the {tag_name} tag
/// has no payload, this does nothing and is only here for completeness.
pub fn as_{tag_name}(&self) {{
()
}}"#,
),
);
// The Debug impl for the single-tag union
{
let opt_impl = Some(format!("impl core::fmt::Debug for {name}"));
let buf = format!(
r#"fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {{
f.write_str("{name}::")?;
f.write_str("{tag_name}")
}}"#
);
add_decl(impls, opt_impl, target_info, buf);
}
}
}
}
// These types don't need to be declared in Rust.
@ -307,6 +388,7 @@ fn add_tag_union(
target_info: TargetInfo,
type_id: TypeId,
tags: &[(String, Option<TypeId>)],
null_tag_index: Option<usize>, // used only in the nullable-wrapped case
discriminant_size: u32,
discriminant_offset: u32,
types: &Types,
@ -528,7 +610,7 @@ pub struct {name} {{
}
}
for (tag_name, opt_payload_id) in tags {
for (tag_index, (tag_name, opt_payload_id)) in tags.iter().enumerate() {
// Add a convenience constructor function to the impl, e.g.
//
// /// Construct a tag named Foo, with the appropriate payload
@ -558,8 +640,14 @@ pub struct {name} {{
owned_get_payload = format!(
r#"{{
let ptr = (self.pointer as usize & !{bitmask}) as *mut {union_name};
let mut uninitialized = core::mem::MaybeUninit::uninit();
let swapped = core::mem::replace(
&mut (*ptr).{tag_name},
core::mem::ManuallyDrop::new(uninitialized.assume_init()),
);
core::mem::forget(self);
core::mem::ManuallyDrop::take(&mut (*ptr).{tag_name})
core::mem::ManuallyDrop::into_inner(swapped)
}}"#
);
borrowed_get_payload = format!(
@ -592,8 +680,18 @@ pub struct {name} {{
}
Recursiveness::NonRecursive => {
if cannot_derive_copy(payload_type, types) {
owned_get_payload =
format!("core::mem::ManuallyDrop::take(&mut self.{tag_name})");
owned_get_payload = format!(
r#"{{
let mut uninitialized = core::mem::MaybeUninit::uninit();
let swapped = core::mem::replace(
&mut self.{tag_name},
core::mem::ManuallyDrop::new(uninitialized.assume_init()),
);
core::mem::forget(self);
core::mem::ManuallyDrop::into_inner(swapped)
}}"#
);
borrowed_get_payload = format!("&self.{tag_name}");
// we need `mut self` for the argument because of ManuallyDrop
self_for_into = "mut self";
@ -737,6 +835,21 @@ pub struct {name} {{
}}"#,
),
);
} else if Some(tag_index) == null_tag_index {
// The null tag index only occurs for nullable-wrapped tag unions,
// and it always has no payload. This is the one scenario where
// that constructor could come up!
add_decl(
impls,
opt_impl.clone(),
target_info,
format!(
r#"/// A tag named {tag_name}, which has no payload.
pub const {tag_name}: Self = Self {{
pointer: core::ptr::null_mut(),
}};"#,
),
);
} else {
add_decl(
impls,
@ -774,7 +887,7 @@ pub struct {name} {{
format!(
r#"/// Other `as` methods return a payload, but since the {tag_name} tag
/// has no payload, this does nothing and is only here for completeness.
pub unsafe fn as_{tag_name}(&self) {{
pub fn as_{tag_name}(&self) {{
()
}}"#,
),
@ -1294,6 +1407,7 @@ fn type_name(id: TypeId, types: &Types) -> String {
RocType::Struct { name, .. }
| RocType::TagUnionPayload { name, .. }
| RocType::TagUnion(RocTagUnion::NonRecursive { name, .. })
| RocType::TagUnion(RocTagUnion::SingleTagUnion { name, .. })
| RocType::TagUnion(RocTagUnion::Recursive { name, .. })
| RocType::TagUnion(RocTagUnion::Enumeration { name, .. })
| RocType::TagUnion(RocTagUnion::NullableWrapped { name, .. })
@ -1501,7 +1615,16 @@ pub struct {name} {{
{
let assign_payload = if cannot_derive_copy {
"core::mem::ManuallyDrop::take(&mut *self.pointer)"
r#"{{
let mut uninitialized = core::mem::MaybeUninit::uninit();
let swapped = core::mem::replace(
&mut *self.pointer,
core::mem::ManuallyDrop::new(uninitialized.assume_init()),
);
core::mem::forget(self);
core::mem::ManuallyDrop::into_inner(swapped)
}}"#
} else {
"*self.pointer"
};
@ -1519,8 +1642,6 @@ pub struct {name} {{
let payload = {assign_payload};
core::mem::drop::<Self>(self);
{owned_ret}
}}"#,
),
@ -1583,7 +1704,7 @@ pub struct {name} {{
format!(
r#"/// Other `as` methods return a payload, but since the {null_tag} tag
/// has no payload, this does nothing and is only here for completeness.
pub unsafe fn as_{null_tag}(&self) {{
pub fn as_{null_tag}(&self) {{
()
}}"#,
),
@ -1909,6 +2030,7 @@ fn cannot_derive_copy(roc_type: &RocType, types: &Types) -> bool {
| RocType::Bool
| RocType::Num(_)
| RocType::TagUnion(RocTagUnion::Enumeration { .. })
| RocType::TagUnion(RocTagUnion::SingleTagUnion { .. })
| RocType::Function { .. } => false,
RocType::RocStr
| RocType::RocList(_)
@ -1960,6 +2082,7 @@ fn has_float_help(roc_type: &RocType, types: &Types, do_not_recurse: &[TypeId])
| RocType::RocStr
| RocType::Bool
| RocType::TagUnion(RocTagUnion::Enumeration { .. })
| RocType::TagUnion(RocTagUnion::SingleTagUnion { .. })
| RocType::Function { .. } => false,
RocType::RocList(id) | RocType::RocSet(id) | RocType::RocBox(id) => {
has_float_help(types.get_type(*id), types, do_not_recurse)
@ -1986,8 +2109,8 @@ fn has_float_help(roc_type: &RocType, types: &Types, do_not_recurse: &[TypeId])
.any(|id| has_float_help(types.get_type(*id), types, do_not_recurse))
})
}
RocType::TagUnion(RocTagUnion::NullableWrapped { non_null_tags, .. }) => {
non_null_tags.iter().any(|(_, _, payloads)| {
RocType::TagUnion(RocTagUnion::NullableWrapped { tags, .. }) => {
tags.iter().any(|(_, payloads)| {
payloads
.iter()
.any(|id| has_float_help(types.get_type(*id), types, do_not_recurse))

View file

@ -85,6 +85,14 @@ impl Types {
use RocTagUnion::*;
match (union_a, union_b) {
(
SingleTagUnion {
tag_name: tag_a, ..
},
SingleTagUnion {
tag_name: tag_b, ..
},
) => tag_a == tag_b,
(Enumeration { tags: tags_a, .. }, Enumeration { tags: tags_b, .. }) => {
tags_a == tags_b
}
@ -146,24 +154,15 @@ impl Types {
},
) => content_a == content_b,
(
NullableWrapped {
null_tag: null_a,
non_null_tags: non_null_a,
..
},
NullableWrapped {
null_tag: null_b,
non_null_tags: non_null_b,
..
},
NullableWrapped { tags: tags_a, .. },
NullableWrapped { tags: tags_b, .. },
) => {
if null_a != null_b || non_null_a.len() != non_null_b.len() {
if tags_a.len() != tags_b.len() {
false
} else {
non_null_a.iter().zip(non_null_b.iter()).all(
|((disc_a, name_a, opt_id_a), (disc_b, name_b, opt_id_b))| {
disc_a == disc_b
&& name_a == name_b
tags_a.iter().zip(tags_b.iter()).all(
|((name_a, opt_id_a), (name_b, opt_id_b))| {
name_a == name_b
&& match (opt_id_a, opt_id_b) {
(Some(id_a), Some(id_b)) => self.is_equivalent(
self.get_type(*id_a),
@ -199,7 +198,9 @@ impl Types {
}
// These are all listed explicitly so that if we ever add a new variant,
// we'll get an exhaustiveness error here.
(Enumeration { .. }, _)
(SingleTagUnion { .. }, _)
| (_, SingleTagUnion { .. })
| (Enumeration { .. }, _)
| (_, Enumeration { .. })
| (NonRecursive { .. }, _)
| (_, NonRecursive { .. })
@ -515,6 +516,10 @@ pub enum RocTagUnion {
tags: Vec<String>,
size: u32,
},
SingleTagUnion {
name: String,
tag_name: String,
},
/// A non-recursive tag union
/// e.g. `Result a e : [Ok a, Err e]`
NonRecursive {
@ -534,7 +539,10 @@ pub enum RocTagUnion {
/// A recursive tag union with just one constructor
/// Optimization: No need to store a tag ID (the payload is "unwrapped")
/// e.g. `RoseTree a : [Tree a (List (RoseTree a))]`
NonNullableUnwrapped { name: String, content: TypeId },
NonNullableUnwrapped {
name: String,
content: TypeId,
},
/// A recursive tag union that has an empty variant
/// Optimization: Represent the empty variant as null pointer => no memory usage & fast comparison
@ -543,8 +551,9 @@ pub enum RocTagUnion {
/// see also: https://youtu.be/ip92VMpf_-A?t=164
NullableWrapped {
name: String,
null_tag: String,
non_null_tags: Vec<(u16, String, Option<TypeId>)>,
index_of_null_tag: u16,
tags: Vec<(String, Option<TypeId>)>,
discriminant_size: u32,
discriminant_offset: u32,
},
@ -1016,7 +1025,7 @@ fn add_tag_union<'a>(
})
.collect();
let typ = match layout {
let tag_union_type = match layout {
Layout::Union(union_layout) => {
use UnionLayout::*;
@ -1030,12 +1039,12 @@ fn add_tag_union<'a>(
.max(1);
let discriminant_offset = union_layout.tag_id_offset(env.target).unwrap();
RocType::TagUnion(RocTagUnion::NonRecursive {
RocTagUnion::NonRecursive {
name: name.clone(),
tags,
discriminant_size,
discriminant_offset,
})
}
}
// A recursive tag union (general case)
// e.g. `Expr : [Sym Str, Add Expr Expr]`
@ -1044,12 +1053,12 @@ fn add_tag_union<'a>(
Discriminant::from_number_of_tags(tags.len()).stack_size();
let discriminant_offset = union_layout.tag_id_offset(env.target).unwrap();
RocType::TagUnion(RocTagUnion::Recursive {
RocTagUnion::Recursive {
name: name.clone(),
tags,
discriminant_size,
discriminant_offset,
})
}
}
// A recursive tag union with just one constructor
// Optimization: No need to store a tag ID (the payload is "unwrapped")
@ -1062,8 +1071,26 @@ fn add_tag_union<'a>(
// It has more than one other variant, so they need tag IDs (payloads are "wrapped")
// e.g. `FingerTree a : [Empty, Single a, More (Some a) (FingerTree (Tuple a)) (Some a)]`
// see also: https://youtu.be/ip92VMpf_-A?t=164
NullableWrapped { .. } => {
todo!()
NullableWrapped {
nullable_id,
other_tags,
} => {
let discriminant_size =
Discriminant::from_number_of_tags(other_tags.len()).stack_size();
let discriminant_offset = union_layout.tag_id_offset(env.target).unwrap();
// nullable_id refers to the index of the tag that is represented at runtime as NULL.
// For example, in `FingerTree a : [Empty, Single a, More (Some a) (FingerTree (Tuple a)) (Some a)]`,
// the ids would be Empty = 0, More = 1, Single = 2, because that's how those tags are
// ordered alphabetically. Since the Empty tag will be represented at runtime as NULL,
// and since Empty's tag id is 0, here nullable_id would be 0.
RocTagUnion::NullableWrapped {
name: name.clone(),
index_of_null_tag: nullable_id,
tags,
discriminant_size,
discriminant_offset,
}
}
// A recursive tag union with only two variants, where one is empty.
// Optimizations: Use null for the empty variant AND don't store a tag ID for the other variant.
@ -1091,41 +1118,53 @@ fn add_tag_union<'a>(
let (non_null_tag, non_null_payload) = non_null;
RocType::TagUnion(RocTagUnion::NullableUnwrapped {
RocTagUnion::NullableUnwrapped {
name: name.clone(),
null_tag,
non_null_tag,
non_null_payload: non_null_payload.unwrap(),
null_represents_first_tag,
})
}
}
}
}
Layout::Builtin(Builtin::Int(int_width)) => RocType::TagUnion(RocTagUnion::Enumeration {
Layout::Builtin(Builtin::Int(int_width)) => RocTagUnion::Enumeration {
name: name.clone(),
tags: tags.into_iter().map(|(tag_name, _)| tag_name).collect(),
size: int_width.stack_size(),
}),
},
Layout::Struct { field_layouts, .. } if field_layouts.is_empty() => {
// This should be a single-tag union.
debug_assert_eq!(tags.len(), 1);
let (tag_name, _) = tags.pop().unwrap();
RocTagUnion::SingleTagUnion {
name: name.clone(),
tag_name,
}
}
Layout::Builtin(_)
| Layout::Struct { .. }
| Layout::Boxed(_)
| Layout::LambdaSet(_)
| Layout::RecursivePointer => {
// These must be single-tag unions. Generate ordinary nonrecursive
// tag unions for them, and let Rust do the unwrapping.
// These must be single-tag wrappers. Generate ordinary nonrecursive
// tag unions for them, and let the generator do any unwrapping.
//
// This should be a very rare use case, and it's not worth overcomplicating
// the rest of glue to make it do something different.
RocType::TagUnion(RocTagUnion::NonRecursive {
RocTagUnion::NonRecursive {
name: name.clone(),
tags,
// These actually have no discriminant, since there's only one tag.
discriminant_size: 1,
discriminant_offset: 0,
})
}
}
};
let typ = RocType::TagUnion(tag_union_type);
let type_id = types.add_named(name, typ, layout);
if is_recursive {

View file

@ -0,0 +1,6 @@
app "app"
packages { pf: "platform.roc" }
imports []
provides [main] to pf
main = More "foo" (More "bar" Empty)

View file

@ -0,0 +1,11 @@
platform "test-platform"
requires {} { main : _ }
exposes []
packages {}
imports []
provides [mainForHost]
StrFingerTree : [Empty, Single Str, More Str StrFingerTree]
mainForHost : StrFingerTree
mainForHost = main

View file

@ -0,0 +1,119 @@
mod test_glue;
use indoc::indoc;
use roc_std::RocStr;
use test_glue::StrFingerTree;
extern "C" {
#[link_name = "roc__mainForHost_1_exposed_generic"]
fn roc_main(_: *mut StrFingerTree);
}
#[no_mangle]
pub extern "C" fn rust_main() -> i32 {
use std::cmp::Ordering;
use std::collections::hash_set::HashSet;
let tag_union = unsafe {
let mut ret: core::mem::MaybeUninit<StrFingerTree> = core::mem::MaybeUninit::uninit();
roc_main(ret.as_mut_ptr());
ret.assume_init()
};
// Eq
assert!(StrFingerTree::Empty == StrFingerTree::Empty);
assert!(StrFingerTree::Empty != tag_union);
assert!(
StrFingerTree::Single(RocStr::from("foo")) == StrFingerTree::Single(RocStr::from("foo"))
);
assert!(StrFingerTree::Single(RocStr::from("foo")) != StrFingerTree::Empty);
// Verify that it has all the expected traits.
assert!(tag_union == tag_union); // PartialEq
assert!(tag_union.clone() == tag_union.clone()); // Clone
assert!(StrFingerTree::Empty.clone() == StrFingerTree::Empty); // Clone
assert!(tag_union.partial_cmp(&tag_union) == Some(Ordering::Equal)); // PartialOrd
assert!(tag_union.cmp(&tag_union) == Ordering::Equal); // Ord
print!(
indoc!(
r#"
tag_union was: {:?}
`More "small str" (Single "other str")` is: {:?}
`More "small str" Empty` is: {:?}
`Single "small str"` is: {:?}
`Empty` is: {:?}
"#
),
tag_union,
StrFingerTree::More(
"small str".into(),
StrFingerTree::Single("other str".into()),
),
StrFingerTree::More("small str".into(), StrFingerTree::Empty),
StrFingerTree::Single("small str".into()),
StrFingerTree::Empty,
); // Debug
let mut set = HashSet::new();
set.insert(tag_union.clone()); // Eq, Hash
set.insert(tag_union);
assert_eq!(set.len(), 1);
// Exit code
0
}
// Externs required by roc_std and by the Roc app
use core::ffi::c_void;
use std::ffi::CStr;
use std::os::raw::c_char;
#[no_mangle]
pub unsafe extern "C" fn roc_alloc(size: usize, _alignment: u32) -> *mut c_void {
return libc::malloc(size);
}
#[no_mangle]
pub unsafe extern "C" fn roc_realloc(
c_ptr: *mut c_void,
new_size: usize,
_old_size: usize,
_alignment: u32,
) -> *mut c_void {
return libc::realloc(c_ptr, new_size);
}
#[no_mangle]
pub unsafe extern "C" fn roc_dealloc(c_ptr: *mut c_void, _alignment: u32) {
return libc::free(c_ptr);
}
#[no_mangle]
pub unsafe extern "C" fn roc_panic(c_ptr: *mut c_void, tag_id: u32) {
match tag_id {
0 => {
let slice = CStr::from_ptr(c_ptr as *const c_char);
let string = slice.to_str().unwrap();
eprintln!("Roc hit a panic: {}", string);
std::process::exit(1);
}
_ => todo!(),
}
}
#[no_mangle]
pub unsafe extern "C" fn roc_memcpy(dst: *mut c_void, src: *mut c_void, n: usize) -> *mut c_void {
libc::memcpy(dst, src, n)
}
#[no_mangle]
pub unsafe extern "C" fn roc_memset(dst: *mut c_void, c: i32, n: usize) -> *mut c_void {
libc::memset(dst, c, n)
}

View file

@ -0,0 +1,6 @@
app "app"
packages { pf: "platform.roc" }
imports []
provides [main] to pf
main = OneTag

View file

@ -0,0 +1,11 @@
platform "test-platform"
requires {} { main : _ }
exposes []
packages {}
imports []
provides [mainForHost]
SingleTagUnion : [OneTag]
mainForHost : SingleTagUnion
mainForHost = main

View file

@ -0,0 +1,99 @@
mod test_glue;
use indoc::indoc;
use test_glue::SingleTagUnion;
extern "C" {
#[link_name = "roc__mainForHost_1_exposed_generic"]
fn roc_main(_: *mut SingleTagUnion);
}
#[no_mangle]
pub extern "C" fn rust_main() -> i32 {
use std::cmp::Ordering;
use std::collections::hash_set::HashSet;
let tag_union = unsafe {
let mut ret: core::mem::MaybeUninit<SingleTagUnion> = core::mem::MaybeUninit::uninit();
roc_main(ret.as_mut_ptr());
ret.assume_init()
};
// Verify that it has all the expected traits.
assert!(tag_union == SingleTagUnion::OneTag); // PartialEq
assert!(tag_union.clone() == tag_union.clone()); // Clone
assert!(tag_union.partial_cmp(&tag_union) == Some(Ordering::Equal)); // PartialOrd
assert!(tag_union.cmp(&tag_union) == Ordering::Equal); // Ord
print!(
indoc!(
r#"
tag_union was: {:?}
"#
),
tag_union,
); // Debug
let mut set = HashSet::new();
set.insert(tag_union.clone()); // Eq, Hash
set.insert(tag_union);
assert_eq!(set.len(), 1);
// Exit code
0
}
// Externs required by roc_std and by the Roc app
use core::ffi::c_void;
use std::ffi::CStr;
use std::os::raw::c_char;
#[no_mangle]
pub unsafe extern "C" fn roc_alloc(size: usize, _alignment: u32) -> *mut c_void {
return libc::malloc(size);
}
#[no_mangle]
pub unsafe extern "C" fn roc_realloc(
c_ptr: *mut c_void,
new_size: usize,
_old_size: usize,
_alignment: u32,
) -> *mut c_void {
return libc::realloc(c_ptr, new_size);
}
#[no_mangle]
pub unsafe extern "C" fn roc_dealloc(c_ptr: *mut c_void, _alignment: u32) {
return libc::free(c_ptr);
}
#[no_mangle]
pub unsafe extern "C" fn roc_panic(c_ptr: *mut c_void, tag_id: u32) {
match tag_id {
0 => {
let slice = CStr::from_ptr(c_ptr as *const c_char);
let string = slice.to_str().unwrap();
eprintln!("Roc hit a panic: {}", string);
std::process::exit(1);
}
_ => todo!(),
}
}
#[no_mangle]
pub unsafe extern "C" fn roc_memcpy(dst: *mut c_void, src: *mut c_void, n: usize) -> *mut c_void {
libc::memcpy(dst, src, n)
}
#[no_mangle]
pub unsafe extern "C" fn roc_memset(dst: *mut c_void, c: i32, n: usize) -> *mut c_void {
libc::memset(dst, c, n)
}

View file

@ -79,6 +79,9 @@ mod glue_cli_run {
`Baz` is: NonRecursive::Baz
`Blah 456` is: NonRecursive::Blah(456)
"#),
single_tag_union:"single-tag-union" => indoc!(r#"
tag_union was: SingleTagUnion::OneTag
"#),
union_without_padding:"union-without-padding" => indoc!(r#"
tag_union was: NonRecursive::Foo("This is a test")
`Foo "small str"` is: NonRecursive::Foo("small str")
@ -86,6 +89,13 @@ mod glue_cli_run {
`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"))
`More "small str" Empty` is: StrFingerTree::More("small str", StrFingerTree::Empty)
`Single "small str"` is: StrFingerTree::Single("small str")
`Empty` is: StrFingerTree::Empty
"#),
nullable_unwrapped:"nullable-unwrapped" => indoc!(r#"
tag_union was: StrConsList::Cons("World!", StrConsList::Cons("Hello ", StrConsList::Nil))
`Cons "small str" Nil` is: StrConsList::Cons("small str", StrConsList::Nil)
@ -147,9 +157,6 @@ mod glue_cli_run {
.unwrap()
.join("fixture-templates");
dbg!(&platform_module_path);
dbg!(&glue_file);
// Copy the rust template from the templates directory into the fixture dir.
dircpy::CopyBuilder::new(fixture_templates_dir.join("rust"), platform_dir)
.overwrite(true) // overwrite any files that were already present

View file

@ -32,7 +32,7 @@ roc_mono = {path = "../compiler/mono"}
roc_parse = {path = "../compiler/parse"}
roc_repl_eval = {path = "../repl_eval"}
roc_reporting = {path = "../reporting"}
roc_std = {path = "../roc_std", default-features = false}
roc_std = {path = "../roc_std"}
roc_target = {path = "../compiler/roc_target"}
roc_types = {path = "../compiler/types"}
roc_region = { path = "../compiler/region" }

View file

@ -20,6 +20,6 @@ roc_mono = {path = "../compiler/mono"}
roc_parse = {path = "../compiler/parse"}
roc_region = {path = "../compiler/region"}
roc_reporting = {path = "../reporting"}
roc_std = {path = "../roc_std", default-features = false}
roc_std = {path = "../roc_std"}
roc_target = {path = "../compiler/roc_target"}
roc_types = {path = "../compiler/types"}

View file

@ -17,7 +17,7 @@ roc_parse = {path = "../compiler/parse"}
roc_module = {path = "../compiler/module"}
roc_repl_eval = {path = "../repl_eval"}
roc_reporting = {path = "../reporting"}
roc_std = {path = "../roc_std", default-features = false}
roc_std = {path = "../roc_std"}
roc_target = {path = "../compiler/roc_target"}
roc_types = {path = "../compiler/types"}
roc_gen_llvm = {path = "../compiler/gen_llvm"}

View file

@ -108,7 +108,7 @@ mod test {
target_info,
render: RenderTarget::ColorTerminal,
threading: Threading::Single,
exec_mode: ExecutionMode::Executable,
exec_mode: ExecutionMode::Test,
};
let loaded = roc_load::load_and_monomorphize_from_str(
arena,

View file

@ -341,10 +341,11 @@ pub fn expect_mono_module_to_dylib<'a>(
// Verify the module
if let Err(errors) = env.module.verify() {
env.module.print_to_file("/tmp/test.ll").unwrap();
let path = std::env::temp_dir().join("test.ll");
env.module.print_to_file(&path).unwrap();
panic!(
"Errors defining module:\n{}\n\nUncomment things nearby to see more details. IR written to `/tmp/test.ll`",
errors.to_string()
"Errors defining module:\n{}\n\nUncomment things nearby to see more details. IR written to `{:?}`",
errors.to_string(), path,
);
}

View file

@ -96,9 +96,9 @@ fn wasmer_create_app(app_bytes_ptr: u32, app_bytes_len: u32) -> u32 {
Err(e) => {
println!("Failed to create Wasm module\n{:?}", e);
if false {
let path = "/tmp/roc_repl_test_invalid_app.wasm";
fs::write(path, app_module_bytes).unwrap();
println!("Wrote invalid wasm to {}", path);
let path = std::env::temp_dir().join("roc_repl_test_invalid_app.wasm");
fs::write(&path, app_module_bytes).unwrap();
println!("Wrote invalid wasm to {:?}", path);
}
return false.into();
}

View file

@ -20,6 +20,4 @@ quickcheck_macros = "1.0.0"
libc = "0.2.106"
[features]
default = ["platform"]
platform = []
no_std = []
std = []

View file

@ -1,6 +1,7 @@
#![no_std]
#![crate_type = "lib"]
#![cfg_attr(feature = "no_std", no_std)]
use arrayvec::ArrayString;
use core::cmp::Ordering;
use core::ffi::c_void;
use core::fmt::{self, Debug};
@ -9,8 +10,6 @@ use core::mem::{ManuallyDrop, MaybeUninit};
use core::ops::Drop;
use core::str;
use arrayvec::ArrayString;
mod roc_box;
mod roc_list;
mod roc_str;
@ -22,7 +21,6 @@ pub use roc_str::{InteriorNulError, RocStr};
pub use storage::Storage;
// A list of C functions that are being imported
#[cfg(feature = "platform")]
extern "C" {
pub fn roc_alloc(size: usize, alignment: u32) -> *mut c_void;
pub fn roc_realloc(
@ -37,57 +35,6 @@ extern "C" {
pub fn roc_memset(dst: *mut c_void, c: i32, n: usize) -> *mut c_void;
}
/// # Safety
/// This is only marked unsafe to typecheck without warnings in the rest of the code here.
#[cfg(not(feature = "platform"))]
#[no_mangle]
pub unsafe extern "C" fn roc_alloc(_size: usize, _alignment: u32) -> *mut c_void {
unimplemented!("It is not valid to call roc alloc from within the compiler. Please use the \"platform\" feature if this is a platform.")
}
/// # Safety
/// This is only marked unsafe to typecheck without warnings in the rest of the code here.
#[cfg(not(feature = "platform"))]
#[no_mangle]
pub unsafe extern "C" fn roc_realloc(
_ptr: *mut c_void,
_new_size: usize,
_old_size: usize,
_alignment: u32,
) -> *mut c_void {
unimplemented!("It is not valid to call roc realloc from within the compiler. Please use the \"platform\" feature if this is a platform.")
}
/// # Safety
/// This is only marked unsafe to typecheck without warnings in the rest of the code here.
#[cfg(not(feature = "platform"))]
#[no_mangle]
pub unsafe extern "C" fn roc_dealloc(_ptr: *mut c_void, _alignment: u32) {
unimplemented!("It is not valid to call roc dealloc from within the compiler. Please use the \"platform\" feature if this is a platform.")
}
#[cfg(not(feature = "platform"))]
#[no_mangle]
pub unsafe extern "C" fn roc_panic(c_ptr: *mut c_void, tag_id: u32) {
unimplemented!("It is not valid to call roc panic from within the compiler. Please use the \"platform\" feature if this is a platform.")
}
/// # Safety
/// This is only marked unsafe to typecheck without warnings in the rest of the code here.
#[cfg(not(feature = "platform"))]
#[no_mangle]
pub fn roc_memcpy(_dst: *mut c_void, _src: *mut c_void, _n: usize) -> *mut c_void {
unimplemented!("It is not valid to call roc memcpy from within the compiler. Please use the \"platform\" feature if this is a platform.")
}
/// # Safety
/// This is only marked unsafe to typecheck without warnings in the rest of the code here.
#[cfg(not(feature = "platform"))]
#[no_mangle]
pub fn roc_memset(_dst: *mut c_void, _c: i32, _n: usize) -> *mut c_void {
unimplemented!("It is not valid to call roc memset from within the compiler. Please use the \"platform\" feature if this is a platform.")
}
pub fn roc_alloc_refcounted<T>() -> *mut T {
let size = core::mem::size_of::<T>();
let align = core::mem::align_of::<T>();
@ -373,7 +320,7 @@ impl RocDec {
}
fn to_str_helper(self, string: &mut ArrayString<{ Self::MAX_STR_LENGTH }>) -> &str {
use std::fmt::Write;
use core::fmt::Write;
if self.as_i128() == 0 {
return "0";

View file

@ -7,11 +7,11 @@ use core::{
fmt::Debug,
hash::Hash,
intrinsics::copy_nonoverlapping,
iter::FromIterator,
mem::{self, ManuallyDrop},
ops::Deref,
ptr::{self, NonNull},
};
use std::iter::FromIterator;
use crate::{roc_alloc, roc_dealloc, roc_realloc, storage::Storage};
@ -474,7 +474,7 @@ where
impl<'a, T> IntoIterator for &'a RocList<T> {
type Item = &'a T;
type IntoIter = std::slice::Iter<'a, T>;
type IntoIter = core::slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.as_slice().iter()
@ -529,7 +529,7 @@ impl<T> Drop for IntoIter<T> {
}
impl<T: Hash> Hash for RocList<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
// This is the same as Rust's Vec implementation, which
// just delegates to the slice implementation. It's a bit surprising
// that Hash::hash_slice doesn't automatically incorporate the length,
@ -551,7 +551,7 @@ impl<T: Clone> FromIterator<T> for RocList<T> {
{
let iter = into.into_iter();
if std::mem::size_of::<T>() == 0 {
if core::mem::size_of::<T>() == 0 {
let count = iter.count();
return Self {
elements: Some(Self::elems_with_capacity(count)),

View file

@ -10,8 +10,8 @@ use core::{
ptr,
};
#[cfg(not(feature = "no_std"))]
use std::ffi::{CStr, CString};
#[cfg(feature = "std")]
use core::ffi::{CStr, CString};
use crate::RocList;
@ -527,7 +527,7 @@ impl Deref for RocStr {
}
/// This can fail because a CStr may contain invalid UTF-8 characters
#[cfg(not(feature = "no_std"))]
#[cfg(feature = "std")]
impl TryFrom<&CStr> for RocStr {
type Error = core::str::Utf8Error;
@ -537,7 +537,7 @@ impl TryFrom<&CStr> for RocStr {
}
/// This can fail because a CString may contain invalid UTF-8 characters
#[cfg(not(feature = "no_std"))]
#[cfg(feature = "std")]
impl TryFrom<CString> for RocStr {
type Error = core::str::Utf8Error;

View file

@ -8,7 +8,7 @@ use core::num::NonZeroIsize;
const REFCOUNT_1: NonZeroIsize = unsafe { NonZeroIsize::new_unchecked(isize::MIN) };
const _ASSERT_STORAGE_SIZE: () =
assert!(std::mem::size_of::<isize>() == std::mem::size_of::<Storage>());
assert!(core::mem::size_of::<isize>() == core::mem::size_of::<Storage>());
#[derive(Clone, Copy, Debug)]
pub enum Storage {

View file

@ -86,30 +86,21 @@ pub fn main() u8 {
const stdout = std.io.getStdOut().writer();
const stderr = std.io.getStdErr().writer();
// start time
var ts1: std.os.timespec = undefined;
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts1) catch unreachable;
var timer = std.time.Timer.start() catch unreachable;
// actually call roc to populate the callresult
var callresult = RocStr.empty();
roc__mainForHost_1_exposed_generic(&callresult);
// end time
var ts2: std.os.timespec = undefined;
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts2) catch unreachable;
const nanos = timer.read();
const seconds = (@intToFloat(f64, nanos) / 1_000_000_000.0);
// stdout the result
stdout.print("{s}", .{callresult.asSlice()}) catch unreachable;
callresult.deinit();
const delta = to_seconds(ts2) - to_seconds(ts1);
stderr.print("runtime: {d:.3}ms\n", .{delta * 1000}) catch unreachable;
stderr.print("runtime: {d:.3}ms\n", .{seconds * 1000}) catch unreachable;
return 0;
}
fn to_seconds(tms: std.os.timespec) f64 {
return @intToFloat(f64, tms.tv_sec) + (@intToFloat(f64, tms.tv_nsec) / 1_000_000_000.0);
}
}