mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 22:09:09 +00:00
Adding Decimals work!!
This commit is contained in:
parent
4d6e5a1a4f
commit
0827123c88
8 changed files with 108 additions and 71 deletions
|
@ -23,6 +23,23 @@ pub const RocDec = extern struct {
|
||||||
return .{ .num = num * one_point_zero_i128 };
|
return .{ .num = num * one_point_zero_i128 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: There's got to be a better way to do this other than converting to Str
|
||||||
|
pub fn fromF64(num: f64) RocDec {
|
||||||
|
var digit_bytes: [19]u8 = undefined; // Max f64 digits + '.' + '-'
|
||||||
|
|
||||||
|
var fbs = std.io.fixedBufferStream(digit_bytes[0..]);
|
||||||
|
std.fmt.formatFloatDecimal(num, .{}, fbs.writer()) catch
|
||||||
|
@panic("TODO runtime exception failing to print float!");
|
||||||
|
|
||||||
|
var dec = RocDec.fromStr(RocStr.init(&digit_bytes, fbs.pos));
|
||||||
|
|
||||||
|
if (dec) |d| {
|
||||||
|
return d;
|
||||||
|
} else {
|
||||||
|
@panic("TODO runtime exception failing convert f64 to RocDec");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fromStr(roc_str: RocStr) ?RocDec {
|
pub fn fromStr(roc_str: RocStr) ?RocDec {
|
||||||
if (roc_str.isEmpty()) {
|
if (roc_str.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -58,7 +75,7 @@ pub const RocDec = extern struct {
|
||||||
|
|
||||||
var after_str_len = (length - 1) - pi;
|
var after_str_len = (length - 1) - pi;
|
||||||
if (after_str_len > decimal_places) {
|
if (after_str_len > decimal_places) {
|
||||||
std.debug.panic("TODO runtime exception for too many decimal places!", .{});
|
@panic("TODO runtime exception for too many decimal places!");
|
||||||
}
|
}
|
||||||
var diff_decimal_places = decimal_places - after_str_len;
|
var diff_decimal_places = decimal_places - after_str_len;
|
||||||
|
|
||||||
|
@ -75,7 +92,7 @@ pub const RocDec = extern struct {
|
||||||
var result: i128 = undefined;
|
var result: i128 = undefined;
|
||||||
var overflowed = @mulWithOverflow(i128, before, one_point_zero_i128, &result);
|
var overflowed = @mulWithOverflow(i128, before, one_point_zero_i128, &result);
|
||||||
if (overflowed) {
|
if (overflowed) {
|
||||||
std.debug.panic("TODO runtime exception for overflow!", .{});
|
@panic("TODO runtime exception for overflow!");
|
||||||
}
|
}
|
||||||
before_val_i128 = result;
|
before_val_i128 = result;
|
||||||
}
|
}
|
||||||
|
@ -86,7 +103,7 @@ pub const RocDec = extern struct {
|
||||||
var result: i128 = undefined;
|
var result: i128 = undefined;
|
||||||
var overflowed = @addWithOverflow(i128, before, after, &result);
|
var overflowed = @addWithOverflow(i128, before, after, &result);
|
||||||
if (overflowed) {
|
if (overflowed) {
|
||||||
std.debug.panic("TODO runtime exception for overflow!", .{});
|
@panic("TODO runtime exception for overflow!");
|
||||||
}
|
}
|
||||||
dec = .{ .num = result };
|
dec = .{ .num = result };
|
||||||
} else {
|
} else {
|
||||||
|
@ -119,7 +136,7 @@ pub const RocDec = extern struct {
|
||||||
// We will handle adding the '-' later
|
// We will handle adding the '-' later
|
||||||
const is_negative = self.num < 0;
|
const is_negative = self.num < 0;
|
||||||
const num = if (is_negative) std.math.negate(self.num) catch {
|
const num = if (is_negative) std.math.negate(self.num) catch {
|
||||||
std.debug.panic("TODO runtime exception failing to negate", .{});
|
@panic("TODO runtime exception failing to negate");
|
||||||
} else self.num;
|
} else self.num;
|
||||||
|
|
||||||
// Format the backing i128 into an array of digits (u8s)
|
// Format the backing i128 into an array of digits (u8s)
|
||||||
|
@ -135,7 +152,7 @@ pub const RocDec = extern struct {
|
||||||
before_digits_slice = digit_bytes[0..before_digits_offset];
|
before_digits_slice = digit_bytes[0..before_digits_offset];
|
||||||
} else {
|
} else {
|
||||||
before_digits_adjust = @intCast(u6, math.absInt(@intCast(i7, num_digits) - decimal_places) catch {
|
before_digits_adjust = @intCast(u6, math.absInt(@intCast(i7, num_digits) - decimal_places) catch {
|
||||||
std.debug.panic("TODO runtime exception for overflow when getting abs", .{});
|
@panic("TODO runtime exception for overflow when getting abs");
|
||||||
});
|
});
|
||||||
before_digits_slice = "0";
|
before_digits_slice = "0";
|
||||||
}
|
}
|
||||||
|
@ -185,7 +202,7 @@ pub const RocDec = extern struct {
|
||||||
// Ideally, we'd use str_len here
|
// Ideally, we'd use str_len here
|
||||||
var str_bytes: [max_digits + 2]u8 = undefined;
|
var str_bytes: [max_digits + 2]u8 = undefined;
|
||||||
_ = std.fmt.bufPrint(str_bytes[0..str_len], "{s}{s}.{s}{s}", .{ sign_slice, before_digits_slice, after_zeros_slice, after_digits_slice }) catch {
|
_ = std.fmt.bufPrint(str_bytes[0..str_len], "{s}{s}.{s}{s}", .{ sign_slice, before_digits_slice, after_zeros_slice, after_digits_slice }) catch {
|
||||||
std.debug.panic("TODO runtime exception failing to print slices", .{});
|
@panic("TODO runtime exception failing to print slices");
|
||||||
};
|
};
|
||||||
|
|
||||||
return RocStr.init(&str_bytes, str_len);
|
return RocStr.init(&str_bytes, str_len);
|
||||||
|
@ -203,7 +220,7 @@ pub const RocDec = extern struct {
|
||||||
if (!overflowed) {
|
if (!overflowed) {
|
||||||
return RocDec{ .num = answer };
|
return RocDec{ .num = answer };
|
||||||
} else {
|
} else {
|
||||||
std.debug.panic("TODO runtime exception for overflow!", .{});
|
@panic("TODO runtime exception for overflow!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +231,7 @@ pub const RocDec = extern struct {
|
||||||
if (!overflowed) {
|
if (!overflowed) {
|
||||||
return RocDec{ .num = answer };
|
return RocDec{ .num = answer };
|
||||||
} else {
|
} else {
|
||||||
std.debug.panic("TODO runtime exception for overflow!", .{});
|
@panic("TODO runtime exception for overflow!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +248,7 @@ pub const RocDec = extern struct {
|
||||||
} else if (other_i128 == RocDec.one_point_zero.num) {
|
} else if (other_i128 == RocDec.one_point_zero.num) {
|
||||||
return self;
|
return self;
|
||||||
} else {
|
} else {
|
||||||
std.debug.panic("TODO runtime exception for overflow!", .{});
|
@panic("TODO runtime exception for overflow!");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -241,7 +258,7 @@ pub const RocDec = extern struct {
|
||||||
} else if (self_i128 == RocDec.one_point_zero.num) {
|
} else if (self_i128 == RocDec.one_point_zero.num) {
|
||||||
return other;
|
return other;
|
||||||
} else {
|
} else {
|
||||||
std.debug.panic("TODO runtime exception for overflow!", .{});
|
@panic("TODO runtime exception for overflow!");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -265,7 +282,7 @@ pub const RocDec = extern struct {
|
||||||
|
|
||||||
// (n / 0) is an error
|
// (n / 0) is an error
|
||||||
if (denominator_i128 == 0) {
|
if (denominator_i128 == 0) {
|
||||||
std.debug.panic("TODO runtime exception for divide by 0!", .{});
|
@panic("TODO runtime exception for divide by 0!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If they're both negative, or if neither is negative, the final answer
|
// If they're both negative, or if neither is negative, the final answer
|
||||||
|
@ -293,7 +310,7 @@ pub const RocDec = extern struct {
|
||||||
if (denominator_i128 == one_point_zero_i128) {
|
if (denominator_i128 == one_point_zero_i128) {
|
||||||
return self;
|
return self;
|
||||||
} else {
|
} else {
|
||||||
std.debug.panic("TODO runtime exception for overflow when dividing!", .{});
|
@panic("TODO runtime exception for overflow when dividing!");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const numerator_u128 = @intCast(u128, numerator_abs_i128);
|
const numerator_u128 = @intCast(u128, numerator_abs_i128);
|
||||||
|
@ -306,7 +323,7 @@ pub const RocDec = extern struct {
|
||||||
if (numerator_i128 == one_point_zero_i128) {
|
if (numerator_i128 == one_point_zero_i128) {
|
||||||
return other;
|
return other;
|
||||||
} else {
|
} else {
|
||||||
std.debug.panic("TODO runtime exception for overflow when dividing!", .{});
|
@panic("TODO runtime exception for overflow when dividing!");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const denominator_u128 = @intCast(u128, denominator_abs_i128);
|
const denominator_u128 = @intCast(u128, denominator_abs_i128);
|
||||||
|
@ -318,7 +335,7 @@ pub const RocDec = extern struct {
|
||||||
if (answer.hi == 0 and answer.lo <= math.maxInt(i128)) {
|
if (answer.hi == 0 and answer.lo <= math.maxInt(i128)) {
|
||||||
unsigned_answer = @intCast(i128, answer.lo);
|
unsigned_answer = @intCast(i128, answer.lo);
|
||||||
} else {
|
} else {
|
||||||
std.debug.panic("TODO runtime exception for overflow when dividing!", .{});
|
@panic("TODO runtime exception for overflow when dividing!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return RocDec{ .num = if (is_answer_negative) -unsigned_answer else unsigned_answer };
|
return RocDec{ .num = if (is_answer_negative) -unsigned_answer else unsigned_answer };
|
||||||
|
@ -438,7 +455,7 @@ fn mul_and_decimalize(a: u128, b: u128) i128 {
|
||||||
overflowed = overflowed or @addWithOverflow(u128, d, c_carry4, &d);
|
overflowed = overflowed or @addWithOverflow(u128, d, c_carry4, &d);
|
||||||
|
|
||||||
if (overflowed) {
|
if (overflowed) {
|
||||||
std.debug.panic("TODO runtime exception for overflow!", .{});
|
@panic("TODO runtime exception for overflow!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final 512bit value is d, c, b, a
|
// Final 512bit value is d, c, b, a
|
||||||
|
@ -653,6 +670,11 @@ test "fromU64" {
|
||||||
try expectEqual(RocDec{ .num = 25000000000000000000 }, dec);
|
try expectEqual(RocDec{ .num = 25000000000000000000 }, dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "fromF64" {
|
||||||
|
var dec = RocDec.fromF64(25.5);
|
||||||
|
try expectEqual(RocDec{ .num = 25500000000000000000 }, dec);
|
||||||
|
}
|
||||||
|
|
||||||
test "fromStr: empty" {
|
test "fromStr: empty" {
|
||||||
var roc_str = RocStr.init("", 0);
|
var roc_str = RocStr.init("", 0);
|
||||||
var dec = RocDec.fromStr(roc_str);
|
var dec = RocDec.fromStr(roc_str);
|
||||||
|
@ -957,8 +979,10 @@ test "div: 10 / 3" {
|
||||||
|
|
||||||
// exports
|
// exports
|
||||||
|
|
||||||
const FromStrResult = extern struct { dec: RocDec, is_ok: bool };
|
pub fn fromF64(arg: f64) callconv(.C) i128 {
|
||||||
|
return @call(.{ .modifier = always_inline }, RocDec.fromF64, .{arg}).num;
|
||||||
pub fn fromStrC(arg: RocStr, output: *FromStrResult) callconv(.C) void {
|
}
|
||||||
output.* = if (@call(.{ .modifier = always_inline }, RocDec.fromStr, .{arg})) |dec| .{ .dec = dec, .is_ok = true } else .{ .dec = RocDec.one_point_zero, .is_ok = false };
|
|
||||||
|
pub fn add(arg1: RocDec, arg2: RocDec) callconv(.C) i128 {
|
||||||
|
return @call(.{ .modifier = always_inline }, RocDec.add, .{ arg1, arg2 }).num;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,8 @@ const testing = std.testing;
|
||||||
const dec = @import("dec.zig");
|
const dec = @import("dec.zig");
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
// exportDecFn(dec.fromStrC, "from_str");
|
exportDecFn(dec.fromF64, "from_f64");
|
||||||
|
exportDecFn(dec.add, "add");
|
||||||
}
|
}
|
||||||
|
|
||||||
// List Module
|
// List Module
|
||||||
|
@ -112,6 +113,11 @@ fn exportDecFn(comptime func: anytype, comptime func_name: []const u8) void {
|
||||||
exportBuiltinFn(func, "dec." ++ func_name);
|
exportBuiltinFn(func, "dec." ++ func_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn panic(message: []const u8, stacktrace: ?*std.builtin.StackTrace) noreturn {
|
||||||
|
std.debug.print("{s}", .{message});
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
// Run all tests in imported modules
|
// Run all tests in imported modules
|
||||||
// https://github.com/ziglang/zig/blob/master/lib/std/std.zig#L94
|
// https://github.com/ziglang/zig/blob/master/lib/std/std.zig#L94
|
||||||
test "" {
|
test "" {
|
||||||
|
|
|
@ -65,3 +65,7 @@ pub const LIST_REVERSE: &str = "roc_builtins.list.reverse";
|
||||||
pub const LIST_SORT_WITH: &str = "roc_builtins.list.sort_with";
|
pub const LIST_SORT_WITH: &str = "roc_builtins.list.sort_with";
|
||||||
pub const LIST_CONCAT: &str = "roc_builtins.list.concat";
|
pub const LIST_CONCAT: &str = "roc_builtins.list.concat";
|
||||||
pub const LIST_SET: &str = "roc_builtins.list.set";
|
pub const LIST_SET: &str = "roc_builtins.list.set";
|
||||||
|
|
||||||
|
pub const DEC_FROM_F64: &str = "roc_builtins.dec.from_f64";
|
||||||
|
pub const DEC_ADD: &str = "roc_builtins.dec.add";
|
||||||
|
pub const DEC_FROM_STR: &str = "roc_builtins.dec.from_str";
|
||||||
|
|
|
@ -362,7 +362,6 @@ fn add_intrinsics<'ctx>(ctx: &'ctx Context, module: &Module<'ctx>) {
|
||||||
// https://releases.llvm.org/10.0.0/docs/LangRef.html#standard-c-library-intrinsics
|
// https://releases.llvm.org/10.0.0/docs/LangRef.html#standard-c-library-intrinsics
|
||||||
let i1_type = ctx.bool_type();
|
let i1_type = ctx.bool_type();
|
||||||
let f64_type = ctx.f64_type();
|
let f64_type = ctx.f64_type();
|
||||||
let i128_type = ctx.i128_type();
|
|
||||||
let i64_type = ctx.i64_type();
|
let i64_type = ctx.i64_type();
|
||||||
let i32_type = ctx.i32_type();
|
let i32_type = ctx.i32_type();
|
||||||
let i16_type = ctx.i16_type();
|
let i16_type = ctx.i16_type();
|
||||||
|
@ -442,11 +441,12 @@ fn add_intrinsics<'ctx>(ctx: &'ctx Context, module: &Module<'ctx>) {
|
||||||
.fn_type(&[i64_type.into(), i64_type.into()], false)
|
.fn_type(&[i64_type.into(), i64_type.into()], false)
|
||||||
});
|
});
|
||||||
|
|
||||||
add_intrinsic(module, LLVM_SADD_WITH_OVERFLOW_I128, {
|
// TODO: This is now exported by zig. Not sure what to do here?
|
||||||
let fields = [i128_type.into(), i1_type.into()];
|
// add_intrinsic(module, LLVM_SADD_WITH_OVERFLOW_I128, {
|
||||||
ctx.struct_type(&fields, false)
|
// let fields = [i128_type.into(), i1_type.into()];
|
||||||
.fn_type(&[i128_type.into(), i128_type.into()], false)
|
// ctx.struct_type(&fields, false)
|
||||||
});
|
// .fn_type(&[i128_type.into(), i128_type.into()], false)
|
||||||
|
// });
|
||||||
|
|
||||||
// sub with overflow
|
// sub with overflow
|
||||||
|
|
||||||
|
@ -474,11 +474,12 @@ fn add_intrinsics<'ctx>(ctx: &'ctx Context, module: &Module<'ctx>) {
|
||||||
.fn_type(&[i64_type.into(), i64_type.into()], false)
|
.fn_type(&[i64_type.into(), i64_type.into()], false)
|
||||||
});
|
});
|
||||||
|
|
||||||
add_intrinsic(module, LLVM_SSUB_WITH_OVERFLOW_I128, {
|
// TODO: This is now exported by zig. Not sure what to do here?
|
||||||
let fields = [i128_type.into(), i1_type.into()];
|
// add_intrinsic(module, LLVM_SSUB_WITH_OVERFLOW_I128, {
|
||||||
ctx.struct_type(&fields, false)
|
// let fields = [i128_type.into(), i1_type.into()];
|
||||||
.fn_type(&[i128_type.into(), i128_type.into()], false)
|
// ctx.struct_type(&fields, false)
|
||||||
});
|
// .fn_type(&[i128_type.into(), i128_type.into()], false)
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVM_MEMSET_I64: &str = "llvm.memset.p0i8.i64";
|
static LLVM_MEMSET_I64: &str = "llvm.memset.p0i8.i64";
|
||||||
|
@ -637,10 +638,15 @@ pub fn float_with_precision<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
value: f64,
|
value: f64,
|
||||||
precision: &Builtin,
|
precision: &Builtin,
|
||||||
) -> FloatValue<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
match precision {
|
match precision {
|
||||||
Builtin::Float64 => env.context.f64_type().const_float(value),
|
Builtin::Decimal => call_bitcode_fn(
|
||||||
Builtin::Float32 => env.context.f32_type().const_float(value),
|
env,
|
||||||
|
&[env.context.f64_type().const_float(value).into()],
|
||||||
|
&bitcode::DEC_FROM_F64,
|
||||||
|
),
|
||||||
|
Builtin::Float64 => env.context.f64_type().const_float(value).into(),
|
||||||
|
Builtin::Float32 => env.context.f32_type().const_float(value).into(),
|
||||||
_ => panic!("Invalid layout for float literal = {:?}", precision),
|
_ => panic!("Invalid layout for float literal = {:?}", precision),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -659,7 +665,7 @@ pub fn build_exp_literal<'a, 'ctx, 'env>(
|
||||||
},
|
},
|
||||||
|
|
||||||
Float(float) => match layout {
|
Float(float) => match layout {
|
||||||
Layout::Builtin(builtin) => float_with_precision(env, *float, builtin).into(),
|
Layout::Builtin(builtin) => float_with_precision(env, *float, builtin),
|
||||||
_ => panic!("Invalid layout for float literal = {:?}", layout),
|
_ => panic!("Invalid layout for float literal = {:?}", layout),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -5339,6 +5345,9 @@ pub fn build_num_binop<'a, 'ctx, 'env>(
|
||||||
rhs_layout,
|
rhs_layout,
|
||||||
op,
|
op,
|
||||||
),
|
),
|
||||||
|
Decimal => {
|
||||||
|
build_dec_binop(env, parent, lhs_arg, lhs_layout, rhs_arg, rhs_layout, op)
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!("Compiler bug: tried to run numeric operation {:?} on invalid builtin layout: ({:?})", op, lhs_layout);
|
unreachable!("Compiler bug: tried to run numeric operation {:?} on invalid builtin layout: ({:?})", op, lhs_layout);
|
||||||
}
|
}
|
||||||
|
@ -5525,6 +5534,23 @@ fn build_float_binop<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_dec_binop<'a, 'ctx, 'env>(
|
||||||
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
_parent: FunctionValue<'ctx>,
|
||||||
|
lhs: BasicValueEnum<'ctx>,
|
||||||
|
_lhs_layout: &Layout<'a>,
|
||||||
|
rhs: BasicValueEnum<'ctx>,
|
||||||
|
_rhs_layout: &Layout<'a>,
|
||||||
|
op: LowLevel,
|
||||||
|
) -> BasicValueEnum<'ctx> {
|
||||||
|
use roc_module::low_level::LowLevel::*;
|
||||||
|
|
||||||
|
match op {
|
||||||
|
NumAdd => call_bitcode_fn(env, &[lhs, rhs], &bitcode::DEC_ADD),
|
||||||
|
_ => panic!("TODO: Add RocDec function for op"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn int_type_signed_min(int_type: IntType) -> IntValue {
|
fn int_type_signed_min(int_type: IntType) -> IntValue {
|
||||||
let width = int_type.get_bit_width();
|
let width = int_type.get_bit_width();
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ pub fn basic_type_from_builtin<'a, 'ctx, 'env>(
|
||||||
Int8 => context.i8_type().as_basic_type_enum(),
|
Int8 => context.i8_type().as_basic_type_enum(),
|
||||||
Int1 => context.bool_type().as_basic_type_enum(),
|
Int1 => context.bool_type().as_basic_type_enum(),
|
||||||
Usize => ptr_int(context, ptr_bytes).as_basic_type_enum(),
|
Usize => ptr_int(context, ptr_bytes).as_basic_type_enum(),
|
||||||
Decimal => zig_dec_type(env).into(),
|
Decimal => context.i128_type().as_basic_type_enum(),
|
||||||
Float128 => context.f128_type().as_basic_type_enum(),
|
Float128 => context.f128_type().as_basic_type_enum(),
|
||||||
Float64 => context.f64_type().as_basic_type_enum(),
|
Float64 => context.f64_type().as_basic_type_enum(),
|
||||||
Float32 => context.f32_type().as_basic_type_enum(),
|
Float32 => context.f32_type().as_basic_type_enum(),
|
||||||
|
@ -182,8 +182,8 @@ pub fn zig_str_type<'a, 'ctx, 'env>(
|
||||||
env.module.get_struct_type("str.RocStr").unwrap()
|
env.module.get_struct_type("str.RocStr").unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zig_dec_type<'a, 'ctx, 'env>(
|
// pub fn zig_dec_type<'a, 'ctx, 'env>(
|
||||||
env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
|
// env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
|
||||||
) -> StructType<'ctx> {
|
// ) -> StructType<'ctx> {
|
||||||
env.module.get_struct_type("dec.RocDec").unwrap()
|
// env.module.get_struct_type("dec.RocDec").unwrap()
|
||||||
}
|
// }
|
||||||
|
|
|
@ -4,7 +4,6 @@ use bumpalo::Bump;
|
||||||
use roc_collections::all::{default_hasher, MutMap, MutSet};
|
use roc_collections::all::{default_hasher, MutMap, MutSet};
|
||||||
use roc_module::ident::{Lowercase, TagName};
|
use roc_module::ident::{Lowercase, TagName};
|
||||||
use roc_module::symbol::{Interns, Symbol};
|
use roc_module::symbol::{Interns, Symbol};
|
||||||
use roc_std::RocDec;
|
|
||||||
use roc_types::subs::{Content, FlatType, Subs, Variable};
|
use roc_types::subs::{Content, FlatType, Subs, Variable};
|
||||||
use roc_types::types::RecordField;
|
use roc_types::types::RecordField;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -870,7 +869,7 @@ impl<'a> Builtin<'a> {
|
||||||
const I8_SIZE: u32 = std::mem::size_of::<i8>() as u32;
|
const I8_SIZE: u32 = std::mem::size_of::<i8>() as u32;
|
||||||
const I1_SIZE: u32 = std::mem::size_of::<bool>() as u32;
|
const I1_SIZE: u32 = std::mem::size_of::<bool>() as u32;
|
||||||
const USIZE_SIZE: u32 = std::mem::size_of::<usize>() as u32;
|
const USIZE_SIZE: u32 = std::mem::size_of::<usize>() as u32;
|
||||||
const DECIMAL_SIZE: u32 = std::mem::size_of::<RocDec>() as u32; // TODO: Is this right?
|
const DECIMAL_SIZE: u32 = std::mem::size_of::<i128>() as u32;
|
||||||
const F128_SIZE: u32 = 16;
|
const F128_SIZE: u32 = 16;
|
||||||
const F64_SIZE: u32 = std::mem::size_of::<f64>() as u32;
|
const F64_SIZE: u32 = std::mem::size_of::<f64>() as u32;
|
||||||
const F32_SIZE: u32 = std::mem::size_of::<f32>() as u32;
|
const F32_SIZE: u32 = std::mem::size_of::<f32>() as u32;
|
||||||
|
@ -927,7 +926,7 @@ impl<'a> Builtin<'a> {
|
||||||
Int8 => align_of::<i8>() as u32,
|
Int8 => align_of::<i8>() as u32,
|
||||||
Int1 => align_of::<bool>() as u32,
|
Int1 => align_of::<bool>() as u32,
|
||||||
Usize => align_of::<usize>() as u32,
|
Usize => align_of::<usize>() as u32,
|
||||||
Decimal => align_of::<RocDec>() as u32, // TODO: Is this right?
|
Decimal => align_of::<i128>() as u32,
|
||||||
Float128 => align_of::<i128>() as u32,
|
Float128 => align_of::<i128>() as u32,
|
||||||
Float64 => align_of::<f64>() as u32,
|
Float64 => align_of::<f64>() as u32,
|
||||||
Float32 => align_of::<f32>() as u32,
|
Float32 => align_of::<f32>() as u32,
|
||||||
|
|
|
@ -3,7 +3,7 @@ mod gen_num {
|
||||||
use crate::assert_evals_to;
|
use crate::assert_evals_to;
|
||||||
use crate::assert_llvm_evals_to;
|
use crate::assert_llvm_evals_to;
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
use roc_std::{RocDec, RocOrder};
|
use roc_std::RocOrder;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nat_alias() {
|
fn nat_alias() {
|
||||||
|
@ -334,10 +334,10 @@ mod gen_num {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
x : Dec
|
x : Dec
|
||||||
x = 3.6
|
x = 2.1
|
||||||
|
|
||||||
y : Dec
|
y : Dec
|
||||||
y = 3.4
|
y = 3.1
|
||||||
|
|
||||||
z : Dec
|
z : Dec
|
||||||
z = x + y
|
z = x + y
|
||||||
|
@ -345,10 +345,8 @@ mod gen_num {
|
||||||
z
|
z
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocDec {
|
5200000000000000000,
|
||||||
num: 7000000000000000000
|
i128
|
||||||
},
|
|
||||||
RocDec
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -39,26 +39,6 @@ pub enum RocOrder {
|
||||||
// );
|
// );
|
||||||
//}
|
//}
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct RocDec {
|
|
||||||
pub num: i128,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for RocDec {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
// RocList { num: 123 }
|
|
||||||
f.debug_struct("RocDec").field("num", &self.num).finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for RocDec {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.num == other.num
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for RocDec {}
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct RocList<T> {
|
pub struct RocList<T> {
|
||||||
elements: *mut T,
|
elements: *mut T,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue