From bade5dd48d135f0177d68ffbce1363bf1f15c776 Mon Sep 17 00:00:00 2001 From: Chadtech Date: Mon, 18 Jan 2021 15:26:21 -0500 Subject: [PATCH] Dictionary rust modules --- compiler/gen/src/llvm/build_dict.rs | 47 +++++++++++++++++++++++++++++ compiler/gen/tests/gen_dict.rs | 29 ++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 compiler/gen/src/llvm/build_dict.rs create mode 100644 compiler/gen/tests/gen_dict.rs diff --git a/compiler/gen/src/llvm/build_dict.rs b/compiler/gen/src/llvm/build_dict.rs new file mode 100644 index 0000000000..d4a08c7069 --- /dev/null +++ b/compiler/gen/src/llvm/build_dict.rs @@ -0,0 +1,47 @@ +use crate::llvm::build::{call_bitcode_fn, load_symbol_and_layout, ptr_from_symbol, Env, Scope}; +use inkwell::values::{BasicValueEnum, IntValue}; +use inkwell::AddressSpace; +use roc_builtins::bitcode; +use roc_module::symbol::Symbol; +use roc_mono::layout::{Builtin, Layout}; + +pub fn dict_size<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + scope: &Scope<'a, 'ctx>, + dict_symbol: Symbol, +) -> BasicValueEnum<'ctx> { + let ctx = env.context; + + let (_, dict_layout) = load_symbol_and_layout(env, scope, &dict_symbol); + + match dict_layout { + Layout::Builtin(Builtin::Dict(_, _)) => { + let dict_as_int = dict_symbol_to_i128(env, scope, dict_symbol); + + call_bitcode_fn(env, &[dict_as_int.into()], &bitcode::DICT_SIZE) + } + Layout::Builtin(Builtin::EmptyDict) => ctx.i64_type().const_zero().into(), + _ => unreachable!("Invalid layout given to Dict.size : {:?}", dict_layout), + } +} + +fn dict_symbol_to_i128<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + scope: &Scope<'a, 'ctx>, + symbol: Symbol, +) -> IntValue<'ctx> { + let str_ptr = ptr_from_symbol(scope, symbol); + + let i128_ptr = env + .builder + .build_bitcast( + *str_ptr, + env.context.i128_type().ptr_type(AddressSpace::Generic), + "cast", + ) + .into_pointer_value(); + + env.builder + .build_load(i128_ptr, "load_as_i128") + .into_int_value() +} diff --git a/compiler/gen/tests/gen_dict.rs b/compiler/gen/tests/gen_dict.rs new file mode 100644 index 0000000000..307dad1646 --- /dev/null +++ b/compiler/gen/tests/gen_dict.rs @@ -0,0 +1,29 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate indoc; + +extern crate bumpalo; +extern crate inkwell; +extern crate libc; +extern crate roc_gen; + +#[macro_use] +mod helpers; + +#[cfg(test)] +mod gen_hash { + + #[test] + fn dict_empty_len() { + assert_evals_to!( + indoc!( + r#" + Dict.size Dict.empty + "# + ), + 1, + usize + ); + } +}