Merge pull request #3452 from rtfeldman/can-builtins-cleanup

Can builtins cleanup
This commit is contained in:
Richard Feldman 2022-07-08 18:54:59 -04:00 committed by GitHub
commit 55931bca9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 1134 additions and 4081 deletions

View file

@ -1075,7 +1075,7 @@ fn lowlevel_spec(
builder.add_make_tuple(block, &[cell, bag])
}
StrFromUtf8 => {
StrFromUtf8Range => {
let list = env.symbols[&arguments[0]];
let cell = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?;

View file

@ -1638,18 +1638,45 @@ inline fn fromUtf8(arg: RocList, update_mode: UpdateMode) FromUtf8Result {
}
}
pub fn fromUtf8RangeC(output: *FromUtf8Result, arg: RocList, countAndStart: CountAndStart) callconv(.C) void {
output.* = @call(.{ .modifier = always_inline }, fromUtf8Range, .{ arg, countAndStart });
pub fn fromUtf8RangeC(
output: *FromUtf8Result,
list: RocList,
start: usize,
count: usize,
update_mode: UpdateMode,
) callconv(.C) void {
output.* = @call(.{ .modifier = always_inline }, fromUtf8Range, .{ list, start, count, update_mode });
}
fn fromUtf8Range(arg: RocList, countAndStart: CountAndStart) FromUtf8Result {
const bytes = @ptrCast([*]const u8, arg.bytes)[countAndStart.start..countAndStart.count];
pub fn fromUtf8Range(arg: RocList, start: usize, count: usize, update_mode: UpdateMode) FromUtf8Result {
const bytes = @ptrCast([*]const u8, arg.bytes)[start..count];
if (unicode.utf8ValidateSlice(bytes)) {
// the output will be correct. Now we need to clone the input
const string = RocStr.init(@ptrCast([*]const u8, bytes), countAndStart.count);
return FromUtf8Result{ .is_ok = true, .string = string, .byte_index = 0, .problem_code = Utf8ByteProblem.InvalidStartByte };
if (count == arg.len() and count > SMALL_STR_MAX_LENGTH) {
const byte_list = arg.makeUniqueExtra(RocStr.alignment, @sizeOf(u8), update_mode);
const string = RocStr{
.str_bytes = byte_list.bytes,
.str_len = byte_list.length,
.str_capacity = byte_list.capacity,
};
return FromUtf8Result{
.is_ok = true,
.string = string,
.byte_index = 0,
.problem_code = Utf8ByteProblem.InvalidStartByte,
};
} else {
return FromUtf8Result{
.is_ok = true,
.string = RocStr.init(@ptrCast([*]const u8, bytes), count),
.byte_index = 0,
.problem_code = Utf8ByteProblem.InvalidStartByte,
};
}
} else {
const temp = errorToProblem(@ptrCast([*]u8, arg.bytes), arg.length);
return FromUtf8Result{ .is_ok = false, .string = RocStr.empty(), .byte_index = temp.index, .problem_code = temp.problem };

View file

@ -68,14 +68,27 @@ interface Dict
## `fn dict1 == fn dict2` also being `True`, even if `fn` relies on the dictionary's ordering.
## An empty dictionary.
empty : Dict k v
single : k, v -> Dict k v
get : Dict k v, k -> Result v [KeyNotFound]*
get = \dict, key ->
result = getLowlevel dict key
when result.flag is
True -> Ok result.value
False -> Err KeyNotFound
getLowlevel : Dict k v, k -> { flag : Bool, value : v }
walk : Dict k v, state, (state, k, v -> state) -> state
insert : Dict k v, k, v -> Dict k v
len : Dict k v -> Nat
remove : Dict k v, k -> Dict k v
contains : Dict k v, k -> Bool
single : k, v -> Dict k v
single = \key, value ->
Dict.empty
|> Dict.insert key value
## Returns a [List] of the dictionary's keys.
keys : Dict k v -> List k

View file

@ -717,6 +717,10 @@ takeLast = \list, outputLength ->
## Drops n elements from the beginning of the list.
drop : List elem, Nat -> List elem
drop = \list, n ->
remaining = Num.subSaturated (List.len list) n
List.takeLast list remaining
## Drops the element at the given index from the list.
##
@ -812,6 +816,10 @@ findIndex = \list, matcher ->
##
## Some languages have a function called **`slice`** which works similarly to this.
sublist : List elem, { start : Nat, len : Nat } -> List elem
sublist = \list, config ->
sublistLowlevel list config.start config.len
sublistLowlevel : List elem, Nat, Nat -> List elem
## Intersperses `sep` between the elements of `list`
## >>> List.intersperse 9 [1, 2, 3] # [1, 9, 2, 9, 3]
@ -835,6 +843,13 @@ intersperse = \list, sep ->
## means if you give an index of 0, the `before` list will be empty and the
## `others` list will have the same elements as the original list.)
split : List elem, Nat -> { before : List elem, others : List elem }
split = \elements, userSplitIndex ->
length = List.len elements
splitIndex = if length > userSplitIndex then userSplitIndex else length
before = List.sublist elements { start: 0, len: splitIndex }
others = List.sublist elements { start: splitIndex, len: length - splitIndex }
{ before, others }
## Primitive for iterating over a List, being able to decide at every element whether to continue
iterate : List elem, s, (s, elem -> [Continue s, Break b]) -> [Continue s, Break b]

View file

@ -509,8 +509,28 @@ Dec : Num (FloatingPoint Decimal)
toStr : Num * -> Str
intCast : Int a -> Int b
bytesToU16Lowlevel : List U8, Nat -> U16
bytesToU32Lowlevel : List U8, Nat -> U32
bytesToU16 : List U8, Nat -> Result U16 [OutOfBounds]
bytesToU16 = \bytes, index ->
# we need at least 1 more byte
offset = 1
if index + offset < List.len bytes then
Ok (bytesToU16Lowlevel bytes index)
else
Err OutOfBounds
bytesToU32 : List U8, Nat -> Result U32 [OutOfBounds]
bytesToU32 = \bytes, index ->
# we need at least 3 more bytes
offset = 3
if index + offset < List.len bytes then
Ok (bytesToU32Lowlevel bytes index)
else
Err OutOfBounds
compare : Num a, Num a -> [LT, EQ, GT]
@ -554,22 +574,27 @@ isGte : Num a, Num a -> Bool
## Returns `True` if the number is `0`, and `False` otherwise.
isZero : Num a -> Bool
isZero = \x -> x == 0
## A number is even if dividing it by 2 gives a remainder of 0.
##
## Examples of even numbers: 0, 2, 4, 6, 8, -2, -4, -6, -8
isEven : Int a -> Bool
isEven = \x -> Num.isMultipleOf x 2
## A number is odd if dividing it by 2 gives a remainder of 1.
##
## Examples of odd numbers: 1, 3, 5, 7, -1, -3, -5, -7
isOdd : Int a -> Bool
isOdd = \x -> Bool.not (Num.isMultipleOf x 2)
## Positive numbers are greater than `0`.
isPositive : Num a -> Bool
isPositive = \x -> x > 0
## Negative numbers are less than `0`.
isNegative : Num a -> Bool
isNegative = \x -> x < 0
toFrac : Num * -> Frac *
@ -682,7 +707,11 @@ mul : Num a, Num a -> Num a
sin : Frac a -> Frac a
cos : Frac a -> Frac a
tan : Frac a -> Frac a
tan = \x ->
# `tan` is not available as an intrinsic in LLVM
Num.div (Num.sin x) (Num.cos x)
asin : Frac a -> Frac a
acos : Frac a -> Frac a
@ -713,9 +742,22 @@ atan : Frac a -> Frac a
##
## >>> Num.sqrt -4.0f64
sqrt : Frac a -> Frac a
sqrtChecked : Frac a -> Result (Frac a) [SqrtOfNegative]*
sqrtChecked = \x ->
if x < 0.0 then
Err SqrtOfNegative
else
Ok (Num.sqrt x)
log : Frac a -> Frac a
logChecked : Frac a -> Result (Frac a) [LogNeedsPositive]*
logChecked = \x ->
if x <= 0.0 then
Err LogNeedsPositive
else
Ok (Num.log x)
## Divide one [Frac] by another.
##
@ -748,9 +790,22 @@ logChecked : Frac a -> Result (Frac a) [LogNeedsPositive]*
## >>> Num.pi
## >>> |> Num.div 2.0
div : Frac a, Frac a -> Frac a
divChecked : Frac a, Frac a -> Result (Frac a) [DivByZero]*
divChecked = \a, b ->
if b == 0 then
Err DivByZero
else
Ok (Num.div a b)
divCeil : Int a, Int a -> Int a
divCeilChecked : Int a, Int a -> Result (Int a) [DivByZero]*
divCeilChecked = \a, b ->
if b == 0 then
Err DivByZero
else
Ok (Num.divCeil a b)
## Divide two integers, truncating the result towards zero.
##
@ -769,7 +824,13 @@ divCeilChecked : Int a, Int a -> Result (Int a) [DivByZero]*
## >>> Num.divTrunc 8 -3
##
divTrunc : Int a, Int a -> Int a
divTruncChecked : Int a, Int a -> Result (Int a) [DivByZero]*
divTruncChecked = \a, b ->
if b == 0 then
Err DivByZero
else
Ok (Num.divTrunc a b)
## Obtain the remainder (truncating modulo) from the division of two integers.
##
@ -783,7 +844,13 @@ divTruncChecked : Int a, Int a -> Result (Int a) [DivByZero]*
##
## >>> Num.rem -8 -3
rem : Int a, Int a -> Int a
remChecked : Int a, Int a -> Result (Int a) [DivByZero]*
remChecked = \a, b ->
if b == 0 then
Err DivByZero
else
Ok (Num.rem a b)
isMultipleOf : Int a, Int a -> Bool
@ -842,6 +909,15 @@ addSaturated : Num a, Num a -> Num a
## This is the same as [Num.add] except if the operation overflows, instead of
## panicking or returning ∞ or -∞, it will return `Err Overflow`.
addChecked : Num a, Num a -> Result (Num a) [Overflow]*
addChecked = \a, b ->
result = addCheckedLowlevel a b
if result.b then
Err Overflow
else
Ok result.a
addCheckedLowlevel : Num a, Num a -> { b : Bool, a : Num a }
subWrap : Int range, Int range -> Int range
@ -859,6 +935,15 @@ subSaturated : Num a, Num a -> Num a
## This is the same as [Num.sub] except if the operation overflows, instead of
## panicking or returning ∞ or -∞, it will return `Err Overflow`.
subChecked : Num a, Num a -> Result (Num a) [Overflow]*
subChecked = \a, b ->
result = subCheckedLowlevel a b
if result.b then
Err Overflow
else
Ok result.a
subCheckedLowlevel : Num a, Num a -> { b : Bool, a : Num a }
mulWrap : Int range, Int range -> Int range
@ -874,6 +959,15 @@ mulSaturated : Num a, Num a -> Num a
## This is the same as [Num.mul] except if the operation overflows, instead of
## panicking or returning ∞ or -∞, it will return `Err Overflow`.
mulChecked : Num a, Num a -> Result (Num a) [Overflow]*
mulChecked = \a, b ->
result = mulCheckedLowlevel a b
if result.b then
Err Overflow
else
Ok result.a
mulCheckedLowlevel : Num a, Num a -> { b : Bool, a : Num a }
## The lowest number that can be stored in an [I8] without underflowing its
## available memory and crashing.

View file

@ -24,10 +24,19 @@ single : k -> Set k
## retrieved or removed from the [Set].
insert : Set k, k -> Set k
len : Set k -> Nat
len = \set ->
set
|> Set.toDict
|> Dict.len
## Drops the given element from the set.
remove : Set k, k -> Set k
contains : Set k, k -> Bool
contains = \set, key ->
set
|> Set.toDict
|> Dict.contains key
# toList = \set -> Dict.keys (toDict set)
toList : Set k -> List k

View file

@ -199,10 +199,35 @@ toScalars : Str -> List U32
## >>> Str.toUtf8 "🐦"
toUtf8 : Str -> List U8
# fromUtf8 : List U8 -> Result Str [BadUtf8 Utf8Problem]*
# fromUtf8Range : List U8 -> Result Str [BadUtf8 Utf8Problem Nat, OutOfBounds]*
fromUtf8 : List U8 -> Result Str [BadUtf8 Utf8ByteProblem Nat]*
fromUtf8 = \bytes ->
result = fromUtf8RangeLowlevel bytes 0 (List.len bytes)
if result.cIsOk then
Ok result.bString
else
Err (BadUtf8 result.dProblemCode result.aByteIndex)
fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [BadUtf8 Utf8ByteProblem Nat, OutOfBounds]*
fromUtf8Range = \bytes, config ->
if config.start + config.count <= List.len bytes then
result = fromUtf8RangeLowlevel bytes config.start config.count
if result.cIsOk then
Ok result.bString
else
Err (BadUtf8 result.dProblemCode result.aByteIndex)
else
Err OutOfBounds
FromUtf8Result : {
aByteIndex : Nat,
bString : Str,
cIsOk : Bool,
dProblemCode : Utf8ByteProblem,
}
fromUtf8RangeLowlevel : List U8, Nat, Nat -> FromUtf8Result
startsWith : Str, Str -> Bool
endsWith : Str, Str -> Bool
@ -214,19 +239,33 @@ trimLeft : Str -> Str
trimRight : Str -> Str
toDec : Str -> Result Dec [InvalidNumStr]*
toDec = \string -> strToNumHelp string
toF64 : Str -> Result F64 [InvalidNumStr]*
toF64 = \string -> strToNumHelp string
toF32 : Str -> Result F32 [InvalidNumStr]*
toF32 = \string -> strToNumHelp string
toNat : Str -> Result Nat [InvalidNumStr]*
toNat = \string -> strToNumHelp string
toU128 : Str -> Result U128 [InvalidNumStr]*
toU128 = \string -> strToNumHelp string
toI128 : Str -> Result I128 [InvalidNumStr]*
toI128 = \string -> strToNumHelp string
toU64 : Str -> Result U64 [InvalidNumStr]*
toU64 = \string -> strToNumHelp string
toI64 : Str -> Result I64 [InvalidNumStr]*
toI64 = \string -> strToNumHelp string
toU32 : Str -> Result U32 [InvalidNumStr]*
toU32 = \string -> strToNumHelp string
toI32 : Str -> Result I32 [InvalidNumStr]*
toI32 = \string -> strToNumHelp string
toU16 : Str -> Result U16 [InvalidNumStr]*
toU16 = \string -> strToNumHelp string
toI16 : Str -> Result I16 [InvalidNumStr]*
toI16 = \string -> strToNumHelp string
toU8 : Str -> Result U8 [InvalidNumStr]*
toU8 = \string -> strToNumHelp string
toI8 : Str -> Result I8 [InvalidNumStr]*
toI8 = \string -> strToNumHelp string
## Gets the byte at the given index, without performing a bounds check
getUnsafe : Str, Nat -> U8
@ -393,3 +432,15 @@ walkScalarsUntilHelp = \string, state, step, index, length ->
newState
else
state
strToNum : Str -> { berrorcode : U8, aresult : Num * }
strToNumHelp : Str -> Result (Num a) [InvalidNumStr]*
strToNumHelp = \string ->
result : { berrorcode : U8, aresult : Num a }
result = strToNum string
if result.berrorcode == 0 then
Ok result.aresult
else
Err InvalidNumStr

View file

@ -326,7 +326,6 @@ pub const STR_TO_DECIMAL: &str = "roc_builtins.str.to_decimal";
pub const STR_EQUAL: &str = "roc_builtins.str.equal";
pub const STR_SUBSTRING_UNSAFE: &str = "roc_builtins.str.substring_unsafe";
pub const STR_TO_UTF8: &str = "roc_builtins.str.to_utf8";
pub const STR_FROM_UTF8: &str = "roc_builtins.str.from_utf8";
pub const STR_FROM_UTF8_RANGE: &str = "roc_builtins.str.from_utf8_range";
pub const STR_REPEAT: &str = "roc_builtins.str.repeat";
pub const STR_TRIM: &str = "roc_builtins.str.trim";

File diff suppressed because it is too large Load diff

View file

@ -11,9 +11,9 @@ use crate::llvm::build_list::{
self, allocate_list, empty_polymorphic_list, list_append_unsafe, list_concat, list_drop_at,
list_get_unsafe, list_len, list_map, list_map2, list_map3, list_map4, list_prepend,
list_replace_unsafe, list_reserve, list_sort_with, list_sublist, list_swap,
list_symbol_to_c_abi, list_to_c_abi, list_with_capacity,
list_symbol_to_c_abi, list_to_c_abi, list_with_capacity, pass_update_mode,
};
use crate::llvm::build_str::{str_from_float, str_from_int, str_from_utf8, str_from_utf8_range};
use crate::llvm::build_str::{str_from_float, str_from_int};
use crate::llvm::compare::{generic_eq, generic_neq};
use crate::llvm::convert::{
self, argument_type_from_layout, basic_type_from_builtin, basic_type_from_layout,
@ -5354,18 +5354,31 @@ fn run_low_level<'a, 'ctx, 'env>(
str_from_float(env, scope, args[0])
}
StrFromUtf8 => {
// Str.fromUtf8 : List U8 -> Result Str Utf8Problem
debug_assert_eq!(args.len(), 1);
str_from_utf8(env, scope, args[0], update_mode)
}
StrFromUtf8Range => {
debug_assert_eq!(args.len(), 2);
debug_assert_eq!(args.len(), 3);
let count_and_start = load_symbol(scope, &args[1]).into_struct_value();
let list = args[0];
let start = load_symbol(scope, &args[1]);
let count = load_symbol(scope, &args[2]);
str_from_utf8_range(env, scope, args[0], count_and_start)
let result_type = env.module.get_struct_type("str.FromUtf8Result").unwrap();
let result_ptr = env
.builder
.build_alloca(result_type, "alloca_utf8_validate_bytes_result");
call_void_bitcode_fn(
env,
&[
result_ptr.into(),
list_symbol_to_c_abi(env, scope, list).into(),
start,
count,
pass_update_mode(env, update_mode),
],
bitcode::STR_FROM_UTF8_RANGE,
);
crate::llvm::build_str::decode_from_utf8_result(env, result_ptr).into()
}
StrToUtf8 => {
// Str.fromInt : Str -> List U8
@ -5549,10 +5562,6 @@ fn run_low_level<'a, 'ctx, 'env>(
)
}
ListSublist => {
// List.sublist : List elem, { start : Nat, len : Nat } -> List elem
//
// As a low-level, record is destructed
// List.sublist : List elem, start : Nat, len : Nat -> List elem
debug_assert_eq!(args.len(), 3);
let (list, list_layout) = load_symbol_and_layout(scope, &args[0]);

View file

@ -1,17 +1,14 @@
use crate::llvm::bitcode::{call_bitcode_fn, call_str_bitcode_fn, call_void_bitcode_fn};
use crate::llvm::bitcode::{call_bitcode_fn, call_str_bitcode_fn};
use crate::llvm::build::{Env, Scope};
use crate::llvm::build_list::pass_update_mode;
use inkwell::builder::Builder;
use inkwell::values::{BasicValueEnum, IntValue, PointerValue, StructValue};
use inkwell::AddressSpace;
use morphic_lib::UpdateMode;
use roc_builtins::bitcode::{self, IntWidth};
use roc_module::symbol::Symbol;
use roc_mono::layout::{Builtin, Layout};
use roc_target::PtrWidth;
use super::build::{create_entry_block_alloca, load_symbol};
use super::build_list::list_symbol_to_c_abi;
pub static CHAR_LAYOUT: Layout = Layout::u8();
@ -70,7 +67,7 @@ pub fn str_from_int<'a, 'ctx, 'env>(
call_str_bitcode_fn(env, &[value.into()], &bitcode::STR_FROM_INT[int_width])
}
fn decode_from_utf8_result<'a, 'ctx, 'env>(
pub fn decode_from_utf8_result<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
pointer: PointerValue<'ctx>,
) -> StructValue<'ctx> {
@ -106,67 +103,6 @@ fn decode_from_utf8_result<'a, 'ctx, 'env>(
}
}
/// Str.fromUtf8 : List U8, { count : Nat, start : Nat } -> { a : Bool, b : Str, c : Nat, d : I8 }
pub fn str_from_utf8_range<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
scope: &Scope<'a, 'ctx>,
list: Symbol,
count_and_start: StructValue<'ctx>,
) -> BasicValueEnum<'ctx> {
let builder = env.builder;
let result_type = env.module.get_struct_type("str.FromUtf8Result").unwrap();
let result_ptr = builder.build_alloca(result_type, "alloca_utf8_validate_bytes_result");
let count = env
.builder
.build_extract_value(count_and_start, 0, "get_count")
.unwrap();
let start = env
.builder
.build_extract_value(count_and_start, 1, "get_start")
.unwrap();
call_void_bitcode_fn(
env,
&[
result_ptr.into(),
list_symbol_to_c_abi(env, scope, list).into(),
count,
start,
],
bitcode::STR_FROM_UTF8_RANGE,
);
decode_from_utf8_result(env, result_ptr).into()
}
/// Str.fromUtf8 : List U8 -> { a : Bool, b : Str, c : Nat, d : I8 }
pub fn str_from_utf8<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
scope: &Scope<'a, 'ctx>,
list: Symbol,
update_mode: UpdateMode,
) -> BasicValueEnum<'ctx> {
let builder = env.builder;
let result_type = env.module.get_struct_type("str.FromUtf8Result").unwrap();
let result_ptr = builder.build_alloca(result_type, "alloca_utf8_validate_bytes_result");
call_void_bitcode_fn(
env,
&[
result_ptr.into(),
list_symbol_to_c_abi(env, scope, list).into(),
pass_update_mode(env, update_mode),
],
bitcode::STR_FROM_UTF8,
);
decode_from_utf8_result(env, result_ptr).into()
}
/// Str.fromFloat : Int -> Str
pub fn str_from_float<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,

