mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
fix i128 bug
This commit is contained in:
parent
e005dbde4c
commit
ecd03186dc
1 changed files with 55 additions and 17 deletions
|
@ -484,6 +484,34 @@ fn get_inplace_from_layout(layout: &Layout<'_>) -> InPlace {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn int_with_precision<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
value: i128,
|
||||
precision: &Builtin,
|
||||
) -> IntValue<'ctx> {
|
||||
match precision {
|
||||
Builtin::Usize => ptr_int(env.context, env.ptr_bytes).const_int(value as u64, false),
|
||||
Builtin::Int128 => const_i128(env, value),
|
||||
Builtin::Int64 => env.context.i64_type().const_int(value as u64, false),
|
||||
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),
|
||||
_ => panic!("Invalid layout for int literal = {:?}", precision),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn float_with_precision<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
value: f64,
|
||||
precision: &Builtin,
|
||||
) -> FloatValue<'ctx> {
|
||||
match precision {
|
||||
Builtin::Float64 => env.context.f64_type().const_float(value),
|
||||
Builtin::Float32 => env.context.f32_type().const_float(value),
|
||||
_ => panic!("Invalid layout for float literal = {:?}", precision),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_exp_literal<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout: &Layout<'_>,
|
||||
|
@ -492,22 +520,16 @@ pub fn build_exp_literal<'a, 'ctx, 'env>(
|
|||
use roc_mono::ir::Literal::*;
|
||||
|
||||
match literal {
|
||||
Int(int) =>
|
||||
(match layout {
|
||||
Layout::Builtin(Builtin::Usize) => ptr_int(env.context, env.ptr_bytes),
|
||||
Layout::Builtin(Builtin::Int128) => env.context.i128_type(), /* TODO file an issue: you can't currently have an int literal bigger than 64 bits long, and also (as we see here), you can't currently have (at least in Inkwell) a when-branch with an i128 literal in its pattren */
|
||||
Layout::Builtin(Builtin::Int64) => env.context.i64_type(),
|
||||
Layout::Builtin(Builtin::Int32) => env.context.i32_type(),
|
||||
Layout::Builtin(Builtin::Int16) => env.context.i16_type(),
|
||||
Layout::Builtin(Builtin::Int8) => env.context.i8_type(),
|
||||
Int(int) => match layout {
|
||||
Layout::Builtin(builtin) => int_with_precision(env, *int as i128, builtin).into(),
|
||||
_ => panic!("Invalid layout for int literal = {:?}", layout),
|
||||
}).const_int(*int as u64, false).into(),
|
||||
Float(num) =>
|
||||
(match layout {
|
||||
Layout::Builtin(Builtin::Float64) => env.context.f64_type(),
|
||||
Layout::Builtin(Builtin::Float32) => env.context.f32_type(),
|
||||
},
|
||||
|
||||
Float(float) => match layout {
|
||||
Layout::Builtin(builtin) => float_with_precision(env, *float, builtin).into(),
|
||||
_ => panic!("Invalid layout for float literal = {:?}", layout),
|
||||
}).const_float(*num).into(),
|
||||
},
|
||||
|
||||
Bool(b) => env.context.bool_type().const_int(*b as u64, false).into(),
|
||||
Byte(b) => env.context.i8_type().const_int(*b as u64, false).into(),
|
||||
Str(str_literal) => {
|
||||
|
@ -1783,6 +1805,22 @@ struct SwitchArgsIr<'a, 'ctx> {
|
|||
pub ret_type: BasicTypeEnum<'ctx>,
|
||||
}
|
||||
|
||||
fn const_i128<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>, value: i128) -> IntValue<'ctx> {
|
||||
// TODO verify the order [a, b] is correct for larger numbers when we can parse them
|
||||
debug_assert!(value <= i64::MAX as i128);
|
||||
|
||||
// truncate the lower 64 bits
|
||||
let value = value as u128;
|
||||
let a = value as u64;
|
||||
|
||||
// get the upper 64 bits
|
||||
let b = (value >> 64) as u64;
|
||||
|
||||
env.context
|
||||
.i128_type()
|
||||
.const_int_arbitrary_precision(&[a, b])
|
||||
}
|
||||
|
||||
fn build_switch_ir<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
|
@ -1860,7 +1898,7 @@ fn build_switch_ir<'a, 'ctx, 'env>(
|
|||
ptr_int(env.context, env.ptr_bytes).const_int(*int as u64, false)
|
||||
}
|
||||
Layout::Builtin(Builtin::Int64) => context.i64_type().const_int(*int as u64, false),
|
||||
Layout::Builtin(Builtin::Int128) => context.i128_type().const_int(*int as u64, false), /* TODO file an issue: you can't currently have an int literal bigger than 64 bits long, and also (as we see here), you can't currently have (at least in Inkwell) a when-branch with an i128 literal in its pattren */
|
||||
Layout::Builtin(Builtin::Int128) => const_i128(env, *int as i128),
|
||||
Layout::Builtin(Builtin::Int32) => context.i32_type().const_int(*int as u64, false),
|
||||
Layout::Builtin(Builtin::Int16) => context.i16_type().const_int(*int as u64, false),
|
||||
Layout::Builtin(Builtin::Int8) => context.i8_type().const_int(*int as u64, false),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue