add equality for strings

This commit is contained in:
Folkert 2021-01-02 18:50:29 +01:00
parent 3e1d6d0965
commit 2ac19fb6e3
7 changed files with 84 additions and 20 deletions

View file

@ -77,6 +77,28 @@ fn str_symbol_to_i128<'a, 'ctx, 'env>(
.into_int_value()
}
fn str_to_i128<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
value: BasicValueEnum<'ctx>,
) -> IntValue<'ctx> {
let cell = env.builder.build_alloca(value.get_type(), "cell");
env.builder.build_store(cell, value);
let i128_ptr = env
.builder
.build_bitcast(
cell,
env.context.i128_type().ptr_type(AddressSpace::Generic),
"cast",
)
.into_pointer_value();
env.builder
.build_load(i128_ptr, "load_as_i128")
.into_int_value()
}
fn zig_str_to_struct<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
zig_str: StructValue<'ctx>,
@ -222,3 +244,19 @@ pub fn str_from_int<'a, 'ctx, 'env>(
zig_str_to_struct(env, zig_result).into()
}
/// Str.equal : Str, Str -> Bool
pub fn str_equal<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
value1: BasicValueEnum<'ctx>,
value2: BasicValueEnum<'ctx>,
) -> BasicValueEnum<'ctx> {
let str1_i128 = str_to_i128(env, value1);
let str2_i128 = str_to_i128(env, value2);
call_bitcode_fn(
env,
&[str1_i128.into(), str2_i128.into()],
&bitcode::STR_EQUAL,
)
}

View file

@ -1,5 +1,6 @@
use crate::llvm::build::Env;
use inkwell::values::BasicValueEnum;
use crate::llvm::build_str::str_equal;
use inkwell::values::{BasicValueEnum, IntValue};
use inkwell::{FloatPredicate, IntPredicate};
use roc_mono::layout::{Builtin, Layout};
@ -43,6 +44,7 @@ pub fn build_eq<'a, 'ctx, 'env>(
(Builtin::Int1, Builtin::Int1) => int_cmp(IntPredicate::EQ, "eq_i1"),
(Builtin::Float64, Builtin::Float64) => float_cmp(FloatPredicate::OEQ, "eq_f64"),
(Builtin::Float32, Builtin::Float32) => float_cmp(FloatPredicate::OEQ, "eq_f32"),
(Builtin::Str, Builtin::Str) => str_equal(env, lhs_val, rhs_val),
(b1, b2) => {
todo!("Handle equals for builtin layouts {:?} == {:?}", b1, b2);
}
@ -95,6 +97,12 @@ pub fn build_neq<'a, 'ctx, 'env>(
(Builtin::Int1, Builtin::Int1) => int_cmp(IntPredicate::NE, "neq_i1"),
(Builtin::Float64, Builtin::Float64) => float_cmp(FloatPredicate::ONE, "neq_f64"),
(Builtin::Float32, Builtin::Float32) => float_cmp(FloatPredicate::ONE, "neq_f32"),
(Builtin::Str, Builtin::Str) => {
let is_equal = str_equal(env, lhs_val, rhs_val).into_int_value();
let result: IntValue = env.builder.build_not(is_equal, "negate");
result.into()
}
(b1, b2) => {
todo!("Handle not equals for builtin layouts {:?} == {:?}", b1, b2);
}