Merge branch 'main' of https://github.com/rtfeldman/roc into ensure-roc-files

This commit is contained in:
Trevor Settles 2024-02-04 21:25:15 -07:00
commit 2fe506ee50
No known key found for this signature in database
GPG key ID: F46B83058222DBAA
236 changed files with 2711 additions and 1765 deletions

View file

@ -537,7 +537,7 @@ pub fn rebuild_host(
// on windows, we need the nightly toolchain so we can use `-Z export-executable-symbols`
// using `+nightly` only works when running cargo through rustup
let mut cmd = rustup();
cmd.args(["run", "nightly-2023-05-28", "cargo"]);
cmd.args(["run", "nightly-2023-07-09", "cargo"]);
cmd
} else {
@ -613,7 +613,8 @@ pub fn rebuild_host(
// Clean up c_host.o
if c_host_dest.exists() {
std::fs::remove_file(c_host_dest).unwrap();
// there can be a race condition on this file cleanup
let _ = std::fs::remove_file(c_host_dest);
}
}
} else if rust_host_src.exists() {
@ -848,6 +849,17 @@ fn strs_to_path(strs: &[&str]) -> PathBuf {
strs.iter().collect()
}
fn extra_link_flags() -> Vec<String> {
match env::var("ROC_LINK_FLAGS") {
Ok(flags) => {
println!("⚠️ CAUTION: The ROC_LINK_FLAGS environment variable is a temporary workaround, and will no longer do anything once surgical linking lands! If you're concerned about what this means for your use case, please ask about it on Zulip.");
flags
}
Err(_) => "".to_string(),
}.split_whitespace().map(|x| x.to_owned()).collect()
}
fn link_linux(
target: &Triple,
output_path: PathBuf,
@ -1037,6 +1049,7 @@ fn link_linux(
.args(&base_args)
.args(["-dynamic-linker", ld_linux])
.args(input_paths)
.args(extra_link_flags())
// ld.lld requires this argument, and does not accept --arch
// .args(&["-L/usr/lib/x86_64-linux-gnu"])
.args([
@ -1108,7 +1121,8 @@ fn link_macos(
"-macos_version_min",
&get_macos_version(),
])
.args(input_paths);
.args(input_paths)
.args(extra_link_flags());
let sdk_path = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib";
if Path::new(sdk_path).exists() {
@ -1116,18 +1130,6 @@ fn link_macos(
ld_command.arg(format!("-L{sdk_path}/swift"));
};
let roc_link_flags = match env::var("ROC_LINK_FLAGS") {
Ok(flags) => {
println!("⚠️ CAUTION: The ROC_LINK_FLAGS environment variable is a temporary workaround, and will no longer do anything once surgical linking lands! If you're concerned about what this means for your use case, please ask about it on Zulip.");
flags
}
Err(_) => "".to_string(),
};
for roc_link_flag in roc_link_flags.split_whitespace() {
ld_command.arg(roc_link_flag);
}
ld_command.args([
// Libraries - see https://github.com/roc-lang/roc/pull/554#discussion_r496392274
// for discussion and further references

View file

@ -24,6 +24,9 @@ pub const RocDec = extern struct {
pub const one_point_zero_i128: i128 = math.pow(i128, 10, RocDec.decimal_places);
pub const one_point_zero: RocDec = .{ .num = one_point_zero_i128 };
pub const two_point_zero: RocDec = RocDec.add(RocDec.one_point_zero, RocDec.one_point_zero);
pub const zero_point_five: RocDec = RocDec.div(RocDec.one_point_zero, RocDec.two_point_zero);
pub fn fromU64(num: u64) RocDec {
return .{ .num = num * one_point_zero_i128 };
}
@ -340,6 +343,77 @@ pub const RocDec = extern struct {
}
}
fn trunc(self: RocDec) RocDec {
return RocDec.sub(self, self.fract());
}
fn fract(self: RocDec) RocDec {
const sign = std.math.sign(self.num);
const digits = @mod(sign * self.num, RocDec.one_point_zero.num);
return RocDec{ .num = sign * digits };
}
// Returns the nearest integer to self. If a value is half-way between two integers, round away from 0.0.
fn round(arg1: RocDec) RocDec {
// this rounds towards zero
const tmp = arg1.trunc();
const sign = std.math.sign(arg1.num);
const abs_fract = sign * arg1.fract().num;
if (abs_fract >= RocDec.zero_point_five.num) {
return RocDec.add(tmp, RocDec{ .num = sign * RocDec.one_point_zero.num });
} else {
return tmp;
}
}
// Returns the largest integer less than or equal to itself
fn floor(arg1: RocDec) RocDec {
const tmp = arg1.trunc();
if (arg1.num < 0 and arg1.fract().num != 0) {
return RocDec.sub(tmp, RocDec.one_point_zero);
} else {
return tmp;
}
}
// Returns the smallest integer greater than or equal to itself
fn ceiling(arg1: RocDec) RocDec {
const tmp = arg1.trunc();
if (arg1.num > 0 and arg1.fract().num != 0) {
return RocDec.add(tmp, RocDec.one_point_zero);
} else {
return tmp;
}
}
fn powInt(base: RocDec, exponent: i128) RocDec {
if (exponent == 0) {
return RocDec.one_point_zero;
} else if (exponent > 0) {
if (@mod(exponent, 2) == 0) {
const half_power = RocDec.powInt(base, exponent >> 1); // `>> 1` == `/ 2`
return RocDec.mul(half_power, half_power);
} else {
return RocDec.mul(base, RocDec.powInt(base, exponent - 1));
}
} else {
return RocDec.div(RocDec.one_point_zero, RocDec.powInt(base, -exponent));
}
}
fn pow(base: RocDec, exponent: RocDec) RocDec {
if (exponent.trunc().num == exponent.num) {
return base.powInt(@divTrunc(exponent.num, RocDec.one_point_zero_i128));
} else {
return fromF64(std.math.pow(f64, base.toF64(), exponent.toF64())).?;
}
}
pub fn mul(self: RocDec, other: RocDec) RocDec {
const answer = RocDec.mulWithOverflow(self, other);
@ -1195,6 +1269,153 @@ test "log: 1" {
try expectEqual(RocDec.fromU64(0), RocDec.log(RocDec.fromU64(1)));
}
test "fract: 0" {
var roc_str = RocStr.init("0", 1);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec{ .num = 0 }, dec.fract());
}
test "fract: 1" {
var roc_str = RocStr.init("1", 1);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec{ .num = 0 }, dec.fract());
}
test "fract: 123.45" {
var roc_str = RocStr.init("123.45", 6);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec{ .num = 450000000000000000 }, dec.fract());
}
test "fract: -123.45" {
var roc_str = RocStr.init("-123.45", 7);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec{ .num = -450000000000000000 }, dec.fract());
}
test "fract: .45" {
var roc_str = RocStr.init(".45", 3);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec{ .num = 450000000000000000 }, dec.fract());
}
test "fract: -0.00045" {
const dec: RocDec = .{ .num = -450000000000000 };
const res = dec.fract();
try expectEqual(dec.num, res.num);
}
test "trunc: 0" {
var roc_str = RocStr.init("0", 1);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec{ .num = 0 }, dec.trunc());
}
test "trunc: 1" {
var roc_str = RocStr.init("1", 1);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec.one_point_zero, dec.trunc());
}
test "trunc: 123.45" {
var roc_str = RocStr.init("123.45", 6);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec{ .num = 123000000000000000000 }, dec.trunc());
}
test "trunc: -123.45" {
var roc_str = RocStr.init("-123.45", 7);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec{ .num = -123000000000000000000 }, dec.trunc());
}
test "trunc: .45" {
var roc_str = RocStr.init(".45", 3);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec{ .num = 0 }, dec.trunc());
}
test "trunc: -0.00045" {
const dec: RocDec = .{ .num = -450000000000000 };
const res = dec.trunc();
try expectEqual(RocDec{ .num = 0 }, res);
}
test "round: 123.45" {
var roc_str = RocStr.init("123.45", 6);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec{ .num = 123000000000000000000 }, dec.round());
}
test "round: -123.45" {
var roc_str = RocStr.init("-123.45", 7);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec{ .num = -123000000000000000000 }, dec.round());
}
test "round: 0.5" {
var roc_str = RocStr.init("0.5", 3);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec.one_point_zero, dec.round());
}
test "round: -0.5" {
var roc_str = RocStr.init("-0.5", 4);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec{ .num = -1000000000000000000 }, dec.round());
}
test "powInt: 3.1 ^ 0" {
var roc_str = RocStr.init("3.1", 3);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(RocDec.one_point_zero, dec.powInt(0));
}
test "powInt: 3.1 ^ 1" {
var roc_str = RocStr.init("3.1", 3);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(dec, dec.powInt(1));
}
test "powInt: 2 ^ 2" {
var roc_str = RocStr.init("4", 1);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(dec, RocDec.two_point_zero.powInt(2));
}
test "powInt: 0.5 ^ 2" {
var roc_str = RocStr.init("0.25", 4);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(dec, RocDec.zero_point_five.powInt(2));
}
test "pow: 0.5 ^ 2.0" {
var roc_str = RocStr.init("0.25", 4);
var dec = RocDec.fromStr(roc_str).?;
try expectEqual(dec, RocDec.zero_point_five.pow(RocDec.two_point_zero));
}
// exports
pub fn fromStr(arg: RocStr) callconv(.C) num_.NumParseResult(i128) {
@ -1295,6 +1516,10 @@ pub fn logC(arg: RocDec) callconv(.C) i128 {
return @call(.always_inline, RocDec.log, .{arg}).num;
}
pub fn powC(arg1: RocDec, arg2: RocDec) callconv(.C) i128 {
return @call(.always_inline, RocDec.pow, .{ arg1, arg2 }).num;
}
pub fn sinC(arg: RocDec) callconv(.C) i128 {
return @call(.always_inline, RocDec.sin, .{arg}).num;
}
@ -1342,3 +1567,30 @@ pub fn mulOrPanicC(arg1: RocDec, arg2: RocDec) callconv(.C) RocDec {
pub fn mulSaturatedC(arg1: RocDec, arg2: RocDec) callconv(.C) RocDec {
return @call(.always_inline, RocDec.mulSaturated, .{ arg1, arg2 });
}
pub fn exportRound(comptime T: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(input: RocDec) callconv(.C) T {
return @as(T, @intCast(@divFloor(input.round().num, RocDec.one_point_zero_i128)));
}
}.func;
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
}
pub fn exportFloor(comptime T: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(input: RocDec) callconv(.C) T {
return @as(T, @intCast(@divFloor(input.floor().num, RocDec.one_point_zero_i128)));
}
}.func;
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
}
pub fn exportCeiling(comptime T: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(input: RocDec) callconv(.C) T {
return @as(T, @intCast(@divFloor(input.ceiling().num, RocDec.one_point_zero_i128)));
}
}.func;
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
}

View file

@ -36,6 +36,7 @@ comptime {
exportDecFn(dec.fromStr, "from_str");
exportDecFn(dec.fromU64C, "from_u64");
exportDecFn(dec.logC, "log");
exportDecFn(dec.powC, "pow");
exportDecFn(dec.mulC, "mul_with_overflow");
exportDecFn(dec.mulOrPanicC, "mul_or_panic");
exportDecFn(dec.mulSaturatedC, "mul_saturated");
@ -52,6 +53,10 @@ comptime {
inline for (INTEGERS) |T| {
dec.exportFromInt(T, ROC_BUILTINS ++ ".dec.from_int.");
dec.exportRound(T, ROC_BUILTINS ++ ".dec.round.");
dec.exportFloor(T, ROC_BUILTINS ++ ".dec.floor.");
dec.exportCeiling(T, ROC_BUILTINS ++ ".dec.ceiling.");
}
}
@ -122,6 +127,9 @@ comptime {
num.exportCeiling(f32, T, ROC_BUILTINS ++ "." ++ NUM ++ ".ceiling_f32.");
num.exportCeiling(f64, T, ROC_BUILTINS ++ "." ++ NUM ++ ".ceiling_f64.");
num.exportNumToFloatCast(T, f32, ROC_BUILTINS ++ "." ++ NUM ++ ".num_to_float_cast_f32.");
num.exportNumToFloatCast(T, f64, ROC_BUILTINS ++ "." ++ NUM ++ ".num_to_float_cast_f64.");
num.exportAddWithOverflow(T, ROC_BUILTINS ++ "." ++ NUM ++ ".add_with_overflow.");
num.exportAddOrPanic(T, ROC_BUILTINS ++ "." ++ NUM ++ ".add_or_panic.");
num.exportAddSaturatedInt(T, ROC_BUILTINS ++ "." ++ NUM ++ ".add_saturated.");

View file

@ -86,6 +86,15 @@ pub fn exportParseFloat(comptime T: type, comptime name: []const u8) void {
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
}
pub fn exportNumToFloatCast(comptime T: type, comptime F: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(x: T) callconv(.C) F {
return @floatFromInt(x);
}
}.func;
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
}
pub fn exportPow(comptime T: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(base: T, exp: T) callconv(.C) T {

View file

@ -729,7 +729,7 @@ incrementDist = \distAndFingerprint ->
distAndFingerprint + distInc
incrementDistN = \distAndFingerprint, n ->
distAndFingerprint + (n * distInc)
distAndFingerprint + (Num.mulWrap n distInc)
decrementDist = \distAndFingerprint ->
distAndFingerprint - distInc
@ -837,7 +837,7 @@ removeBucketHelper = \buckets, bucketIndex ->
nextIndex = nextBucketIndex bucketIndex (List.len buckets)
nextBucket = listGetUnsafe buckets nextIndex
# shift down until either empty or an element with correct spot is found
if nextBucket.distAndFingerprint >= distInc * 2 then
if nextBucket.distAndFingerprint >= Num.mulWrap distInc 2 then
List.set buckets bucketIndex { nextBucket & distAndFingerprint: decrementDist nextBucket.distAndFingerprint }
|> removeBucketHelper nextIndex
else
@ -857,7 +857,7 @@ increaseSize = \@Dict { data, maxBucketCapacity, maxLoadFactor, shifts } ->
shifts: newShifts,
}
else
crash "Dict hit limit of \(Num.toStr maxBucketCount) elements. Unable to grow more."
crash "Dict hit limit of $(Num.toStr maxBucketCount) elements. Unable to grow more."
allocBucketsFromShift : U8, F32 -> (List Bucket, U64)
allocBucketsFromShift = \shifts, maxLoadFactor ->
@ -1417,7 +1417,7 @@ wymix = \a, b ->
wymum : U64, U64 -> { lower : U64, upper : U64 }
wymum = \a, b ->
r = Num.toU128 a * Num.toU128 b
r = Num.mulWrap (Num.toU128 a) (Num.toU128 b)
lower = Num.toU64 r
upper = Num.shiftRightZfBy r 64 |> Num.toU64

View file

@ -1002,13 +1002,21 @@ divCeilChecked = \a, b ->
## Num.divTrunc 8 -3
## ```
divTrunc : Int a, Int a -> Int a
divTrunc = \a, b ->
if Num.isZero b then
crash "Integer division by 0!"
else
Num.divTruncUnchecked a b
divTruncChecked : Int a, Int a -> Result (Int a) [DivByZero]
divTruncChecked = \a, b ->
if Num.isZero b then
Err DivByZero
else
Ok (Num.divTrunc a b)
Ok (Num.divTruncUnchecked a b)
## traps (hardware fault) when given zero as the second argument.
divTruncUnchecked : Int a, Int a -> Int a
## Obtains the remainder (truncating modulo) from the division of two integers.
##
@ -1023,13 +1031,21 @@ divTruncChecked = \a, b ->
## Num.rem -8 -3
## ```
rem : Int a, Int a -> Int a
rem = \a, b ->
if Num.isZero b then
crash "Integer division by 0!"
else
Num.remUnchecked a b
remChecked : Int a, Int a -> Result (Int a) [DivByZero]
remChecked = \a, b ->
if Num.isZero b then
Err DivByZero
else
Ok (Num.rem a b)
Ok (Num.remUnchecked a b)
## traps (hardware fault) when given zero as the second argument.
remUnchecked : Int a, Int a -> Int a
isMultipleOf : Int a, Int a -> Bool

View file

@ -844,7 +844,7 @@ replaceFirst : Str, Str, Str -> Str
replaceFirst = \haystack, needle, flower ->
when splitFirst haystack needle is
Ok { before, after } ->
"\(before)\(flower)\(after)"
"$(before)$(flower)$(after)"
Err NotFound -> haystack
@ -862,7 +862,7 @@ replaceLast : Str, Str, Str -> Str
replaceLast = \haystack, needle, flower ->
when splitLast haystack needle is
Ok { before, after } ->
"\(before)\(flower)\(after)"
"$(before)$(flower)$(after)"
Err NotFound -> haystack

View file

@ -130,10 +130,10 @@ impl IntWidth {
// according to https://reviews.llvm.org/D28990#655487
//
// however, rust does not always think that this is true
// Our alignmets here are correct, but they will not match rust/zig/llvm until they update to llvm version 18.
match target_info.architecture {
Architecture::X86_64 => 16,
Architecture::Aarch64 | Architecture::Aarch32 | Architecture::Wasm32 => 16,
Architecture::X86_32 => 8,
Architecture::X86_64 | Architecture::Aarch64 | Architecture::X86_32 => 16,
Architecture::Aarch32 | Architecture::Wasm32 => 8,
}
}
}
@ -292,6 +292,10 @@ pub const NUM_FLOOR_F32: IntrinsicName = int_intrinsic!("roc_builtins.num.floor_
pub const NUM_FLOOR_F64: IntrinsicName = int_intrinsic!("roc_builtins.num.floor_f64");
pub const NUM_ROUND_F32: IntrinsicName = int_intrinsic!("roc_builtins.num.round_f32");
pub const NUM_ROUND_F64: IntrinsicName = int_intrinsic!("roc_builtins.num.round_f64");
pub const INT_TO_FLOAT_CAST_F32: IntrinsicName =
int_intrinsic!("roc_builtins.num.num_to_float_cast_f32");
pub const INT_TO_FLOAT_CAST_F64: IntrinsicName =
int_intrinsic!("roc_builtins.num.num_to_float_cast_f64");
pub const NUM_ADD_OR_PANIC_INT: IntrinsicName = int_intrinsic!("roc_builtins.num.add_or_panic");
pub const NUM_ADD_SATURATED_INT: IntrinsicName = int_intrinsic!("roc_builtins.num.add_saturated");
@ -404,6 +408,7 @@ pub const DEC_FROM_INT: IntrinsicName = int_intrinsic!("roc_builtins.dec.from_in
pub const DEC_FROM_STR: &str = "roc_builtins.dec.from_str";
pub const DEC_FROM_U64: &str = "roc_builtins.dec.from_u64";
pub const DEC_LOG: &str = "roc_builtins.dec.log";
pub const DEC_POW: &str = "roc_builtins.dec.pow";
pub const DEC_MUL_OR_PANIC: &str = "roc_builtins.dec.mul_or_panic";
pub const DEC_MUL_SATURATED: &str = "roc_builtins.dec.mul_saturated";
pub const DEC_MUL_WITH_OVERFLOW: &str = "roc_builtins.dec.mul_with_overflow";
@ -416,6 +421,9 @@ pub const DEC_SUB_WITH_OVERFLOW: &str = "roc_builtins.dec.sub_with_overflow";
pub const DEC_TAN: &str = "roc_builtins.dec.tan";
pub const DEC_TO_I128: &str = "roc_builtins.dec.to_i128";
pub const DEC_TO_STR: &str = "roc_builtins.dec.to_str";
pub const DEC_ROUND: IntrinsicName = int_intrinsic!("roc_builtins.dec.round");
pub const DEC_FLOOR: IntrinsicName = int_intrinsic!("roc_builtins.dec.floor");
pub const DEC_CEILING: IntrinsicName = int_intrinsic!("roc_builtins.dec.ceiling");
pub const UTILS_DBG_IMPL: &str = "roc_builtins.utils.dbg_impl";
pub const UTILS_TEST_PANIC: &str = "roc_builtins.utils.test_panic";

View file

@ -128,7 +128,6 @@ map_symbol_to_lowlevel_and_arity! {
StrSubstringUnsafe; STR_SUBSTRING_UNSAFE; 3,
StrReserve; STR_RESERVE; 2,
StrToNum; STR_TO_NUM; 1,
StrGetCapacity; STR_CAPACITY; 1,
StrWithCapacity; STR_WITH_CAPACITY; 1,
StrReleaseExcessCapacity; STR_RELEASE_EXCESS_CAPACITY; 1,
@ -173,9 +172,9 @@ map_symbol_to_lowlevel_and_arity! {
NumLte; NUM_LTE; 2,
NumCompare; NUM_COMPARE; 2,
NumDivFrac; NUM_DIV_FRAC; 2,
NumDivTruncUnchecked; NUM_DIV_TRUNC; 2,
NumDivTruncUnchecked; NUM_DIV_TRUNC_UNCHECKED; 2,
NumDivCeilUnchecked; NUM_DIV_CEIL; 2,
NumRemUnchecked; NUM_REM; 2,
NumRemUnchecked; NUM_REM_UNCHECKED; 2,
NumIsMultipleOf; NUM_IS_MULTIPLE_OF; 2,
NumAbs; NUM_ABS; 1,
NumNeg; NUM_NEG; 1,

View file

@ -2600,10 +2600,38 @@ fn flatten_str_lines<'a>(
fn desugar_str_segments(var_store: &mut VarStore, segments: Vec<StrSegment>) -> Expr {
use StrSegment::*;
let n = segments.len();
let mut iter = segments.into_iter().rev();
let mut loc_expr = match iter.next() {
Some(Plaintext(string)) => Loc::at(Region::zero(), Expr::Str(string)),
Some(Interpolation(loc_expr)) => loc_expr,
Some(Interpolation(loc_expr)) => {
if n == 1 {
// We concat with the empty string to ensure a type error when loc_expr is not a string
let empty_string = Loc::at(Region::zero(), Expr::Str("".into()));
let fn_expr = Loc::at(
Region::zero(),
Expr::Var(Symbol::STR_CONCAT, var_store.fresh()),
);
let expr = Expr::Call(
Box::new((
var_store.fresh(),
fn_expr,
var_store.fresh(),
var_store.fresh(),
)),
vec![
(var_store.fresh(), empty_string),
(var_store.fresh(), loc_expr),
],
CalledVia::StringInterpolation,
);
Loc::at(Region::zero(), expr)
} else {
loc_expr
}
}
None => {
// No segments? Empty string!

View file

@ -1051,14 +1051,13 @@ fn fix_values_captured_in_closure_expr(
debug_assert!(!captures.is_empty());
captured_symbols.extend(captures);
captured_symbols.swap_remove(i);
// Jump two, because the next element is now one of the newly-added captures,
// which we don't need to check.
i += 2;
added_captures = true;
} else {
i += 1;
}
// Always jump one, because the current element either does not have captures or
// is now one of the newly-added captures, which we don't need to check.
i += 1;
}
if added_captures {
// Re-sort, since we've added new captures.

View file

@ -594,7 +594,7 @@ pub fn desugar_expr<'a>(
// line_info is an option so that we can lazily calculate it.
// That way it there are no `dbg` statements, we never pay the cast of scanning the source an extra time.
if matches!(line_info, None) {
if line_info.is_none() {
*line_info = Some(LineInfo::new(src));
}
let line_col = line_info.as_ref().unwrap().convert_pos(region.start());

View file

@ -1831,7 +1831,7 @@ mod test_can {
// "abcd\$(efg)hij"
// "#
// ),
// Str(r"abcd\(efg)hij".into()),
// Str(r"abcd$(efg)hij".into()),
// );
// }

View file

@ -154,7 +154,9 @@ fn fmt_comment(buf: &mut Buf, comment: &str) {
}
buf.push('#');
if !comment.starts_with(' ') {
// Add a space between the starting `#` and the rest of the comment,
// unless there already is a space or the comment is of the form `#### something`.
if !comment.starts_with(' ') && !comment.starts_with('#') {
buf.spaces(1);
}
buf.push_str(comment.trim_end());

View file

@ -1,3 +1,6 @@
#![allow(clippy::redundant_closure_call)]
//|> clippy false positive: https://github.com/rust-lang/rust-clippy/issues/1553
use crate::generic64::{storage::StorageManager, Assembler, CallConv, RegTrait};
use crate::{
pointer_layouts, single_register_floats, single_register_int_builtins,
@ -1668,6 +1671,11 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
Self::mov_freg64_mem64_offset32(buf, dst, AArch64GeneralReg::FP, offset)
}
#[inline(always)]
fn mov_freg32_base32(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, offset: i32) {
Self::mov_freg32_mem32_offset32(buf, dst, AArch64GeneralReg::FP, offset)
}
#[inline(always)]
fn mov_reg_mem_offset32(
buf: &mut Vec<'_, u8>,

View file

@ -1,3 +1,6 @@
#![allow(clippy::redundant_closure_call)]
//|> clippy false positive: https://github.com/rust-lang/rust-clippy/issues/1553
pub fn merge_instructions_without_line_numbers(instructions: capstone::Instructions) -> String {
instructions
.iter()

View file

@ -358,6 +358,7 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
// base32 is similar to stack based instructions but they reference the base/frame pointer.
fn mov_freg64_base32(buf: &mut Vec<'_, u8>, dst: FloatReg, offset: i32);
fn mov_freg32_base32(buf: &mut Vec<'_, u8>, dst: FloatReg, offset: i32);
fn mov_reg_base32(
buf: &mut Vec<'_, u8>,
@ -2154,6 +2155,30 @@ impl<
);
}
fn build_int_to_float_cast(
&mut self,
dst: &Symbol,
src: &Symbol,
int_width: IntWidth,
float_width: FloatWidth,
) {
use roc_builtins::bitcode::{INT_TO_FLOAT_CAST_F32, INT_TO_FLOAT_CAST_F64};
self.build_fn_call(
dst,
match float_width {
FloatWidth::F32 => INT_TO_FLOAT_CAST_F32[int_width].to_string(),
FloatWidth::F64 => INT_TO_FLOAT_CAST_F64[int_width].to_string(),
},
&[*src],
&[Layout::from_int_width(int_width)],
match float_width {
FloatWidth::F32 => &Layout::F32,
FloatWidth::F64 => &Layout::F64,
},
);
}
fn build_num_cmp(
&mut self,
dst: &Symbol,
@ -2924,7 +2949,11 @@ impl<
self.load_layout_alignment(list_layout, Symbol::DEV_TMP);
// Load element_width argument (usize).
self.load_layout_stack_size(*ret_layout, Symbol::DEV_TMP2);
let element_layout = match self.interner().get_repr(*ret_layout) {
LayoutRepr::Builtin(Builtin::List(e)) => e,
_ => unreachable!(),
};
self.load_layout_stack_size(element_layout, Symbol::DEV_TMP2);
// Load UpdateMode.Immutable argument (0u8)
let u8_layout = Layout::U8;
@ -3270,7 +3299,7 @@ impl<
let elem_layout = arg_layouts[1];
// List alignment argument (u32).
self.load_layout_alignment(*ret_layout, Symbol::DEV_TMP);
self.load_layout_alignment(elem_layout, Symbol::DEV_TMP);
// Have to pass the input element by pointer, so put it on the stack and load it's address.
self.storage_manager
@ -4846,14 +4875,28 @@ impl<
// move a zero into the lower 8 bytes
ASM::mov_reg64_imm64(buf, tmp_reg, 0x0);
ASM::mov_base32_reg64(buf, base_offset, tmp_reg);
ASM::mov_base32_reg64(buf, base_offset + 8, tmp_reg);
ASM::mov_base32_reg64(buf, base_offset + 8, src_reg);
ASM::mov_base32_reg64(buf, base_offset, src_reg);
self.free_symbol(&tmp);
return;
}
(U128, I128) | (I128, U128) => {
let to_offset = self.storage_manager.claim_stack_area_layout(
self.layout_interner,
*dst,
Layout::from_int_width(target),
);
let (from_offset, size) = self.storage_manager.stack_offset_and_size(src);
self.storage_manager
.copy_to_stack_offset(buf, size, from_offset, to_offset);
return;
}
_ => {}
}
@ -4977,39 +5020,51 @@ impl<
}
fn num_to_f32(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>) {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
match self.layout_interner.get_repr(*arg_layout) {
LayoutRepr::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::I64)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
ASM::to_float_freg32_reg64(&mut self.buf, dst_reg, src_reg);
}
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::to_float_freg32_freg64(&mut self.buf, dst_reg, src_reg);
}
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::mov_freg64_freg64(&mut self.buf, dst_reg, src_reg);
}
LayoutRepr::Builtin(Builtin::Int(_)) => {
let int_width = arg_layout.to_int_width();
self.build_int_to_float_cast(dst, src, int_width, FloatWidth::F32);
}
arg => todo!("NumToFrac: layout, arg {arg:?}, ret {:?}", Layout::F32),
}
}
fn num_to_f64(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>) {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
match self.layout_interner.get_repr(*arg_layout) {
LayoutRepr::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::I64)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
ASM::to_float_freg64_reg64(&mut self.buf, dst_reg, src_reg);
}
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::to_float_freg64_freg32(&mut self.buf, dst_reg, src_reg);
}
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::mov_freg64_freg64(&mut self.buf, dst_reg, src_reg);
}
LayoutRepr::Builtin(Builtin::Int(_)) => {
let int_width = arg_layout.to_int_width();
self.build_int_to_float_cast(dst, src, int_width, FloatWidth::F64);
}
arg => todo!("NumToFrac: layout, arg {arg:?}, ret {:?}", Layout::F64),
}
}

View file

@ -448,17 +448,26 @@ impl<
}
Stack(ReferencedPrimitive {
base_offset, size, ..
}) if base_offset % 8 == 0 && size == 8 => {
// The primitive is aligned and the data is exactly 8 bytes, treat it like regular stack.
let reg = self.get_float_reg(buf);
ASM::mov_freg64_base32(buf, reg, base_offset);
self.float_used_regs.push((reg, *sym));
self.symbol_storage_map.insert(*sym, Reg(Float(reg)));
self.free_reference(sym);
reg
}
Stack(ReferencedPrimitive { .. }) => {
todo!("loading referenced primitives")
}) => {
if base_offset % 8 == 0 && size == 8 {
// The primitive is aligned and the data is exactly 8 bytes, treat it like regular stack.
let reg = self.get_float_reg(buf);
ASM::mov_freg64_base32(buf, reg, base_offset);
self.float_used_regs.push((reg, *sym));
self.symbol_storage_map.insert(*sym, Reg(Float(reg)));
self.free_reference(sym);
reg
} else if base_offset % 4 == 0 && size == 4 {
// The primitive is aligned and the data is exactly 8 bytes, treat it like regular stack.
let reg = self.get_float_reg(buf);
ASM::mov_freg32_base32(buf, reg, base_offset);
self.float_used_regs.push((reg, *sym));
self.symbol_storage_map.insert(*sym, Reg(Float(reg)));
self.free_reference(sym);
reg
} else {
todo!("loading referenced primitives")
}
}
Stack(Complex { .. }) => {
internal_error!("Cannot load large values into float registers: {}", sym)
@ -570,12 +579,15 @@ impl<
}
Stack(ReferencedPrimitive {
base_offset, size, ..
}) if base_offset % 8 == 0 && *size == 8 => {
// The primitive is aligned and the data is exactly 8 bytes, treat it like regular stack.
ASM::mov_freg64_base32(buf, reg, *base_offset);
}
Stack(ReferencedPrimitive { .. }) => {
todo!("loading referenced primitives")
}) => {
if base_offset % 8 == 0 && *size == 8 {
// The primitive is aligned and the data is exactly 8 bytes, treat it like regular stack.
ASM::mov_freg64_base32(buf, reg, *base_offset);
} else if base_offset % 4 == 0 && *size == 4 {
ASM::mov_freg32_base32(buf, reg, *base_offset);
} else {
todo!("loading referenced primitives")
}
}
Stack(Complex { .. }) => {
internal_error!("Cannot load large values into float registers: {}", sym)

View file

@ -1,3 +1,6 @@
#![allow(clippy::redundant_closure_call)]
//|> clippy false positive: https://github.com/rust-lang/rust-clippy/issues/1553
use crate::generic64::{storage::StorageManager, Assembler, CallConv, RegTrait};
use crate::{
pointer_layouts, single_register_floats, single_register_int_builtins,
@ -2433,6 +2436,11 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
movsd_freg64_base64_offset32(buf, dst, X86_64GeneralReg::RBP, offset)
}
#[inline(always)]
fn mov_freg32_base32(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, offset: i32) {
movss_freg32_base32_offset32(buf, dst, X86_64GeneralReg::RBP, offset)
}
#[inline(always)]
fn mov_reg_base32(
buf: &mut Vec<'_, u8>,

View file

@ -358,27 +358,21 @@ trait Backend<'a> {
where
I: Iterator<Item = InLayout<'b>>,
{
use std::fmt::Write;
use std::hash::{BuildHasher, Hash, Hasher};
let symbol = name.name();
let mut buf = String::with_capacity(1024);
// NOTE: due to randomness, this will not be consistent between runs
let mut state = roc_collections::all::BuildHasher::default().build_hasher();
for a in arguments {
write!(buf, "{:?}", self.interner().dbg_stable(a)).expect("capacity");
a.hash(&mut state);
}
// lambda set should not matter; it should already be added as an argument
// but the niche of the lambda name may be the only thing differentiating two different
// implementations of a function with the same symbol
write!(buf, "{:?}", name.niche().dbg_stable(self.interner())).expect("capacity");
write!(buf, "{:?}", self.interner().dbg_stable(result)).expect("capacity");
// NOTE: due to randomness, this will not be consistent between runs
let mut state = roc_collections::all::BuildHasher::default().build_hasher();
buf.hash(&mut state);
name.niche().hash(&mut state);
result.hash(&mut state);
let interns = self.interns();
let ident_string = symbol.as_str(interns);
@ -1099,37 +1093,43 @@ trait Backend<'a> {
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
&bitcode::NUM_POW[float_width]
}
LayoutRepr::DEC => todo!("exponentiation for decimals"),
LayoutRepr::DEC => bitcode::DEC_POW,
_ => unreachable!("invalid layout for NumPow"),
};
self.build_fn_call(sym, intrinsic.to_string(), args, arg_layouts, ret_layout)
}
LowLevel::NumRound => {
let repr = self.interner().get_repr(*ret_layout);
let LayoutRepr::Builtin(Builtin::Int(int_width)) = repr else {
unreachable!("invalid return layout for NumRound")
};
let intrinsic = match arg_layouts[0] {
Layout::F32 => &bitcode::NUM_ROUND_F32[int_width],
Layout::F64 => &bitcode::NUM_ROUND_F64[int_width],
Layout::DEC => &bitcode::DEC_ROUND[int_width],
_ => unreachable!("invalid layout for NumRound"),
};
self.build_fn_call(sym, intrinsic.to_string(), args, arg_layouts, ret_layout)
}
LowLevel::NumFloor => {
let repr = self.interner().get_repr(*ret_layout);
let LayoutRepr::Builtin(Builtin::Int(int_width)) = repr else {
unreachable!("invalid return layout for NumFloor")
};
match arg_layouts[0] {
Layout::F32 => self.build_fn_call(
sym,
bitcode::NUM_FLOOR_F32[int_width].to_string(),
args,
arg_layouts,
ret_layout,
),
Layout::F64 => self.build_fn_call(
sym,
bitcode::NUM_FLOOR_F64[int_width].to_string(),
args,
arg_layouts,
ret_layout,
),
Layout::DEC => todo!("NumFloor for decimals"),
let intrinsic = match arg_layouts[0] {
Layout::F32 => &bitcode::NUM_FLOOR_F32[int_width],
Layout::F64 => &bitcode::NUM_FLOOR_F64[int_width],
Layout::DEC => &bitcode::DEC_FLOOR[int_width],
_ => unreachable!("invalid layout for NumFloor"),
}
};
self.build_fn_call(sym, intrinsic.to_string(), args, arg_layouts, ret_layout)
}
LowLevel::NumCeiling => {
@ -1138,24 +1138,14 @@ trait Backend<'a> {
unreachable!("invalid return layout for NumCeiling")
};
match arg_layouts[0] {
Layout::F32 => self.build_fn_call(
sym,
bitcode::NUM_CEILING_F32[int_width].to_string(),
args,
arg_layouts,
ret_layout,
),
Layout::F64 => self.build_fn_call(
sym,
bitcode::NUM_CEILING_F64[int_width].to_string(),
args,
arg_layouts,
ret_layout,
),
Layout::DEC => todo!("NumCeiling for decimals"),
let intrinsic = match arg_layouts[0] {
Layout::F32 => &bitcode::NUM_CEILING_F32[int_width],
Layout::F64 => &bitcode::NUM_CEILING_F64[int_width],
Layout::DEC => &bitcode::DEC_CEILING[int_width],
_ => unreachable!("invalid layout for NumCeiling"),
}
};
self.build_fn_call(sym, intrinsic.to_string(), args, arg_layouts, ret_layout)
}
LowLevel::NumSub => {
@ -1494,13 +1484,6 @@ trait Backend<'a> {
self.build_fn_call(sym, intrinsic.to_string(), args, arg_layouts, ret_layout)
}
LowLevel::NumRound => self.build_fn_call(
sym,
bitcode::NUM_ROUND_F64[IntWidth::I64].to_string(),
args,
arg_layouts,
ret_layout,
),
LowLevel::ListLen => {
debug_assert_eq!(
1,
@ -2019,6 +2002,23 @@ trait Backend<'a> {
self.build_num_cmp(sym, &args[0], &args[1], &arg_layouts[0]);
}
LowLevel::NumToFloatCast => {
let float_width = match *ret_layout {
Layout::F64 => FloatWidth::F64,
Layout::F32 => FloatWidth::F32,
_ => unreachable!("invalid return layout for NumToFloatCast"),
};
match arg_layouts[0].try_to_int_width() {
Some(int_width) => {
self.build_int_to_float_cast(sym, &args[0], int_width, float_width);
}
None => {
self.build_num_to_frac(sym, &args[0], &arg_layouts[0], ret_layout);
}
}
}
x => todo!("low level, {:?}", x),
}
}
@ -2135,6 +2135,14 @@ trait Backend<'a> {
target: IntWidth,
);
fn build_int_to_float_cast(
&mut self,
dst: &Symbol,
src: &Symbol,
int_width: IntWidth,
float_width: FloatWidth,
);
/// build_num_abs stores the absolute value of src into dst.
fn build_num_abs(&mut self, dst: &Symbol, src: &Symbol, layout: &InLayout<'a>);

View file

@ -29,6 +29,28 @@ pub fn build_module<'a, 'r>(
layout_interner: &'r mut STLayoutInterner<'a>,
target: &Triple,
procedures: MutMap<(symbol::Symbol, ProcLayout<'a>), Proc<'a>>,
) -> Object<'a> {
let module_object = build_module_help(env, interns, layout_interner, target, procedures);
if std::env::var("ROC_DEV_WRITE_OBJ").is_ok() {
let module_out = module_object
.write()
.expect("failed to build output object");
let file_path = std::env::temp_dir().join("app.o");
println!("gen-test object file written to {}", file_path.display());
std::fs::write(&file_path, module_out).expect("failed to write object to file");
}
module_object
}
fn build_module_help<'a, 'r>(
env: &'r Env<'a>,
interns: &'r mut Interns,
layout_interner: &'r mut STLayoutInterner<'a>,
target: &Triple,
procedures: MutMap<(symbol::Symbol, ProcLayout<'a>), Proc<'a>>,
) -> Object<'a> {
match target {
Triple {

View file

@ -4903,10 +4903,8 @@ fn expose_function_to_host_help_c_abi_v2<'a, 'ctx>(
Attribute::get_named_enum_kind_id("byval"),
c_abi_type.as_any_type_enum(),
);
let nonnull = context.create_type_attribute(
Attribute::get_named_enum_kind_id("nonnull"),
c_abi_type.as_any_type_enum(),
);
let nonnull = context
.create_enum_attribute(Attribute::get_named_enum_kind_id("nonnull"), 0);
// C return pointer goes at the beginning of params, and we must skip it if it exists.
let returns_pointer = matches!(cc_return, CCReturn::ByPointer);
let param_index = i as u32 + returns_pointer as u32;
@ -6753,9 +6751,7 @@ pub fn to_cc_return<'a>(
) -> CCReturn {
let return_size = layout_interner.stack_size(layout);
let pass_result_by_pointer = match env.target_info.operating_system {
roc_target::OperatingSystem::Windows => {
return_size >= 2 * env.target_info.ptr_width() as u32
}
roc_target::OperatingSystem::Windows => return_size > env.target_info.ptr_width() as u32,
roc_target::OperatingSystem::Unix => return_size > 2 * env.target_info.ptr_width() as u32,
roc_target::OperatingSystem::Wasi => return_size > 2 * env.target_info.ptr_width() as u32,
};

View file

@ -533,12 +533,6 @@ pub(crate) fn run_low_level<'a, 'ctx>(
bitcode::STR_COUNT_UTF8_BYTES,
)
}
StrGetCapacity => {
// Str.capacity : Str -> Nat
arguments!(string);
call_bitcode_fn(env, &[string], bitcode::STR_CAPACITY)
}
StrSubstringUnsafe => {
// Str.substringUnsafe : Str, Nat, Nat -> Str
arguments!(string, start, length);
@ -2059,6 +2053,54 @@ fn dec_unary_op<'ctx>(
}
}
fn dec_binary_op<'ctx>(
env: &Env<'_, 'ctx, '_>,
fn_name: &str,
dec1: BasicValueEnum<'ctx>,
dec2: BasicValueEnum<'ctx>,
) -> BasicValueEnum<'ctx> {
use roc_target::Architecture::*;
use roc_target::OperatingSystem::*;
let dec1 = dec1.into_int_value();
let dec2 = dec2.into_int_value();
match env.target_info {
TargetInfo {
architecture: X86_64 | X86_32,
operating_system: Unix,
} => {
let (low1, high1) = dec_split_into_words(env, dec1);
let (low2, high2) = dec_split_into_words(env, dec2);
let lowr_highr = call_bitcode_fn(
env,
&[low1.into(), high1.into(), low2.into(), high2.into()],
fn_name,
);
let block = env.builder.get_insert_block().expect("to be in a function");
let parent = block.get_parent().expect("to be in a function");
let ptr =
create_entry_block_alloca(env, parent, env.context.i128_type().into(), "to_i128");
env.builder.build_store(ptr, lowr_highr).unwrap();
env.builder
.build_load(env.context.i128_type(), ptr, "to_i128")
.unwrap()
}
TargetInfo {
architecture: Wasm32,
operating_system: Unix,
} => call_bitcode_fn(env, &[dec1.into(), dec2.into()], fn_name),
_ => call_bitcode_fn(
env,
&[dec_alloca(env, dec1), dec_alloca(env, dec2)],
fn_name,
),
}
}
fn dec_binop_with_overflow<'ctx>(
env: &Env<'_, 'ctx, '_>,
fn_name: &str,
@ -2189,11 +2231,13 @@ fn build_dec_unary_op<'a, 'ctx>(
_layout_interner: &STLayoutInterner<'a>,
_parent: FunctionValue<'ctx>,
arg: BasicValueEnum<'ctx>,
_return_layout: InLayout<'a>,
return_layout: InLayout<'a>,
op: LowLevel,
) -> BasicValueEnum<'ctx> {
use roc_module::low_level::LowLevel::*;
let int_width = || return_layout.to_int_width();
match op {
NumAbs => dec_unary_op(env, bitcode::DEC_ABS, arg),
NumAcos => dec_unary_op(env, bitcode::DEC_ACOS, arg),
@ -2203,6 +2247,10 @@ fn build_dec_unary_op<'a, 'ctx>(
NumSin => dec_unary_op(env, bitcode::DEC_SIN, arg),
NumTan => dec_unary_op(env, bitcode::DEC_TAN, arg),
NumRound => dec_unary_op(env, &bitcode::DEC_ROUND[int_width()], arg),
NumFloor => dec_unary_op(env, &bitcode::DEC_FLOOR[int_width()], arg),
NumCeiling => dec_unary_op(env, &bitcode::DEC_CEILING[int_width()], arg),
_ => {
unreachable!("Unrecognized dec unary operation: {:?}", op);
}
@ -2271,6 +2319,7 @@ fn build_dec_binop<'a, 'ctx>(
&[lhs, rhs],
&bitcode::NUM_GREATER_THAN_OR_EQUAL[IntWidth::I128],
),
NumPow => dec_binary_op(env, bitcode::DEC_POW, lhs, rhs),
_ => {
unreachable!("Unrecognized dec binary operation: {:?}", op);
}
@ -2684,42 +2733,39 @@ fn build_float_unary_op<'a, 'ctx>(
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
_ => internal_error!("Ceiling return layout is not int: {:?}", layout),
};
match float_width {
FloatWidth::F32 => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_CEILING_F32[int_width])
}
FloatWidth::F64 => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_CEILING_F64[int_width])
}
}
let intrinsic = match float_width {
FloatWidth::F32 => &bitcode::NUM_CEILING_F32[int_width],
FloatWidth::F64 => &bitcode::NUM_CEILING_F64[int_width],
};
call_bitcode_fn(env, &[arg.into()], intrinsic)
}
NumFloor => {
let int_width = match layout_interner.get_repr(layout) {
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
_ => internal_error!("Floor return layout is not int: {:?}", layout),
};
match float_width {
FloatWidth::F32 => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_FLOOR_F32[int_width])
}
FloatWidth::F64 => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_FLOOR_F64[int_width])
}
}
let intrinsic = match float_width {
FloatWidth::F32 => &bitcode::NUM_FLOOR_F32[int_width],
FloatWidth::F64 => &bitcode::NUM_FLOOR_F64[int_width],
};
call_bitcode_fn(env, &[arg.into()], intrinsic)
}
NumRound => {
let int_width = match layout_interner.get_repr(layout) {
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
_ => internal_error!("Round return layout is not int: {:?}", layout),
};
match float_width {
FloatWidth::F32 => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_ROUND_F32[int_width])
}
FloatWidth::F64 => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_ROUND_F64[int_width])
}
}
let intrinsic = match float_width {
FloatWidth::F32 => &bitcode::NUM_ROUND_F32[int_width],
FloatWidth::F64 => &bitcode::NUM_ROUND_F64[int_width],
};
call_bitcode_fn(env, &[arg.into()], intrinsic)
}
NumIsNan => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_IS_NAN[float_width]),
NumIsInfinite => {

View file

@ -128,7 +128,7 @@ macro_rules! run_jit_function {
Err((error_msg, _)) => {
eprintln!("This Roc code crashed with: \"{error_msg}\"");
Expr::MalformedClosure
Expr::REPL_RUNTIME_CRASH
}
}
}};
@ -165,10 +165,10 @@ macro_rules! run_jit_function_dynamic_type {
let result = Result::from(call_result);
match result {
Ok(()) => $transform(output.add(CALL_RESULT_WIDTH) as usize),
Err((msg, _crash_tag)) => {
eprintln!("{}", msg);
panic!("Roc hit an error");
Ok(()) => Some($transform(output.add(CALL_RESULT_WIDTH) as usize)),
Err((error_msg, _)) => {
eprintln!("This Roc code crashed with: \"{error_msg}\"");
None
}
}
}

View file

@ -204,7 +204,6 @@ impl<'a> LowLevelCall<'a> {
StrCountUtf8Bytes => {
self.load_args_and_call_zig(backend, bitcode::STR_COUNT_UTF8_BYTES)
}
StrGetCapacity => self.load_args_and_call_zig(backend, bitcode::STR_CAPACITY),
StrToNum => {
let number_layout = match backend.layout_interner.get_repr(self.ret_layout) {
LayoutRepr::Struct(field_layouts) => field_layouts[0],
@ -1585,6 +1584,10 @@ impl<'a> LowLevelCall<'a> {
LayoutRepr::Builtin(Builtin::Float(width)) => {
self.load_args_and_call_zig(backend, &bitcode::NUM_POW[width]);
}
LayoutRepr::Builtin(Builtin::Decimal) => {
self.load_args_and_call_zig(backend, bitcode::DEC_POW);
}
_ => panic_ret_type(),
},
@ -1636,6 +1639,7 @@ impl<'a> LowLevelCall<'a> {
match arg_type {
F32 => self.load_args_and_call_zig(backend, &bitcode::NUM_ROUND_F32[width]),
F64 => self.load_args_and_call_zig(backend, &bitcode::NUM_ROUND_F64[width]),
Decimal => self.load_args_and_call_zig(backend, &bitcode::DEC_ROUND[width]),
_ => internal_error!("Invalid argument type for round: {:?}", arg_type),
}
}
@ -1643,6 +1647,14 @@ impl<'a> LowLevelCall<'a> {
self.load_args(backend);
let arg_type = CodeGenNumType::for_symbol(backend, self.arguments[0]);
let ret_type = CodeGenNumType::from(self.ret_layout);
let width = match ret_type {
CodeGenNumType::I32 => IntWidth::I32,
CodeGenNumType::I64 => IntWidth::I64,
CodeGenNumType::I128 => todo!("{:?} for I128", self.lowlevel),
_ => internal_error!("Invalid return type for round: {:?}", ret_type),
};
match (arg_type, self.lowlevel) {
(F32, NumCeiling) => {
backend.code_builder.f32_ceil();
@ -1650,14 +1662,21 @@ impl<'a> LowLevelCall<'a> {
(F64, NumCeiling) => {
backend.code_builder.f64_ceil();
}
(Decimal, NumCeiling) => {
return self.load_args_and_call_zig(backend, &bitcode::DEC_CEILING[width]);
}
(F32, NumFloor) => {
backend.code_builder.f32_floor();
}
(F64, NumFloor) => {
backend.code_builder.f64_floor();
}
(Decimal, NumFloor) => {
return self.load_args_and_call_zig(backend, &bitcode::DEC_FLOOR[width]);
}
_ => internal_error!("Invalid argument type for ceiling: {:?}", arg_type),
}
match (ret_type, arg_type) {
// TODO: unsigned truncation
(I32, F32) => backend.code_builder.i32_trunc_s_f32(),

View file

@ -22,8 +22,21 @@ macro_rules! wasm32_sized_primitive {
}
}
wasm32_sized_primitive!(u8, i8, u16, i16, u32, i32, char, u64, i64, u128, i128, f32, f64, bool,);
wasm32_sized_primitive!(RocDec, RocOrder, I128, U128,);
wasm32_sized_primitive!(u8, i8, u16, i16, u32, i32, char, u64, i64, f32, f64, bool,);
wasm32_sized_primitive!(RocOrder,);
macro_rules! wasm32_16byte_aligned8 {
($($type_name:ident ,)+) => {
$(
impl Wasm32Sized for $type_name {
const SIZE_OF_WASM: usize = 16;
const ALIGN_OF_WASM: usize = 8;
}
)*
}
}
wasm32_16byte_aligned8!(i128, u128, I128, U128, RocDec,);
impl Wasm32Sized for () {
const SIZE_OF_WASM: usize = 0;
@ -75,19 +88,36 @@ impl Wasm32Sized for isize {
const ALIGN_OF_WASM: usize = 4;
}
const fn next_multiple_of(lhs: usize, rhs: usize) -> usize {
if lhs == 0 {
return lhs;
}
match lhs % rhs {
0 => lhs,
r => lhs + (rhs - r),
}
}
impl<T: Wasm32Sized, U: Wasm32Sized> Wasm32Sized for (T, U) {
const SIZE_OF_WASM: usize = T::SIZE_OF_WASM + U::SIZE_OF_WASM;
const SIZE_OF_WASM: usize =
next_multiple_of(T::SIZE_OF_WASM + U::SIZE_OF_WASM, Self::ALIGN_OF_WASM);
const ALIGN_OF_WASM: usize = max(&[T::ALIGN_OF_WASM, U::ALIGN_OF_WASM]);
}
impl<T: Wasm32Sized, U: Wasm32Sized, V: Wasm32Sized> Wasm32Sized for (T, U, V) {
const SIZE_OF_WASM: usize = T::SIZE_OF_WASM + U::SIZE_OF_WASM + V::SIZE_OF_WASM;
const SIZE_OF_WASM: usize = next_multiple_of(
T::SIZE_OF_WASM + U::SIZE_OF_WASM + V::SIZE_OF_WASM,
Self::ALIGN_OF_WASM,
);
const ALIGN_OF_WASM: usize = max(&[T::ALIGN_OF_WASM, U::ALIGN_OF_WASM, V::ALIGN_OF_WASM]);
}
impl<T: Wasm32Sized, U: Wasm32Sized, V: Wasm32Sized, W: Wasm32Sized> Wasm32Sized for (T, U, V, W) {
const SIZE_OF_WASM: usize =
T::SIZE_OF_WASM + U::SIZE_OF_WASM + V::SIZE_OF_WASM + W::SIZE_OF_WASM;
const SIZE_OF_WASM: usize = next_multiple_of(
T::SIZE_OF_WASM + U::SIZE_OF_WASM + V::SIZE_OF_WASM + W::SIZE_OF_WASM,
Self::ALIGN_OF_WASM,
);
const ALIGN_OF_WASM: usize = max(&[
T::ALIGN_OF_WASM,
U::ALIGN_OF_WASM,

View file

@ -5549,7 +5549,7 @@ mod test_reporting {
r#"
greeting = "Privet"
if Bool.true then 1 else "\(greeting), World!"
if Bool.true then 1 else "$(greeting), World!"
"#,
),
@r#"
@ -5557,7 +5557,7 @@ mod test_reporting {
This `if` has an `else` branch with a different type from its `then` branch:
6 if Bool.true then 1 else "\(greeting), World!"
6 if Bool.true then 1 else "$(greeting), World!"
^^^^^^^^^^^^^^^^^^^^^
The `else` branch is a string of type:

View file

@ -86,7 +86,7 @@ pub enum CalledVia {
UnaryOp(UnaryOp),
/// This call is the result of desugaring string interpolation,
/// e.g. "\(first) \(last)" is transformed into Str.concat (Str.concat first " ") last.
/// e.g. "$(first) $(last)" is transformed into Str.concat (Str.concat first " ") last.
StringInterpolation,
/// This call is the result of desugaring a Record Builder field.

View file

@ -24,7 +24,6 @@ pub enum LowLevel {
StrGetUnsafe,
StrSubstringUnsafe,
StrReserve,
StrGetCapacity,
StrWithCapacity,
StrReleaseExcessCapacity,
ListLen,
@ -271,7 +270,6 @@ map_symbol_to_lowlevel! {
StrSubstringUnsafe <= STR_SUBSTRING_UNSAFE;
StrReserve <= STR_RESERVE;
StrToNum <= STR_TO_NUM;
StrGetCapacity <= STR_CAPACITY;
StrWithCapacity <= STR_WITH_CAPACITY;
StrReleaseExcessCapacity <= STR_RELEASE_EXCESS_CAPACITY;
ListLen <= LIST_LEN;
@ -308,8 +306,8 @@ map_symbol_to_lowlevel! {
NumCompare <= NUM_COMPARE;
NumDivFrac <= NUM_DIV_FRAC;
NumDivCeilUnchecked <= NUM_DIV_CEIL;
NumDivTruncUnchecked <= NUM_DIV_TRUNC;
NumRemUnchecked <= NUM_REM;
NumDivTruncUnchecked <= NUM_DIV_TRUNC_UNCHECKED;
NumRemUnchecked <= NUM_REM_UNCHECKED;
NumIsMultipleOf <= NUM_IS_MULTIPLE_OF;
NumAbs <= NUM_ABS;
NumNeg <= NUM_NEG;

View file

@ -1275,6 +1275,8 @@ define_builtins! {
163 NUM_TAU: "tau"
164 NUM_BITWISE_NOT: "bitwiseNot"
165 NUM_IS_APPROX_EQ: "isApproxEq"
166 NUM_DIV_TRUNC_UNCHECKED: "divTruncUnchecked" // traps on division by zero
167 NUM_REM_UNCHECKED: "remUnchecked" // traps on division by zero
}
4 BOOL: "Bool" => {
0 BOOL_BOOL: "Bool" exposed_type=true // the Bool.Bool type alias

View file

@ -1533,8 +1533,8 @@ fn low_level_no_rc(lowlevel: &LowLevel) -> RC {
match lowlevel {
Unreachable => RC::Uknown,
ListLen | StrIsEmpty | StrCountUtf8Bytes | StrGetCapacity | ListGetCapacity
| ListWithCapacity | StrWithCapacity => RC::NoRc,
ListLen | StrIsEmpty | StrCountUtf8Bytes | ListGetCapacity | ListWithCapacity
| StrWithCapacity => RC::NoRc,
ListReplaceUnsafe => RC::Rc,
StrGetUnsafe | ListGetUnsafe => RC::NoRc,
ListConcat => RC::Rc,

View file

@ -1283,7 +1283,7 @@ fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[Ownership] {
match op {
Unreachable => arena.alloc_slice_copy(&[irrelevant]),
DictPseudoSeed => arena.alloc_slice_copy(&[irrelevant]),
ListLen | StrIsEmpty | StrCountUtf8Bytes | StrGetCapacity | ListGetCapacity => {
ListLen | StrIsEmpty | StrCountUtf8Bytes | ListGetCapacity => {
arena.alloc_slice_copy(&[borrowed])
}
ListWithCapacity | StrWithCapacity => arena.alloc_slice_copy(&[irrelevant]),

View file

@ -5156,6 +5156,21 @@ pub fn with_hole<'a>(
Err(_) => return runtime_error(env, "Can't update record with improper layout"),
};
let sorted_fields_filtered =
sorted_fields
.iter()
.filter_map(|(label, _, opt_field_layout)| {
match opt_field_layout {
Ok(_) => Some(label),
Err(_) => {
debug_assert!(!updates.contains_key(label));
// this was an optional field, and now does not exist!
None
}
}
});
let sorted_fields = Vec::from_iter_in(sorted_fields_filtered, env.arena);
let single_field_struct = sorted_fields.len() == 1;
// The struct indexing generated by the current context
@ -5164,44 +5179,38 @@ pub fn with_hole<'a>(
let mut new_struct_symbols = Vec::with_capacity_in(sorted_fields.len(), env.arena);
// Information about the fields that are being updated
let mut fields = Vec::with_capacity_in(sorted_fields.len(), env.arena);
let mut index = 0;
for (label, _, opt_field_layout) in sorted_fields.iter() {
let record_index = (structure, index);
match opt_field_layout {
Err(_) => {
debug_assert!(!updates.contains_key(label));
// this was an optional field, and now does not exist!
// do not increment `index`!
}
Ok(_field_layout) => {
current_struct_indexing.push(record_index);
// Create a symbol for each of the fields as they might be referenced later.
// The struct with a single field is optimized in such a way that replacing later indexing will cause an incorrect IR.
// Thus, only insert these struct_indices if there is more than one field in the struct.
if !single_field_struct {
for index in 0..sorted_fields.len() {
let record_index = (structure, index as u64);
// The struct with a single field is optimized in such a way that replacing later indexing will cause an incorrect IR.
// Thus, only insert these struct_indices if there is more than one field in the struct.
if !single_field_struct {
let original_struct_symbol = env.unique_symbol();
env.struct_indexing
.insert(record_index, original_struct_symbol);
}
if let Some(field) = updates.get(label) {
let new_struct_symbol = possible_reuse_symbol_or_specialize(
env,
procs,
layout_cache,
&field.loc_expr.value,
field.var,
);
new_struct_symbols.push(new_struct_symbol);
fields.push(UpdateExisting(field));
} else {
new_struct_symbols
.push(*env.struct_indexing.get(record_index).unwrap());
fields.push(CopyExisting);
}
current_struct_indexing.push(record_index);
index += 1;
}
let original_struct_symbol = env.unique_symbol();
env.struct_indexing
.insert(record_index, original_struct_symbol);
}
}
for (index, label) in sorted_fields.iter().enumerate() {
let record_index = (structure, index as u64);
if let Some(field) = updates.get(label) {
let new_struct_symbol = possible_reuse_symbol_or_specialize(
env,
procs,
layout_cache,
&field.loc_expr.value,
field.var,
);
new_struct_symbols.push(new_struct_symbol);
fields.push(UpdateExisting(field));
} else {
new_struct_symbols.push(*env.struct_indexing.get(record_index).unwrap());
fields.push(CopyExisting);
}
}

View file

@ -103,6 +103,13 @@ macro_rules! impl_to_from_int_width {
_ => roc_error_macros::internal_error!("not an integer layout!")
}
}
pub fn try_to_int_width(&self) -> Option<IntWidth> {
match self {
$(&$layout => Some($int_width),)*
_ => None,
}
}
}
};
}

View file

@ -1296,6 +1296,16 @@ impl<'a> Spaceable<'a> for ImplementsAbilities<'a> {
}
impl<'a> Expr<'a> {
pub const REPL_OPAQUE_FUNCTION: Self = Expr::Var {
module_name: "",
ident: "<function>",
};
pub const REPL_RUNTIME_CRASH: Self = Expr::Var {
module_name: "",
ident: "*",
};
pub fn loc_ref(&'a self, region: Region) -> Loc<&'a Self> {
Loc {
region,

View file

@ -173,6 +173,8 @@ pub fn parse_str_like_literal<'a>() -> impl Parser<'a, StrLikeLiteral<'a>, EStri
};
}
let mut preceded_by_dollar = false;
while let Some(&byte) = bytes.next() {
// This is for the byte we just grabbed from the iterator.
segment_parsed_bytes += 1;
@ -349,68 +351,6 @@ pub fn parse_str_like_literal<'a>() -> impl Parser<'a, StrLikeLiteral<'a>, EStri
return Err((MadeProgress, EString::EndlessSingleLine(start_state.pos())));
}
}
b'$' if !is_single_quote => {
// This is for the byte we're about to parse.
segment_parsed_bytes += 1;
// iff the '$' is followed by '(', this is string interpolation.
if let Some(b'(') = bytes.next() {
// We're about to begin string interpolation!
//
// End the previous segment so we can begin a new one.
// Retroactively end it right before the `$` char we parsed.
// (We can't use end_segment! here because it ends it right after
// the just-parsed character, which here would be '(' rather than '$')
// Don't push anything if the string would be empty.
if segment_parsed_bytes > 2 {
// exclude the 2 chars we just parsed, namely '$' and '('
let string_bytes = &state.bytes()[0..(segment_parsed_bytes - 2)];
match std::str::from_utf8(string_bytes) {
Ok(string) => {
state.advance_mut(string.len());
segments.push(StrSegment::Plaintext(string));
}
Err(_) => {
return Err((
MadeProgress,
EString::Space(BadInputError::BadUtf8, state.pos()),
));
}
}
}
// Advance past the `$(`
state.advance_mut(2);
let original_byte_count = state.bytes().len();
// Parse an arbitrary expression, followed by ')'
let (_progress, loc_expr, new_state) = skip_second!(
specialize_ref(
EString::Format,
loc(allocated(reset_min_indent(expr::expr_help())))
),
word1(b')', EString::FormatEnd)
)
.parse(arena, state, min_indent)?;
// Advance the iterator past the expr we just parsed.
for _ in 0..(original_byte_count - new_state.bytes().len()) {
bytes.next();
}
segments.push(StrSegment::Interpolated(loc_expr));
// Reset the segment
segment_parsed_bytes = 0;
state = new_state;
}
// If the '$' wasn't followed by '(', then this wasn't interpolation,
// and we don't need to do anything special.
}
b'\\' => {
// We're about to begin an escaped segment of some sort!
//
@ -510,10 +450,67 @@ pub fn parse_str_like_literal<'a>() -> impl Parser<'a, StrLikeLiteral<'a>, EStri
}
}
}
b'(' if preceded_by_dollar && !is_single_quote => {
// We're about to begin string interpolation!
//
// End the previous segment so we can begin a new one.
// Retroactively end it right before the `$` char we parsed.
// (We can't use end_segment! here because it ends it right after
// the just-parsed character, which here would be '(' rather than '$')
// Don't push anything if the string would be empty.
if segment_parsed_bytes > 2 {
// exclude the 2 chars we just parsed, namely '$' and '('
let string_bytes = &state.bytes()[0..(segment_parsed_bytes - 2)];
match std::str::from_utf8(string_bytes) {
Ok(string) => {
state.advance_mut(string.len());
segments.push(StrSegment::Plaintext(string));
}
Err(_) => {
return Err((
MadeProgress,
EString::Space(BadInputError::BadUtf8, state.pos()),
));
}
}
}
// Advance past the `$(`
state.advance_mut(2);
let original_byte_count = state.bytes().len();
// Parse an arbitrary expression, followed by ')'
let (_progress, loc_expr, new_state) = skip_second!(
specialize_ref(
EString::Format,
loc(allocated(reset_min_indent(expr::expr_help())))
),
word1(b')', EString::FormatEnd)
)
.parse(arena, state, min_indent)?;
// Advance the iterator past the expr we just parsed.
for _ in 0..(original_byte_count - new_state.bytes().len()) {
bytes.next();
}
segments.push(StrSegment::Interpolated(loc_expr));
// Reset the segment
segment_parsed_bytes = 0;
state = new_state;
}
_ => {
// All other characters need no special handling.
}
}
// iff the '$' is followed by '(', this is string interpolation.
// We'll check for the '(' on the next iteration of the loop.
preceded_by_dollar = byte == b'$';
}
// We ran out of characters before finding a closed quote

View file

@ -200,6 +200,36 @@ mod test_parse {
});
}
#[test]
fn string_of_just_dollar_sign() {
let arena = Bump::new();
assert_eq!(
Ok(Expr::Str(PlainLine("$"))),
parse_expr_with(&arena, arena.alloc(r#""$""#))
);
}
#[test]
fn string_beginning_with_dollar() {
let arena = Bump::new();
assert_eq!(
Ok(Expr::Str(PlainLine("$foo"))),
parse_expr_with(&arena, arena.alloc(r#""$foo""#))
);
}
#[test]
fn string_ending_with_dollar() {
let arena = Bump::new();
assert_eq!(
Ok(Expr::Str(PlainLine("foo$"))),
parse_expr_with(&arena, arena.alloc(r#""foo$""#))
);
}
#[test]
fn string_with_interpolation_in_back() {
assert_segments(r#""Hello $(name)""#, |arena| {

View file

@ -312,7 +312,7 @@ mod solve_expr {
r#"
whatItIs = "great"
"type inference is \(whatItIs)!"
"type inference is $(whatItIs)!"
"#
),
"Str",
@ -326,7 +326,7 @@ mod solve_expr {
r#"
whatItIs = "great"
str = "type inference is \(whatItIs)!"
str = "type inference is $(whatItIs)!"
whatItIs
"#
@ -342,7 +342,7 @@ mod solve_expr {
r#"
rec = { whatItIs: "great" }
str = "type inference is \(rec.whatItIs)!"
str = "type inference is $(rec.whatItIs)!"
rec
"#
@ -4739,7 +4739,7 @@ mod solve_expr {
r#"
setRocEmail : _ -> { name: Str, email: Str }_
setRocEmail = \person ->
{ person & email: "\(person.name)@roclang.com" }
{ person & email: "$(person.name)@roclang.com" }
setRocEmail
"#
),

View file

@ -948,7 +948,7 @@ fn specialize_unique_newtype_records() {
main =
when Str.fromUtf8 (Encode.toBytes {a: Bool.true} TotallyNotJson.json) is
Ok s -> when Str.fromUtf8 (Encode.toBytes {b: Bool.true} TotallyNotJson.json) is
Ok t -> "\(s)\(t)"
Ok t -> "$(s)$(t)"
_ -> "<bad>"
_ -> "<bad>"
"#

View file

@ -330,7 +330,7 @@ fn list_map_try_ok() {
List.mapTry [1, 2, 3] \num ->
str = Num.toStr (num * 2)
Ok "\(str)!"
Ok "$(str)!"
"#,
// Result Str [] is unwrapped to just Str
RocList::<RocStr>::from_slice(&[
@ -821,6 +821,30 @@ fn list_append_longer_list() {
);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn list_append_record() {
assert_evals_to!(
indoc!(
r#"
[
{ name: "foo", content: "cfoo" },
{ name: "bar", content: "cbar" },
{ name: "baz", content: "cbaz" },
]
|> List.append { name: "spam", content: "cspam" }
"#
),
RocList::from_slice(&[
(RocStr::from("cfoo"), RocStr::from("foo"),),
(RocStr::from("cbar"), RocStr::from("bar"),),
(RocStr::from("cbaz"), RocStr::from("baz"),),
(RocStr::from("cspam"), RocStr::from("spam"),),
]),
RocList<(RocStr, RocStr)>
);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn list_prepend() {
@ -886,6 +910,25 @@ fn list_prepend_big_list() {
);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn list_prepend_record() {
assert_evals_to!(
indoc!(
r"
payment1 : { amount: Dec, date: [RD I32] }
payment1 = { amount: 1dec, date: (RD 1000) }
payment2 : { amount: Dec, date: [RD I32] }
payment2 = { amount: 2dec, date: (RD 1001) }
List.prepend [payment2] payment1
"
),
RocList::from_slice(&[(RocDec::from(1), 1000i32), (RocDec::from(2), 1001i32),]),
RocList<(RocDec, i32)>
);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn list_walk_backwards_empty_all_inline() {
@ -3695,10 +3738,10 @@ fn issue_3571_lowlevel_call_function_with_bool_lambda_set() {
List.concat state mappedVals
add2 : Str -> Str
add2 = \x -> "added \(x)"
add2 = \x -> "added $(x)"
mul2 : Str -> Str
mul2 = \x -> "multiplied \(x)"
mul2 = \x -> "multiplied $(x)"
foo = [add2, mul2]
bar = ["1", "2", "3", "4"]

View file

@ -1154,19 +1154,20 @@ fn gen_div_u64() {
assert_evals_to!("1000u64 // 10", 100, u64);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
#[should_panic(expected = r#"User crash with message: "Integer division by 0!"#)]
fn gen_div_by_zero_i64() {
assert_evals_to!("1i64 // 0", 100, i64);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn gen_div_checked_i64() {
assert_evals_to!(
indoc!(
r"
when Num.divTruncChecked 1000 10 is
Ok val -> val
Err _ -> -1
"
),
100,
i64
"Num.divTruncChecked 1000 10",
RocResult::ok(100),
RocResult<i64, ()>
);
}
@ -1174,15 +1175,9 @@ fn gen_div_checked_i64() {
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn gen_div_checked_by_zero_i64() {
assert_evals_to!(
indoc!(
r"
when Num.divTruncChecked 1000 0 is
Err DivByZero -> 99
_ -> -24
"
),
99,
i64
"Num.divTruncChecked 1000 0",
RocResult::err(()),
RocResult<i64, ()>
);
}
@ -1192,19 +1187,30 @@ fn gen_rem_i64() {
assert_evals_to!("Num.rem 8 3", 2, i64);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
#[should_panic(expected = r#"User crash with message: "Integer division by 0!"#)]
fn gen_rem_div_by_zero_i64() {
assert_evals_to!("Num.rem 42 0", 100, i64);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn gen_rem_checked_i64() {
assert_evals_to!(
"Num.remChecked 42 40",
RocResult::ok(2),
RocResult<i64, ()>
);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn gen_rem_checked_div_by_zero_i64() {
assert_evals_to!(
indoc!(
r"
when Num.remChecked 8 0 is
Err DivByZero -> 4
Ok _ -> -23
"
),
4,
i64
"Num.remChecked 8 0",
RocResult::err(()),
RocResult<i64, ()>
);
}
@ -1819,21 +1825,68 @@ fn float_compare() {
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn pow() {
fn pow_f64() {
assert_evals_to!("Num.pow 2.0f64 2.0f64", 4.0, f64);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn ceiling() {
assert_evals_to!("Num.ceiling 1.1f64", 2, i64);
fn pow_dec() {
assert_evals_to!("Num.pow 2.0dec 2.0dec", RocDec::from(4), RocDec);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn floor() {
fn round_f64() {
assert_evals_to!("Num.round 1.9f64", 2, i64);
assert_evals_to!("Num.round -1.9f64", -2, i64);
assert_evals_to!("Num.round 0.5f64", 1, i64);
assert_evals_to!("Num.round -0.5f64", -1, i64);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn round_dec() {
assert_evals_to!("Num.round 1.9dec", 2, i64);
assert_evals_to!("Num.round -1.9dec", -2, i64);
assert_evals_to!("Num.round 0.5dec", 1, i64);
assert_evals_to!("Num.round -0.5dec", -1, i64);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn ceiling_f64() {
assert_evals_to!("Num.ceiling 1.9f64", 2, i64);
assert_evals_to!("Num.ceiling -1.9f64", -1, i64);
assert_evals_to!("Num.ceiling 0.5f64", 1, i64);
assert_evals_to!("Num.ceiling -0.5f64", 0, i64);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn ceiling_dec() {
assert_evals_to!("Num.ceiling 1.9dec", 2, i64);
assert_evals_to!("Num.ceiling -1.9dec", -1, i64);
assert_evals_to!("Num.ceiling 0.5dec", 1, i64);
assert_evals_to!("Num.ceiling -0.5dec", 0, i64);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn floor_f64() {
assert_evals_to!("Num.floor 1.9f64", 1, i64);
assert_evals_to!("Num.floor -1.9f64", -2, i64);
assert_evals_to!("Num.floor 0.5f64", 0, i64);
assert_evals_to!("Num.floor -0.5f64", -1, i64);
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn floor_dec() {
assert_evals_to!("Num.floor 1.9dec", 1, i64);
assert_evals_to!("Num.floor -1.9dec", -2, i64);
assert_evals_to!("Num.floor 0.5dec", 0, i64);
assert_evals_to!("Num.floor -0.5dec", -1, i64);
}
#[test]
@ -2320,7 +2373,7 @@ num_conversion_tests! {
to_i64_truncate_wraps, "10_000_000_000_000_000_000i128", -8446744073709551616
)
"Num.toI128", i128, (
to_i128_same_width, "15u128", 15
to_i128_same_width, "15u128", 15, ["gen-dev"]
to_i128_extend, "15i8", 15
)
"Num.toU8", u8, (
@ -2347,8 +2400,9 @@ num_conversion_tests! {
to_u64_truncate_wraps, "10_000_000_000_000_000_000_000i128", 1864712049423024128
)
"Num.toU128", u128, (
to_u128_same_width, "15i128", 15
to_u128_same_width, "15i128", 15, ["gen-dev"]
to_u128_extend, "15i8", 15
to_u128_big, "11562537357600483583u64", 11562537357600483583, ["gen-dev"]
)
"Num.toNat", usize, (
to_nat_same_width, "15i64", 15, ["gen-wasm", "gen-dev"]
@ -2356,34 +2410,34 @@ num_conversion_tests! {
to_nat_truncate, "115i128", 115
)
"Num.toF32", f32, (
to_f32_from_i8, "15i8", 15.0
to_f32_from_i16, "15i16", 15.0
to_f32_from_i32, "15i32", 15.0
to_f32_from_i64, "15i64", 15.0
to_f32_from_i128, "15i128", 15.0
to_f32_from_u8, "15u8", 15.0
to_f32_from_u16, "15u16", 15.0
to_f32_from_u32, "15u32", 15.0
to_f32_from_u64, "15u64", 15.0
to_f32_from_u128, "15u128", 15.0
to_f32_from_nat, "15nat", 15.0
to_f32_from_f32, "1.5f32", 1.5
to_f32_from_f64, "1.5f64", 1.5
to_f32_from_i8, "15i8", 15.0, ["gen-wasm", "gen-dev"]
to_f32_from_i16, "15i16", 15.0, ["gen-wasm", "gen-dev"]
to_f32_from_i32, "15i32", 15.0, ["gen-wasm", "gen-dev"]
to_f32_from_i64, "15i64", 15.0, ["gen-wasm", "gen-dev"]
to_f32_from_i128, "15i128", 15.0, ["gen-dev"]
to_f32_from_u8, "15u8", 15.0, ["gen-wasm", "gen-dev"]
to_f32_from_u16, "15u16", 15.0, ["gen-wasm", "gen-dev"]
to_f32_from_u32, "15u32", 15.0, ["gen-wasm", "gen-dev"]
to_f32_from_u64, "15u64", 15.0, ["gen-wasm", "gen-dev"]
to_f32_from_u128, "15u128", 15.0, ["gen-dev"]
to_f32_from_nat, "15nat", 15.0, ["gen-wasm", "gen-dev"]
to_f32_from_f32, "1.5f32", 1.5, ["gen-wasm", "gen-dev"]
to_f32_from_f64, "1.5f64", 1.5, ["gen-wasm", "gen-dev"]
)
"Num.toF64", f64, (
to_f64_from_i8, "15i8", 15.0
to_f64_from_i16, "15i16", 15.0
to_f64_from_i32, "15i32", 15.0
to_f64_from_i64, "15i64", 15.0
to_f64_from_i128, "15i128", 15.0
to_f64_from_u8, "15u8", 15.0
to_f64_from_u16, "15u16", 15.0
to_f64_from_u32, "15u32", 15.0
to_f64_from_u64, "15u64", 15.0
to_f64_from_u128, "15u128", 15.0
to_f64_from_nat, "15nat", 15.0
to_f64_from_f32, "1.5f32", 1.5
to_f64_from_f64, "1.5f64", 1.5
to_f64_from_i8, "15i8", 15.0, ["gen-wasm", "gen-dev"]
to_f64_from_i16, "15i16", 15.0, ["gen-wasm", "gen-dev"]
to_f64_from_i32, "15i32", 15.0, ["gen-wasm", "gen-dev"]
to_f64_from_i64, "15i64", 15.0, ["gen-wasm", "gen-dev"]
to_f64_from_i128, "15i128", 15.0, ["gen-dev"]
to_f64_from_u8, "15u8", 15.0, ["gen-wasm", "gen-dev"]
to_f64_from_u16, "15u16", 15.0, ["gen-wasm", "gen-dev"]
to_f64_from_u32, "15u32", 15.0, ["gen-wasm", "gen-dev"]
to_f64_from_u64, "15u64", 15.0, ["gen-wasm", "gen-dev"]
to_f64_from_u128, "15u128", 15.0, ["gen-dev"]
to_f64_from_nat, "15nat", 15.0, ["gen-wasm", "gen-dev"]
to_f64_from_f32, "1.5f32", 1.5, ["gen-dev"]
to_f64_from_f64, "1.5f64", 1.5, ["gen-wasm", "gen-dev"]
)
}
@ -3457,7 +3511,7 @@ fn monomorphized_ints_aliased() {
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn to_float_f32() {
assert_evals_to!(
indoc!(
@ -3476,7 +3530,7 @@ fn to_float_f32() {
}
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
fn to_float_f64() {
assert_evals_to!(
indoc!(

View file

@ -3197,7 +3197,7 @@ fn recursively_build_effect() {
hi = "Hello"
name = "World"
"\(hi), \(name)!"
"$(hi), $(name)!"
main =
when nestHelp 4 is
@ -3953,8 +3953,8 @@ fn compose_recursive_lambda_set_productive_toplevel() {
compose = \f, g -> \x -> g (f x)
identity = \x -> x
exclaim = \s -> "\(s)!"
whisper = \s -> "(\(s))"
exclaim = \s -> "$(s)!"
whisper = \s -> "($(s))"
main =
res: Str -> Str
@ -3976,8 +3976,8 @@ fn compose_recursive_lambda_set_productive_nested() {
compose = \f, g -> \x -> g (f x)
identity = \x -> x
exclaim = \s -> "\(s)!"
whisper = \s -> "(\(s))"
exclaim = \s -> "$(s)!"
whisper = \s -> "($(s))"
res: Str -> Str
res = List.walk [ exclaim, whisper ] identity compose
@ -3998,8 +3998,8 @@ fn compose_recursive_lambda_set_productive_inferred() {
compose = \f, g -> \x -> g (f x)
identity = \x -> x
exclaim = \s -> "\(s)!"
whisper = \s -> "(\(s))"
exclaim = \s -> "$(s)!"
whisper = \s -> "($(s))"
res = List.walk [ exclaim, whisper ] identity compose
res "hello"
@ -4024,8 +4024,8 @@ fn compose_recursive_lambda_set_productive_nullable_wrapped() {
else \x -> f (g x)
identity = \x -> x
exclame = \s -> "\(s)!"
whisper = \s -> "(\(s))"
exclame = \s -> "$(s)!"
whisper = \s -> "($(s))"
main =
res: Str -> Str
@ -4552,7 +4552,7 @@ fn reset_recursive_type_wraps_in_named_type() {
Cons x xs ->
strX = f x
strXs = printLinkedList xs f
"Cons \(strX) (\(strXs))"
"Cons $(strX) ($(strXs))"
"#
),
RocStr::from("Cons 2 (Cons 3 (Cons 4 (Nil)))"),

View file

@ -1741,11 +1741,11 @@ fn str_walk_utf8() {
assert_evals_to!(
indoc!(
r#"
Str.walkUtf8WithIndex "abcd" [] (\list, byte, index -> List.append list (Pair index byte))
Str.walkUtf8 "abcd" [] (\list, byte -> List.prepend list byte)
"#
),
RocList::from_slice(&[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]),
RocList<(u32, char)>
RocList::from_slice(&[b'd', b'c', b'b', b'a']),
RocList<u8>
);
}

View file

@ -215,12 +215,6 @@ pub fn helper(
let builtins_host_tempfile =
roc_bitcode::host_tempfile().expect("failed to write host builtins object to tempfile");
if std::env::var("ROC_DEV_WRITE_OBJ").is_ok() {
let file_path = std::env::temp_dir().join("app.o");
println!("gen-test object file written to {}", file_path.display());
std::fs::copy(&app_o_file, file_path).unwrap();
}
let (mut child, dylib_path) = link(
&target,
app_o_file.clone(),

View file

@ -91,15 +91,11 @@ impl<T: FromWasm32Memory + Clone> FromWasm32Memory for RocList<T> {
let capacity =
<u32 as FromWasm32Memory>::decode(memory, offset + 4 * Builtin::WRAPPER_CAPACITY);
let mut items = Vec::with_capacity(length as usize);
let step = <T as Wasm32Sized>::SIZE_OF_WASM;
for i in 0..length {
let item = <T as FromWasm32Memory>::decode(
memory,
elements + i * <T as Wasm32Sized>::SIZE_OF_WASM as u32,
);
items.push(item);
}
let items: Vec<_> = (0..length)
.map(|i| <T as FromWasm32Memory>::decode(memory, elements + i * step as u32))
.collect();
let mut list = RocList::with_capacity(capacity as usize);
list.extend_from_slice(&items);

View file

@ -78,16 +78,16 @@ procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
jump List.591 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.300 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.300;
let Num.306 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.306;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.299 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.299;
let Num.305 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.305;
procedure Num.77 (#Attr.2, #Attr.3):
let Num.298 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.304;
procedure Test.1 (Test.2):
let Test.13 : U64 = 0i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Test.4 (Test.27):
let Test.39 : [<rnu>C [<rnu><null>, C *self *self] *self, <null>] = TagId(0) ;

View file

@ -28,12 +28,12 @@ procedure List.90 (#Derived_gen.3, #Derived_gen.4, #Derived_gen.5, #Derived_gen.
jump List.574 #Derived_gen.3 #Derived_gen.4 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.298 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.304;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.297 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.303;
procedure Test.10 (Test.69, #Attr.12):
let Test.72 : {} = UnionAtIndex (Id 0) (Index 0) #Attr.12;

View file

@ -47,8 +47,8 @@ procedure List.9 (List.333):
ret List.573;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.297 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.303;
procedure Result.5 (Result.12, Result.13):
let Result.39 : U8 = 1i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.298 : I128 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : I128 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.304;
procedure Test.0 ():
let Test.6 : I128 = 18446744073709551616i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : U128 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U128 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Test.0 ():
let Test.2 : U128 = 170141183460469231731687303715884105728u128;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Test.0 ():
let Test.2 : U64 = 9999999999999999999i64;

View file

@ -32,12 +32,12 @@ procedure List.90 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
jump List.574 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.298 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.304;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.297 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.303;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.253 : Str = lowlevel StrConcat #Attr.2 #Attr.3;

View file

@ -30,8 +30,8 @@ procedure List.6 (#Attr.2):
ret List.571;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.297 : U8 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U8 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.303;
procedure Test.0 ():
let Test.3 : {} = Struct {};

View file

@ -25,8 +25,8 @@ procedure List.66 (#Attr.2, #Attr.3):
ret List.576;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.297 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.303;
procedure Test.2 (Test.5):
dec Test.5;

View file

@ -250,40 +250,40 @@ procedure List.90 (#Derived_gen.45, #Derived_gen.46, #Derived_gen.47, #Derived_g
jump List.629 #Derived_gen.45 #Derived_gen.46 #Derived_gen.47 #Derived_gen.48 #Derived_gen.49;
procedure Num.127 (#Attr.2):
let Num.312 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.312;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.316 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.316;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.313 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.313;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.318 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
let Num.318 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.318;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.324 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.322 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.322;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.319 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.319;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.324 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.324;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.330 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.330;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.326 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.326;
let Num.332 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.332;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.321 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.321;
let Num.327 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.327;
procedure Num.75 (#Attr.2, #Attr.3):
let Num.325 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.325;
let Num.331 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.331;
procedure Num.94 (#Attr.2, #Attr.3):
let Num.317 : U64 = lowlevel NumDivCeilUnchecked #Attr.2 #Attr.3;
ret Num.317;
let Num.323 : U64 = lowlevel NumDivCeilUnchecked #Attr.2 #Attr.3;
ret Num.323;
procedure Str.12 (#Attr.2):
let Str.263 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -193,40 +193,40 @@ procedure List.90 (#Derived_gen.26, #Derived_gen.27, #Derived_gen.28, #Derived_g
jump List.595 #Derived_gen.26 #Derived_gen.27 #Derived_gen.28 #Derived_gen.29 #Derived_gen.30;
procedure Num.127 (#Attr.2):
let Num.302 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.302;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.306 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.306;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.303 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.303;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.308 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
let Num.308 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.308;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.314 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.312 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.312;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.309 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.309;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.314 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.314;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.320 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.320;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.316 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.316;
let Num.322 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.322;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.311 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.311;
let Num.317 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.317;
procedure Num.75 (#Attr.2, #Attr.3):
let Num.315 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.315;
let Num.321 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.321;
procedure Num.94 (#Attr.2, #Attr.3):
let Num.307 : U64 = lowlevel NumDivCeilUnchecked #Attr.2 #Attr.3;
ret Num.307;
let Num.313 : U64 = lowlevel NumDivCeilUnchecked #Attr.2 #Attr.3;
ret Num.313;
procedure Str.12 (#Attr.2):
let Str.262 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -200,40 +200,40 @@ procedure List.90 (#Derived_gen.30, #Derived_gen.31, #Derived_gen.32, #Derived_g
jump List.595 #Derived_gen.30 #Derived_gen.31 #Derived_gen.32 #Derived_gen.33 #Derived_gen.34;
procedure Num.127 (#Attr.2):
let Num.302 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.302;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.306 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.306;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.303 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.303;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.308 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
let Num.308 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.308;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.314 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.312 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.312;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.309 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.309;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.314 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.314;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.320 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.320;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.316 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.316;
let Num.322 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.322;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.311 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.311;
let Num.317 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.317;
procedure Num.75 (#Attr.2, #Attr.3):
let Num.315 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.315;
let Num.321 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.321;
procedure Num.94 (#Attr.2, #Attr.3):
let Num.307 : U64 = lowlevel NumDivCeilUnchecked #Attr.2 #Attr.3;
ret Num.307;
let Num.313 : U64 = lowlevel NumDivCeilUnchecked #Attr.2 #Attr.3;
ret Num.313;
procedure Str.12 (#Attr.2):
let Str.262 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -122,32 +122,32 @@ procedure List.90 (#Derived_gen.8, #Derived_gen.9, #Derived_gen.10, #Derived_gen
jump List.587 #Derived_gen.8 #Derived_gen.9 #Derived_gen.10 #Derived_gen.11 #Derived_gen.12;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.298 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.298;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.300 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.300;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.304 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
let Num.304 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.304;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.306 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.306 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.306;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.310 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.310;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.312 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.312;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.302 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.302;
let Num.308 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.308;
procedure Num.75 (#Attr.2, #Attr.3):
let Num.305 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.305;
let Num.311 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.311;
procedure Num.94 (#Attr.2, #Attr.3):
let Num.299 : U64 = lowlevel NumDivCeilUnchecked #Attr.2 #Attr.3;
ret Num.299;
let Num.305 : U64 = lowlevel NumDivCeilUnchecked #Attr.2 #Attr.3;
ret Num.305;
procedure Str.12 (#Attr.2):
let Str.261 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -195,40 +195,40 @@ procedure List.90 (#Derived_gen.18, #Derived_gen.19, #Derived_gen.20, #Derived_g
jump List.601 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21 #Derived_gen.22;
procedure Num.127 (#Attr.2):
let Num.304 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.304;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.308 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.308;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.305 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.305;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.310 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
let Num.310 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.310;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.316 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.314 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.314;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.311 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.311;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.316 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.316;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.322 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.322;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.318 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.318;
let Num.324 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.324;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.313 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.313;
let Num.319 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.319;
procedure Num.75 (#Attr.2, #Attr.3):
let Num.317 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.317;
let Num.323 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.323;
procedure Num.94 (#Attr.2, #Attr.3):
let Num.309 : U64 = lowlevel NumDivCeilUnchecked #Attr.2 #Attr.3;
ret Num.309;
let Num.315 : U64 = lowlevel NumDivCeilUnchecked #Attr.2 #Attr.3;
ret Num.315;
procedure Str.12 (#Attr.2):
let Str.262 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -198,40 +198,40 @@ procedure List.90 (#Derived_gen.24, #Derived_gen.25, #Derived_gen.26, #Derived_g
jump List.613 #Derived_gen.24 #Derived_gen.25 #Derived_gen.26 #Derived_gen.27 #Derived_gen.28;
procedure Num.127 (#Attr.2):
let Num.304 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.304;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.308 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.308;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.305 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.305;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.310 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
let Num.310 : U8 = lowlevel NumIntCast #Attr.2;
ret Num.310;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.316 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.314 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.314;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.311 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.311;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.316 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.316;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.322 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.322;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.318 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.318;
let Num.324 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.324;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.313 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.313;
let Num.319 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.319;
procedure Num.75 (#Attr.2, #Attr.3):
let Num.317 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.317;
let Num.323 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.323;
procedure Num.94 (#Attr.2, #Attr.3):
let Num.309 : U64 = lowlevel NumDivCeilUnchecked #Attr.2 #Attr.3;
ret Num.309;
let Num.315 : U64 = lowlevel NumDivCeilUnchecked #Attr.2 #Attr.3;
ret Num.315;
procedure Str.12 (#Attr.2):
let Str.262 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -1,10 +1,10 @@
procedure Num.20 (#Attr.2, #Attr.3):
let Num.298 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.304;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.297 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.303;
procedure Test.1 (#Derived_gen.0, #Derived_gen.1):
joinpoint Test.7 Test.2 Test.3:

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Test.1 (Test.8):
let Test.3 : I64 = 10i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.298 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.304;
procedure Test.1 (Test.9):
let Test.4 : U8 = 10i64;

View file

@ -3,8 +3,8 @@ procedure Bool.1 ():
ret Bool.23;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Test.3 (Test.4):
ret Test.4;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.299 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.299;
let Num.305 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.305;
procedure Test.2 (Test.3):
switch Test.3:

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.298 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.304;
procedure Test.2 (Test.3, Test.1):
let Test.18 : Int1 = false;

View file

@ -45,8 +45,8 @@ procedure Dict.1 (Dict.726):
procedure Dict.10 (Dict.727, Dict.180, Dict.181):
let Dict.179 : List {Str, I64} = StructAtIndex 1 Dict.727;
let #Derived_gen.68 : List {U32, U32} = StructAtIndex 0 Dict.727;
dec #Derived_gen.68;
let #Derived_gen.66 : List {U32, U32} = StructAtIndex 0 Dict.727;
dec #Derived_gen.66;
let Dict.1113 : {Str, Int1} = CallByName List.18 Dict.179 Dict.180 Dict.181;
ret Dict.1113;
@ -165,8 +165,8 @@ procedure Dict.399 (Dict.400, Dict.848, Dict.402, Dict.398):
procedure Dict.4 (Dict.732):
let Dict.157 : List {Str, I64} = StructAtIndex 1 Dict.732;
let #Derived_gen.66 : List {U32, U32} = StructAtIndex 0 Dict.732;
dec #Derived_gen.66;
let #Derived_gen.67 : List {U32, U32} = StructAtIndex 0 Dict.732;
dec #Derived_gen.67;
let Dict.893 : U64 = CallByName List.6 Dict.157;
dec Dict.157;
ret Dict.893;
@ -219,8 +219,8 @@ procedure Dict.59 (Dict.722):
let Dict.378 : U64 = StructAtIndex 2 Dict.722;
let Dict.379 : Float32 = StructAtIndex 3 Dict.722;
let Dict.380 : U8 = StructAtIndex 4 Dict.722;
let #Derived_gen.67 : List {U32, U32} = StructAtIndex 0 Dict.722;
dec #Derived_gen.67;
let #Derived_gen.68 : List {U32, U32} = StructAtIndex 0 Dict.722;
dec #Derived_gen.68;
let Dict.888 : U64 = CallByName Dict.47;
let Dict.844 : Int1 = CallByName Bool.7 Dict.378 Dict.888;
if Dict.844 then
@ -287,7 +287,7 @@ procedure Dict.65 (Dict.405, Dict.406, Dict.407):
let Dict.854 : {U64, U32} = CallByName Dict.66 Dict.405 Dict.410 Dict.409;
ret Dict.854;
procedure Dict.66 (#Derived_gen.37, #Derived_gen.38, #Derived_gen.39):
procedure Dict.66 (#Derived_gen.25, #Derived_gen.26, #Derived_gen.27):
joinpoint Dict.855 Dict.411 Dict.412 Dict.413:
let Dict.863 : U64 = CallByName Num.137 Dict.412;
let Dict.414 : {U32, U32} = CallByName Dict.22 Dict.411 Dict.863;
@ -303,9 +303,9 @@ procedure Dict.66 (#Derived_gen.37, #Derived_gen.38, #Derived_gen.39):
let Dict.856 : {U64, U32} = Struct {Dict.412, Dict.413};
ret Dict.856;
in
jump Dict.855 #Derived_gen.37 #Derived_gen.38 #Derived_gen.39;
jump Dict.855 #Derived_gen.25 #Derived_gen.26 #Derived_gen.27;
procedure Dict.67 (#Derived_gen.48, #Derived_gen.49, #Derived_gen.50):
procedure Dict.67 (#Derived_gen.38, #Derived_gen.39, #Derived_gen.40):
joinpoint Dict.756 Dict.415 Dict.416 Dict.417:
let Dict.770 : U64 = CallByName Num.137 Dict.417;
let Dict.418 : {U32, U32} = CallByName Dict.22 Dict.415 Dict.770;
@ -327,7 +327,7 @@ procedure Dict.67 (#Derived_gen.48, #Derived_gen.49, #Derived_gen.50):
let Dict.757 : List {U32, U32} = CallByName List.3 Dict.415 Dict.758 Dict.416;
ret Dict.757;
in
jump Dict.756 #Derived_gen.48 #Derived_gen.49 #Derived_gen.50;
jump Dict.756 #Derived_gen.38 #Derived_gen.39 #Derived_gen.40;
procedure Dict.68 (Dict.420, Dict.421):
let Dict.752 : U64 = 1i64;
@ -510,7 +510,7 @@ procedure Dict.82 (Dict.705, Dict.481):
let Dict.929 : {U64, U64, U64} = CallByName Dict.83 Dict.479 Dict.479 Dict.479 Dict.481 Dict.931 Dict.482;
jump Dict.930 Dict.929;
procedure Dict.83 (#Derived_gen.31, #Derived_gen.32, #Derived_gen.33, #Derived_gen.34, #Derived_gen.35, #Derived_gen.36):
procedure Dict.83 (#Derived_gen.41, #Derived_gen.42, #Derived_gen.43, #Derived_gen.44, #Derived_gen.45, #Derived_gen.46):
joinpoint Dict.932 Dict.487 Dict.488 Dict.489 Dict.490 Dict.491 Dict.492:
inc 6 Dict.490;
let Dict.1039 : U64 = CallByName Dict.91 Dict.490 Dict.491;
@ -572,9 +572,9 @@ procedure Dict.83 (#Derived_gen.31, #Derived_gen.32, #Derived_gen.33, #Derived_g
let Dict.933 : {U64, U64, U64} = Struct {Dict.934, Dict.935, Dict.499};
ret Dict.933;
in
jump Dict.932 #Derived_gen.31 #Derived_gen.32 #Derived_gen.33 #Derived_gen.34 #Derived_gen.35 #Derived_gen.36;
jump Dict.932 #Derived_gen.41 #Derived_gen.42 #Derived_gen.43 #Derived_gen.44 #Derived_gen.45 #Derived_gen.46;
procedure Dict.84 (#Derived_gen.51, #Derived_gen.52, #Derived_gen.53, #Derived_gen.54):
procedure Dict.84 (#Derived_gen.32, #Derived_gen.33, #Derived_gen.34, #Derived_gen.35):
joinpoint Dict.985 Dict.500 Dict.501 Dict.502 Dict.503:
inc 2 Dict.501;
let Dict.1005 : U64 = CallByName Dict.91 Dict.501 Dict.502;
@ -606,7 +606,7 @@ procedure Dict.84 (#Derived_gen.51, #Derived_gen.52, #Derived_gen.53, #Derived_g
else
jump Dict.985 Dict.504 Dict.501 Dict.506 Dict.505;
in
jump Dict.985 #Derived_gen.51 #Derived_gen.52 #Derived_gen.53 #Derived_gen.54;
jump Dict.985 #Derived_gen.32 #Derived_gen.33 #Derived_gen.34 #Derived_gen.35;
procedure Dict.85 ():
let Dict.921 : U64 = 11562461410679940143i64;
@ -634,7 +634,7 @@ procedure Dict.89 (Dict.507, Dict.508):
procedure Dict.90 (Dict.511, Dict.512):
let Dict.913 : U128 = CallByName Num.135 Dict.511;
let Dict.914 : U128 = CallByName Num.135 Dict.512;
let Dict.513 : U128 = CallByName Num.21 Dict.913 Dict.914;
let Dict.513 : U128 = CallByName Num.78 Dict.913 Dict.914;
let Dict.514 : U64 = CallByName Num.133 Dict.513;
let Dict.912 : U8 = 64i64;
let Dict.911 : U128 = CallByName Num.74 Dict.513 Dict.912;
@ -991,7 +991,7 @@ procedure List.83 (List.167, List.168, List.169):
let List.610 : List {U32, U32} = CallByName List.91 List.167 List.168 List.169 List.611 List.612;
ret List.610;
procedure List.88 (#Derived_gen.58, #Derived_gen.59, #Derived_gen.60):
procedure List.88 (#Derived_gen.54, #Derived_gen.55, #Derived_gen.56):
joinpoint List.622 List.138 List.139 List.140:
let List.630 : U64 = 0i64;
let List.624 : Int1 = CallByName Num.24 List.139 List.630;
@ -1003,25 +1003,9 @@ procedure List.88 (#Derived_gen.58, #Derived_gen.59, #Derived_gen.60):
else
ret List.140;
in
jump List.622 #Derived_gen.58 #Derived_gen.59 #Derived_gen.60;
jump List.622 #Derived_gen.54 #Derived_gen.55 #Derived_gen.56;
procedure List.90 (#Derived_gen.17, #Derived_gen.18, #Derived_gen.19, #Derived_gen.20, #Derived_gen.21):
joinpoint List.638 List.161 List.162 List.163 List.164 List.165:
let List.640 : Int1 = CallByName Num.22 List.164 List.165;
if List.640 then
let List.644 : {Str, I64} = CallByName List.66 List.161 List.164;
inc List.644;
let List.166 : {Str, Int1} = CallByName Dict.182 List.162 List.644 List.163;
let List.643 : U64 = 1i64;
let List.642 : U64 = CallByName Num.51 List.164 List.643;
jump List.638 List.161 List.166 List.163 List.642 List.165;
else
dec List.161;
ret List.162;
in
jump List.638 #Derived_gen.17 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21;
procedure List.90 (#Derived_gen.26, #Derived_gen.27, #Derived_gen.28, #Derived_gen.29, #Derived_gen.30):
procedure List.90 (#Derived_gen.16, #Derived_gen.17, #Derived_gen.18, #Derived_gen.19, #Derived_gen.20):
joinpoint List.574 List.161 List.162 List.163 List.164 List.165:
let List.576 : Int1 = CallByName Num.22 List.164 List.165;
if List.576 then
@ -1035,9 +1019,25 @@ procedure List.90 (#Derived_gen.26, #Derived_gen.27, #Derived_gen.28, #Derived_g
dec List.161;
ret List.162;
in
jump List.574 #Derived_gen.26 #Derived_gen.27 #Derived_gen.28 #Derived_gen.29 #Derived_gen.30;
jump List.574 #Derived_gen.16 #Derived_gen.17 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20;
procedure List.91 (#Derived_gen.61, #Derived_gen.62, #Derived_gen.63, #Derived_gen.64, #Derived_gen.65):
procedure List.90 (#Derived_gen.49, #Derived_gen.50, #Derived_gen.51, #Derived_gen.52, #Derived_gen.53):
joinpoint List.638 List.161 List.162 List.163 List.164 List.165:
let List.640 : Int1 = CallByName Num.22 List.164 List.165;
if List.640 then
let List.644 : {Str, I64} = CallByName List.66 List.161 List.164;
inc List.644;
let List.166 : {Str, Int1} = CallByName Dict.182 List.162 List.644 List.163;
let List.643 : U64 = 1i64;
let List.642 : U64 = CallByName Num.51 List.164 List.643;
jump List.638 List.161 List.166 List.163 List.642 List.165;
else
dec List.161;
ret List.162;
in
jump List.638 #Derived_gen.49 #Derived_gen.50 #Derived_gen.51 #Derived_gen.52 #Derived_gen.53;
procedure List.91 (#Derived_gen.57, #Derived_gen.58, #Derived_gen.59, #Derived_gen.60, #Derived_gen.61):
joinpoint List.613 List.170 List.171 List.172 List.173 List.174:
let List.615 : Int1 = CallByName Num.22 List.173 List.174;
if List.615 then
@ -1051,146 +1051,146 @@ procedure List.91 (#Derived_gen.61, #Derived_gen.62, #Derived_gen.63, #Derived_g
dec List.170;
ret List.171;
in
jump List.613 #Derived_gen.61 #Derived_gen.62 #Derived_gen.63 #Derived_gen.64 #Derived_gen.65;
jump List.613 #Derived_gen.57 #Derived_gen.58 #Derived_gen.59 #Derived_gen.60 #Derived_gen.61;
procedure Num.131 (#Attr.2):
let Num.316 : U32 = lowlevel NumIntCast #Attr.2;
ret Num.316;
let Num.322 : U32 = lowlevel NumIntCast #Attr.2;
ret Num.322;
procedure Num.133 (#Attr.2):
let Num.371 : U64 = lowlevel NumIntCast #Attr.2;
ret Num.371;
let Num.377 : U64 = lowlevel NumIntCast #Attr.2;
ret Num.377;
procedure Num.133 (#Attr.2):
let Num.372 : U64 = lowlevel NumIntCast #Attr.2;
ret Num.372;
let Num.378 : U64 = lowlevel NumIntCast #Attr.2;
ret Num.378;
procedure Num.133 (#Attr.2):
let Num.387 : U64 = lowlevel NumIntCast #Attr.2;
ret Num.387;
procedure Num.135 (#Attr.2):
let Num.393 : U128 = lowlevel NumIntCast #Attr.2;
let Num.393 : U64 = lowlevel NumIntCast #Attr.2;
ret Num.393;
procedure Num.137 (#Attr.2):
let Num.307 : U64 = lowlevel NumIntCast #Attr.2;
ret Num.307;
procedure Num.135 (#Attr.2):
let Num.399 : U128 = lowlevel NumIntCast #Attr.2;
ret Num.399;
procedure Num.137 (#Attr.2):
let Num.313 : U64 = lowlevel NumIntCast #Attr.2;
ret Num.313;
procedure Num.139 (#Attr.2):
let Num.340 : Float32 = lowlevel NumToFloatCast #Attr.2;
ret Num.340;
procedure Num.137 (#Attr.2):
let Num.319 : U64 = lowlevel NumIntCast #Attr.2;
ret Num.319;
procedure Num.159 (Num.245, Num.246):
let Num.342 : Int1 = CallByName Num.22 Num.245 Num.246;
if Num.342 then
ret Num.245;
procedure Num.139 (#Attr.2):
let Num.346 : Float32 = lowlevel NumToFloatCast #Attr.2;
ret Num.346;
procedure Num.159 (Num.247, Num.248):
let Num.348 : Int1 = CallByName Num.22 Num.247 Num.248;
if Num.348 then
ret Num.247;
else
ret Num.246;
ret Num.248;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : U32 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U32 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.317 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.317;
let Num.323 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.323;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.320 : U8 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.320;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.333 : Float32 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.333;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.391 : U128 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.391;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.337 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.337;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.466 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.466;
procedure Num.23 (#Attr.2, #Attr.3):
let Num.459 : Int1 = lowlevel NumLte #Attr.2 #Attr.3;
ret Num.459;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.321 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.321;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.462 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.462;
procedure Num.25 (#Attr.2, #Attr.3):
let Num.463 : Int1 = lowlevel NumGte #Attr.2 #Attr.3;
ret Num.463;
procedure Num.50 (#Attr.2):
let Num.339 : U64 = lowlevel NumFloor #Attr.2;
ret Num.339;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.465 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.465;
procedure Num.69 (#Attr.2, #Attr.3):
let Num.325 : U32 = lowlevel NumBitwiseAnd #Attr.2 #Attr.3;
ret Num.325;
procedure Num.70 (#Attr.2, #Attr.3):
let Num.369 : U64 = lowlevel NumBitwiseXor #Attr.2 #Attr.3;
ret Num.369;
procedure Num.71 (#Attr.2, #Attr.3):
let Num.324 : U32 = lowlevel NumBitwiseOr #Attr.2 #Attr.3;
ret Num.324;
procedure Num.71 (#Attr.2, #Attr.3):
let Num.407 : U64 = lowlevel NumBitwiseOr #Attr.2 #Attr.3;
ret Num.407;
procedure Num.72 (#Attr.2, #Attr.3):
let Num.298 : U32 = lowlevel NumShiftLeftBy #Attr.2 #Attr.3;
ret Num.298;
procedure Num.72 (#Attr.2, #Attr.3):
let Num.422 : U64 = lowlevel NumShiftLeftBy #Attr.2 #Attr.3;
ret Num.422;
procedure Num.74 (#Attr.2, #Attr.3):
let Num.388 : U128 = lowlevel NumShiftRightZfBy #Attr.2 #Attr.3;
ret Num.388;
procedure Num.74 (#Attr.2, #Attr.3):
let Num.390 : U64 = lowlevel NumShiftRightZfBy #Attr.2 #Attr.3;
ret Num.390;
procedure Num.75 (#Attr.2, #Attr.3):
let Num.326 : U32 = lowlevel NumSubWrap #Attr.2 #Attr.3;
let Num.326 : U8 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.326;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.345 : Float32 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.345;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.342 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.342;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.472 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.472;
procedure Num.23 (#Attr.2, #Attr.3):
let Num.465 : Int1 = lowlevel NumLte #Attr.2 #Attr.3;
ret Num.465;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.327 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.327;
procedure Num.24 (#Attr.2, #Attr.3):
let Num.468 : Int1 = lowlevel NumGt #Attr.2 #Attr.3;
ret Num.468;
procedure Num.25 (#Attr.2, #Attr.3):
let Num.469 : Int1 = lowlevel NumGte #Attr.2 #Attr.3;
ret Num.469;
procedure Num.50 (#Attr.2):
let Num.344 : U64 = lowlevel NumFloor #Attr.2;
ret Num.344;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.471 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.471;
procedure Num.69 (#Attr.2, #Attr.3):
let Num.331 : U32 = lowlevel NumBitwiseAnd #Attr.2 #Attr.3;
ret Num.331;
procedure Num.70 (#Attr.2, #Attr.3):
let Num.375 : U64 = lowlevel NumBitwiseXor #Attr.2 #Attr.3;
ret Num.375;
procedure Num.71 (#Attr.2, #Attr.3):
let Num.330 : U32 = lowlevel NumBitwiseOr #Attr.2 #Attr.3;
ret Num.330;
procedure Num.71 (#Attr.2, #Attr.3):
let Num.413 : U64 = lowlevel NumBitwiseOr #Attr.2 #Attr.3;
ret Num.413;
procedure Num.72 (#Attr.2, #Attr.3):
let Num.304 : U32 = lowlevel NumShiftLeftBy #Attr.2 #Attr.3;
ret Num.304;
procedure Num.72 (#Attr.2, #Attr.3):
let Num.428 : U64 = lowlevel NumShiftLeftBy #Attr.2 #Attr.3;
ret Num.428;
procedure Num.74 (#Attr.2, #Attr.3):
let Num.394 : U128 = lowlevel NumShiftRightZfBy #Attr.2 #Attr.3;
ret Num.394;
procedure Num.74 (#Attr.2, #Attr.3):
let Num.396 : U64 = lowlevel NumShiftRightZfBy #Attr.2 #Attr.3;
ret Num.396;
procedure Num.75 (#Attr.2, #Attr.3):
let Num.456 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.456;
let Num.332 : U32 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.332;
procedure Num.75 (#Attr.2, #Attr.3):
let Num.462 : U64 = lowlevel NumSubWrap #Attr.2 #Attr.3;
ret Num.462;
procedure Num.78 (#Attr.2, #Attr.3):
let Num.397 : U128 = lowlevel NumMulWrap #Attr.2 #Attr.3;
ret Num.397;
procedure Num.96 (#Attr.2):
let Num.336 : Str = lowlevel NumToStr #Attr.2;
ret Num.336;
let Num.341 : Str = lowlevel NumToStr #Attr.2;
ret Num.341;
procedure Num.96 (#Attr.2):
let Num.464 : Str = lowlevel NumToStr #Attr.2;
ret Num.464;
let Num.470 : Str = lowlevel NumToStr #Attr.2;
ret Num.470;
procedure Str.12 (#Attr.2):
let Str.253 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -155,16 +155,16 @@ procedure List.90 (#Derived_gen.10, #Derived_gen.11, #Derived_gen.12, #Derived_g
jump List.574 #Derived_gen.10 #Derived_gen.11 #Derived_gen.12 #Derived_gen.13 #Derived_gen.14;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.299 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.299;
let Num.305 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.305;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.298 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.304;
procedure Num.96 (#Attr.2):
let Num.297 : Str = lowlevel NumToStr #Attr.2;
ret Num.297;
let Num.303 : Str = lowlevel NumToStr #Attr.2;
ret Num.303;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.251 : Str = lowlevel StrConcat #Attr.2 #Attr.3;

View file

@ -261,12 +261,12 @@ procedure List.90 (#Derived_gen.37, #Derived_gen.38, #Derived_gen.39, #Derived_g
jump List.574 #Derived_gen.37 #Derived_gen.38 #Derived_gen.39 #Derived_gen.40 #Derived_gen.41;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.300 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.300;
let Num.306 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.306;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.299 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.299;
let Num.305 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.305;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.252 : Str = lowlevel StrConcat #Attr.2 #Attr.3;

View file

@ -181,20 +181,20 @@ procedure List.90 (#Derived_gen.16, #Derived_gen.17, #Derived_gen.18, #Derived_g
jump List.574 #Derived_gen.16 #Derived_gen.17 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.300 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.300;
let Num.306 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.306;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.299 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.299;
let Num.305 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.305;
procedure Num.96 (#Attr.2):
let Num.297 : Str = lowlevel NumToStr #Attr.2;
ret Num.297;
let Num.303 : Str = lowlevel NumToStr #Attr.2;
ret Num.303;
procedure Num.96 (#Attr.2):
let Num.298 : Str = lowlevel NumToStr #Attr.2;
ret Num.298;
let Num.304 : Str = lowlevel NumToStr #Attr.2;
ret Num.304;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.251 : Str = lowlevel StrConcat #Attr.2 #Attr.3;

View file

@ -158,12 +158,12 @@ procedure List.90 (#Derived_gen.20, #Derived_gen.21, #Derived_gen.22, #Derived_g
jump List.574 #Derived_gen.20 #Derived_gen.21 #Derived_gen.22 #Derived_gen.23 #Derived_gen.24;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.298 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.304;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.297 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.303;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.251 : Str = lowlevel StrConcat #Attr.2 #Attr.3;

View file

@ -165,12 +165,12 @@ procedure List.90 (#Derived_gen.24, #Derived_gen.25, #Derived_gen.26, #Derived_g
jump List.574 #Derived_gen.24 #Derived_gen.25 #Derived_gen.26 #Derived_gen.27 #Derived_gen.28;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.298 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.304;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.297 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.303;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.251 : Str = lowlevel StrConcat #Attr.2 #Attr.3;

View file

@ -160,12 +160,12 @@ procedure List.90 (#Derived_gen.18, #Derived_gen.19, #Derived_gen.20, #Derived_g
jump List.574 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21 #Derived_gen.22;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.298 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.304;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.297 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.303;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.251 : Str = lowlevel StrConcat #Attr.2 #Attr.3;

View file

@ -163,12 +163,12 @@ procedure List.90 (#Derived_gen.17, #Derived_gen.18, #Derived_gen.19, #Derived_g
jump List.574 #Derived_gen.17 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.298 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.304;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.297 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.303;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.251 : Str = lowlevel StrConcat #Attr.2 #Attr.3;

View file

@ -3,8 +3,8 @@ procedure List.6 (#Attr.2):
ret List.571;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.299 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.299;
let Num.305 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.305;
procedure Test.0 ():
let Test.1 : List I64 = Array [1i64, 2i64];

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Test.0 ():
let Test.2 : I64 = 1i64;

View file

@ -1,6 +1,6 @@
procedure Num.45 (#Attr.2):
let Num.297 : I64 = lowlevel NumRound #Attr.2;
ret Num.297;
let Num.303 : I64 = lowlevel NumRound #Attr.2;
ret Num.303;
procedure Test.0 ():
let Test.2 : Decimal = 3.6dec;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Test.0 ():
let Test.1 : I64 = 3i64;

View file

@ -1,22 +1,22 @@
procedure Num.166 (#Attr.2, #Attr.3):
let Num.305 : I64 = lowlevel NumDivTruncUnchecked #Attr.2 #Attr.3;
ret Num.305;
procedure Num.30 (#Attr.2):
let Num.304 : I64 = 0i64;
let Num.303 : Int1 = lowlevel Eq #Attr.2 Num.304;
ret Num.303;
let Num.310 : I64 = 0i64;
let Num.309 : Int1 = lowlevel Eq #Attr.2 Num.310;
ret Num.309;
procedure Num.39 (#Attr.2, #Attr.3):
let Num.299 : I64 = lowlevel NumDivTruncUnchecked #Attr.2 #Attr.3;
ret Num.299;
procedure Num.40 (Num.267, Num.268):
let Num.300 : Int1 = CallByName Num.30 Num.268;
if Num.300 then
let Num.302 : {} = Struct {};
let Num.301 : [C {}, C I64] = TagId(0) Num.302;
ret Num.301;
procedure Num.40 (Num.271, Num.272):
let Num.306 : Int1 = CallByName Num.30 Num.272;
if Num.306 then
let Num.308 : {} = Struct {};
let Num.307 : [C {}, C I64] = TagId(0) Num.308;
ret Num.307;
else
let Num.298 : I64 = CallByName Num.39 Num.267 Num.268;
let Num.297 : [C {}, C I64] = TagId(1) Num.298;
ret Num.297;
let Num.304 : I64 = CallByName Num.166 Num.271 Num.272;
let Num.303 : [C {}, C I64] = TagId(1) Num.304;
ret Num.303;
procedure Test.0 ():
let Test.8 : I64 = 1000i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Test.0 ():
let Test.10 : I64 = 41i64;

View file

@ -44,8 +44,8 @@ procedure List.9 (List.333):
ret List.573;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.297 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.303;
procedure Str.27 (Str.88):
let Str.251 : [C Int1, C I64] = CallByName Str.61 Str.88;

View file

@ -179,44 +179,44 @@ procedure List.80 (#Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.
jump List.636 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4 #Derived_gen.5;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.300 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.300;
let Num.306 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.306;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.309 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.309;
let Num.315 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.315;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.312 : U8 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.312;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.334 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.334;
procedure Num.23 (#Attr.2, #Attr.3):
let Num.318 : Int1 = lowlevel NumLte #Attr.2 #Attr.3;
let Num.318 : U8 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.318;
procedure Num.25 (#Attr.2, #Attr.3):
let Num.324 : Int1 = lowlevel NumGte #Attr.2 #Attr.3;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.340 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.340;
procedure Num.23 (#Attr.2, #Attr.3):
let Num.324 : Int1 = lowlevel NumLte #Attr.2 #Attr.3;
ret Num.324;
procedure Num.25 (#Attr.2, #Attr.3):
let Num.330 : Int1 = lowlevel NumGte #Attr.2 #Attr.3;
ret Num.330;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.335 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.335;
let Num.341 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.341;
procedure Num.71 (#Attr.2, #Attr.3):
let Num.297 : U8 = lowlevel NumBitwiseOr #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U8 = lowlevel NumBitwiseOr #Attr.2 #Attr.3;
ret Num.303;
procedure Num.72 (#Attr.2, #Attr.3):
let Num.298 : U8 = lowlevel NumShiftLeftBy #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : U8 = lowlevel NumShiftLeftBy #Attr.2 #Attr.3;
ret Num.304;
procedure Num.77 (#Attr.2, #Attr.3):
let Num.331 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.331;
let Num.337 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.337;
procedure Str.43 (#Attr.2, #Attr.3, #Attr.4):
let Str.260 : {U64, Str, Int1, U8} = lowlevel StrFromUtf8Range #Attr.2 #Attr.3 #Attr.4;

View file

@ -82,16 +82,16 @@ procedure List.80 (#Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.
jump List.587 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4 #Derived_gen.5;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.297 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.303;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.300 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.300;
let Num.306 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.306;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.299 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.299;
let Num.305 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.305;
procedure Test.1 (#Derived_gen.0):
joinpoint Test.26 Test.6:

View file

@ -153,44 +153,44 @@ procedure List.80 (#Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.
jump List.632 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4 #Derived_gen.5;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.300 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.300;
let Num.306 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.306;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.309 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.309;
let Num.315 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.315;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.312 : U8 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.312;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.334 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.334;
procedure Num.23 (#Attr.2, #Attr.3):
let Num.318 : Int1 = lowlevel NumLte #Attr.2 #Attr.3;
let Num.318 : U8 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.318;
procedure Num.25 (#Attr.2, #Attr.3):
let Num.324 : Int1 = lowlevel NumGte #Attr.2 #Attr.3;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.340 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.340;
procedure Num.23 (#Attr.2, #Attr.3):
let Num.324 : Int1 = lowlevel NumLte #Attr.2 #Attr.3;
ret Num.324;
procedure Num.25 (#Attr.2, #Attr.3):
let Num.330 : Int1 = lowlevel NumGte #Attr.2 #Attr.3;
ret Num.330;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.335 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.335;
let Num.341 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.341;
procedure Num.71 (#Attr.2, #Attr.3):
let Num.297 : U8 = lowlevel NumBitwiseOr #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U8 = lowlevel NumBitwiseOr #Attr.2 #Attr.3;
ret Num.303;
procedure Num.72 (#Attr.2, #Attr.3):
let Num.298 : U8 = lowlevel NumShiftLeftBy #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : U8 = lowlevel NumShiftLeftBy #Attr.2 #Attr.3;
ret Num.304;
procedure Num.77 (#Attr.2, #Attr.3):
let Num.331 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.331;
let Num.337 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
ret Num.337;
procedure Str.12 (#Attr.2):
let Str.260 : List U8 = lowlevel StrToUtf8 #Attr.2;

View file

@ -0,0 +1,11 @@
procedure Test.1 (Test.2):
let Test.7 : I64 = StructAtIndex 1 Test.2;
let Test.5 : {I64, I64} = Struct {Test.7, Test.7};
ret Test.5;
procedure Test.0 ():
let Test.8 : I64 = 0i64;
let Test.9 : I64 = 0i64;
let Test.4 : {I64, I64} = Struct {Test.8, Test.9};
let Test.3 : {I64, I64} = CallByName Test.1 Test.4;
ret Test.3;

View file

@ -0,0 +1,37 @@
procedure Bool.1 ():
let Bool.23 : Int1 = false;
ret Bool.23;
procedure Test.2 (Test.11, Test.1):
if Test.1 then
let Test.29 : I64 = 0i64;
let Test.28 : [C {}, C I64] = TagId(1) Test.29;
ret Test.28;
else
let Test.27 : {} = Struct {};
let Test.26 : [C {}, C I64] = TagId(0) Test.27;
ret Test.26;
procedure Test.3 (Test.12, Test.1):
if Test.1 then
let Test.23 : I64 = 0i64;
let Test.22 : [C {}, C I64] = TagId(1) Test.23;
ret Test.22;
else
let Test.21 : {} = Struct {};
let Test.20 : [C {}, C I64] = TagId(0) Test.21;
ret Test.20;
procedure Test.4 (Test.13, Test.1):
let Test.25 : {} = Struct {};
let Test.17 : [C {}, C I64] = CallByName Test.2 Test.25 Test.1;
let Test.19 : {} = Struct {};
let Test.18 : [C {}, C I64] = CallByName Test.3 Test.19 Test.1;
let Test.16 : List [C {}, C I64] = Array [Test.17, Test.18];
ret Test.16;
procedure Test.0 ():
let Test.1 : Int1 = CallByName Bool.1;
let Test.15 : {} = Struct {};
let Test.14 : List [C {}, C I64] = CallByName Test.4 Test.15 Test.1;
ret Test.14;

View file

@ -1,6 +1,6 @@
procedure Num.20 (#Attr.2, #Attr.3):
let Num.297 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.303;
procedure Test.1 (#Derived_gen.0, #Derived_gen.1):
joinpoint Test.12 Test.2 Test.3:

View file

@ -1,10 +1,10 @@
procedure Num.96 (#Attr.2):
let Num.297 : Str = lowlevel NumToStr #Attr.2;
ret Num.297;
let Num.303 : Str = lowlevel NumToStr #Attr.2;
ret Num.303;
procedure Num.96 (#Attr.2):
let Num.298 : Str = lowlevel NumToStr #Attr.2;
ret Num.298;
let Num.304 : Str = lowlevel NumToStr #Attr.2;
ret Num.304;
procedure Test.1 (Test.4):
let Test.13 : [C U8, C U64] = TagId(1) Test.4;

View file

@ -1,10 +1,14 @@
procedure Str.3 (#Attr.2, #Attr.3):
let Str.251 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
ret Str.251;
procedure Test.1 (Test.5):
let Test.16 : [C {}, C U64, C Str] = TagId(0) Test.5;
ret Test.16;
procedure Test.1 (Test.5):
let Test.30 : [C {}, C U64, C Str] = TagId(1) Test.5;
ret Test.30;
let Test.31 : [C {}, C U64, C Str] = TagId(1) Test.5;
ret Test.31;
procedure Test.2 (Test.7):
let Test.23 : [C {}, C U64, C Str] = TagId(2) Test.7;
@ -16,13 +20,16 @@ procedure Test.6 (Test.17, #Attr.12):
ret Test.19;
procedure Test.6 (Test.17, #Attr.12):
let Test.34 : U64 = UnionAtIndex (Id 1) (Index 0) #Attr.12;
let Test.33 : Str = "";
ret Test.33;
let Test.35 : U64 = UnionAtIndex (Id 1) (Index 0) #Attr.12;
let Test.34 : Str = "";
ret Test.34;
procedure Test.8 (Test.24, #Attr.12):
let Test.27 : Str = UnionAtIndex (Id 2) (Index 0) #Attr.12;
ret Test.27;
let Test.28 : Str = UnionAtIndex (Id 2) (Index 0) #Attr.12;
let Test.27 : Str = "";
let Test.26 : Str = CallByName Str.3 Test.27 Test.28;
dec Test.28;
ret Test.26;
procedure Test.0 ():
let Test.3 : U8 = 0u8;
@ -55,7 +62,7 @@ procedure Test.0 ():
jump Test.13 Test.21;
default:
let Test.29 : U64 = 1i64;
let Test.28 : [C {}, C U64, C Str] = CallByName Test.1 Test.29;
jump Test.13 Test.28;
let Test.30 : U64 = 1i64;
let Test.29 : [C {}, C U64, C Str] = CallByName Test.1 Test.30;
jump Test.13 Test.29;

View file

@ -7,12 +7,12 @@ procedure Bool.2 ():
ret Bool.24;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.298 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : U64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.304;
procedure Test.0 (Test.8):
let Test.20 : Int1 = CallByName Bool.2;

View file

@ -29,12 +29,12 @@ procedure List.90 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
jump List.574 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.298 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.304;
procedure Num.51 (#Attr.2, #Attr.3):
let Num.297 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U64 = lowlevel NumAddWrap #Attr.2 #Attr.3;
ret Num.303;
procedure Test.7 (Test.11, Test.12):
let Test.17 : {[<rnu>C *self, <null>], [<rnu><null>, C {[<rnu>C *self, <null>], *self}]} = Struct {Test.12, Test.11};

View file

@ -1,11 +1,11 @@
procedure Num.31 (Num.239):
let Num.298 : I64 = 2i64;
let Num.297 : Int1 = CallByName Num.86 Num.239 Num.298;
ret Num.297;
procedure Num.31 (Num.241):
let Num.304 : I64 = 2i64;
let Num.303 : Int1 = CallByName Num.86 Num.241 Num.304;
ret Num.303;
procedure Num.86 (#Attr.2, #Attr.3):
let Num.299 : Int1 = lowlevel NumIsMultipleOf #Attr.2 #Attr.3;
ret Num.299;
let Num.305 : Int1 = lowlevel NumIsMultipleOf #Attr.2 #Attr.3;
ret Num.305;
procedure Test.2 (#Derived_gen.0, #Derived_gen.1):
let #Derived_gen.3 : [<rnu><null>, C I64 *self] = NullPointer;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Test.10 (Test.11):
let Test.28 : I64 = 1i64;

View file

@ -22,12 +22,12 @@ procedure List.67 (#Attr.2, #Attr.3, #Attr.4):
ret List.578;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.298 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.298;
let Num.304 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.304;
procedure Test.1 ():
let Test.8 : List I64 = Array [1i64, 2i64, 3i64];

View file

@ -21,8 +21,8 @@ procedure List.66 (#Attr.2, #Attr.3):
ret List.576;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.297 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.303;
procedure Test.1 (Test.2):
let Test.6 : List I64 = Array [1i64, 2i64, 3i64];

View file

@ -7,8 +7,8 @@ procedure List.6 (#Attr.2):
ret List.572;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.297 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.303;
procedure Test.0 ():
let Test.1 : List I64 = Array [1i64, 2i64, 3i64];

View file

@ -27,8 +27,8 @@ procedure List.66 (#Attr.2, #Attr.3):
ret List.576;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.297 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.303;
procedure Str.16 (#Attr.2, #Attr.3):
let Str.251 : Str = lowlevel StrRepeat #Attr.2 #Attr.3;

View file

@ -27,8 +27,8 @@ procedure List.66 (#Attr.2, #Attr.3):
ret List.576;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.297 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.297;
let Num.303 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.303;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.252 : Str = lowlevel StrConcat #Attr.2 #Attr.3;

View file

@ -21,8 +21,8 @@ procedure List.5 (#Attr.2, #Attr.3):
procedure Num.19 (#Attr.2, #Attr.3):
let Num.299 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.299;
let Num.305 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.305;
procedure Test.4 (Test.5, #Attr.12):
let Test.16 : U8 = UnionAtIndex (Id 0) (Index 0) #Attr.12;

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