equality for Byte and Bool

This commit is contained in:
Folkert 2020-03-13 17:01:18 +01:00
parent f894459159
commit 05a3e8c3d8
5 changed files with 59 additions and 6 deletions

View file

@ -576,7 +576,7 @@ fn call_by_name<'a, B: Backend>(
builder.ins().ineg(num) builder.ins().ineg(num)
} }
Symbol::INT_EQ => { Symbol::INT_EQ_I64 | Symbol::INT_EQ_I8 | Symbol::INT_EQ_I1 => {
debug_assert!(args.len() == 2); debug_assert!(args.len() == 2);
let a = build_arg(&args[0], env, scope, module, builder, procs); let a = build_arg(&args[0], env, scope, module, builder, procs);
let b = build_arg(&args[1], env, scope, module, builder, procs); let b = build_arg(&args[1], env, scope, module, builder, procs);

View file

@ -46,6 +46,7 @@ pub fn build_expr<'a, 'ctx, 'env>(
Int(num) => env.context.i64_type().const_int(*num as u64, true).into(), Int(num) => env.context.i64_type().const_int(*num as u64, true).into(),
Float(num) => env.context.f64_type().const_float(*num).into(), Float(num) => env.context.f64_type().const_float(*num).into(),
Bool(b) => env.context.bool_type().const_int(*b as u64, false).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(),
Cond { Cond {
cond, cond,
pass, pass,
@ -513,6 +514,7 @@ pub fn verify_fn(fn_val: FunctionValue<'_>) {
} }
#[inline(always)] #[inline(always)]
#[allow(clippy::cognitive_complexity)]
fn call_with_args<'a, 'ctx, 'env>( fn call_with_args<'a, 'ctx, 'env>(
symbol: Symbol, symbol: Symbol,
args: &[BasicValueEnum<'ctx>], args: &[BasicValueEnum<'ctx>],
@ -583,7 +585,7 @@ fn call_with_args<'a, 'ctx, 'env>(
BasicValueEnum::IntValue(int_val) BasicValueEnum::IntValue(int_val)
} }
Symbol::INT_EQ => { Symbol::INT_EQ_I64 => {
debug_assert!(args.len() == 2); debug_assert!(args.len() == 2);
let int_val = env.builder.build_int_compare( let int_val = env.builder.build_int_compare(
@ -595,6 +597,30 @@ fn call_with_args<'a, 'ctx, 'env>(
BasicValueEnum::IntValue(int_val) BasicValueEnum::IntValue(int_val)
} }
Symbol::INT_EQ_I1 => {
debug_assert!(args.len() == 2);
let int_val = env.builder.build_int_compare(
IntPredicate::EQ,
args[0].into_int_value(),
args[1].into_int_value(),
"cmp_i1",
);
BasicValueEnum::IntValue(int_val)
}
Symbol::INT_EQ_I8 => {
debug_assert!(args.len() == 2);
let int_val = env.builder.build_int_compare(
IntPredicate::EQ,
args[0].into_int_value(),
args[1].into_int_value(),
"cmp_i8",
);
BasicValueEnum::IntValue(int_val)
}
Symbol::FLOAT_EQ => { Symbol::FLOAT_EQ => {
debug_assert!(args.len() == 2); debug_assert!(args.len() == 2);

View file

@ -970,6 +970,27 @@ mod test_gen {
); );
} }
#[test]
fn basic_enum() {
assert_evals_to!(
indoc!(
r#"
Fruit : [ Apple, Orange, Banana ]
apple : Fruit
apple = Apple
orange : Fruit
orange = Orange
apple == orange
"#
),
false,
bool
);
}
// #[test] // #[test]
// fn basic_record() { // fn basic_record() {
// assert_evals_to!( // assert_evals_to!(

View file

@ -591,7 +591,9 @@ define_builtins! {
6 INT_LOWEST: "lowest" 6 INT_LOWEST: "lowest"
7 INT_ADD: "#add" 7 INT_ADD: "#add"
8 INT_SUB: "#sub" 8 INT_SUB: "#sub"
9 INT_EQ: "#eq" 9 INT_EQ_I64: "#eqi64" // Equality on 64-bit integers, the standard in Roc
10 INT_EQ_I1: "#eqi1" // Equality on boolean (theoretically i1) values
11 INT_EQ_I8: "#eqi8" // Equality on byte (theoretically i8) values
} }
3 FLOAT: "Float" => { 3 FLOAT: "Float" => {
0 FLOAT_FLOAT: "Float" imported // the Float.Float type alias 0 FLOAT_FLOAT: "Float" imported // the Float.Float type alias

View file

@ -497,9 +497,11 @@ fn from_can<'a>(
match Layout::from_var(env.arena, loc_args[0].0, env.subs, env.pointer_size) match Layout::from_var(env.arena, loc_args[0].0, env.subs, env.pointer_size)
{ {
Ok(Layout::Builtin(builtin)) => match builtin { Ok(Layout::Builtin(builtin)) => match builtin {
Builtin::Int64 => Symbol::INT_EQ, Builtin::Int64 => Symbol::INT_EQ_I64,
Builtin::Float64 => Symbol::FLOAT_EQ, Builtin::Float64 => Symbol::FLOAT_EQ,
_ => panic!("Equality not unimplemented for {:?}", builtin), Builtin::Bool(_, _) => Symbol::INT_EQ_I1,
Builtin::Byte(_) => Symbol::INT_EQ_I8,
_ => panic!("Equality not implemented for {:?}", builtin),
}, },
Ok(complex) => panic!( Ok(complex) => panic!(
"TODO support equality on complex layouts like {:?}", "TODO support equality on complex layouts like {:?}",
@ -831,7 +833,9 @@ fn from_can_when<'a>(
let (fn_symbol, builtin, cond_rhs_expr) = match to_int_or_float(env.subs, *var) let (fn_symbol, builtin, cond_rhs_expr) = match to_int_or_float(env.subs, *var)
{ {
IntOrFloat::IntType => (Symbol::INT_EQ, Builtin::Int64, Expr::Int(*num)), IntOrFloat::IntType => {
(Symbol::INT_EQ_I64, Builtin::Int64, Expr::Int(*num))
}
IntOrFloat::FloatType => { IntOrFloat::FloatType => {
(Symbol::FLOAT_EQ, Builtin::Float64, Expr::Float(*num as f64)) (Symbol::FLOAT_EQ, Builtin::Float64, Expr::Float(*num as f64))
} }