Address various bits of feedback

This commit is contained in:
Jared Ramirez 2021-07-09 09:30:45 -07:00
parent 8ffe02110d
commit a35cc321ab
4 changed files with 81 additions and 23 deletions

View file

@ -443,13 +443,7 @@ fn add_intrinsics<'ctx>(ctx: &'ctx Context, module: &Module<'ctx>) {
ctx.struct_type(&fields, false)
.fn_type(&[i64_type.into(), i64_type.into()], false)
});
// TODO: This is now exported by zig. Not sure what to do here?
// add_intrinsic(module, LLVM_SADD_WITH_OVERFLOW_I128, {
// let fields = [i128_type.into(), i1_type.into()];
// ctx.struct_type(&fields, false)
// .fn_type(&[i128_type.into(), i128_type.into()], false)
// });
// LLVM_SADD_WITH_OVERFLOW_I128 is expoerted in bitcode
// sub with overflow
@ -476,13 +470,7 @@ fn add_intrinsics<'ctx>(ctx: &'ctx Context, module: &Module<'ctx>) {
ctx.struct_type(&fields, false)
.fn_type(&[i64_type.into(), i64_type.into()], false)
});
// TODO: This is now exported by zig. Not sure what to do here?
// add_intrinsic(module, LLVM_SSUB_WITH_OVERFLOW_I128, {
// let fields = [i128_type.into(), i1_type.into()];
// ctx.struct_type(&fields, false)
// .fn_type(&[i128_type.into(), i128_type.into()], false)
// });
// LLVM_SSUB_WITH_OVERFLOW_I128 is expoerted in bitcode
}
static LLVM_MEMSET_I64: &str = "llvm.memset.p0i8.i64";

View file

@ -127,13 +127,11 @@ fn hash_builtin<'a, 'ctx, 'env>(
| Builtin::Float32
| Builtin::Float128
| Builtin::Float16
| Builtin::Decimal
| Builtin::Usize => {
let hash_bytes = store_and_use_as_u8_ptr(env, val, &layout);
hash_bitcode_fn(env, seed, hash_bytes, layout.stack_size(ptr_bytes))
}
Builtin::Decimal => {
panic!("TODO: Hash Decimal");
}
Builtin::Str => {
// let zig deal with big vs small string
call_bitcode_fn(

View file

@ -3,7 +3,7 @@ mod gen_num {
use crate::assert_evals_to;
use crate::assert_llvm_evals_to;
use indoc::indoc;
use roc_std::RocOrder;
use roc_std::{RocDec, RocOrder};
#[test]
fn nat_alias() {
@ -339,7 +339,7 @@ mod gen_num {
x
"#
),
2100000000000000000,
RocDec::from_str_to_i128_unsafe(&"2.1"),
i128
);
}
@ -576,7 +576,7 @@ mod gen_num {
z
"#
),
5200000000000000000,
RocDec::from_str_to_i128_unsafe(&"5.2"),
i128
);
}
@ -639,7 +639,7 @@ mod gen_num {
Err _ -> -1
"#
),
3333333333333333333,
RocDec::from_str_to_i128_unsafe(&"3.333333333333333333"),
i128
);
}
@ -755,7 +755,7 @@ mod gen_num {
x - y - z
"#
),
-3900000000000000000,
RocDec::from_str_to_i128_unsafe(&"-3.9"),
i128
);
}
@ -803,7 +803,7 @@ mod gen_num {
x * y * z
"#
),
48000000000000000000,
RocDec::from_str_to_i128_unsafe(&"48.0"),
i128
);
}

View file

@ -1,5 +1,6 @@
#![crate_type = "lib"]
#![no_std]
use core::convert::From;
use core::ffi::c_void;
use core::{fmt, mem, ptr};
@ -694,3 +695,74 @@ impl<'a, T: Sized + Copy> From<&'a RocCallResult<T>> for Result<T, &'a str> {
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct RocDec(pub i128);
impl RocDec {
pub const MIN: Self = Self(i128::MIN);
pub const MAX: Self = Self(i128::MAX);
pub const DECIMAL_PLACES: u32 = 18;
pub const ONE_POINT_ZERO: i128 = 10i128.pow(Self::DECIMAL_PLACES);
pub fn from_str(value: &str) -> Result<Self, ()> {
// Split the string into the parts before and after the "."
let mut parts = value.split(".");
let before_point = match parts.next() {
Some(answer) => answer,
None => {
return Err(());
}
};
let after_point = match parts.next() {
Some(answer) if answer.len() <= Self::DECIMAL_PLACES as usize => answer,
_ => {
return Err(());
}
};
// There should have only been one "." in the string!
if parts.next().is_some() {
return Err(());
}
// Calculate the low digits - the ones after the decimal point.
let lo = match after_point.parse::<i128>() {
Ok(answer) => {
// Translate e.g. the 1 from 0.1 into 10000000000000000000
// by "restoring" the elided trailing zeroes to the number!
let trailing_zeroes = Self::DECIMAL_PLACES as usize - after_point.len();
let lo = answer * 10i128.pow(trailing_zeroes as u32);
if !before_point.starts_with("-") {
lo
} else {
-lo
}
}
Err(_) => {
return Err(());
}
};
// Calculate the high digits - the ones before the decimal point.
match before_point.parse::<i128>() {
Ok(answer) => match answer.checked_mul(10i128.pow(Self::DECIMAL_PLACES)) {
Some(hi) => match hi.checked_add(lo) {
Some(num) => Ok(RocDec(num)),
None => Err(()),
},
None => Err(()),
},
Err(_) => Err(()),
}
}
pub fn from_str_to_i128_unsafe(val: &str) -> i128 {
RocDec::from_str(val).unwrap().0
}
}