View file

@ -264,16 +264,19 @@ impl<'a> LowLevelCall<'a> {
}
StrFromInt => self.num_to_str(backend),
StrFromFloat => self.num_to_str(backend),
StrFromUtf8 => {
StrFromUtf8Range => {
/*
Low-level op returns a struct with all the data for both Ok and Err.
Roc AST wrapper converts this to a tag union, with app-dependent tag IDs.
fromUtf8C(output: *FromUtf8Result, arg: RocList, update_mode: UpdateMode) callconv(.C) void
output: *FromUtf8Result i32
arg: RocList i64, i32
start i32
count i32
update_mode: UpdateMode i32
*/
// loads arg, start, count
backend.storage.load_symbols_for_call(
backend.env.arena,
&mut backend.code_builder,
@ -283,9 +286,8 @@ impl<'a> LowLevelCall<'a> {
CallConv::Zig,
);
backend.code_builder.i32_const(UPDATE_MODE_IMMUTABLE);
backend.call_host_fn_after_loading_args(bitcode::STR_FROM_UTF8, 4, false);
backend.call_host_fn_after_loading_args(bitcode::STR_FROM_UTF8_RANGE, 6, false);
}
StrFromUtf8Range => self.load_args_and_call_zig(backend, bitcode::STR_FROM_UTF8_RANGE),
StrTrimLeft => self.load_args_and_call_zig(backend, bitcode::STR_TRIM_LEFT),
StrTrimRight => self.load_args_and_call_zig(backend, bitcode::STR_TRIM_RIGHT),
StrToUtf8 => self.load_args_and_call_zig(backend, bitcode::STR_TO_UTF8),

View file

@ -1,7 +1,7 @@
use std::path::PathBuf;
use bumpalo::Bump;
use roc_load_internal::file::Threading;
use roc_load_internal::file::{LoadingProblem, Threading};
use roc_module::symbol::ModuleId;
const MODULES: &[(ModuleId, &str)] = &[
@ -47,7 +47,16 @@ fn write_subs_for_module(module_id: ModuleId, filename: &str) {
Threading::AllAvailable,
);
let module = res_module.unwrap();
let module = match res_module {
Ok(v) => v,
Err(LoadingProblem::FormattedReport(report)) => {
panic!("{}", report);
}
Err(other) => {
panic!("build_file failed with error:\n{:?}", other);
}
};
let subs = module.solved.inner();
let exposed_vars_by_symbol: Vec<_> = module.exposed_to_host.into_iter().collect();

View file

@ -15,7 +15,6 @@ pub enum LowLevel {
StrCountGraphemes,
StrCountUtf8Bytes,
StrFromInt,
StrFromUtf8,
StrFromUtf8Range,
StrToUtf8,
StrRepeat,
@ -161,141 +160,181 @@ impl LowLevel {
pub enum LowLevelWrapperType {
/// This wrapper function contains no logic and we can remove it in code gen
CanBeReplacedBy(LowLevel),
/// This wrapper function contains important logic and we cannot remove it in code gen
WrapperIsRequired,
NotALowLevelWrapper,
}
impl LowLevelWrapperType {
pub fn from_symbol(symbol: Symbol) -> LowLevelWrapperType {
use LowLevel::*;
use LowLevelWrapperType::*;
match symbol {
Symbol::STR_CONCAT => CanBeReplacedBy(StrConcat),
Symbol::STR_GET_UNSAFE => CanBeReplacedBy(StrGetUnsafe),
Symbol::STR_TO_SCALARS => CanBeReplacedBy(StrToScalars),
Symbol::STR_JOIN_WITH => CanBeReplacedBy(StrJoinWith),
Symbol::STR_IS_EMPTY => CanBeReplacedBy(StrIsEmpty),
Symbol::STR_STARTS_WITH => CanBeReplacedBy(StrStartsWith),
Symbol::STR_STARTS_WITH_SCALAR => CanBeReplacedBy(StrStartsWithScalar),
Symbol::STR_ENDS_WITH => CanBeReplacedBy(StrEndsWith),
Symbol::STR_SPLIT => CanBeReplacedBy(StrSplit),
Symbol::STR_COUNT_GRAPHEMES => CanBeReplacedBy(StrCountGraphemes),
Symbol::STR_COUNT_UTF8_BYTES => CanBeReplacedBy(StrCountUtf8Bytes),
Symbol::STR_FROM_UTF8 => WrapperIsRequired,
Symbol::STR_FROM_UTF8_RANGE => WrapperIsRequired,
Symbol::STR_TO_UTF8 => CanBeReplacedBy(StrToUtf8),
Symbol::STR_REPEAT => CanBeReplacedBy(StrRepeat),
Symbol::STR_RESERVE => CanBeReplacedBy(StrReserve),
Symbol::STR_APPEND_SCALAR_UNSAFE => CanBeReplacedBy(StrAppendScalar),
Symbol::STR_TRIM => CanBeReplacedBy(StrTrim),
Symbol::STR_TRIM_LEFT => CanBeReplacedBy(StrTrimLeft),
Symbol::STR_TRIM_RIGHT => CanBeReplacedBy(StrTrimRight),
Symbol::STR_TO_DEC => WrapperIsRequired,
Symbol::STR_TO_F64 => WrapperIsRequired,
Symbol::STR_TO_F32 => WrapperIsRequired,
Symbol::STR_TO_NAT => WrapperIsRequired,
Symbol::STR_TO_U128 => WrapperIsRequired,
Symbol::STR_TO_I128 => WrapperIsRequired,
Symbol::STR_TO_U64 => WrapperIsRequired,
Symbol::STR_TO_I64 => WrapperIsRequired,
Symbol::STR_TO_U32 => WrapperIsRequired,
Symbol::STR_TO_I32 => WrapperIsRequired,
Symbol::STR_TO_U16 => WrapperIsRequired,
Symbol::STR_TO_I16 => WrapperIsRequired,
Symbol::STR_TO_U8 => WrapperIsRequired,
Symbol::STR_TO_I8 => WrapperIsRequired,
Symbol::LIST_LEN => CanBeReplacedBy(ListLen),
Symbol::LIST_GET => WrapperIsRequired,
Symbol::LIST_REPLACE => WrapperIsRequired,
Symbol::LIST_CONCAT => CanBeReplacedBy(ListConcat),
Symbol::LIST_APPEND_UNSAFE => CanBeReplacedBy(ListAppendUnsafe),
Symbol::LIST_PREPEND => CanBeReplacedBy(ListPrepend),
Symbol::LIST_MAP => WrapperIsRequired,
Symbol::LIST_MAP2 => WrapperIsRequired,
Symbol::LIST_MAP3 => WrapperIsRequired,
Symbol::LIST_MAP4 => WrapperIsRequired,
Symbol::LIST_SORT_WITH => WrapperIsRequired,
Symbol::LIST_SUBLIST => WrapperIsRequired,
Symbol::LIST_DROP_AT => CanBeReplacedBy(ListDropAt),
Symbol::LIST_SWAP => CanBeReplacedBy(ListSwap),
Symbol::LIST_ANY => WrapperIsRequired,
Symbol::LIST_ALL => WrapperIsRequired,
Symbol::LIST_FIND => WrapperIsRequired,
Symbol::DICT_LEN => CanBeReplacedBy(DictSize),
Symbol::DICT_EMPTY => CanBeReplacedBy(DictEmpty),
Symbol::DICT_INSERT => CanBeReplacedBy(DictInsert),
Symbol::DICT_REMOVE => CanBeReplacedBy(DictRemove),
Symbol::DICT_CONTAINS => CanBeReplacedBy(DictContains),
Symbol::DICT_GET => WrapperIsRequired,
Symbol::DICT_KEYS => CanBeReplacedBy(DictKeys),
Symbol::DICT_VALUES => CanBeReplacedBy(DictValues),
Symbol::DICT_UNION => CanBeReplacedBy(DictUnion),
Symbol::DICT_INTERSECTION => CanBeReplacedBy(DictIntersection),
Symbol::DICT_DIFFERENCE => CanBeReplacedBy(DictDifference),
Symbol::DICT_WALK => WrapperIsRequired,
Symbol::SET_FROM_LIST => CanBeReplacedBy(SetFromList),
Symbol::NUM_ADD => CanBeReplacedBy(NumAdd),
Symbol::NUM_ADD_WRAP => CanBeReplacedBy(NumAddWrap),
Symbol::NUM_ADD_CHECKED => WrapperIsRequired,
Symbol::NUM_ADD_SATURATED => CanBeReplacedBy(NumAddSaturated),
Symbol::NUM_SUB => CanBeReplacedBy(NumSub),
Symbol::NUM_SUB_WRAP => CanBeReplacedBy(NumSubWrap),
Symbol::NUM_SUB_CHECKED => WrapperIsRequired,
Symbol::NUM_SUB_SATURATED => CanBeReplacedBy(NumSubSaturated),
Symbol::NUM_MUL => CanBeReplacedBy(NumMul),
Symbol::NUM_MUL_WRAP => CanBeReplacedBy(NumMulWrap),
Symbol::NUM_MUL_SATURATED => CanBeReplacedBy(NumMulSaturated),
Symbol::NUM_MUL_CHECKED => WrapperIsRequired,
Symbol::NUM_GT => CanBeReplacedBy(NumGt),
Symbol::NUM_GTE => CanBeReplacedBy(NumGte),
Symbol::NUM_LT => CanBeReplacedBy(NumLt),
Symbol::NUM_LTE => CanBeReplacedBy(NumLte),
Symbol::NUM_COMPARE => CanBeReplacedBy(NumCompare),
Symbol::NUM_DIV_FRAC => CanBeReplacedBy(NumDivUnchecked),
Symbol::NUM_DIV_FRAC_CHECKED => WrapperIsRequired,
Symbol::NUM_DIV_CEIL => CanBeReplacedBy(NumDivCeilUnchecked),
Symbol::NUM_DIV_CEIL_CHECKED => WrapperIsRequired,
Symbol::NUM_REM => CanBeReplacedBy(NumRemUnchecked),
Symbol::NUM_REM_CHECKED => WrapperIsRequired,
Symbol::NUM_IS_MULTIPLE_OF => CanBeReplacedBy(NumIsMultipleOf),
Symbol::NUM_ABS => CanBeReplacedBy(NumAbs),
Symbol::NUM_NEG => CanBeReplacedBy(NumNeg),
Symbol::NUM_SIN => CanBeReplacedBy(NumSin),
Symbol::NUM_COS => CanBeReplacedBy(NumCos),
Symbol::NUM_SQRT => CanBeReplacedBy(NumSqrtUnchecked),
Symbol::NUM_SQRT_CHECKED => WrapperIsRequired,
Symbol::NUM_LOG => CanBeReplacedBy(NumLogUnchecked),
Symbol::NUM_LOG_CHECKED => WrapperIsRequired,
Symbol::NUM_ROUND => CanBeReplacedBy(NumRound),
Symbol::NUM_TO_FRAC => CanBeReplacedBy(NumToFrac),
Symbol::NUM_POW => CanBeReplacedBy(NumPow),
Symbol::NUM_CEILING => CanBeReplacedBy(NumCeiling),
Symbol::NUM_POW_INT => CanBeReplacedBy(NumPowInt),
Symbol::NUM_FLOOR => CanBeReplacedBy(NumFloor),
Symbol::NUM_TO_STR => CanBeReplacedBy(NumToStr),
// => CanBeReplacedBy(NumIsFinite),
Symbol::NUM_ATAN => CanBeReplacedBy(NumAtan),
Symbol::NUM_ACOS => CanBeReplacedBy(NumAcos),
Symbol::NUM_ASIN => CanBeReplacedBy(NumAsin),
Symbol::NUM_BYTES_TO_U16 => WrapperIsRequired,
Symbol::NUM_BYTES_TO_U32 => WrapperIsRequired,
Symbol::NUM_BITWISE_AND => CanBeReplacedBy(NumBitwiseAnd),
Symbol::NUM_BITWISE_XOR => CanBeReplacedBy(NumBitwiseXor),
Symbol::NUM_BITWISE_OR => CanBeReplacedBy(NumBitwiseOr),
Symbol::NUM_SHIFT_LEFT => CanBeReplacedBy(NumShiftLeftBy),
Symbol::NUM_SHIFT_RIGHT => CanBeReplacedBy(NumShiftRightBy),
Symbol::NUM_SHIFT_RIGHT_ZERO_FILL => CanBeReplacedBy(NumShiftRightZfBy),
Symbol::NUM_INT_CAST => CanBeReplacedBy(NumIntCast),
Symbol::BOOL_EQ => CanBeReplacedBy(Eq),
Symbol::BOOL_NEQ => CanBeReplacedBy(NotEq),
Symbol::BOOL_AND => CanBeReplacedBy(And),
Symbol::BOOL_OR => CanBeReplacedBy(Or),
Symbol::BOOL_NOT => CanBeReplacedBy(Not),
// => CanBeReplacedBy(Hash),
// => CanBeReplacedBy(ExpectTrue),
_ => NotALowLevelWrapper,
}
for_symbol_help(symbol)
}
}
/// We use a rust macro to ensure that every LowLevel gets handled
macro_rules! map_symbol_to_lowlevel {
($($lowlevel:ident <= $symbol:ident),* $(,)?) => {
fn for_symbol_help(symbol: Symbol) -> LowLevelWrapperType {
use $crate::low_level::LowLevelWrapperType::*;
// expands to a big (but non-exhaustive) match on symbols and maps them to a lowlevel
match symbol {
$(
Symbol::$symbol => CanBeReplacedBy(LowLevel::$lowlevel),
)*
_ => NotALowLevelWrapper,
}
}
fn _enforce_exhaustiveness(lowlevel: LowLevel) -> Symbol {
// when adding a new lowlevel, this match will stop being exhaustive, and give a
// compiler error. Most likely, you are adding a new lowlevel that maps directly to a
// symbol. For instance, you want to have `List.foo` to stand for the `ListFoo`
// lowlevel. In that case, see below in the invocation of `map_symbol_to_lowlevel!`
//
// Below, we explicitly handle some exceptions to the pattern where a lowlevel maps
// directly to a symbol. If you are unsure if your lowlevel is an exception, assume
// that it isn't and just see if that works.
match lowlevel {
$(
LowLevel::$lowlevel => Symbol::$symbol,
)*
// these are higher-order lowlevels. these need the surrounding
// function to provide enough type information for code generation
LowLevel::ListMap => unreachable!(),
LowLevel::ListMap2 => unreachable!(),
LowLevel::ListMap3 => unreachable!(),
LowLevel::ListMap4 => unreachable!(),
LowLevel::ListSortWith => unreachable!(),
LowLevel::DictWalk => unreachable!(),
// (un)boxing is handled in a custom way
LowLevel::BoxExpr => unreachable!(),
LowLevel::UnboxExpr => unreachable!(),
// these functions return polymorphic values
LowLevel::NumIntCast => unreachable!(),
LowLevel::NumToFloatCast => unreachable!(),
LowLevel::NumToIntChecked => unreachable!(),
LowLevel::NumToFloatChecked => unreachable!(),
LowLevel::NumDivUnchecked => unreachable!(),
LowLevel::DictEmpty => unreachable!(),
// these are used internally and not tied to a symbol
LowLevel::Hash => unimplemented!(),
LowLevel::PtrCast => unimplemented!(),
LowLevel::RefCountInc => unimplemented!(),
LowLevel::RefCountDec => unimplemented!(),
// these are not implemented, not sure why
LowLevel::StrFromInt => unimplemented!(),
LowLevel::StrFromFloat => unimplemented!(),
LowLevel::NumIsFinite => unimplemented!(),
}
}
};
}
// here is where we actually specify the mapping for the fast majority of cases that follow the
// pattern of a symbol mapping directly to a lowlevel. In other words, most lowlevels (left) are generated
// by only one specific symbol (right)
map_symbol_to_lowlevel! {
StrConcat <= STR_CONCAT,
StrJoinWith <= STR_JOIN_WITH,
StrIsEmpty <= STR_IS_EMPTY,
StrStartsWith <= STR_STARTS_WITH,
StrStartsWithScalar <= STR_STARTS_WITH_SCALAR,
StrEndsWith <= STR_ENDS_WITH,
StrSplit <= STR_SPLIT,
StrCountGraphemes <= STR_COUNT_GRAPHEMES,
StrCountUtf8Bytes <= STR_COUNT_UTF8_BYTES,
StrFromUtf8Range <= STR_FROM_UTF8_RANGE_LOWLEVEL,
StrToUtf8 <= STR_TO_UTF8,
StrRepeat <= STR_REPEAT,
StrTrim <= STR_TRIM,
StrTrimLeft <= STR_TRIM_LEFT,
StrTrimRight <= STR_TRIM_RIGHT,
StrToScalars <= STR_TO_SCALARS,
StrGetUnsafe <= STR_GET_UNSAFE,
StrSubstringUnsafe <= STR_SUBSTRING_UNSAFE,
StrReserve <= STR_RESERVE,
StrAppendScalar <= STR_APPEND_SCALAR_UNSAFE,
StrGetScalarUnsafe <= STR_GET_SCALAR_UNSAFE,
StrToNum <= STR_TO_NUM,
ListLen <= LIST_LEN,
ListWithCapacity <= LIST_WITH_CAPACITY,
ListReserve <= LIST_RESERVE,
ListIsUnique <= LIST_IS_UNIQUE,
ListAppendUnsafe <= LIST_APPEND_UNSAFE,
ListPrepend <= LIST_PREPEND,
ListGetUnsafe <= LIST_GET_UNSAFE,
ListReplaceUnsafe <= LIST_REPLACE_UNSAFE,
ListConcat <= LIST_CONCAT,
ListSublist <= LIST_SUBLIST_LOWLEVEL,
ListDropAt <= LIST_DROP_AT,
ListSwap <= LIST_SWAP,
DictSize <= DICT_LEN,
DictInsert <= DICT_INSERT,
DictRemove <= DICT_REMOVE,
DictContains <= DICT_CONTAINS,
DictGetUnsafe <= DICT_GET_LOWLEVEL,
DictKeys <= DICT_KEYS,
DictValues <= DICT_VALUES,
DictUnion <= DICT_UNION,
DictIntersection <= DICT_INTERSECTION,
DictDifference <= DICT_DIFFERENCE,
SetFromList <= SET_FROM_LIST,
SetToDict <= SET_TO_DICT,
NumAdd <= NUM_ADD,
NumAddWrap <= NUM_ADD_WRAP,
NumAddChecked <= NUM_ADD_CHECKED_LOWLEVEL,
NumAddSaturated <= NUM_ADD_SATURATED,
NumSub <= NUM_SUB,
NumSubWrap <= NUM_SUB_WRAP,
NumSubChecked <= NUM_SUB_CHECKED_LOWLEVEL,
NumSubSaturated <= NUM_SUB_SATURATED,
NumMul <= NUM_MUL,
NumMulWrap <= NUM_MUL_WRAP,
NumMulSaturated <= NUM_MUL_SATURATED,
NumMulChecked <= NUM_MUL_CHECKED_LOWLEVEL,
NumGt <= NUM_GT,
NumGte <= NUM_GTE,
NumLt <= NUM_LT,
NumLte <= NUM_LTE,
NumCompare <= NUM_COMPARE,
NumDivCeilUnchecked <= NUM_DIV_CEIL,
NumRemUnchecked <= NUM_REM,
NumIsMultipleOf <= NUM_IS_MULTIPLE_OF,
NumAbs <= NUM_ABS,
NumNeg <= NUM_NEG,
NumSin <= NUM_SIN,
NumCos <= NUM_COS,
NumSqrtUnchecked <= NUM_SQRT,
NumLogUnchecked <= NUM_LOG,
NumRound <= NUM_ROUND,
NumToFrac <= NUM_TO_FRAC,
NumPow <= NUM_POW,
NumCeiling <= NUM_CEILING,
NumPowInt <= NUM_POW_INT,
NumFloor <= NUM_FLOOR,
NumAtan <= NUM_ATAN,
NumAcos <= NUM_ACOS,
NumAsin <= NUM_ASIN,
NumBytesToU16 <= NUM_BYTES_TO_U16_LOWLEVEL,
NumBytesToU32 <= NUM_BYTES_TO_U32_LOWLEVEL,
NumBitwiseAnd <= NUM_BITWISE_AND,
NumBitwiseXor <= NUM_BITWISE_XOR,
NumBitwiseOr <= NUM_BITWISE_OR,
NumShiftLeftBy <= NUM_SHIFT_LEFT,
NumShiftRightBy <= NUM_SHIFT_RIGHT,
NumShiftRightZfBy <= NUM_SHIFT_RIGHT_ZERO_FILL,
NumToStr <= NUM_TO_STR,
Eq <= BOOL_EQ,
NotEq <= BOOL_NEQ,
And <= BOOL_AND,
Or <= BOOL_OR,
Not <= BOOL_NOT,
Unreachable <= LIST_UNREACHABLE,
}

View file

@ -997,6 +997,8 @@ define_builtins! {
28 DEV_TMP3: "#dev_tmp3"
29 DEV_TMP4: "#dev_tmp4"
30 DEV_TMP5: "#dev_tmp5"
31 ATTR_INVALID: "#attr_invalid"
}
// Fake module for storing derived function symbols
1 DERIVED: "#Derived" => {
@ -1143,6 +1145,11 @@ define_builtins! {
138 NUM_TO_F64_CHECKED: "toF64Checked"
139 NUM_MAX_F64: "maxF64"
140 NUM_MIN_F64: "minF64"
141 NUM_ADD_CHECKED_LOWLEVEL: "addCheckedLowlevel"
142 NUM_SUB_CHECKED_LOWLEVEL: "subCheckedLowlevel"
143 NUM_MUL_CHECKED_LOWLEVEL: "mulCheckedLowlevel"
144 NUM_BYTES_TO_U16_LOWLEVEL: "bytesToU16Lowlevel"
145 NUM_BYTES_TO_U32_LOWLEVEL: "bytesToU32Lowlevel"
}
3 BOOL: "Bool" => {
0 BOOL_BOOL: "Bool" // the Bool.Bool type alias
@ -1205,6 +1212,8 @@ define_builtins! {
44 STR_GET_SCALAR_UNSAFE: "getScalarUnsafe"
45 STR_WALK_SCALARS: "walkScalars"
46 STR_WALK_SCALARS_UNTIL: "walkScalarsUntil"
47 STR_TO_NUM: "strToNum"
48 STR_FROM_UTF8_RANGE_LOWLEVEL: "fromUtf8RangeLowlevel"
}
5 LIST: "List" => {
0 LIST_LIST: "List" imported // the List.List type alias
@ -1274,6 +1283,7 @@ define_builtins! {
64 LIST_UNREACHABLE: "unreachable"
65 LIST_RESERVE: "reserve"
66 LIST_APPEND_UNSAFE: "appendUnsafe"
67 LIST_SUBLIST_LOWLEVEL: "sublistLowlevel"
}
6 RESULT: "Result" => {
0 RESULT_RESULT: "Result" // the Result.Result type alias
@ -1306,6 +1316,8 @@ define_builtins! {
12 DICT_UNION: "union"
13 DICT_INTERSECTION: "intersection"
14 DICT_DIFFERENCE: "difference"
15 DICT_GET_LOWLEVEL: "getLowlevel"
}
8 SET: "Set" => {
0 SET_SET: "Set" imported // the Set.Set type alias

View file

@ -934,8 +934,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
NumBytesToU32 => arena.alloc_slice_copy(&[borrowed, irrelevant]),
StrStartsWith | StrEndsWith => arena.alloc_slice_copy(&[borrowed, borrowed]),
StrStartsWithScalar => arena.alloc_slice_copy(&[borrowed, irrelevant]),
StrFromUtf8 => arena.alloc_slice_copy(&[owned]),
StrFromUtf8Range => arena.alloc_slice_copy(&[borrowed, irrelevant]),
StrFromUtf8Range => arena.alloc_slice_copy(&[borrowed, irrelevant, irrelevant]),
StrToUtf8 => arena.alloc_slice_copy(&[owned]),
StrRepeat => arena.alloc_slice_copy(&[borrowed, irrelevant]),
StrFromInt | StrFromFloat => arena.alloc_slice_copy(&[irrelevant]),

View file

@ -1,7 +1,7 @@
procedure List.5 (#Attr.2, #Attr.3):
let List.283 : List {} = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.2 #Attr.3;
let List.295 : List {} = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.2 #Attr.3;
decref #Attr.2;
ret List.283;
ret List.295;
procedure Test.2 (Test.3):
let Test.7 : {} = Struct {};

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
procedure List.6 (#Attr.2):
let List.283 : U64 = lowlevel ListLen #Attr.2;
ret List.283;
let List.295 : U64 = lowlevel ListLen #Attr.2;
ret List.295;
procedure Test.1 (Test.5):
let Test.2 : I64 = 41i64;

View file

@ -1,11 +1,11 @@
procedure Dict.1 ():
let Dict.16 : Dict [] [] = lowlevel DictEmpty ;
ret Dict.16;
let Dict.25 : Dict [] [] = lowlevel DictEmpty ;
ret Dict.25;
procedure Dict.7 (#Attr.2):
let Dict.15 : U64 = lowlevel DictSize #Attr.2;
let Dict.24 : U64 = lowlevel DictSize #Attr.2;
dec #Attr.2;
ret Dict.15;
ret Dict.24;
procedure Test.0 ():
let Test.2 : Dict [] [] = CallByName Dict.1;

View file

@ -1,26 +1,26 @@
procedure List.2 (List.77, List.78):
let List.288 : U64 = CallByName List.6 List.77;
let List.285 : Int1 = CallByName Num.22 List.78 List.288;
if List.285 then
let List.287 : {} = CallByName List.60 List.77 List.78;
let List.286 : [C {}, C {}] = TagId(1) List.287;
ret List.286;
procedure List.2 (List.78, List.79):
let List.300 : U64 = CallByName List.6 List.78;
let List.297 : Int1 = CallByName Num.22 List.79 List.300;
if List.297 then
let List.299 : {} = CallByName List.60 List.78 List.79;
let List.298 : [C {}, C {}] = TagId(1) List.299;
ret List.298;
else
let List.284 : {} = Struct {};
let List.283 : [C {}, C {}] = TagId(0) List.284;
ret List.283;
let List.296 : {} = Struct {};
let List.295 : [C {}, C {}] = TagId(0) List.296;
ret List.295;
procedure List.6 (#Attr.2):
let List.290 : U64 = lowlevel ListLen #Attr.2;
ret List.290;
let List.302 : U64 = lowlevel ListLen #Attr.2;
ret List.302;
procedure List.60 (#Attr.2, #Attr.3):
let List.289 : {} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.289;
let List.301 : {} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.301;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.188 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.257;
procedure Test.2 (Test.6):
let Test.18 : Str = "bar";

View file

@ -1,16 +1,16 @@
procedure List.4 (List.88, List.89):
let List.285 : U64 = 1i64;
let List.284 : List U8 = CallByName List.65 List.88 List.285;
let List.283 : List U8 = CallByName List.66 List.284 List.89;
ret List.283;
procedure List.4 (List.89, List.90):
let List.297 : U64 = 1i64;
let List.296 : List U8 = CallByName List.65 List.89 List.297;
let List.295 : List U8 = CallByName List.66 List.296 List.90;
ret List.295;
procedure List.65 (#Attr.2, #Attr.3):
let List.287 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3;
ret List.287;
let List.299 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3;
ret List.299;
procedure List.66 (#Attr.2, #Attr.3):
let List.286 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3;
ret List.286;
let List.298 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3;
ret List.298;
procedure Test.20 (Test.22):
let Test.34 : {U8} = Struct {Test.22};

View file

@ -1,10 +1,10 @@
procedure Num.20 (#Attr.2, #Attr.3):
let Num.189 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.189;
let Num.258 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.258;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.188 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.257;
procedure Test.1 (Test.15, Test.16):
joinpoint Test.7 Test.2 Test.3:

View file

@ -1,10 +1,10 @@
procedure List.6 (#Attr.2):
let List.283 : U64 = lowlevel ListLen #Attr.2;
ret List.283;
let List.295 : U64 = lowlevel ListLen #Attr.2;
ret List.295;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.190 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.190;
let Num.259 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.259;
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.188 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.257;
procedure Test.0 ():
let Test.2 : I64 = 1i64;

View file

@ -1,6 +1,6 @@
procedure Num.45 (#Attr.2):
let Num.188 : I64 = lowlevel NumRound #Attr.2;
ret Num.188;
let Num.257 : I64 = lowlevel NumRound #Attr.2;
ret Num.257;
procedure Test.0 ():
let Test.2 : Float64 = 3.6f64;

View file

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

View file

@ -1,14 +1,22 @@
procedure Num.40 (#Attr.2, #Attr.3):
let Num.193 : I64 = 0i64;
let Num.190 : Int1 = lowlevel NotEq #Attr.3 Num.193;
if Num.190 then
let Num.192 : I64 = lowlevel NumDivUnchecked #Attr.2 #Attr.3;
let Num.191 : [C {}, C I64] = TagId(1) Num.192;
ret Num.191;
procedure Bool.7 (#Attr.2, #Attr.3):
let Bool.9 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
ret Bool.9;
procedure Num.39 (#Attr.2, #Attr.3):
let Num.263 : I64 = lowlevel NumDivUnchecked #Attr.2 #Attr.3;
ret Num.263;
procedure Num.40 (Num.229, Num.230):
let Num.262 : I64 = 0i64;
let Num.259 : Int1 = CallByName Bool.7 Num.230 Num.262;
if Num.259 then
let Num.261 : {} = Struct {};
let Num.260 : [C {}, C I64] = TagId(0) Num.261;
ret Num.260;
else
let Num.189 : {} = Struct {};
let Num.188 : [C {}, C I64] = TagId(0) Num.189;
ret Num.188;
let Num.258 : I64 = CallByName Num.39 Num.229 Num.230;
let Num.257 : [C {}, C I64] = TagId(1) Num.258;
ret Num.257;
procedure Test.0 ():
let Test.8 : I64 = 1000i64;

View file

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

View file

@ -1,55 +1,67 @@
procedure List.2 (List.77, List.78):
let List.297 : U64 = CallByName List.6 List.77;
let List.293 : Int1 = CallByName Num.22 List.78 List.297;
if List.293 then
let List.295 : I64 = CallByName List.60 List.77 List.78;
let List.294 : [C {}, C I64] = TagId(1) List.295;
ret List.294;
procedure Bool.7 (#Attr.2, #Attr.3):
let Bool.9 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
ret Bool.9;
procedure List.2 (List.78, List.79):
let List.309 : U64 = CallByName List.6 List.78;
let List.305 : Int1 = CallByName Num.22 List.79 List.309;
if List.305 then
let List.307 : I64 = CallByName List.60 List.78 List.79;
let List.306 : [C {}, C I64] = TagId(1) List.307;
ret List.306;
else
let List.292 : {} = Struct {};
let List.291 : [C {}, C I64] = TagId(0) List.292;
ret List.291;
let List.304 : {} = Struct {};
let List.303 : [C {}, C I64] = TagId(0) List.304;
ret List.303;
procedure List.6 (#Attr.2):
let List.298 : U64 = lowlevel ListLen #Attr.2;
ret List.298;
let List.310 : U64 = lowlevel ListLen #Attr.2;
ret List.310;
procedure List.60 (#Attr.2, #Attr.3):
let List.296 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.296;
let List.308 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.308;
procedure List.9 (List.205):
let List.290 : U64 = 0i64;
let List.283 : [C {}, C I64] = CallByName List.2 List.205 List.290;
let List.287 : U8 = 1i64;
let List.288 : U8 = GetTagId List.283;
let List.289 : Int1 = lowlevel Eq List.287 List.288;
if List.289 then
let List.206 : I64 = UnionAtIndex (Id 1) (Index 0) List.283;
let List.284 : [C Int1, C I64] = TagId(1) List.206;
ret List.284;
procedure List.9 (List.206):
let List.302 : U64 = 0i64;
let List.295 : [C {}, C I64] = CallByName List.2 List.206 List.302;
let List.299 : U8 = 1i64;
let List.300 : U8 = GetTagId List.295;
let List.301 : Int1 = lowlevel Eq List.299 List.300;
if List.301 then
let List.207 : I64 = UnionAtIndex (Id 1) (Index 0) List.295;
let List.296 : [C Int1, C I64] = TagId(1) List.207;
ret List.296;
else
let List.286 : Int1 = true;
let List.285 : [C Int1, C I64] = TagId(0) List.286;
ret List.285;
let List.298 : Int1 = true;
let List.297 : [C Int1, C I64] = TagId(0) List.298;
ret List.297;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.188 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.257;
procedure Str.27 (#Attr.2):
let #Attr.3 : {I64, U8} = lowlevel StrToNum #Attr.2;
let Str.159 : U8 = StructAtIndex 1 #Attr.3;
let Str.160 : U8 = 0i64;
let Str.156 : Int1 = lowlevel NumGt Str.159 Str.160;
if Str.156 then
let Str.158 : Int1 = false;
let Str.157 : [C Int1, C I64] = TagId(0) Str.158;
ret Str.157;
procedure Str.27 (Str.88):
let Str.194 : [C Int1, C I64] = CallByName Str.67 Str.88;
ret Str.194;
procedure Str.47 (#Attr.2):
let Str.202 : {I64, U8} = lowlevel StrToNum #Attr.2;
ret Str.202;
procedure Str.67 (Str.189):
let Str.190 : {I64, U8} = CallByName Str.47 Str.189;
let Str.200 : U8 = StructAtIndex 1 Str.190;
let Str.201 : U8 = 0i64;
let Str.197 : Int1 = CallByName Bool.7 Str.200 Str.201;
if Str.197 then
let Str.199 : I64 = StructAtIndex 0 Str.190;
let Str.198 : [C Int1, C I64] = TagId(1) Str.199;
ret Str.198;
else
let Str.155 : I64 = StructAtIndex 0 #Attr.3;
let Str.154 : [C Int1, C I64] = TagId(1) Str.155;
ret Str.154;
let Str.196 : Int1 = false;
let Str.195 : [C Int1, C I64] = TagId(0) Str.196;
ret Str.195;
procedure Test.0 ():
let Test.4 : Int1 = true;

View file

@ -1,10 +1,10 @@
procedure Num.94 (#Attr.2):
let Num.188 : Str = lowlevel NumToStr #Attr.2;
ret Num.188;
let Num.257 : Str = lowlevel NumToStr #Attr.2;
ret Num.257;
procedure Num.94 (#Attr.2):
let Num.189 : Str = lowlevel NumToStr #Attr.2;
ret Num.189;
let Num.258 : Str = lowlevel NumToStr #Attr.2;
ret Num.258;
procedure Test.1 (Test.4):
let Test.16 : [C U8, C U64] = TagId(1) Test.4;

View file

@ -1,16 +1,16 @@
procedure List.4 (List.88, List.89):
let List.285 : U64 = 1i64;
let List.284 : List I64 = CallByName List.65 List.88 List.285;
let List.283 : List I64 = CallByName List.66 List.284 List.89;
ret List.283;
procedure List.4 (List.89, List.90):
let List.297 : U64 = 1i64;
let List.296 : List I64 = CallByName List.65 List.89 List.297;
let List.295 : List I64 = CallByName List.66 List.296 List.90;
ret List.295;
procedure List.65 (#Attr.2, #Attr.3):
let List.287 : List I64 = lowlevel ListReserve #Attr.2 #Attr.3;
ret List.287;
let List.299 : List I64 = lowlevel ListReserve #Attr.2 #Attr.3;
ret List.299;
procedure List.66 (#Attr.2, #Attr.3):
let List.286 : List I64 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3;
ret List.286;
let List.298 : List I64 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3;
ret List.298;
procedure Test.0 ():
let Test.2 : List I64 = Array [1i64];

View file

@ -1,16 +1,16 @@
procedure List.4 (List.88, List.89):
let List.285 : U64 = 1i64;
let List.284 : List I64 = CallByName List.65 List.88 List.285;
let List.283 : List I64 = CallByName List.66 List.284 List.89;
ret List.283;
procedure List.4 (List.89, List.90):
let List.297 : U64 = 1i64;
let List.296 : List I64 = CallByName List.65 List.89 List.297;
let List.295 : List I64 = CallByName List.66 List.296 List.90;
ret List.295;
procedure List.65 (#Attr.2, #Attr.3):
let List.287 : List I64 = lowlevel ListReserve #Attr.2 #Attr.3;
ret List.287;
let List.299 : List I64 = lowlevel ListReserve #Attr.2 #Attr.3;
ret List.299;
procedure List.66 (#Attr.2, #Attr.3):
let List.286 : List I64 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3;
ret List.286;
let List.298 : List I64 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3;
ret List.298;
procedure Test.1 (Test.2):
let Test.6 : I64 = 42i64;

View file

@ -1,35 +1,35 @@
procedure List.3 (List.85, List.86, List.87):
let List.286 : {List I64, I64} = CallByName List.57 List.85 List.86 List.87;
let List.285 : List I64 = StructAtIndex 0 List.286;
inc List.285;
dec List.286;
ret List.285;
procedure List.3 (List.86, List.87, List.88):
let List.298 : {List I64, I64} = CallByName List.57 List.86 List.87 List.88;
let List.297 : List I64 = StructAtIndex 0 List.298;
inc List.297;
dec List.298;
ret List.297;
procedure List.57 (List.82, List.83, List.84):
let List.291 : U64 = CallByName List.6 List.82;
let List.288 : Int1 = CallByName Num.22 List.83 List.291;
if List.288 then
let List.289 : {List I64, I64} = CallByName List.61 List.82 List.83 List.84;
ret List.289;
procedure List.57 (List.83, List.84, List.85):
let List.303 : U64 = CallByName List.6 List.83;
let List.300 : Int1 = CallByName Num.22 List.84 List.303;
if List.300 then
let List.301 : {List I64, I64} = CallByName List.61 List.83 List.84 List.85;
ret List.301;
else
let List.287 : {List I64, I64} = Struct {List.82, List.84};
ret List.287;
let List.299 : {List I64, I64} = Struct {List.83, List.85};
ret List.299;
procedure List.6 (#Attr.2):
let List.284 : U64 = lowlevel ListLen #Attr.2;
ret List.284;
let List.296 : U64 = lowlevel ListLen #Attr.2;
ret List.296;
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
let List.290 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
ret List.290;
let List.302 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
ret List.302;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.188 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.257;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.189 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.189;
let Num.258 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.258;
procedure Test.1 ():
let Test.8 : List I64 = Array [1i64, 2i64, 3i64];

View file

@ -1,26 +1,26 @@
procedure List.2 (List.77, List.78):
let List.288 : U64 = CallByName List.6 List.77;
let List.285 : Int1 = CallByName Num.22 List.78 List.288;
if List.285 then
let List.287 : I64 = CallByName List.60 List.77 List.78;
let List.286 : [C {}, C I64] = TagId(1) List.287;
ret List.286;
procedure List.2 (List.78, List.79):
let List.300 : U64 = CallByName List.6 List.78;
let List.297 : Int1 = CallByName Num.22 List.79 List.300;
if List.297 then
let List.299 : I64 = CallByName List.60 List.78 List.79;
let List.298 : [C {}, C I64] = TagId(1) List.299;
ret List.298;
else
let List.284 : {} = Struct {};
let List.283 : [C {}, C I64] = TagId(0) List.284;
ret List.283;
let List.296 : {} = Struct {};
let List.295 : [C {}, C I64] = TagId(0) List.296;
ret List.295;
procedure List.6 (#Attr.2):
let List.290 : U64 = lowlevel ListLen #Attr.2;
ret List.290;
let List.302 : U64 = lowlevel ListLen #Attr.2;
ret List.302;
procedure List.60 (#Attr.2, #Attr.3):
let List.289 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.289;
let List.301 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.301;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.188 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.257;
procedure Test.1 (Test.2):
let Test.6 : List I64 = Array [1i64, 2i64, 3i64];

View file

@ -1,14 +1,14 @@
procedure List.6 (#Attr.2):
let List.283 : U64 = lowlevel ListLen #Attr.2;
ret List.283;
let List.295 : U64 = lowlevel ListLen #Attr.2;
ret List.295;
procedure List.6 (#Attr.2):
let List.284 : U64 = lowlevel ListLen #Attr.2;
ret List.284;
let List.296 : U64 = lowlevel ListLen #Attr.2;
ret List.296;
procedure Num.19 (#Attr.2, #Attr.3):
let Num.188 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.257;
procedure Test.0 ():
let Test.1 : List I64 = Array [1i64, 2i64, 3i64];

View file

@ -1,38 +1,38 @@
procedure List.2 (List.77, List.78):
let List.288 : U64 = CallByName List.6 List.77;
let List.285 : Int1 = CallByName Num.22 List.78 List.288;
if List.285 then
let List.287 : Str = CallByName List.60 List.77 List.78;
let List.286 : [C {}, C Str] = TagId(1) List.287;
ret List.286;
procedure List.2 (List.78, List.79):
let List.300 : U64 = CallByName List.6 List.78;
let List.297 : Int1 = CallByName Num.22 List.79 List.300;
if List.297 then
let List.299 : Str = CallByName List.60 List.78 List.79;
let List.298 : [C {}, C Str] = TagId(1) List.299;
ret List.298;
else
let List.284 : {} = Struct {};
let List.283 : [C {}, C Str] = TagId(0) List.284;
ret List.283;
let List.296 : {} = Struct {};
let List.295 : [C {}, C Str] = TagId(0) List.296;
ret List.295;
procedure List.5 (#Attr.2, #Attr.3):
let List.289 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.3 #Attr.3;
ret List.289;
let List.301 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.3 #Attr.3;
ret List.301;
procedure List.6 (#Attr.2):
let List.291 : U64 = lowlevel ListLen #Attr.2;
ret List.291;
let List.303 : U64 = lowlevel ListLen #Attr.2;
ret List.303;
procedure List.60 (#Attr.2, #Attr.3):
let List.290 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.290;
let List.302 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.302;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.188 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.257;
procedure Str.16 (#Attr.2, #Attr.3):
let Str.154 : Str = lowlevel StrRepeat #Attr.2 #Attr.3;
ret Str.154;
let Str.194 : Str = lowlevel StrRepeat #Attr.2 #Attr.3;
ret Str.194;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.155 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
ret Str.155;
let Str.195 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
ret Str.195;
procedure Test.1 ():
let Test.21 : Str = "lllllllllllllllllllllooooooooooong";

View file

@ -1,36 +1,36 @@
procedure List.2 (List.77, List.78):
let List.288 : U64 = CallByName List.6 List.77;
let List.285 : Int1 = CallByName Num.22 List.78 List.288;
if List.285 then
let List.287 : Str = CallByName List.60 List.77 List.78;
let List.286 : [C {}, C Str] = TagId(1) List.287;
ret List.286;
procedure List.2 (List.78, List.79):
let List.300 : U64 = CallByName List.6 List.78;
let List.297 : Int1 = CallByName Num.22 List.79 List.300;
if List.297 then
let List.299 : Str = CallByName List.60 List.78 List.79;
let List.298 : [C {}, C Str] = TagId(1) List.299;
ret List.298;
else
let List.284 : {} = Struct {};
let List.283 : [C {}, C Str] = TagId(0) List.284;
ret List.283;
let List.296 : {} = Struct {};
let List.295 : [C {}, C Str] = TagId(0) List.296;
ret List.295;
procedure List.5 (#Attr.2, #Attr.3):
inc #Attr.2;
let List.289 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.3 #Attr.3;
let List.301 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.3 #Attr.3;
decref #Attr.2;
ret List.289;
ret List.301;
procedure List.6 (#Attr.2):
let List.291 : U64 = lowlevel ListLen #Attr.2;
ret List.291;
let List.303 : U64 = lowlevel ListLen #Attr.2;
ret List.303;
procedure List.60 (#Attr.2, #Attr.3):
let List.290 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.290;
let List.302 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.302;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.188 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.257;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.155 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
ret Str.155;
let Str.195 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
ret Str.195;
procedure Test.1 ():
let Test.21 : Str = "lllllllllllllllllllllooooooooooong";

View file

@ -1,31 +1,31 @@
procedure List.3 (List.85, List.86, List.87):
let List.284 : {List I64, I64} = CallByName List.57 List.85 List.86 List.87;
let List.283 : List I64 = StructAtIndex 0 List.284;
inc List.283;
dec List.284;
ret List.283;
procedure List.3 (List.86, List.87, List.88):
let List.296 : {List I64, I64} = CallByName List.57 List.86 List.87 List.88;
let List.295 : List I64 = StructAtIndex 0 List.296;
inc List.295;
dec List.296;
ret List.295;
procedure List.57 (List.82, List.83, List.84):
let List.289 : U64 = CallByName List.6 List.82;
let List.286 : Int1 = CallByName Num.22 List.83 List.289;
if List.286 then
let List.287 : {List I64, I64} = CallByName List.61 List.82 List.83 List.84;
ret List.287;
procedure List.57 (List.83, List.84, List.85):
let List.301 : U64 = CallByName List.6 List.83;
let List.298 : Int1 = CallByName Num.22 List.84 List.301;
if List.298 then
let List.299 : {List I64, I64} = CallByName List.61 List.83 List.84 List.85;
ret List.299;
else
let List.285 : {List I64, I64} = Struct {List.82, List.84};
ret List.285;
let List.297 : {List I64, I64} = Struct {List.83, List.85};
ret List.297;
procedure List.6 (#Attr.2):
let List.290 : U64 = lowlevel ListLen #Attr.2;
ret List.290;
let List.302 : U64 = lowlevel ListLen #Attr.2;
ret List.302;
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
let List.288 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
ret List.288;
let List.300 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
ret List.300;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.188 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.257;
procedure Test.2 (Test.3):
let Test.6 : U64 = 0i64;

View file

@ -1,20 +1,20 @@
procedure List.28 (#Attr.2, #Attr.3):
let List.285 : List I64 = lowlevel ListSortWith { xs: `#Attr.#arg1` } #Attr.2 Num.46 #Attr.3;
let List.297 : List I64 = lowlevel ListSortWith { xs: `#Attr.#arg1` } #Attr.2 Num.46 #Attr.3;
let Bool.9 : Int1 = lowlevel ListIsUnique #Attr.2;
if Bool.9 then
ret List.285;
ret List.297;
else
decref #Attr.2;
ret List.285;
ret List.297;
procedure List.54 (List.200):
let List.284 : {} = Struct {};
let List.283 : List I64 = CallByName List.28 List.200 List.284;
ret List.283;
procedure List.54 (List.201):
let List.296 : {} = Struct {};
let List.295 : List I64 = CallByName List.28 List.201 List.296;
ret List.295;
procedure Num.46 (#Attr.2, #Attr.3):
let Num.188 : U8 = lowlevel NumCompare #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : U8 = lowlevel NumCompare #Attr.2 #Attr.3;
ret Num.257;
procedure Test.0 ():
let Test.2 : List I64 = Array [4i64, 3i64, 2i64, 1i64];

View file

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

View file

@ -1,6 +1,6 @@
procedure Num.21 (#Attr.2, #Attr.3):
let Num.190 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.190;
let Num.259 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.259;
procedure Test.1 (Test.6):
let Test.21 : Int1 = false;

View file

@ -1,14 +1,14 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.188 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.257;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.189 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.189;
let Num.258 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.258;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.190 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.190;
let Num.259 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.259;
procedure Test.1 (Test.24, Test.25, Test.26):
joinpoint Test.12 Test.2 Test.3 Test.4:

View file

@ -1,47 +1,47 @@
procedure List.2 (List.77, List.78):
let List.298 : U64 = CallByName List.6 List.77;
let List.295 : Int1 = CallByName Num.22 List.78 List.298;
if List.295 then
let List.297 : I64 = CallByName List.60 List.77 List.78;
let List.296 : [C {}, C I64] = TagId(1) List.297;
ret List.296;
procedure List.2 (List.78, List.79):
let List.310 : U64 = CallByName List.6 List.78;
let List.307 : Int1 = CallByName Num.22 List.79 List.310;
if List.307 then
let List.309 : I64 = CallByName List.60 List.78 List.79;
let List.308 : [C {}, C I64] = TagId(1) List.309;
ret List.308;
else
let List.294 : {} = Struct {};
let List.293 : [C {}, C I64] = TagId(0) List.294;
ret List.293;
let List.306 : {} = Struct {};
let List.305 : [C {}, C I64] = TagId(0) List.306;
ret List.305;
procedure List.3 (List.85, List.86, List.87):
let List.286 : {List I64, I64} = CallByName List.57 List.85 List.86 List.87;
let List.285 : List I64 = StructAtIndex 0 List.286;
inc List.285;
dec List.286;
ret List.285;
procedure List.3 (List.86, List.87, List.88):
let List.298 : {List I64, I64} = CallByName List.57 List.86 List.87 List.88;
let List.297 : List I64 = StructAtIndex 0 List.298;
inc List.297;
dec List.298;
ret List.297;
procedure List.57 (List.82, List.83, List.84):
let List.303 : U64 = CallByName List.6 List.82;
let List.300 : Int1 = CallByName Num.22 List.83 List.303;
if List.300 then
let List.301 : {List I64, I64} = CallByName List.61 List.82 List.83 List.84;
ret List.301;
procedure List.57 (List.83, List.84, List.85):
let List.315 : U64 = CallByName List.6 List.83;
let List.312 : Int1 = CallByName Num.22 List.84 List.315;
if List.312 then
let List.313 : {List I64, I64} = CallByName List.61 List.83 List.84 List.85;
ret List.313;
else
let List.299 : {List I64, I64} = Struct {List.82, List.84};
ret List.299;
let List.311 : {List I64, I64} = Struct {List.83, List.85};
ret List.311;
procedure List.6 (#Attr.2):
let List.304 : U64 = lowlevel ListLen #Attr.2;
ret List.304;
let List.316 : U64 = lowlevel ListLen #Attr.2;
ret List.316;
procedure List.60 (#Attr.2, #Attr.3):
let List.305 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.305;
let List.317 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.317;
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
let List.302 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
ret List.302;
let List.314 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
ret List.314;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.190 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.190;
let Num.259 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.259;
procedure Test.1 (Test.2):
let Test.28 : U64 = 0i64;

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.188 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.257;
procedure Test.1 (Test.4):
let Test.2 : I64 = StructAtIndex 0 Test.4;

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.188 : U32 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : U32 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.257;
procedure Test.1 (Test.2):
let Test.9 : U32 = 0i64;

View file

@ -1,47 +1,47 @@
procedure List.2 (List.77, List.78):
let List.298 : U64 = CallByName List.6 List.77;
let List.295 : Int1 = CallByName Num.22 List.78 List.298;
if List.295 then
let List.297 : I64 = CallByName List.60 List.77 List.78;
let List.296 : [C {}, C I64] = TagId(1) List.297;
ret List.296;
procedure List.2 (List.78, List.79):
let List.310 : U64 = CallByName List.6 List.78;
let List.307 : Int1 = CallByName Num.22 List.79 List.310;
if List.307 then
let List.309 : I64 = CallByName List.60 List.78 List.79;
let List.308 : [C {}, C I64] = TagId(1) List.309;
ret List.308;
else
let List.294 : {} = Struct {};
let List.293 : [C {}, C I64] = TagId(0) List.294;
ret List.293;
let List.306 : {} = Struct {};
let List.305 : [C {}, C I64] = TagId(0) List.306;
ret List.305;
procedure List.3 (List.85, List.86, List.87):
let List.286 : {List I64, I64} = CallByName List.57 List.85 List.86 List.87;
let List.285 : List I64 = StructAtIndex 0 List.286;
inc List.285;
dec List.286;
ret List.285;
procedure List.3 (List.86, List.87, List.88):
let List.298 : {List I64, I64} = CallByName List.57 List.86 List.87 List.88;
let List.297 : List I64 = StructAtIndex 0 List.298;
inc List.297;
dec List.298;
ret List.297;
procedure List.57 (List.82, List.83, List.84):
let List.303 : U64 = CallByName List.6 List.82;
let List.300 : Int1 = CallByName Num.22 List.83 List.303;
if List.300 then
let List.301 : {List I64, I64} = CallByName List.61 List.82 List.83 List.84;
ret List.301;
procedure List.57 (List.83, List.84, List.85):
let List.315 : U64 = CallByName List.6 List.83;
let List.312 : Int1 = CallByName Num.22 List.84 List.315;
if List.312 then
let List.313 : {List I64, I64} = CallByName List.61 List.83 List.84 List.85;
ret List.313;
else
let List.299 : {List I64, I64} = Struct {List.82, List.84};
ret List.299;
let List.311 : {List I64, I64} = Struct {List.83, List.85};
ret List.311;
procedure List.6 (#Attr.2):
let List.304 : U64 = lowlevel ListLen #Attr.2;
ret List.304;
let List.316 : U64 = lowlevel ListLen #Attr.2;
ret List.316;
procedure List.60 (#Attr.2, #Attr.3):
let List.305 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.305;
let List.317 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.317;
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
let List.302 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
ret List.302;
let List.314 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
ret List.314;
procedure Num.22 (#Attr.2, #Attr.3):
let Num.190 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.190;
let Num.259 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
ret Num.259;
procedure Test.1 (Test.2, Test.3, Test.4):
let Test.29 : [C {}, C I64] = CallByName List.2 Test.4 Test.3;

View file

@ -1,10 +1,10 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.189 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.189;
let Num.258 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.258;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.188 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.257;
procedure Test.1 (Test.2, Test.3):
let Test.17 : U8 = GetTagId Test.2;

View file

@ -1,10 +1,10 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.189 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.189;
let Num.258 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.258;
procedure Num.21 (#Attr.2, #Attr.3):
let Num.188 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : I64 = lowlevel NumMul #Attr.2 #Attr.3;
ret Num.257;
procedure Test.6 (Test.8, #Attr.12):
let Test.4 : I64 = UnionAtIndex (Id 0) (Index 0) #Attr.12;

View file

@ -1,10 +1,10 @@
procedure Num.19 (#Attr.2, #Attr.3):
let Num.188 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.188;
let Num.257 : I64 = lowlevel NumAdd #Attr.2 #Attr.3;
ret Num.257;
procedure Num.20 (#Attr.2, #Attr.3):
let Num.189 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.189;
let Num.258 : I64 = lowlevel NumSub #Attr.2 #Attr.3;
ret Num.258;
procedure Test.1 (Test.15, Test.16):
joinpoint Test.7 Test.2 Test.3:

View file

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

View file

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

View file

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

View file

@ -84,7 +84,7 @@ impl SubsHeader {
fn from_subs(subs: &Subs, exposed_vars_by_symbol: usize) -> Self {
// TODO what do we do with problems? they should
// be reported and then removed from Subs I think
debug_assert!(subs.problems.is_empty());
debug_assert!(subs.problems.is_empty(), "{:?}", &subs.problems);
Self {
utable: subs.utable.len() as u64,