mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
Choose i128/u128 num layouts when necessary
This commit is contained in:
parent
f31f78fde1
commit
ba450367ca
5 changed files with 170 additions and 252 deletions
|
@ -63,7 +63,7 @@ impl Output {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, Copy)]
|
||||||
pub enum IntValue {
|
pub enum IntValue {
|
||||||
I128([u8; 16]),
|
I128([u8; 16]),
|
||||||
U128([u8; 16]),
|
U128([u8; 16]),
|
||||||
|
|
|
@ -3610,66 +3610,22 @@ fn specialize_naked_symbol<'a>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_make_literal<'a>(
|
fn try_make_literal<'a>(can_expr: &roc_can::expr::Expr, layout: Layout<'a>) -> Option<Literal<'a>> {
|
||||||
env: &mut Env<'a, '_>,
|
|
||||||
can_expr: &roc_can::expr::Expr,
|
|
||||||
) -> Option<Literal<'a>> {
|
|
||||||
use roc_can::expr::Expr::*;
|
use roc_can::expr::Expr::*;
|
||||||
|
|
||||||
match can_expr {
|
match can_expr {
|
||||||
Int(_, precision, _, int, _bound) => {
|
Int(_, _, int_str, int, _bound) => {
|
||||||
match num_argument_to_int_or_float(env.subs, env.target_info, *precision, false) {
|
Some(make_num_literal(layout, int_str, IntOrFloatValue::Int(*int)).to_expr_literal())
|
||||||
IntOrFloat::Int(_) => Some(match *int {
|
|
||||||
IntValue::I128(n) => Literal::Int(n),
|
|
||||||
IntValue::U128(n) => Literal::U128(n),
|
|
||||||
}),
|
|
||||||
_ => unreachable!("unexpected float precision for integer"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Float(_, precision, float_str, float, _bound) => {
|
Float(_, _, float_str, float, _bound) => Some(
|
||||||
match num_argument_to_int_or_float(env.subs, env.target_info, *precision, true) {
|
make_num_literal(layout, float_str, IntOrFloatValue::Float(*float)).to_expr_literal(),
|
||||||
IntOrFloat::Float(_) => Some(Literal::Float(*float)),
|
|
||||||
IntOrFloat::DecimalFloatType => {
|
|
||||||
let dec = match RocDec::from_str(float_str) {
|
|
||||||
Some(d) => d,
|
|
||||||
None => panic!(
|
|
||||||
r"Invalid decimal for float literal = {}. TODO: Make this a nice, user-friendly error message",
|
|
||||||
float_str
|
|
||||||
),
|
),
|
||||||
};
|
|
||||||
|
|
||||||
Some(Literal::Decimal(dec.to_ne_bytes()))
|
|
||||||
}
|
|
||||||
_ => unreachable!("unexpected float precision for integer"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO investigate lifetime trouble
|
// TODO investigate lifetime trouble
|
||||||
// Str(string) => Some(Literal::Str(env.arena.alloc(string))),
|
// Str(string) => Some(Literal::Str(env.arena.alloc(string))),
|
||||||
Num(var, num_str, num, _bound) => {
|
Num(_, num_str, num, _bound) => {
|
||||||
// first figure out what kind of number this is
|
Some(make_num_literal(layout, num_str, IntOrFloatValue::Int(*num)).to_expr_literal())
|
||||||
match num_argument_to_int_or_float(env.subs, env.target_info, *var, false) {
|
|
||||||
IntOrFloat::Int(_) => Some(match *num {
|
|
||||||
IntValue::I128(n) => Literal::Int(n),
|
|
||||||
IntValue::U128(n) => Literal::U128(n),
|
|
||||||
}),
|
|
||||||
IntOrFloat::Float(_) => Some(match *num {
|
|
||||||
IntValue::I128(n) => Literal::Float(i128::from_ne_bytes(n) as f64),
|
|
||||||
IntValue::U128(n) => Literal::Float(u128::from_ne_bytes(n) as f64),
|
|
||||||
}),
|
|
||||||
IntOrFloat::DecimalFloatType => {
|
|
||||||
let dec = match RocDec::from_str(num_str) {
|
|
||||||
Some(d) => d,
|
|
||||||
None => panic!(
|
|
||||||
r"Invalid decimal for float literal = {}. TODO: Make this a nice, user-friendly error message",
|
|
||||||
num_str
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(Literal::Decimal(dec.to_ne_bytes()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -3689,44 +3645,35 @@ pub fn with_hole<'a>(
|
||||||
let arena = env.arena;
|
let arena = env.arena;
|
||||||
|
|
||||||
match can_expr {
|
match can_expr {
|
||||||
Int(_, precision, _, int, _bound) => {
|
Int(_, _, int_str, int, _bound) => assign_num_literal_expr(
|
||||||
match num_argument_to_int_or_float(env.subs, env.target_info, precision, false) {
|
env,
|
||||||
IntOrFloat::Int(precision) => Stmt::Let(
|
layout_cache,
|
||||||
assigned,
|
assigned,
|
||||||
Expr::Literal(match int {
|
variable,
|
||||||
IntValue::I128(n) => Literal::Int(n),
|
&int_str,
|
||||||
IntValue::U128(n) => Literal::U128(n),
|
IntOrFloatValue::Int(int),
|
||||||
}),
|
|
||||||
Layout::Builtin(Builtin::Int(precision)),
|
|
||||||
hole,
|
hole,
|
||||||
),
|
),
|
||||||
_ => unreachable!("unexpected float precision for integer"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Float(_, precision, float_str, float, _bound) => {
|
Float(_, _, float_str, float, _bound) => assign_num_literal_expr(
|
||||||
match num_argument_to_int_or_float(env.subs, env.target_info, precision, true) {
|
env,
|
||||||
IntOrFloat::Float(precision) => Stmt::Let(
|
layout_cache,
|
||||||
assigned,
|
assigned,
|
||||||
Expr::Literal(Literal::Float(float)),
|
variable,
|
||||||
Layout::Builtin(Builtin::Float(precision)),
|
&float_str,
|
||||||
|
IntOrFloatValue::Float(float),
|
||||||
hole,
|
hole,
|
||||||
),
|
),
|
||||||
IntOrFloat::DecimalFloatType => {
|
|
||||||
let dec = match RocDec::from_str(&float_str) {
|
Num(_, num_str, num, _bound) => assign_num_literal_expr(
|
||||||
Some(d) => d,
|
env,
|
||||||
None => panic!("Invalid decimal for float literal = {}. TODO: Make this a nice, user-friendly error message", float_str),
|
layout_cache,
|
||||||
};
|
|
||||||
Stmt::Let(
|
|
||||||
assigned,
|
assigned,
|
||||||
Expr::Literal(Literal::Decimal(dec.to_ne_bytes())),
|
variable,
|
||||||
Layout::Builtin(Builtin::Decimal),
|
&num_str,
|
||||||
|
IntOrFloatValue::Int(num),
|
||||||
hole,
|
hole,
|
||||||
)
|
),
|
||||||
}
|
|
||||||
_ => unreachable!("unexpected float precision for integer"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Str(string) => Stmt::Let(
|
Str(string) => Stmt::Let(
|
||||||
assigned,
|
assigned,
|
||||||
|
@ -3741,16 +3688,6 @@ pub fn with_hole<'a>(
|
||||||
Layout::int_width(IntWidth::I32),
|
Layout::int_width(IntWidth::I32),
|
||||||
hole,
|
hole,
|
||||||
),
|
),
|
||||||
|
|
||||||
Num(_, num_str, num, _bound) => assign_num_literal(
|
|
||||||
env,
|
|
||||||
layout_cache,
|
|
||||||
assigned,
|
|
||||||
variable,
|
|
||||||
&num_str,
|
|
||||||
IntOrFloatValue::Int(num),
|
|
||||||
hole,
|
|
||||||
),
|
|
||||||
LetNonRec(def, cont) => from_can_let(
|
LetNonRec(def, cont) => from_can_let(
|
||||||
env,
|
env,
|
||||||
procs,
|
procs,
|
||||||
|
@ -4255,8 +4192,12 @@ pub fn with_hole<'a>(
|
||||||
|
|
||||||
let mut symbol_exprs = Vec::with_capacity_in(loc_elems.len(), env.arena);
|
let mut symbol_exprs = Vec::with_capacity_in(loc_elems.len(), env.arena);
|
||||||
|
|
||||||
|
let elem_layout = layout_cache
|
||||||
|
.from_var(env.arena, elem_var, env.subs)
|
||||||
|
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
for arg_expr in loc_elems.into_iter() {
|
for arg_expr in loc_elems.into_iter() {
|
||||||
if let Some(literal) = try_make_literal(env, &arg_expr.value) {
|
if let Some(literal) = try_make_literal(&arg_expr.value, elem_layout) {
|
||||||
elements.push(ListLiteralElement::Literal(literal));
|
elements.push(ListLiteralElement::Literal(literal));
|
||||||
} else {
|
} else {
|
||||||
let symbol = possible_reuse_symbol_or_specialize(
|
let symbol = possible_reuse_symbol_or_specialize(
|
||||||
|
@ -4274,10 +4215,6 @@ pub fn with_hole<'a>(
|
||||||
}
|
}
|
||||||
let arg_symbols = arg_symbols.into_bump_slice();
|
let arg_symbols = arg_symbols.into_bump_slice();
|
||||||
|
|
||||||
let elem_layout = layout_cache
|
|
||||||
.from_var(env.arena, elem_var, env.subs)
|
|
||||||
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
|
||||||
|
|
||||||
let expr = Expr::Array {
|
let expr = Expr::Array {
|
||||||
elem_layout,
|
elem_layout,
|
||||||
elems: elements.into_bump_slice(),
|
elems: elements.into_bump_slice(),
|
||||||
|
@ -8249,40 +8186,20 @@ fn from_can_pattern_help<'a>(
|
||||||
Underscore => Ok(Pattern::Underscore),
|
Underscore => Ok(Pattern::Underscore),
|
||||||
Identifier(symbol) => Ok(Pattern::Identifier(*symbol)),
|
Identifier(symbol) => Ok(Pattern::Identifier(*symbol)),
|
||||||
AbilityMemberSpecialization { ident, .. } => Ok(Pattern::Identifier(*ident)),
|
AbilityMemberSpecialization { ident, .. } => Ok(Pattern::Identifier(*ident)),
|
||||||
IntLiteral(_, precision_var, _, int, _bound) => {
|
IntLiteral(_, precision_var, int_str, int, _bound) => Ok(make_num_literal_pattern(
|
||||||
match num_argument_to_int_or_float(env.subs, env.target_info, *precision_var, false) {
|
env,
|
||||||
IntOrFloat::Int(precision) => match *int {
|
layout_cache,
|
||||||
IntValue::I128(n) | IntValue::U128(n) => Ok(Pattern::IntLiteral(n, precision)),
|
*precision_var,
|
||||||
},
|
int_str,
|
||||||
other => {
|
IntOrFloatValue::Int(*int),
|
||||||
panic!(
|
)),
|
||||||
"Invalid precision for int pattern: {:?} has {:?}",
|
FloatLiteral(_, precision_var, float_str, float, _bound) => Ok(make_num_literal_pattern(
|
||||||
can_pattern, other
|
env,
|
||||||
)
|
layout_cache,
|
||||||
}
|
*precision_var,
|
||||||
}
|
float_str,
|
||||||
}
|
IntOrFloatValue::Float(*float),
|
||||||
FloatLiteral(_, precision_var, float_str, float, _bound) => {
|
)),
|
||||||
// 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.target_info, *precision_var, true) {
|
|
||||||
IntOrFloat::Int(_) => {
|
|
||||||
panic!("Invalid precision for float pattern {:?}", precision_var)
|
|
||||||
}
|
|
||||||
IntOrFloat::Float(precision) => {
|
|
||||||
Ok(Pattern::FloatLiteral(f64::to_bits(*float), precision))
|
|
||||||
}
|
|
||||||
IntOrFloat::DecimalFloatType => {
|
|
||||||
let dec = match RocDec::from_str(float_str) {
|
|
||||||
Some(d) => d,
|
|
||||||
None => panic!(
|
|
||||||
r"Invalid decimal for float literal = {}. TODO: Make this a nice, user-friendly error message",
|
|
||||||
float_str
|
|
||||||
),
|
|
||||||
};
|
|
||||||
Ok(Pattern::DecimalLiteral(dec.to_ne_bytes()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StrLiteral(v) => Ok(Pattern::StrLiteral(v.clone())),
|
StrLiteral(v) => Ok(Pattern::StrLiteral(v.clone())),
|
||||||
SingleQuote(c) => Ok(Pattern::IntLiteral(
|
SingleQuote(c) => Ok(Pattern::IntLiteral(
|
||||||
(*c as i128).to_ne_bytes(),
|
(*c as i128).to_ne_bytes(),
|
||||||
|
@ -8302,30 +8219,13 @@ fn from_can_pattern_help<'a>(
|
||||||
// TODO(opaques) should be `RuntimeError::OpaqueNotDefined`
|
// TODO(opaques) should be `RuntimeError::OpaqueNotDefined`
|
||||||
Err(RuntimeError::UnsupportedPattern(loc_ident.region))
|
Err(RuntimeError::UnsupportedPattern(loc_ident.region))
|
||||||
}
|
}
|
||||||
NumLiteral(var, num_str, num, _bound) => {
|
NumLiteral(var, num_str, num, _bound) => Ok(make_num_literal_pattern(
|
||||||
match num_argument_to_int_or_float(env.subs, env.target_info, *var, false) {
|
env,
|
||||||
IntOrFloat::Int(precision) => Ok(match num {
|
layout_cache,
|
||||||
IntValue::I128(num) | IntValue::U128(num) => {
|
*var,
|
||||||
Pattern::IntLiteral(*num, precision)
|
num_str,
|
||||||
}
|
IntOrFloatValue::Int(*num),
|
||||||
}),
|
)),
|
||||||
IntOrFloat::Float(precision) => {
|
|
||||||
// TODO: this may be lossy
|
|
||||||
let num = match *num {
|
|
||||||
IntValue::I128(n) => f64::to_bits(i128::from_ne_bytes(n) as f64),
|
|
||||||
IntValue::U128(n) => f64::to_bits(u128::from_ne_bytes(n) as f64),
|
|
||||||
};
|
|
||||||
Ok(Pattern::FloatLiteral(num, precision))
|
|
||||||
}
|
|
||||||
IntOrFloat::DecimalFloatType => {
|
|
||||||
let dec = match RocDec::from_str(num_str) {
|
|
||||||
Some(d) => d,
|
|
||||||
None => panic!("Invalid decimal for float literal = {}. TODO: Make this a nice, user-friendly error message", num_str),
|
|
||||||
};
|
|
||||||
Ok(Pattern::DecimalLiteral(dec.to_ne_bytes()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AppliedTag {
|
AppliedTag {
|
||||||
whole_var,
|
whole_var,
|
||||||
|
@ -8936,40 +8836,52 @@ fn from_can_record_destruct<'a>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum IntOrFloat {
|
|
||||||
Int(IntWidth),
|
|
||||||
Float(FloatWidth),
|
|
||||||
DecimalFloatType,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum IntOrFloatValue {
|
enum IntOrFloatValue {
|
||||||
Int(IntValue),
|
Int(IntValue),
|
||||||
Float(f64),
|
Float(f64),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assign_num_literal<'a>(
|
enum NumLiteral {
|
||||||
env: &mut Env<'a, '_>,
|
Int([u8; 16], IntWidth),
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
U128([u8; 16]),
|
||||||
assigned: Symbol,
|
Float(f64, FloatWidth),
|
||||||
variable: Variable,
|
Decimal([u8; 16]),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NumLiteral {
|
||||||
|
fn to_expr_literal(self) -> Literal<'static> {
|
||||||
|
match self {
|
||||||
|
NumLiteral::Int(n, _) => Literal::Int(n),
|
||||||
|
NumLiteral::U128(n) => Literal::U128(n),
|
||||||
|
NumLiteral::Float(n, _) => Literal::Float(n),
|
||||||
|
NumLiteral::Decimal(n) => Literal::Decimal(n),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn to_pattern(self) -> Pattern<'static> {
|
||||||
|
match self {
|
||||||
|
NumLiteral::Int(n, w) => Pattern::IntLiteral(n, w),
|
||||||
|
NumLiteral::U128(_) => todo!(),
|
||||||
|
NumLiteral::Float(n, w) => Pattern::FloatLiteral(f64::to_bits(n), w),
|
||||||
|
NumLiteral::Decimal(n) => Pattern::DecimalLiteral(n),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_num_literal<'a>(
|
||||||
|
layout: Layout<'a>,
|
||||||
num_str: &str,
|
num_str: &str,
|
||||||
num_value: IntOrFloatValue,
|
num_value: IntOrFloatValue,
|
||||||
hole: &'a Stmt<'a>,
|
) -> NumLiteral {
|
||||||
) -> Stmt<'a> {
|
match layout {
|
||||||
let layout = layout_cache
|
Layout::Builtin(Builtin::Int(width)) => match num_value {
|
||||||
.from_var(env.arena, variable, &env.subs)
|
IntOrFloatValue::Int(IntValue::I128(n)) => NumLiteral::Int(n, width),
|
||||||
.unwrap();
|
IntOrFloatValue::Int(IntValue::U128(n)) => NumLiteral::U128(n),
|
||||||
let literal = match layout {
|
|
||||||
Layout::Builtin(Builtin::Int(_)) => match num_value {
|
|
||||||
IntOrFloatValue::Int(IntValue::I128(n)) => Literal::Int(n),
|
|
||||||
IntOrFloatValue::Int(IntValue::U128(n)) => Literal::U128(n),
|
|
||||||
IntOrFloatValue::Float(..) => {
|
IntOrFloatValue::Float(..) => {
|
||||||
internal_error!("Float value where int was expected, should have been a type error")
|
internal_error!("Float value where int was expected, should have been a type error")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Layout::Builtin(Builtin::Float(_)) => match num_value {
|
Layout::Builtin(Builtin::Float(width)) => match num_value {
|
||||||
IntOrFloatValue::Float(n) => Literal::Float(n),
|
IntOrFloatValue::Float(n) => NumLiteral::Float(n, width),
|
||||||
IntOrFloatValue::Int(..) => {
|
IntOrFloatValue::Int(..) => {
|
||||||
internal_error!("Int value where float was expected, should have been a type error")
|
internal_error!("Int value where float was expected, should have been a type error")
|
||||||
}
|
}
|
||||||
|
@ -8982,81 +8894,44 @@ fn assign_num_literal<'a>(
|
||||||
num_str
|
num_str
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
Literal::Decimal(dec.to_ne_bytes())
|
NumLiteral::Decimal(dec.to_ne_bytes())
|
||||||
}
|
}
|
||||||
layout => internal_error!(
|
layout => internal_error!(
|
||||||
"Found a non-num layout where a number was expected: {:?}",
|
"Found a non-num layout where a number was expected: {:?}",
|
||||||
layout
|
layout
|
||||||
),
|
),
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assign_num_literal_expr<'a>(
|
||||||
|
env: &mut Env<'a, '_>,
|
||||||
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
|
assigned: Symbol,
|
||||||
|
variable: Variable,
|
||||||
|
num_str: &str,
|
||||||
|
num_value: IntOrFloatValue,
|
||||||
|
hole: &'a Stmt<'a>,
|
||||||
|
) -> Stmt<'a> {
|
||||||
|
let layout = layout_cache
|
||||||
|
.from_var(env.arena, variable, &env.subs)
|
||||||
|
.unwrap();
|
||||||
|
let literal = make_num_literal(layout, num_str, num_value).to_expr_literal();
|
||||||
|
|
||||||
Stmt::Let(assigned, Expr::Literal(literal), layout, hole)
|
Stmt::Let(assigned, Expr::Literal(literal), layout, hole)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given the `a` in `Num a`, determines whether it's an int or a float
|
fn make_num_literal_pattern<'a>(
|
||||||
pub fn num_argument_to_int_or_float(
|
env: &mut Env<'a, '_>,
|
||||||
subs: &Subs,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
target_info: TargetInfo,
|
variable: Variable,
|
||||||
var: Variable,
|
num_str: &str,
|
||||||
known_to_be_float: bool,
|
num_value: IntOrFloatValue,
|
||||||
) -> IntOrFloat {
|
) -> Pattern<'a> {
|
||||||
match subs.get_content_without_compacting(var) {
|
let layout = layout_cache
|
||||||
Content::FlexVar(_) | Content::RigidVar(_) if known_to_be_float => {
|
.from_var(env.arena, variable, &env.subs)
|
||||||
IntOrFloat::Float(FloatWidth::F64)
|
.unwrap();
|
||||||
}
|
let literal = make_num_literal(layout, num_str, num_value);
|
||||||
Content::FlexVar(_) | Content::RigidVar(_) => IntOrFloat::Int(IntWidth::I64), // We default (Num *) to I64
|
literal.to_pattern()
|
||||||
|
|
||||||
Content::Alias(Symbol::NUM_INTEGER, args, _, _) => {
|
|
||||||
debug_assert!(args.len() == 1);
|
|
||||||
|
|
||||||
// Recurse on the second argument
|
|
||||||
let var = subs[args.all_variables().into_iter().next().unwrap()];
|
|
||||||
num_argument_to_int_or_float(subs, target_info, var, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
other @ Content::Alias(symbol, args, _, _) => {
|
|
||||||
if let Some(int_width) = IntWidth::try_from_symbol(*symbol) {
|
|
||||||
return IntOrFloat::Int(int_width);
|
|
||||||
}
|
|
||||||
|
|
||||||
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.all_variables().into_iter().next().unwrap()];
|
|
||||||
num_argument_to_int_or_float(subs, target_info, var, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
Symbol::NUM_DECIMAL => IntOrFloat::DecimalFloatType,
|
|
||||||
|
|
||||||
Symbol::NUM_NAT | Symbol::NUM_NATURAL => {
|
|
||||||
let int_width = match target_info.ptr_width() {
|
|
||||||
roc_target::PtrWidth::Bytes4 => IntWidth::U32,
|
|
||||||
roc_target::PtrWidth::Bytes8 => IntWidth::U64,
|
|
||||||
};
|
|
||||||
|
|
||||||
IntOrFloat::Int(int_width)
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => panic!(
|
|
||||||
"Unrecognized Num type argument for var {:?} with Content: {:?}",
|
|
||||||
var, other
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
other => {
|
|
||||||
panic!(
|
|
||||||
"Unrecognized Num type argument for var {:?} with Content: {:?}",
|
|
||||||
var, other
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ToLowLevelCallArguments<'a> = (
|
type ToLowLevelCallArguments<'a> = (
|
||||||
|
|
13
crates/compiler/test_mono/generated/choose_i128_layout.txt
Normal file
13
crates/compiler/test_mono/generated/choose_i128_layout.txt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
procedure Num.19 (#Attr.2, #Attr.3):
|
||||||
|
let Num.189 : I128 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
|
ret Num.189;
|
||||||
|
|
||||||
|
procedure Test.0 ():
|
||||||
|
let Test.6 : I128 = 18446744073709551616i64;
|
||||||
|
let Test.7 : I128 = 1i64;
|
||||||
|
let Test.2 : I128 = CallByName Num.19 Test.6 Test.7;
|
||||||
|
let Test.4 : I128 = -9223372036854775809i64;
|
||||||
|
let Test.5 : I128 = 1i64;
|
||||||
|
let Test.3 : I128 = CallByName Num.19 Test.4 Test.5;
|
||||||
|
let Test.1 : {I128, I128} = Struct {Test.2, Test.3};
|
||||||
|
ret Test.1;
|
|
@ -0,0 +1,9 @@
|
||||||
|
procedure Num.19 (#Attr.2, #Attr.3):
|
||||||
|
let Num.188 : U128 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||||
|
ret Num.188;
|
||||||
|
|
||||||
|
procedure Test.0 ():
|
||||||
|
let Test.2 : U128 = 170141183460469231731687303715884105728u128;
|
||||||
|
let Test.3 : U128 = 1i64;
|
||||||
|
let Test.1 : U128 = CallByName Num.19 Test.2 Test.3;
|
||||||
|
ret Test.1;
|
|
@ -1661,3 +1661,24 @@ fn choose_u64_layout() {
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[mono_test]
|
||||||
|
fn choose_i128_layout() {
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
{
|
||||||
|
a: 18446744073709551616 + 1,
|
||||||
|
b: -9223372036854775809 + 1,
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[mono_test]
|
||||||
|
fn choose_u128_layout() {
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
170141183460469231731687303715884105728 + 1
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue