mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
working mono
This commit is contained in:
parent
25a64f4a57
commit
c4ec9aa898
15 changed files with 431 additions and 358 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3458,6 +3458,7 @@ dependencies = [
|
|||
"bumpalo",
|
||||
"hashbrown 0.11.2",
|
||||
"morphic_lib",
|
||||
"roc_builtins",
|
||||
"roc_can",
|
||||
"roc_collections",
|
||||
"roc_module",
|
||||
|
|
|
@ -71,7 +71,7 @@ fn jit_to_ast_help<'a>(
|
|||
content: &Content,
|
||||
) -> Result<Expr<'a>, ToAstProblem> {
|
||||
match layout {
|
||||
Layout::Builtin(Builtin::Int1) => Ok(run_jit_function!(lib, main_fn_name, bool, |num| {
|
||||
Layout::Builtin(Builtin::Bool) => Ok(run_jit_function!(lib, main_fn_name, bool, |num| {
|
||||
bool_to_ast(env, num, content)
|
||||
})),
|
||||
Layout::Builtin(Builtin::Int8) => {
|
||||
|
@ -248,7 +248,7 @@ fn jit_to_ast_help<'a>(
|
|||
.unwrap_or(0);
|
||||
|
||||
let tag_id = match union_layout.tag_id_builtin() {
|
||||
Builtin::Int1 => {
|
||||
Builtin::Bool => {
|
||||
*(ptr.add(offset as usize) as *const i8) as i64
|
||||
}
|
||||
Builtin::Int8 => {
|
||||
|
@ -406,7 +406,7 @@ fn ptr_to_ast<'a>(
|
|||
|
||||
num_to_ast(env, number_literal_to_ast(env.arena, num), content)
|
||||
}
|
||||
Layout::Builtin(Builtin::Int1) => {
|
||||
Layout::Builtin(Builtin::Bool) => {
|
||||
// TODO: bits are not as expected here.
|
||||
// num is always false at the moment.
|
||||
let num = unsafe { *(ptr as *const bool) };
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use roc_module::symbol::Symbol;
|
||||
use std::ops::Index;
|
||||
|
||||
pub const BUILTINS_HOST_OBJ_PATH: &str = env!(
|
||||
|
@ -27,13 +28,55 @@ pub enum DecWidth {
|
|||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum FloatWidth {
|
||||
F32,
|
||||
F64,
|
||||
F128,
|
||||
}
|
||||
|
||||
impl FloatWidth {
|
||||
pub const fn stack_size(&self) -> u32 {
|
||||
use FloatWidth::*;
|
||||
|
||||
match self {
|
||||
F32 => 4,
|
||||
F64 => 8,
|
||||
F128 => 16,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn alignment_bytes(&self) -> u32 {
|
||||
use std::mem::align_of;
|
||||
use FloatWidth::*;
|
||||
|
||||
// TODO actually alignment is architecture-specific
|
||||
match self {
|
||||
F32 => align_of::<f32>() as u32,
|
||||
F64 => align_of::<f64>() as u32,
|
||||
F128 => align_of::<i128>() as u32,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn try_from_symbol(symbol: Symbol) -> Option<Self> {
|
||||
match symbol {
|
||||
Symbol::NUM_FLOAT => Some(FloatWidth::F64),
|
||||
|
||||
Symbol::NUM_F64 | Symbol::NUM_BINARY64 | Symbol::NUM_AT_BINARY64 => {
|
||||
Some(FloatWidth::F64)
|
||||
}
|
||||
|
||||
Symbol::NUM_F32 | Symbol::NUM_BINARY32 | Symbol::NUM_AT_BINARY32 => {
|
||||
Some(FloatWidth::F32)
|
||||
}
|
||||
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum IntWidth {
|
||||
U8,
|
||||
U16,
|
||||
|
@ -47,6 +90,61 @@ pub enum IntWidth {
|
|||
I128,
|
||||
}
|
||||
|
||||
impl IntWidth {
|
||||
pub const fn stack_size(&self) -> u32 {
|
||||
use IntWidth::*;
|
||||
|
||||
match self {
|
||||
U8 | I8 => 1,
|
||||
U16 | I16 => 2,
|
||||
U32 | I32 => 4,
|
||||
U64 | I64 => 8,
|
||||
U128 | I128 => 16,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn alignment_bytes(&self) -> u32 {
|
||||
use std::mem::align_of;
|
||||
use IntWidth::*;
|
||||
|
||||
// TODO actually alignment is architecture-specific
|
||||
match self {
|
||||
U8 | I8 => align_of::<i8>() as u32,
|
||||
U16 | I16 => align_of::<i16>() as u32,
|
||||
U32 | I32 => align_of::<i32>() as u32,
|
||||
U64 | I64 => align_of::<i64>() as u32,
|
||||
U128 | I128 => align_of::<i128>() as u32,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn try_from_symbol(symbol: Symbol) -> Option<Self> {
|
||||
match symbol {
|
||||
Symbol::NUM_INT => Some(IntWidth::I64),
|
||||
Symbol::NUM_I128 | Symbol::NUM_SIGNED128 | Symbol::NUM_AT_SIGNED128 => {
|
||||
Some(IntWidth::I128)
|
||||
}
|
||||
Symbol::NUM_I64 | Symbol::NUM_SIGNED64 | Symbol::NUM_AT_SIGNED64 => Some(IntWidth::I64),
|
||||
Symbol::NUM_I32 | Symbol::NUM_SIGNED32 | Symbol::NUM_AT_SIGNED32 => Some(IntWidth::I32),
|
||||
Symbol::NUM_I16 | Symbol::NUM_SIGNED16 | Symbol::NUM_AT_SIGNED16 => Some(IntWidth::I16),
|
||||
Symbol::NUM_I8 | Symbol::NUM_SIGNED8 | Symbol::NUM_AT_SIGNED8 => Some(IntWidth::I8),
|
||||
Symbol::NUM_U128 | Symbol::NUM_UNSIGNED128 | Symbol::NUM_AT_UNSIGNED128 => {
|
||||
Some(IntWidth::U128)
|
||||
}
|
||||
Symbol::NUM_U64 | Symbol::NUM_UNSIGNED64 | Symbol::NUM_AT_UNSIGNED64 => {
|
||||
Some(IntWidth::U64)
|
||||
}
|
||||
Symbol::NUM_U32 | Symbol::NUM_UNSIGNED32 | Symbol::NUM_AT_UNSIGNED32 => {
|
||||
Some(IntWidth::U32)
|
||||
}
|
||||
Symbol::NUM_U16 | Symbol::NUM_UNSIGNED16 | Symbol::NUM_AT_UNSIGNED16 => {
|
||||
Some(IntWidth::U16)
|
||||
}
|
||||
Symbol::NUM_U8 | Symbol::NUM_UNSIGNED8 | Symbol::NUM_AT_UNSIGNED8 => Some(IntWidth::U8),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<DecWidth> for IntrinsicName {
|
||||
type Output = str;
|
||||
|
||||
|
|
|
@ -410,7 +410,7 @@ where
|
|||
"Eq: expected all arguments of to have the same layout"
|
||||
);
|
||||
debug_assert_eq!(
|
||||
Layout::Builtin(Builtin::Int1),
|
||||
Layout::Builtin(Builtin::Bool),
|
||||
*ret_layout,
|
||||
"Eq: expected to have return layout of type I1"
|
||||
);
|
||||
|
@ -427,7 +427,7 @@ where
|
|||
"NotEq: expected all arguments of to have the same layout"
|
||||
);
|
||||
debug_assert_eq!(
|
||||
Layout::Builtin(Builtin::Int1),
|
||||
Layout::Builtin(Builtin::Bool),
|
||||
*ret_layout,
|
||||
"NotEq: expected to have return layout of type I1"
|
||||
);
|
||||
|
|
|
@ -715,7 +715,7 @@ pub fn int_with_precision<'a, 'ctx, 'env>(
|
|||
Builtin::Int32 => env.context.i32_type().const_int(value as u64, false),
|
||||
Builtin::Int16 => env.context.i16_type().const_int(value as u64, false),
|
||||
Builtin::Int8 => env.context.i8_type().const_int(value as u64, false),
|
||||
Builtin::Int1 => env.context.bool_type().const_int(value as u64, false),
|
||||
Builtin::Bool => env.context.bool_type().const_int(value as u64, false),
|
||||
_ => panic!("Invalid layout for int literal = {:?}", precision),
|
||||
}
|
||||
}
|
||||
|
@ -3072,7 +3072,7 @@ fn build_switch_ir<'a, 'ctx, 'env>(
|
|||
// Build the cases
|
||||
let mut incoming = Vec::with_capacity_in(branches.len(), arena);
|
||||
|
||||
if let Layout::Builtin(Builtin::Int1) = cond_layout {
|
||||
if let Layout::Builtin(Builtin::Bool) = cond_layout {
|
||||
match (branches, default_branch) {
|
||||
([(0, _, false_branch)], true_branch) | ([(1, _, true_branch)], false_branch) => {
|
||||
let then_block = context.append_basic_block(parent, "then_block");
|
||||
|
@ -5133,7 +5133,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
Layout::Builtin(Builtin::Int1),
|
||||
Layout::Builtin(Builtin::Bool),
|
||||
);
|
||||
|
||||
list_any(env, roc_function_call, list, element_layout)
|
||||
|
@ -5160,7 +5160,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
Layout::Builtin(Builtin::Int1),
|
||||
Layout::Builtin(Builtin::Bool),
|
||||
);
|
||||
|
||||
list_all(env, roc_function_call, list, element_layout)
|
||||
|
@ -5193,7 +5193,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
Layout::Builtin(Builtin::Int1),
|
||||
Layout::Builtin(Builtin::Bool),
|
||||
);
|
||||
list_find_unsafe(env, layout_ids, roc_function_call, list, element_layout)
|
||||
}
|
||||
|
@ -6101,7 +6101,7 @@ fn to_cc_type_builtin<'a, 'ctx, 'env>(
|
|||
| Builtin::Int32
|
||||
| Builtin::Int16
|
||||
| Builtin::Int8
|
||||
| Builtin::Int1
|
||||
| Builtin::Bool
|
||||
| Builtin::Usize
|
||||
| Builtin::Decimal
|
||||
| Builtin::Float128
|
||||
|
|
|
@ -128,7 +128,7 @@ fn hash_builtin<'a, 'ctx, 'env>(
|
|||
| Builtin::Int32
|
||||
| Builtin::Int16
|
||||
| Builtin::Int8
|
||||
| Builtin::Int1
|
||||
| Builtin::Bool
|
||||
| Builtin::Float64
|
||||
| Builtin::Float32
|
||||
| Builtin::Float128
|
||||
|
|
|
@ -93,7 +93,7 @@ fn build_eq_builtin<'a, 'ctx, 'env>(
|
|||
Builtin::Int32 => int_cmp(IntPredicate::EQ, "eq_i32"),
|
||||
Builtin::Int16 => int_cmp(IntPredicate::EQ, "eq_i16"),
|
||||
Builtin::Int8 => int_cmp(IntPredicate::EQ, "eq_i8"),
|
||||
Builtin::Int1 => int_cmp(IntPredicate::EQ, "eq_i1"),
|
||||
Builtin::Bool => int_cmp(IntPredicate::EQ, "eq_i1"),
|
||||
|
||||
Builtin::Usize => int_cmp(IntPredicate::EQ, "eq_usize"),
|
||||
|
||||
|
@ -236,7 +236,7 @@ fn build_neq_builtin<'a, 'ctx, 'env>(
|
|||
Builtin::Int32 => int_cmp(IntPredicate::NE, "neq_i32"),
|
||||
Builtin::Int16 => int_cmp(IntPredicate::NE, "neq_i16"),
|
||||
Builtin::Int8 => int_cmp(IntPredicate::NE, "neq_i8"),
|
||||
Builtin::Int1 => int_cmp(IntPredicate::NE, "neq_i1"),
|
||||
Builtin::Bool => int_cmp(IntPredicate::NE, "neq_i1"),
|
||||
|
||||
Builtin::Usize => int_cmp(IntPredicate::NE, "neq_usize"),
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ pub fn basic_type_from_builtin<'a, 'ctx, 'env>(
|
|||
Int32 => context.i32_type().as_basic_type_enum(),
|
||||
Int16 => context.i16_type().as_basic_type_enum(),
|
||||
Int8 => context.i8_type().as_basic_type_enum(),
|
||||
Int1 => context.bool_type().as_basic_type_enum(),
|
||||
Bool => context.bool_type().as_basic_type_enum(),
|
||||
Usize => ptr_int(context, ptr_bytes).as_basic_type_enum(),
|
||||
Decimal => context.i128_type().as_basic_type_enum(),
|
||||
Float128 => context.f128_type().as_basic_type_enum(),
|
||||
|
|
|
@ -328,7 +328,7 @@ impl<'a> WasmBackend<'a> {
|
|||
self.start_block(BlockType::NoResult)
|
||||
}
|
||||
|
||||
let is_bool = matches!(cond_layout, Layout::Builtin(Builtin::Int1));
|
||||
let is_bool = matches!(cond_layout, Layout::Builtin(Builtin::Bool));
|
||||
let cond_type = WasmLayout::new(cond_layout).value_type();
|
||||
|
||||
// then, we jump whenever the value under scrutiny is equal to the value of a branch
|
||||
|
|
|
@ -26,7 +26,7 @@ impl WasmLayout {
|
|||
let alignment_bytes = layout.alignment_bytes(PTR_SIZE);
|
||||
|
||||
match layout {
|
||||
Layout::Builtin(Int32 | Int16 | Int8 | Int1 | Usize) => Self::Primitive(I32, size),
|
||||
Layout::Builtin(Int32 | Int16 | Int8 | Bool | Usize) => Self::Primitive(I32, size),
|
||||
|
||||
Layout::Builtin(Int64) => Self::Primitive(I64, size),
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ roc_unify = { path = "../unify" }
|
|||
roc_solve = { path = "../solve" }
|
||||
roc_std = { path = "../../roc_std" }
|
||||
roc_problem = { path = "../problem" }
|
||||
roc_builtins = { path = "../builtins" }
|
||||
ven_pretty = { path = "../../vendor/pretty" }
|
||||
morphic_lib = { path = "../../vendor/morphic_lib" }
|
||||
bumpalo = { version = "3.8.0", features = ["collections"] }
|
||||
|
|
|
@ -590,7 +590,7 @@ impl<'a> ResultRepr<'a> {
|
|||
err: tags[ERR_TAG_ID as usize][0],
|
||||
ok: tags[OK_TAG_ID as usize][0],
|
||||
},
|
||||
Layout::Builtin(Builtin::Int1) => ResultRepr::Int1,
|
||||
Layout::Builtin(Builtin::Bool) => ResultRepr::Int1,
|
||||
other => unreachable!("unexpected layout: {:?}", other),
|
||||
}
|
||||
}
|
||||
|
@ -1086,7 +1086,7 @@ fn call_spec(
|
|||
Ok(new_state)
|
||||
};
|
||||
|
||||
let state_layout = Layout::Builtin(Builtin::Int1);
|
||||
let state_layout = Layout::Builtin(Builtin::Bool);
|
||||
let state_type = layout_spec(builder, &state_layout)?;
|
||||
|
||||
let init_state = new_num(builder, block)?;
|
||||
|
@ -1105,7 +1105,7 @@ fn call_spec(
|
|||
Ok(new_state)
|
||||
};
|
||||
|
||||
let state_layout = Layout::Builtin(Builtin::Int1);
|
||||
let state_layout = Layout::Builtin(Builtin::Bool);
|
||||
let state_type = layout_spec(builder, &state_layout)?;
|
||||
|
||||
let init_state = new_num(builder, block)?;
|
||||
|
@ -1116,7 +1116,7 @@ fn call_spec(
|
|||
let list = env.symbols[xs];
|
||||
|
||||
// ListFindUnsafe returns { value: v, found: Bool=Int1 }
|
||||
let output_layouts = vec![arg_layouts[0], Layout::Builtin(Builtin::Int1)];
|
||||
let output_layouts = vec![arg_layouts[0], Layout::Builtin(Builtin::Bool)];
|
||||
let output_layout = Layout::Struct(&output_layouts);
|
||||
let output_type = layout_spec(builder, &output_layout)?;
|
||||
|
||||
|
@ -1718,8 +1718,8 @@ fn builtin_spec(
|
|||
use Builtin::*;
|
||||
|
||||
match builtin {
|
||||
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Usize => builder.add_tuple_type(&[]),
|
||||
Decimal | Float128 | Float64 | Float32 => builder.add_tuple_type(&[]),
|
||||
Int(_) | Usize | Bool => builder.add_tuple_type(&[]),
|
||||
Decimal | Float(_) => builder.add_tuple_type(&[]),
|
||||
Str | EmptyStr => str_type(builder),
|
||||
Dict(key_layout, value_layout) => {
|
||||
let value_type = layout_spec_help(builder, value_layout, when_recursive)?;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::exhaustive::{Ctor, RenderAs, TagId, Union};
|
||||
use crate::ir::{
|
||||
BranchInfo, DestructType, Env, Expr, FloatPrecision, IntPrecision, JoinPointId, Literal, Param,
|
||||
Pattern, Procs, Stmt,
|
||||
BranchInfo, DestructType, Env, Expr, JoinPointId, Literal, Param, Pattern, Procs, Stmt,
|
||||
};
|
||||
use crate::layout::{Builtin, Layout, LayoutCache, TagIdIntType, UnionLayout};
|
||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||
use roc_collections::all::{MutMap, MutSet};
|
||||
use roc_module::ident::TagName;
|
||||
use roc_module::low_level::LowLevel;
|
||||
|
@ -86,8 +86,8 @@ enum Test<'a> {
|
|||
union: crate::exhaustive::Union,
|
||||
arguments: Vec<(Pattern<'a>, Layout<'a>)>,
|
||||
},
|
||||
IsInt(i128, IntPrecision),
|
||||
IsFloat(u64, FloatPrecision),
|
||||
IsInt(i128, IntWidth),
|
||||
IsFloat(u64, FloatWidth),
|
||||
IsDecimal(RocDec),
|
||||
IsStr(Box<str>),
|
||||
IsBit(bool),
|
||||
|
@ -1300,7 +1300,7 @@ fn test_to_equality<'a>(
|
|||
debug_assert!(test_int <= i64::MAX as i128);
|
||||
let lhs = Expr::Literal(Literal::Int(test_int as i128));
|
||||
let lhs_symbol = env.unique_symbol();
|
||||
stores.push((lhs_symbol, precision.as_layout(), lhs));
|
||||
stores.push((lhs_symbol, Layout::int_width(precision), lhs));
|
||||
|
||||
(stores, lhs_symbol, rhs_symbol, None)
|
||||
}
|
||||
|
@ -1310,7 +1310,7 @@ fn test_to_equality<'a>(
|
|||
let test_float = f64::from_bits(test_int as u64);
|
||||
let lhs = Expr::Literal(Literal::Float(test_float));
|
||||
let lhs_symbol = env.unique_symbol();
|
||||
stores.push((lhs_symbol, precision.as_layout(), lhs));
|
||||
stores.push((lhs_symbol, Layout::float_width(precision), lhs));
|
||||
|
||||
(stores, lhs_symbol, rhs_symbol, None)
|
||||
}
|
||||
|
@ -1330,7 +1330,7 @@ fn test_to_equality<'a>(
|
|||
|
||||
let lhs = Expr::Literal(Literal::Byte(test_byte as u8));
|
||||
let lhs_symbol = env.unique_symbol();
|
||||
stores.push((lhs_symbol, Layout::Builtin(Builtin::Int8), lhs));
|
||||
stores.push((lhs_symbol, Layout::u8(), lhs));
|
||||
|
||||
(stores, lhs_symbol, rhs_symbol, None)
|
||||
}
|
||||
|
@ -1338,7 +1338,7 @@ fn test_to_equality<'a>(
|
|||
Test::IsBit(test_bit) => {
|
||||
let lhs = Expr::Literal(Literal::Bool(test_bit));
|
||||
let lhs_symbol = env.unique_symbol();
|
||||
stores.push((lhs_symbol, Layout::Builtin(Builtin::Int1), lhs));
|
||||
stores.push((lhs_symbol, Layout::Builtin(Builtin::Bool), lhs));
|
||||
|
||||
(stores, lhs_symbol, rhs_symbol, None)
|
||||
}
|
||||
|
@ -1459,7 +1459,7 @@ fn compile_test_help<'a>(
|
|||
|
||||
cond = Stmt::Switch {
|
||||
cond_symbol: test_symbol,
|
||||
cond_layout: Layout::Builtin(Builtin::Int1),
|
||||
cond_layout: Layout::Builtin(Builtin::Bool),
|
||||
ret_layout,
|
||||
branches,
|
||||
default_branch,
|
||||
|
@ -1478,7 +1478,7 @@ fn compile_test_help<'a>(
|
|||
cond = Stmt::Let(
|
||||
test_symbol,
|
||||
test,
|
||||
Layout::Builtin(Builtin::Int1),
|
||||
Layout::Builtin(Builtin::Bool),
|
||||
arena.alloc(cond),
|
||||
);
|
||||
|
||||
|
@ -1622,7 +1622,7 @@ fn decide_to_branching<'a>(
|
|||
let decide = crate::ir::cond(
|
||||
env,
|
||||
test_symbol,
|
||||
Layout::Builtin(Builtin::Int1),
|
||||
Layout::Builtin(Builtin::Bool),
|
||||
pass_expr,
|
||||
fail_expr,
|
||||
ret_layout,
|
||||
|
@ -1631,7 +1631,7 @@ fn decide_to_branching<'a>(
|
|||
// calculate the guard value
|
||||
let param = Param {
|
||||
symbol: test_symbol,
|
||||
layout: Layout::Builtin(Builtin::Int1),
|
||||
layout: Layout::Builtin(Builtin::Bool),
|
||||
borrow: false,
|
||||
};
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ use crate::layout::{
|
|||
};
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||
use roc_can::expr::ClosureData;
|
||||
use roc_collections::all::{default_hasher, BumpMap, BumpMapDefault, MutMap};
|
||||
use roc_module::ident::{ForeignSymbol, Lowercase, TagName};
|
||||
|
@ -2424,11 +2425,11 @@ fn specialize_external<'a>(
|
|||
}
|
||||
|
||||
ClosureRepresentation::Other(layout) => match layout {
|
||||
Layout::Builtin(Builtin::Int1) => {
|
||||
Layout::Builtin(Builtin::Bool) => {
|
||||
// just ignore this value
|
||||
// IDEA don't pass this value in the future
|
||||
}
|
||||
Layout::Builtin(Builtin::Int8) => {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::U8)) => {
|
||||
// just ignore this value
|
||||
// IDEA don't pass this value in the future
|
||||
}
|
||||
|
@ -2953,16 +2954,14 @@ fn try_make_literal<'a>(
|
|||
match can_expr {
|
||||
Int(_, precision, _, int) => {
|
||||
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *precision, false) {
|
||||
IntOrFloat::SignedIntType(_) | IntOrFloat::UnsignedIntType(_) => {
|
||||
Some(Literal::Int(*int))
|
||||
}
|
||||
IntOrFloat::Int(_) | IntOrFloat::Natural => Some(Literal::Int(*int)),
|
||||
_ => unreachable!("unexpected float precision for integer"),
|
||||
}
|
||||
}
|
||||
|
||||
Float(_, precision, float_str, float) => {
|
||||
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *precision, true) {
|
||||
IntOrFloat::BinaryFloatType(_) => Some(Literal::Float(*float)),
|
||||
IntOrFloat::Float(_) => Some(Literal::Float(*float)),
|
||||
IntOrFloat::DecimalFloatType => {
|
||||
let dec = match RocDec::from_str(float_str) {
|
||||
Some(d) => d,
|
||||
|
@ -2980,10 +2979,8 @@ fn try_make_literal<'a>(
|
|||
Num(var, num_str, num) => {
|
||||
// first figure out what kind of number this is
|
||||
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *var, false) {
|
||||
IntOrFloat::SignedIntType(_) | IntOrFloat::UnsignedIntType(_) => {
|
||||
Some(Literal::Int((*num).into()))
|
||||
}
|
||||
IntOrFloat::BinaryFloatType(_) => Some(Literal::Float(*num as f64)),
|
||||
IntOrFloat::Int(_) | IntOrFloat::Natural => Some(Literal::Int((*num).into())),
|
||||
IntOrFloat::Float(_) => Some(Literal::Float(*num as f64)),
|
||||
IntOrFloat::DecimalFloatType => {
|
||||
let dec = match RocDec::from_str(num_str) {
|
||||
Some(d) => d,
|
||||
|
@ -3017,16 +3014,16 @@ pub fn with_hole<'a>(
|
|||
match can_expr {
|
||||
Int(_, precision, _, int) => {
|
||||
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, precision, false) {
|
||||
IntOrFloat::SignedIntType(precision) => Stmt::Let(
|
||||
IntOrFloat::Int(precision) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Int(int)),
|
||||
precision.as_layout(),
|
||||
Layout::Builtin(Builtin::Int(precision)),
|
||||
hole,
|
||||
),
|
||||
IntOrFloat::UnsignedIntType(precision) => Stmt::Let(
|
||||
IntOrFloat::Natural => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Int(int)),
|
||||
precision.as_layout(),
|
||||
Layout::usize(),
|
||||
hole,
|
||||
),
|
||||
_ => unreachable!("unexpected float precision for integer"),
|
||||
|
@ -3035,10 +3032,10 @@ pub fn with_hole<'a>(
|
|||
|
||||
Float(_, precision, float_str, float) => {
|
||||
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, precision, true) {
|
||||
IntOrFloat::BinaryFloatType(precision) => Stmt::Let(
|
||||
IntOrFloat::Float(precision) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Float(float)),
|
||||
precision.as_layout(),
|
||||
Layout::Builtin(Builtin::Float(precision)),
|
||||
hole,
|
||||
),
|
||||
IntOrFloat::DecimalFloatType => {
|
||||
|
@ -3067,22 +3064,22 @@ pub fn with_hole<'a>(
|
|||
Num(var, num_str, num) => {
|
||||
// first figure out what kind of number this is
|
||||
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, var, false) {
|
||||
IntOrFloat::SignedIntType(precision) => Stmt::Let(
|
||||
IntOrFloat::Int(precision) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Int(num.into())),
|
||||
precision.as_layout(),
|
||||
Layout::int_width(precision),
|
||||
hole,
|
||||
),
|
||||
IntOrFloat::UnsignedIntType(precision) => Stmt::Let(
|
||||
IntOrFloat::Natural => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Int(num.into())),
|
||||
precision.as_layout(),
|
||||
Layout::usize(),
|
||||
hole,
|
||||
),
|
||||
IntOrFloat::BinaryFloatType(precision) => Stmt::Let(
|
||||
IntOrFloat::Float(precision) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Float(num as f64)),
|
||||
precision.as_layout(),
|
||||
Layout::float_width(precision),
|
||||
hole,
|
||||
),
|
||||
IntOrFloat::DecimalFloatType => {
|
||||
|
@ -4467,7 +4464,7 @@ fn construct_closure_data<'a>(
|
|||
|
||||
Stmt::Let(assigned, expr, lambda_set_layout, hole)
|
||||
}
|
||||
ClosureRepresentation::Other(Layout::Builtin(Builtin::Int1)) => {
|
||||
ClosureRepresentation::Other(Layout::Builtin(Builtin::Bool)) => {
|
||||
debug_assert_eq!(symbols.len(), 0);
|
||||
|
||||
debug_assert_eq!(lambda_set.set.len(), 2);
|
||||
|
@ -4476,7 +4473,7 @@ fn construct_closure_data<'a>(
|
|||
|
||||
Stmt::Let(assigned, expr, lambda_set_layout, hole)
|
||||
}
|
||||
ClosureRepresentation::Other(Layout::Builtin(Builtin::Int8)) => {
|
||||
ClosureRepresentation::Other(Layout::Builtin(Builtin::Int(IntWidth::U8))) => {
|
||||
debug_assert_eq!(symbols.len(), 0);
|
||||
|
||||
debug_assert!(lambda_set.set.len() > 2);
|
||||
|
@ -4533,7 +4530,7 @@ fn convert_tag_union<'a>(
|
|||
BoolUnion { ttrue, .. } => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Bool(tag_name == ttrue)),
|
||||
Layout::Builtin(Builtin::Int1),
|
||||
Layout::Builtin(Builtin::Bool),
|
||||
hole,
|
||||
),
|
||||
ByteUnion(tag_names) => {
|
||||
|
@ -4543,7 +4540,7 @@ fn convert_tag_union<'a>(
|
|||
Some(tag_id) => Stmt::Let(
|
||||
assigned,
|
||||
Expr::Literal(Literal::Byte(tag_id as u8)),
|
||||
Layout::Builtin(Builtin::Int8),
|
||||
Layout::Builtin(Builtin::Int(IntWidth::U8)),
|
||||
hole,
|
||||
),
|
||||
None => Stmt::RuntimeError("tag must be in its own type"),
|
||||
|
@ -5054,7 +5051,7 @@ pub fn from_can<'a>(
|
|||
Expect(condition, rest) => {
|
||||
let rest = from_can(env, variable, rest.value, procs, layout_cache);
|
||||
|
||||
let bool_layout = Layout::Builtin(Builtin::Int1);
|
||||
let bool_layout = Layout::Builtin(Builtin::Bool);
|
||||
let cond_symbol = env.unique_symbol();
|
||||
|
||||
let op = LowLevel::ExpectTrue;
|
||||
|
@ -7237,8 +7234,8 @@ fn call_specialized_proc<'a>(
|
|||
pub enum Pattern<'a> {
|
||||
Identifier(Symbol),
|
||||
Underscore,
|
||||
IntLiteral(i128, IntPrecision),
|
||||
FloatLiteral(u64, FloatPrecision),
|
||||
IntLiteral(i128, IntWidth),
|
||||
FloatLiteral(u64, FloatWidth),
|
||||
DecimalLiteral(RocDec),
|
||||
BitLiteral {
|
||||
value: bool,
|
||||
|
@ -7318,9 +7315,8 @@ fn from_can_pattern_help<'a>(
|
|||
Identifier(symbol) => Ok(Pattern::Identifier(*symbol)),
|
||||
IntLiteral(var, _, int) => {
|
||||
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *var, false) {
|
||||
IntOrFloat::SignedIntType(precision) | IntOrFloat::UnsignedIntType(precision) => {
|
||||
Ok(Pattern::IntLiteral(*int as i128, precision))
|
||||
}
|
||||
IntOrFloat::Natural => todo!(),
|
||||
IntOrFloat::Int(precision) => Ok(Pattern::IntLiteral(*int as i128, precision)),
|
||||
other => {
|
||||
panic!(
|
||||
"Invalid precision for int pattern: {:?} has {:?}",
|
||||
|
@ -7332,10 +7328,10 @@ fn from_can_pattern_help<'a>(
|
|||
FloatLiteral(var, float_str, float) => {
|
||||
// TODO: Can I reuse num_argument_to_int_or_float here if I pass in true?
|
||||
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *var, true) {
|
||||
IntOrFloat::SignedIntType(_) | IntOrFloat::UnsignedIntType(_) => {
|
||||
IntOrFloat::Int(_) | IntOrFloat::Natural => {
|
||||
panic!("Invalid precision for float pattern {:?}", var)
|
||||
}
|
||||
IntOrFloat::BinaryFloatType(precision) => {
|
||||
IntOrFloat::Float(precision) => {
|
||||
Ok(Pattern::FloatLiteral(f64::to_bits(*float), precision))
|
||||
}
|
||||
IntOrFloat::DecimalFloatType => {
|
||||
|
@ -7362,15 +7358,9 @@ fn from_can_pattern_help<'a>(
|
|||
}
|
||||
NumLiteral(var, num_str, num) => {
|
||||
match num_argument_to_int_or_float(env.subs, env.ptr_bytes, *var, false) {
|
||||
IntOrFloat::SignedIntType(precision) => {
|
||||
Ok(Pattern::IntLiteral(*num as i128, precision))
|
||||
}
|
||||
IntOrFloat::UnsignedIntType(precision) => {
|
||||
Ok(Pattern::IntLiteral(*num as i128, precision))
|
||||
}
|
||||
IntOrFloat::BinaryFloatType(precision) => {
|
||||
Ok(Pattern::FloatLiteral(*num as u64, precision))
|
||||
}
|
||||
IntOrFloat::Int(precision) => Ok(Pattern::IntLiteral(*num as i128, precision)),
|
||||
IntOrFloat::Float(precision) => Ok(Pattern::FloatLiteral(*num as u64, precision)),
|
||||
IntOrFloat::Natural => todo!(),
|
||||
IntOrFloat::DecimalFloatType => {
|
||||
let dec = match RocDec::from_str(num_str) {
|
||||
Some(d) => d,
|
||||
|
@ -7952,60 +7942,12 @@ fn from_can_record_destruct<'a>(
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Hash)]
|
||||
pub enum IntPrecision {
|
||||
Usize,
|
||||
I128,
|
||||
I64,
|
||||
I32,
|
||||
I16,
|
||||
I8,
|
||||
}
|
||||
|
||||
impl IntPrecision {
|
||||
pub fn as_layout(&self) -> Layout<'static> {
|
||||
Layout::Builtin(self.as_builtin())
|
||||
}
|
||||
|
||||
pub fn as_builtin(&self) -> Builtin<'static> {
|
||||
use IntPrecision::*;
|
||||
match self {
|
||||
I128 => Builtin::Int128,
|
||||
I64 => Builtin::Int64,
|
||||
I32 => Builtin::Int32,
|
||||
I16 => Builtin::Int16,
|
||||
I8 => Builtin::Int8,
|
||||
Usize => Builtin::Usize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Hash)]
|
||||
pub enum FloatPrecision {
|
||||
F64,
|
||||
F32,
|
||||
}
|
||||
|
||||
impl FloatPrecision {
|
||||
pub fn as_layout(&self) -> Layout<'static> {
|
||||
Layout::Builtin(self.as_builtin())
|
||||
}
|
||||
|
||||
pub fn as_builtin(&self) -> Builtin<'static> {
|
||||
use FloatPrecision::*;
|
||||
match self {
|
||||
F64 => Builtin::Float64,
|
||||
F32 => Builtin::Float32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum IntOrFloat {
|
||||
SignedIntType(IntPrecision),
|
||||
UnsignedIntType(IntPrecision),
|
||||
BinaryFloatType(FloatPrecision),
|
||||
Int(IntWidth),
|
||||
Float(FloatWidth),
|
||||
DecimalFloatType,
|
||||
Natural,
|
||||
}
|
||||
|
||||
/// Given the `a` in `Num a`, determines whether it's an int or a float
|
||||
|
@ -8015,11 +7957,13 @@ pub fn num_argument_to_int_or_float(
|
|||
var: Variable,
|
||||
known_to_be_float: bool,
|
||||
) -> IntOrFloat {
|
||||
match subs.get_content_without_compacting(var){
|
||||
Content::FlexVar(_) | Content::RigidVar(_) if known_to_be_float => IntOrFloat::BinaryFloatType(FloatPrecision::F64),
|
||||
Content::FlexVar(_) | Content::RigidVar(_) => IntOrFloat::SignedIntType(IntPrecision::I64), // We default (Num *) to I64
|
||||
match subs.get_content_without_compacting(var) {
|
||||
Content::FlexVar(_) | Content::RigidVar(_) if known_to_be_float => {
|
||||
IntOrFloat::Float(FloatWidth::F64)
|
||||
}
|
||||
Content::FlexVar(_) | Content::RigidVar(_) => IntOrFloat::Int(IntWidth::I64), // We default (Num *) to I64
|
||||
|
||||
Content::Alias(Symbol::NUM_INTEGER, args, _) => {
|
||||
Content::Alias(Symbol::NUM_INTEGER, args, _) => {
|
||||
debug_assert!(args.len() == 1);
|
||||
|
||||
// Recurse on the second argument
|
||||
|
@ -8027,85 +7971,39 @@ pub fn num_argument_to_int_or_float(
|
|||
num_argument_to_int_or_float(subs, ptr_bytes, var, false)
|
||||
}
|
||||
|
||||
Content::Alias(Symbol::NUM_I128, _, _)
|
||||
| Content::Alias(Symbol::NUM_SIGNED128, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_SIGNED128, _, _) => {
|
||||
IntOrFloat::SignedIntType(IntPrecision::I128)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_INT, _, _)// We default Integer to I64
|
||||
| Content::Alias(Symbol::NUM_I64, _, _)
|
||||
| Content::Alias(Symbol::NUM_SIGNED64, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_SIGNED64, _, _) => {
|
||||
IntOrFloat::SignedIntType(IntPrecision::I64)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_I32, _, _)
|
||||
| Content::Alias(Symbol::NUM_SIGNED32, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_SIGNED32, _, _) => {
|
||||
IntOrFloat::SignedIntType(IntPrecision::I32)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_I16, _, _)
|
||||
| Content::Alias(Symbol::NUM_SIGNED16, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_SIGNED16, _, _) => {
|
||||
IntOrFloat::SignedIntType(IntPrecision::I16)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_I8, _, _)
|
||||
| Content::Alias(Symbol::NUM_SIGNED8, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_SIGNED8, _, _) => {
|
||||
IntOrFloat::SignedIntType(IntPrecision::I8)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_U128, _, _)
|
||||
| Content::Alias(Symbol::NUM_UNSIGNED128, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_UNSIGNED128, _, _) => {
|
||||
IntOrFloat::UnsignedIntType(IntPrecision::I128)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_U64, _, _)
|
||||
| Content::Alias(Symbol::NUM_UNSIGNED64, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_UNSIGNED64, _, _) => {
|
||||
IntOrFloat::UnsignedIntType(IntPrecision::I64)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_U32, _, _)
|
||||
| Content::Alias(Symbol::NUM_UNSIGNED32, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_UNSIGNED32, _, _) => {
|
||||
IntOrFloat::UnsignedIntType(IntPrecision::I32)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_U16, _, _)
|
||||
| Content::Alias(Symbol::NUM_UNSIGNED16, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_UNSIGNED16, _, _) => {
|
||||
IntOrFloat::UnsignedIntType(IntPrecision::I16)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_U8, _, _)
|
||||
| Content::Alias(Symbol::NUM_UNSIGNED8, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_UNSIGNED8, _, _) => {
|
||||
IntOrFloat::UnsignedIntType(IntPrecision::I8)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_FLOATINGPOINT, args, _) => {
|
||||
debug_assert!(args.len() == 1);
|
||||
other @ Content::Alias(symbol, args, _) => {
|
||||
if let Some(int_width) = IntWidth::try_from_symbol(*symbol) {
|
||||
return IntOrFloat::Int(int_width);
|
||||
}
|
||||
|
||||
// Recurse on the second argument
|
||||
let var = subs[args.variables().into_iter().next().unwrap()];
|
||||
num_argument_to_int_or_float(subs, ptr_bytes, var, true)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_FLOAT, _, _) // We default FloatingPoint to F64
|
||||
| Content::Alias(Symbol::NUM_F64, _, _)
|
||||
| Content::Alias(Symbol::NUM_BINARY64, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_BINARY64, _, _) => {
|
||||
IntOrFloat::BinaryFloatType(FloatPrecision::F64)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_DECIMAL, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_DECIMAL, _, _) => {
|
||||
IntOrFloat::DecimalFloatType
|
||||
}
|
||||
Content::Alias(Symbol::NUM_F32, _, _)
|
||||
| Content::Alias(Symbol::NUM_BINARY32, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_BINARY32, _, _) => {
|
||||
IntOrFloat::BinaryFloatType(FloatPrecision::F32)
|
||||
}
|
||||
Content::Alias(Symbol::NUM_NAT, _, _)
|
||||
| Content::Alias(Symbol::NUM_NATURAL, _, _)
|
||||
| Content::Alias(Symbol::NUM_AT_NATURAL, _, _) => {
|
||||
IntOrFloat::UnsignedIntType(IntPrecision::Usize)
|
||||
if let Some(float_width) = FloatWidth::try_from_symbol(*symbol) {
|
||||
return IntOrFloat::Float(float_width);
|
||||
}
|
||||
|
||||
match *symbol {
|
||||
Symbol::NUM_FLOATINGPOINT => {
|
||||
debug_assert!(args.len() == 1);
|
||||
|
||||
// Recurse on the second argument
|
||||
let var = subs[args.variables().into_iter().next().unwrap()];
|
||||
num_argument_to_int_or_float(subs, ptr_bytes, var, true)
|
||||
}
|
||||
|
||||
Symbol::NUM_DECIMAL | Symbol::NUM_AT_DECIMAL => {
|
||||
return IntOrFloat::DecimalFloatType;
|
||||
}
|
||||
|
||||
Symbol::NUM_NAT | Symbol::NUM_NATURAL | Symbol::NUM_AT_NATURAL => {
|
||||
return IntOrFloat::Natural;
|
||||
}
|
||||
|
||||
_ => panic!(
|
||||
"Unrecognized Num type argument for var {:?} with Content: {:?}",
|
||||
var, other
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
other => {
|
||||
panic!(
|
||||
"Unrecognized Num type argument for var {:?} with Content: {:?}",
|
||||
|
@ -8187,14 +8085,14 @@ where
|
|||
hole.clone()
|
||||
}
|
||||
},
|
||||
Layout::Builtin(Builtin::Int1) => {
|
||||
Layout::Builtin(Builtin::Bool) => {
|
||||
let closure_tag_id_symbol = closure_data_symbol;
|
||||
|
||||
lowlevel_enum_lambda_set_to_switch(
|
||||
env,
|
||||
lambda_set.set,
|
||||
closure_tag_id_symbol,
|
||||
Layout::Builtin(Builtin::Int1),
|
||||
Layout::Builtin(Builtin::Bool),
|
||||
closure_data_symbol,
|
||||
lambda_set.is_represented(),
|
||||
to_lowlevel_call,
|
||||
|
@ -8203,14 +8101,14 @@ where
|
|||
hole,
|
||||
)
|
||||
}
|
||||
Layout::Builtin(Builtin::Int8) => {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::U8)) => {
|
||||
let closure_tag_id_symbol = closure_data_symbol;
|
||||
|
||||
lowlevel_enum_lambda_set_to_switch(
|
||||
env,
|
||||
lambda_set.set,
|
||||
closure_tag_id_symbol,
|
||||
Layout::Builtin(Builtin::Int8),
|
||||
Layout::Builtin(Builtin::Int(IntWidth::U8)),
|
||||
closure_data_symbol,
|
||||
lambda_set.is_represented(),
|
||||
to_lowlevel_call,
|
||||
|
@ -8351,14 +8249,14 @@ fn match_on_lambda_set<'a>(
|
|||
hole,
|
||||
)
|
||||
}
|
||||
Layout::Builtin(Builtin::Int1) => {
|
||||
Layout::Builtin(Builtin::Bool) => {
|
||||
let closure_tag_id_symbol = closure_data_symbol;
|
||||
|
||||
enum_lambda_set_to_switch(
|
||||
env,
|
||||
lambda_set.set,
|
||||
closure_tag_id_symbol,
|
||||
Layout::Builtin(Builtin::Int1),
|
||||
Layout::Builtin(Builtin::Bool),
|
||||
closure_data_symbol,
|
||||
argument_symbols,
|
||||
argument_layouts,
|
||||
|
@ -8367,14 +8265,14 @@ fn match_on_lambda_set<'a>(
|
|||
hole,
|
||||
)
|
||||
}
|
||||
Layout::Builtin(Builtin::Int8) => {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::U8)) => {
|
||||
let closure_tag_id_symbol = closure_data_symbol;
|
||||
|
||||
enum_lambda_set_to_switch(
|
||||
env,
|
||||
lambda_set.set,
|
||||
closure_tag_id_symbol,
|
||||
Layout::Builtin(Builtin::Int8),
|
||||
Layout::Builtin(Builtin::Int(IntWidth::U8)),
|
||||
closure_data_symbol,
|
||||
argument_symbols,
|
||||
argument_layouts,
|
||||
|
@ -8502,7 +8400,9 @@ fn union_lambda_set_branch_help<'a>(
|
|||
hole: &'a Stmt<'a>,
|
||||
) -> Stmt<'a> {
|
||||
let (argument_layouts, argument_symbols) = match closure_data_layout {
|
||||
Layout::Struct(&[]) | Layout::Builtin(Builtin::Int1) | Layout::Builtin(Builtin::Int8) => {
|
||||
Layout::Struct(&[])
|
||||
| Layout::Builtin(Builtin::Bool)
|
||||
| Layout::Builtin(Builtin::Int(IntWidth::U8)) => {
|
||||
(argument_layouts_slice, argument_symbols_slice)
|
||||
}
|
||||
_ if lambda_set.member_does_not_need_closure_argument(function_symbol) => {
|
||||
|
@ -8627,7 +8527,9 @@ fn enum_lambda_set_branch<'a>(
|
|||
let assigned = result_symbol;
|
||||
|
||||
let (argument_layouts, argument_symbols) = match closure_data_layout {
|
||||
Layout::Struct(&[]) | Layout::Builtin(Builtin::Int1) | Layout::Builtin(Builtin::Int8) => {
|
||||
Layout::Struct(&[])
|
||||
| Layout::Builtin(Builtin::Bool)
|
||||
| Layout::Builtin(Builtin::Int(IntWidth::U8)) => {
|
||||
(argument_layouts_slice, argument_symbols_slice)
|
||||
}
|
||||
_ => {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::ir::Parens;
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||
use roc_collections::all::{default_hasher, MutMap};
|
||||
use roc_module::ident::{Lowercase, TagName};
|
||||
use roc_module::symbol::{Interns, Symbol};
|
||||
|
@ -24,9 +25,6 @@ pub type TagIdIntType = u16;
|
|||
pub const MAX_ENUM_SIZE: usize = (std::mem::size_of::<TagIdIntType>() * 8) as usize;
|
||||
const GENERATE_NULLABLE: bool = true;
|
||||
|
||||
/// If a (Num *) gets translated to a Layout, this is the numeric type it defaults to.
|
||||
const DEFAULT_NUM_BUILTIN: Builtin<'_> = Builtin::Int64;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum LayoutProblem {
|
||||
UnresolvedTypeVar(Variable),
|
||||
|
@ -61,60 +59,61 @@ impl<'a> RawFunctionLayout<'a> {
|
|||
// Ints
|
||||
Alias(Symbol::NUM_I128, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Int128)))
|
||||
Ok(Self::ZeroArgumentThunk(Layout::i128()))
|
||||
}
|
||||
Alias(Symbol::NUM_I64, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Int64)))
|
||||
Ok(Self::ZeroArgumentThunk(Layout::i64()))
|
||||
}
|
||||
Alias(Symbol::NUM_I32, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Int32)))
|
||||
Ok(Self::ZeroArgumentThunk(Layout::i32()))
|
||||
}
|
||||
Alias(Symbol::NUM_I16, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Int16)))
|
||||
Ok(Self::ZeroArgumentThunk(Layout::i16()))
|
||||
}
|
||||
Alias(Symbol::NUM_I8, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Int8)))
|
||||
Ok(Self::ZeroArgumentThunk(Layout::i8()))
|
||||
}
|
||||
|
||||
// I think unsigned and signed use the same layout
|
||||
Alias(Symbol::NUM_U128, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Int128)))
|
||||
Ok(Self::ZeroArgumentThunk(Layout::u128()))
|
||||
}
|
||||
Alias(Symbol::NUM_U64, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Int64)))
|
||||
Ok(Self::ZeroArgumentThunk(Layout::u64()))
|
||||
}
|
||||
Alias(Symbol::NUM_U32, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Int32)))
|
||||
Ok(Self::ZeroArgumentThunk(Layout::u32()))
|
||||
}
|
||||
Alias(Symbol::NUM_U16, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Int16)))
|
||||
Ok(Self::ZeroArgumentThunk(Layout::u16()))
|
||||
}
|
||||
Alias(Symbol::NUM_U8, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Int8)))
|
||||
}
|
||||
|
||||
Alias(Symbol::NUM_NAT, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Usize)))
|
||||
Ok(Self::ZeroArgumentThunk(Layout::u8()))
|
||||
}
|
||||
|
||||
// Floats
|
||||
Alias(Symbol::NUM_F64, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Float64)))
|
||||
Ok(Self::ZeroArgumentThunk(Layout::f64()))
|
||||
}
|
||||
Alias(Symbol::NUM_F32, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::Builtin(Builtin::Float32)))
|
||||
Ok(Self::ZeroArgumentThunk(Layout::f32()))
|
||||
}
|
||||
|
||||
// Nat
|
||||
Alias(Symbol::NUM_NAT, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Self::ZeroArgumentThunk(Layout::usize()))
|
||||
}
|
||||
|
||||
Alias(symbol, _, _) if symbol.is_builtin() => Ok(Self::ZeroArgumentThunk(
|
||||
|
@ -315,9 +314,9 @@ impl<'a> UnionLayout<'a> {
|
|||
|
||||
fn tag_id_builtin_help(union_size: usize) -> Builtin<'a> {
|
||||
if union_size <= u8::MAX as usize {
|
||||
Builtin::Int8
|
||||
Builtin::Int(IntWidth::U8)
|
||||
} else if union_size <= u16::MAX as usize {
|
||||
Builtin::Int16
|
||||
Builtin::Int(IntWidth::U16)
|
||||
} else {
|
||||
panic!("tag union is too big")
|
||||
}
|
||||
|
@ -332,7 +331,7 @@ impl<'a> UnionLayout<'a> {
|
|||
// The quicksort-benchmarks version of Quicksort.roc segfaults when
|
||||
// this number is not I64. There must be some dependence on that fact
|
||||
// somewhere in the code, I have not found where that is yet...
|
||||
Builtin::Int64
|
||||
Builtin::Int(IntWidth::U64)
|
||||
}
|
||||
UnionLayout::Recursive(tags) => {
|
||||
let union_size = tags.len();
|
||||
|
@ -343,8 +342,8 @@ impl<'a> UnionLayout<'a> {
|
|||
UnionLayout::NullableWrapped { other_tags, .. } => {
|
||||
Self::tag_id_builtin_help(other_tags.len() + 1)
|
||||
}
|
||||
UnionLayout::NonNullableUnwrapped(_) => Builtin::Int1,
|
||||
UnionLayout::NullableUnwrapped { .. } => Builtin::Int1,
|
||||
UnionLayout::NonNullableUnwrapped(_) => Builtin::Bool,
|
||||
UnionLayout::NullableUnwrapped { .. } => Builtin::Bool,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,7 +545,8 @@ impl<'a> LambdaSet<'a> {
|
|||
// singleton, so we pass no extra argument
|
||||
argument_layouts
|
||||
}
|
||||
Layout::Builtin(Builtin::Int1) | Layout::Builtin(Builtin::Int8) => {
|
||||
Layout::Builtin(Builtin::Bool)
|
||||
| Layout::Builtin(Builtin::Int(IntWidth::I8 | IntWidth::U8)) => {
|
||||
// we don't pass this along either
|
||||
argument_layouts
|
||||
}
|
||||
|
@ -628,8 +628,8 @@ impl<'a> LambdaSet<'a> {
|
|||
use UnionVariant::*;
|
||||
match variant {
|
||||
Never => Layout::Union(UnionLayout::NonRecursive(&[])),
|
||||
BoolUnion { .. } => Layout::Builtin(Builtin::Int1),
|
||||
ByteUnion { .. } => Layout::Builtin(Builtin::Int8),
|
||||
BoolUnion { .. } => Layout::bool(),
|
||||
ByteUnion { .. } => Layout::u8(),
|
||||
Unit | UnitWithArguments => {
|
||||
// no useful information to store
|
||||
Layout::Struct(&[])
|
||||
|
@ -680,17 +680,11 @@ impl<'a> LambdaSet<'a> {
|
|||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum Builtin<'a> {
|
||||
Int128,
|
||||
Int64,
|
||||
Int32,
|
||||
Int16,
|
||||
Int8,
|
||||
Int1,
|
||||
Int(IntWidth),
|
||||
Float(FloatWidth),
|
||||
Bool,
|
||||
Usize,
|
||||
Decimal,
|
||||
Float128,
|
||||
Float64,
|
||||
Float32,
|
||||
Str,
|
||||
Dict(&'a Layout<'a>, &'a Layout<'a>),
|
||||
Set(&'a Layout<'a>),
|
||||
|
@ -759,61 +753,61 @@ impl<'a> Layout<'a> {
|
|||
// Ints
|
||||
Alias(Symbol::NUM_I128, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Int128))
|
||||
Ok(Layout::i128())
|
||||
}
|
||||
Alias(Symbol::NUM_I64, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Int64))
|
||||
Ok(Layout::i64())
|
||||
}
|
||||
Alias(Symbol::NUM_I32, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Int32))
|
||||
Ok(Layout::i32())
|
||||
}
|
||||
Alias(Symbol::NUM_I16, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Int16))
|
||||
Ok(Layout::i16())
|
||||
}
|
||||
Alias(Symbol::NUM_I8, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Int8))
|
||||
Ok(Layout::i8())
|
||||
}
|
||||
|
||||
// I think unsigned and signed use the same layout
|
||||
Alias(Symbol::NUM_U128, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Int128))
|
||||
Ok(Layout::u128())
|
||||
}
|
||||
Alias(Symbol::NUM_U64, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Int64))
|
||||
Ok(Layout::u64())
|
||||
}
|
||||
Alias(Symbol::NUM_U32, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Int32))
|
||||
Ok(Layout::u32())
|
||||
}
|
||||
Alias(Symbol::NUM_U16, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Int16))
|
||||
Ok(Layout::u16())
|
||||
}
|
||||
Alias(Symbol::NUM_U8, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Int8))
|
||||
Ok(Layout::u8())
|
||||
}
|
||||
|
||||
// Floats
|
||||
Alias(Symbol::NUM_F64, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Float64))
|
||||
Ok(Layout::f64())
|
||||
}
|
||||
Alias(Symbol::NUM_F32, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Float32))
|
||||
Ok(Layout::f32())
|
||||
}
|
||||
|
||||
// Nat
|
||||
Alias(Symbol::NUM_NAT, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
Ok(Layout::Builtin(Builtin::Usize))
|
||||
Ok(Layout::usize())
|
||||
}
|
||||
|
||||
Alias(_, _, var) => Self::from_var(env, var),
|
||||
|
@ -1148,6 +1142,76 @@ impl<'a> LayoutCache<'a> {
|
|||
// placeholder for the type ven_ena::unify::Snapshot<ven_ena::unify::InPlace<CachedVariable<'a>>>
|
||||
pub struct SnapshotKeyPlaceholder;
|
||||
|
||||
impl<'a> Layout<'a> {
|
||||
pub fn int_width(width: IntWidth) -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Int(width))
|
||||
}
|
||||
|
||||
pub fn float_width(width: FloatWidth) -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Float(width))
|
||||
}
|
||||
|
||||
pub fn f64() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Float(FloatWidth::F64))
|
||||
}
|
||||
|
||||
pub fn f32() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Float(FloatWidth::F32))
|
||||
}
|
||||
|
||||
pub fn usize() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Usize)
|
||||
}
|
||||
|
||||
pub fn bool() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Bool)
|
||||
}
|
||||
|
||||
pub fn u8() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::U8))
|
||||
}
|
||||
|
||||
pub fn u16() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::U16))
|
||||
}
|
||||
|
||||
pub fn u32() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::U32))
|
||||
}
|
||||
|
||||
pub fn u64() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::U64))
|
||||
}
|
||||
|
||||
pub fn u128() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::U128))
|
||||
}
|
||||
|
||||
pub fn i8() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::I8))
|
||||
}
|
||||
|
||||
pub fn i16() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::I16))
|
||||
}
|
||||
|
||||
pub fn i32() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::I32))
|
||||
}
|
||||
|
||||
pub fn i64() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::I64))
|
||||
}
|
||||
|
||||
pub fn i128() -> Layout<'a> {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::I128))
|
||||
}
|
||||
|
||||
pub fn default_integer() -> Layout<'a> {
|
||||
Layout::i64()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Builtin<'a> {
|
||||
const I128_SIZE: u32 = std::mem::size_of::<i128>() as u32;
|
||||
const I64_SIZE: u32 = std::mem::size_of::<i64>() as u32;
|
||||
|
@ -1177,17 +1241,11 @@ impl<'a> Builtin<'a> {
|
|||
use Builtin::*;
|
||||
|
||||
match self {
|
||||
Int128 => Builtin::I128_SIZE,
|
||||
Int64 => Builtin::I64_SIZE,
|
||||
Int32 => Builtin::I32_SIZE,
|
||||
Int16 => Builtin::I16_SIZE,
|
||||
Int8 => Builtin::I8_SIZE,
|
||||
Int1 => Builtin::I1_SIZE,
|
||||
Int(int) => int.stack_size(),
|
||||
Float(float) => float.stack_size(),
|
||||
Bool => Builtin::I1_SIZE,
|
||||
Usize => pointer_size,
|
||||
Decimal => Builtin::DECIMAL_SIZE,
|
||||
Float128 => Builtin::F128_SIZE,
|
||||
Float64 => Builtin::F64_SIZE,
|
||||
Float32 => Builtin::F32_SIZE,
|
||||
Str | EmptyStr => Builtin::STR_WORDS * pointer_size,
|
||||
Dict(_, _) | EmptyDict => Builtin::DICT_WORDS * pointer_size,
|
||||
Set(_) | EmptySet => Builtin::SET_WORDS * pointer_size,
|
||||
|
@ -1203,17 +1261,11 @@ impl<'a> Builtin<'a> {
|
|||
// since both of those are one pointer size, the alignment of that structure is a pointer
|
||||
// size
|
||||
match self {
|
||||
Int128 => align_of::<i128>() as u32,
|
||||
Int64 => align_of::<i64>() as u32,
|
||||
Int32 => align_of::<i32>() as u32,
|
||||
Int16 => align_of::<i16>() as u32,
|
||||
Int8 => align_of::<i8>() as u32,
|
||||
Int1 => align_of::<bool>() as u32,
|
||||
Int(int_width) => int_width.alignment_bytes(),
|
||||
Float(float_width) => float_width.alignment_bytes(),
|
||||
Bool => align_of::<bool>() as u32,
|
||||
Usize => pointer_size,
|
||||
Decimal => align_of::<i128>() as u32,
|
||||
Float128 => align_of::<i128>() as u32,
|
||||
Float64 => align_of::<f64>() as u32,
|
||||
Float32 => align_of::<f32>() as u32,
|
||||
Dict(_, _) | EmptyDict => pointer_size,
|
||||
Set(_) | EmptySet => pointer_size,
|
||||
// we often treat these as i128 (64-bit systems)
|
||||
|
@ -1230,8 +1282,9 @@ impl<'a> Builtin<'a> {
|
|||
use Builtin::*;
|
||||
|
||||
match self {
|
||||
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Usize | Decimal | Float128 | Float64
|
||||
| Float32 | EmptyStr | EmptyDict | EmptyList | EmptySet => true,
|
||||
Int(_) | Usize | Float(_) | Bool | Decimal | EmptyStr | EmptyDict | EmptyList
|
||||
| EmptySet => true,
|
||||
|
||||
Str | Dict(_, _) | Set(_) | List(_) => false,
|
||||
}
|
||||
}
|
||||
|
@ -1241,8 +1294,8 @@ impl<'a> Builtin<'a> {
|
|||
use Builtin::*;
|
||||
|
||||
match self {
|
||||
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Usize | Decimal | Float128 | Float64
|
||||
| Float32 | EmptyStr | EmptyDict | EmptyList | EmptySet => false,
|
||||
Int(_) | Usize | Float(_) | Bool | Decimal | EmptyStr | EmptyDict | EmptyList
|
||||
| EmptySet => false,
|
||||
List(_) => true,
|
||||
|
||||
Str | Dict(_, _) | Set(_) => true,
|
||||
|
@ -1258,17 +1311,36 @@ impl<'a> Builtin<'a> {
|
|||
use Builtin::*;
|
||||
|
||||
match self {
|
||||
Int128 => alloc.text("Int128"),
|
||||
Int64 => alloc.text("Int64"),
|
||||
Int32 => alloc.text("Int32"),
|
||||
Int16 => alloc.text("Int16"),
|
||||
Int8 => alloc.text("Int8"),
|
||||
Int1 => alloc.text("Int1"),
|
||||
Int(int_width) => {
|
||||
use IntWidth::*;
|
||||
|
||||
match int_width {
|
||||
I128 => alloc.text("I128"),
|
||||
I64 => alloc.text("I64"),
|
||||
I32 => alloc.text("I32"),
|
||||
I16 => alloc.text("I16"),
|
||||
I8 => alloc.text("I8"),
|
||||
U128 => alloc.text("U128"),
|
||||
U64 => alloc.text("U64"),
|
||||
U32 => alloc.text("U32"),
|
||||
U16 => alloc.text("U16"),
|
||||
U8 => alloc.text("U8"),
|
||||
}
|
||||
}
|
||||
|
||||
Float(float_width) => {
|
||||
use FloatWidth::*;
|
||||
|
||||
match float_width {
|
||||
F128 => alloc.text("Float128"),
|
||||
F64 => alloc.text("Float64"),
|
||||
F32 => alloc.text("Float32"),
|
||||
}
|
||||
}
|
||||
|
||||
Bool => alloc.text("Int1"),
|
||||
Usize => alloc.text("Usize"),
|
||||
Decimal => alloc.text("Decimal"),
|
||||
Float128 => alloc.text("Float128"),
|
||||
Float64 => alloc.text("Float64"),
|
||||
Float32 => alloc.text("Float32"),
|
||||
|
||||
EmptyStr => alloc.text("EmptyStr"),
|
||||
EmptyList => alloc.text("EmptyList"),
|
||||
|
@ -1292,17 +1364,11 @@ impl<'a> Builtin<'a> {
|
|||
|
||||
pub fn allocation_alignment_bytes(&self, pointer_size: u32) -> u32 {
|
||||
let allocation = match self {
|
||||
Builtin::Int128
|
||||
| Builtin::Int64
|
||||
| Builtin::Int32
|
||||
| Builtin::Int16
|
||||
| Builtin::Int8
|
||||
| Builtin::Int1
|
||||
Builtin::Int(_)
|
||||
| Builtin::Float(_)
|
||||
| Builtin::Bool
|
||||
| Builtin::Usize
|
||||
| Builtin::Decimal
|
||||
| Builtin::Float128
|
||||
| Builtin::Float64
|
||||
| Builtin::Float32 => unreachable!("not heap-allocated"),
|
||||
| Builtin::Decimal => unreachable!("not heap-allocated"),
|
||||
Builtin::Str => pointer_size,
|
||||
Builtin::Dict(k, v) => k
|
||||
.alignment_bytes(pointer_size)
|
||||
|
@ -1342,44 +1408,44 @@ fn layout_from_flat_type<'a>(
|
|||
|
||||
Symbol::NUM_I128 => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
Ok(Layout::Builtin(Builtin::Int128))
|
||||
Ok(Layout::i128())
|
||||
}
|
||||
Symbol::NUM_I64 => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
Ok(Layout::Builtin(Builtin::Int64))
|
||||
Ok(Layout::i64())
|
||||
}
|
||||
Symbol::NUM_I32 => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
Ok(Layout::Builtin(Builtin::Int32))
|
||||
Ok(Layout::i32())
|
||||
}
|
||||
Symbol::NUM_I16 => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
Ok(Layout::Builtin(Builtin::Int16))
|
||||
Ok(Layout::i16())
|
||||
}
|
||||
Symbol::NUM_I8 => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
Ok(Layout::Builtin(Builtin::Int8))
|
||||
Ok(Layout::i8())
|
||||
}
|
||||
|
||||
Symbol::NUM_U128 => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
Ok(Layout::Builtin(Builtin::Int128))
|
||||
Ok(Layout::u128())
|
||||
}
|
||||
Symbol::NUM_U64 => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
Ok(Layout::Builtin(Builtin::Int64))
|
||||
Ok(Layout::u64())
|
||||
}
|
||||
Symbol::NUM_U32 => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
Ok(Layout::Builtin(Builtin::Int32))
|
||||
Ok(Layout::u32())
|
||||
}
|
||||
Symbol::NUM_U16 => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
Ok(Layout::Builtin(Builtin::Int16))
|
||||
Ok(Layout::u16())
|
||||
}
|
||||
Symbol::NUM_U8 => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
Ok(Layout::Builtin(Builtin::Int8))
|
||||
Ok(Layout::u8())
|
||||
}
|
||||
|
||||
// Floats
|
||||
|
@ -1389,11 +1455,11 @@ fn layout_from_flat_type<'a>(
|
|||
}
|
||||
Symbol::NUM_F64 => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
Ok(Layout::Builtin(Builtin::Float64))
|
||||
Ok(Layout::f64())
|
||||
}
|
||||
Symbol::NUM_F32 => {
|
||||
debug_assert_eq!(args.len(), 0);
|
||||
Ok(Layout::Builtin(Builtin::Float32))
|
||||
Ok(Layout::f32())
|
||||
}
|
||||
|
||||
Symbol::NUM_NUM | Symbol::NUM_AT_NUM => {
|
||||
|
@ -2295,8 +2361,8 @@ fn layout_from_tag_union<'a>(
|
|||
match variant {
|
||||
Never => Layout::Union(UnionLayout::NonRecursive(&[])),
|
||||
Unit | UnitWithArguments => Layout::Struct(&[]),
|
||||
BoolUnion { .. } => Layout::Builtin(Builtin::Int1),
|
||||
ByteUnion(_) => Layout::Builtin(Builtin::Int8),
|
||||
BoolUnion { .. } => Layout::bool(),
|
||||
ByteUnion(_) => Layout::u8(),
|
||||
Newtype {
|
||||
arguments: field_layouts,
|
||||
..
|
||||
|
@ -2396,30 +2462,32 @@ fn layout_from_num_content<'a>(content: &Content) -> Result<Layout<'a>, LayoutPr
|
|||
// type variable, then assume it's a 64-bit integer.
|
||||
//
|
||||
// (e.g. for (5 + 5) assume both 5s are 64-bit integers.)
|
||||
Ok(Layout::Builtin(DEFAULT_NUM_BUILTIN))
|
||||
Ok(Layout::default_integer())
|
||||
}
|
||||
Structure(Apply(symbol, args)) => match *symbol {
|
||||
// Ints
|
||||
Symbol::NUM_NAT => Ok(Layout::Builtin(Builtin::Usize)),
|
||||
Symbol::NUM_NAT => Ok(Layout::usize()),
|
||||
|
||||
Symbol::NUM_INTEGER => Ok(Layout::Builtin(Builtin::Int64)),
|
||||
Symbol::NUM_I128 => Ok(Layout::Builtin(Builtin::Int128)),
|
||||
Symbol::NUM_I64 => Ok(Layout::Builtin(Builtin::Int64)),
|
||||
Symbol::NUM_I32 => Ok(Layout::Builtin(Builtin::Int32)),
|
||||
Symbol::NUM_I16 => Ok(Layout::Builtin(Builtin::Int16)),
|
||||
Symbol::NUM_I8 => Ok(Layout::Builtin(Builtin::Int8)),
|
||||
Symbol::NUM_INTEGER => Ok(Layout::i64()),
|
||||
Symbol::NUM_I128 => Ok(Layout::i128()),
|
||||
Symbol::NUM_I64 => Ok(Layout::i64()),
|
||||
Symbol::NUM_I32 => Ok(Layout::i32()),
|
||||
Symbol::NUM_I16 => Ok(Layout::i16()),
|
||||
Symbol::NUM_I8 => Ok(Layout::i8()),
|
||||
|
||||
Symbol::NUM_U128 => Ok(Layout::Builtin(Builtin::Int128)),
|
||||
Symbol::NUM_U64 => Ok(Layout::Builtin(Builtin::Int64)),
|
||||
Symbol::NUM_U32 => Ok(Layout::Builtin(Builtin::Int32)),
|
||||
Symbol::NUM_U16 => Ok(Layout::Builtin(Builtin::Int16)),
|
||||
Symbol::NUM_U8 => Ok(Layout::Builtin(Builtin::Int8)),
|
||||
Symbol::NUM_U128 => Ok(Layout::u128()),
|
||||
Symbol::NUM_U64 => Ok(Layout::u64()),
|
||||
Symbol::NUM_U32 => Ok(Layout::u32()),
|
||||
Symbol::NUM_U16 => Ok(Layout::u16()),
|
||||
Symbol::NUM_U8 => Ok(Layout::u8()),
|
||||
|
||||
// Floats
|
||||
Symbol::NUM_FLOATINGPOINT => Ok(Layout::Builtin(Builtin::Float64)),
|
||||
Symbol::NUM_FLOATINGPOINT => Ok(Layout::f64()),
|
||||
Symbol::NUM_F64 => Ok(Layout::f64()),
|
||||
Symbol::NUM_F32 => Ok(Layout::f32()),
|
||||
|
||||
// Dec
|
||||
Symbol::NUM_DEC => Ok(Layout::Builtin(Builtin::Decimal)),
|
||||
Symbol::NUM_F64 => Ok(Layout::Builtin(Builtin::Float64)),
|
||||
Symbol::NUM_F32 => Ok(Layout::Builtin(Builtin::Float32)),
|
||||
|
||||
_ => {
|
||||
panic!(
|
||||
|
@ -2451,26 +2519,29 @@ fn unwrap_num_tag<'a>(subs: &Subs, var: Variable) -> Result<Layout<'a>, LayoutPr
|
|||
Content::Alias(symbol, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
|
||||
let builtin = match *symbol {
|
||||
Symbol::NUM_SIGNED128 => Builtin::Int128,
|
||||
Symbol::NUM_SIGNED64 => Builtin::Int64,
|
||||
Symbol::NUM_SIGNED32 => Builtin::Int32,
|
||||
Symbol::NUM_SIGNED16 => Builtin::Int16,
|
||||
Symbol::NUM_SIGNED8 => Builtin::Int8,
|
||||
Symbol::NUM_UNSIGNED128 => Builtin::Int128,
|
||||
Symbol::NUM_UNSIGNED64 => Builtin::Int64,
|
||||
Symbol::NUM_UNSIGNED32 => Builtin::Int32,
|
||||
Symbol::NUM_UNSIGNED16 => Builtin::Int16,
|
||||
Symbol::NUM_UNSIGNED8 => Builtin::Int8,
|
||||
Symbol::NUM_NATURAL => Builtin::Usize,
|
||||
let width = match *symbol {
|
||||
Symbol::NUM_SIGNED128 => IntWidth::I128,
|
||||
Symbol::NUM_SIGNED64 => IntWidth::I64,
|
||||
Symbol::NUM_SIGNED32 => IntWidth::I32,
|
||||
Symbol::NUM_SIGNED16 => IntWidth::I16,
|
||||
Symbol::NUM_SIGNED8 => IntWidth::I8,
|
||||
Symbol::NUM_UNSIGNED128 => IntWidth::U128,
|
||||
Symbol::NUM_UNSIGNED64 => IntWidth::U64,
|
||||
Symbol::NUM_UNSIGNED32 => IntWidth::U32,
|
||||
Symbol::NUM_UNSIGNED16 => IntWidth::U16,
|
||||
Symbol::NUM_UNSIGNED8 => IntWidth::U8,
|
||||
Symbol::NUM_NATURAL => {
|
||||
return Ok(Layout::usize());
|
||||
}
|
||||
|
||||
_ => unreachable!("not a valid int variant: {:?} {:?}", symbol, args),
|
||||
};
|
||||
|
||||
Ok(Layout::Builtin(builtin))
|
||||
Ok(Layout::Builtin(Builtin::Int(width)))
|
||||
}
|
||||
Content::FlexVar(_) | Content::RigidVar(_) => {
|
||||
// default to i64
|
||||
Ok(Layout::Builtin(Builtin::Int64))
|
||||
Ok(Layout::i64())
|
||||
}
|
||||
_ => unreachable!("not a valid int variant: {:?}", precision),
|
||||
}
|
||||
|
@ -2486,12 +2557,12 @@ fn unwrap_num_tag<'a>(subs: &Subs, var: Variable) -> Result<Layout<'a>, LayoutPr
|
|||
Content::Alias(Symbol::NUM_BINARY32, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
|
||||
Ok(Layout::Builtin(Builtin::Float32))
|
||||
Ok(Layout::f32())
|
||||
}
|
||||
Content::Alias(Symbol::NUM_BINARY64, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
|
||||
Ok(Layout::Builtin(Builtin::Float64))
|
||||
Ok(Layout::f64())
|
||||
}
|
||||
Content::Alias(Symbol::NUM_DECIMAL, args, _) => {
|
||||
debug_assert!(args.is_empty());
|
||||
|
@ -2500,14 +2571,14 @@ fn unwrap_num_tag<'a>(subs: &Subs, var: Variable) -> Result<Layout<'a>, LayoutPr
|
|||
}
|
||||
Content::FlexVar(_) | Content::RigidVar(_) => {
|
||||
// default to f64
|
||||
Ok(Layout::Builtin(Builtin::Float64))
|
||||
Ok(Layout::f64())
|
||||
}
|
||||
_ => unreachable!("not a valid float variant: {:?}", precision),
|
||||
}
|
||||
}
|
||||
Content::FlexVar(_) | Content::RigidVar(_) => {
|
||||
// If this was still a (Num *) then default to compiling it to i64
|
||||
Ok(Layout::Builtin(DEFAULT_NUM_BUILTIN))
|
||||
Ok(Layout::default_integer())
|
||||
}
|
||||
other => {
|
||||
todo!("TODO non structure Num.@Num flat_type {:?}", other);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue