convert zig struct to roc record

This commit is contained in:
Folkert 2021-09-04 16:41:29 +02:00
parent 9713645806
commit 93817a38e2

View file

@ -1,5 +1,5 @@
use crate::llvm::bitcode::{call_bitcode_fn, call_void_bitcode_fn};
use crate::llvm::build::{complex_bitcast, Env, Scope};
use crate::llvm::build::{complex_bitcast, struct_from_fields, Env, Scope};
use crate::llvm::build_list::{allocate_list, call_bitcode_fn_returns_list, store_list};
use inkwell::builder::Builder;
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue};
@ -260,6 +260,73 @@ pub fn str_to_utf8<'a, 'ctx, 'env>(
call_bitcode_fn_returns_list(env, &[string], bitcode::STR_TO_UTF8)
}
fn decode_from_utf8_result<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
pointer: PointerValue<'ctx>,
) -> StructValue<'ctx> {
let builder = env.builder;
let ctx = env.context;
let fields = match env.ptr_bytes {
8 => [
env.ptr_int().into(),
super::convert::zig_str_type(env).into(),
env.context.bool_type().into(),
ctx.i8_type().into(),
],
4 => [
super::convert::zig_str_type(env).into(),
env.ptr_int().into(),
env.context.bool_type().into(),
ctx.i8_type().into(),
],
_ => unreachable!(),
};
let record_type = env.context.struct_type(&fields, false);
match env.ptr_bytes {
8 => {
let zig_struct = builder
.build_load(pointer, "load_utf8_validate_bytes_result")
.into_struct_value();
let string = builder
.build_extract_value(zig_struct, 0, "string")
.unwrap();
let byte_index = builder
.build_extract_value(zig_struct, 1, "byte_index")
.unwrap();
let is_ok = builder.build_extract_value(zig_struct, 2, "is_ok").unwrap();
let problem_code = builder
.build_extract_value(zig_struct, 3, "problem_code")
.unwrap();
let values = [byte_index, string, is_ok, problem_code];
struct_from_fields(env, record_type, values.iter().copied().enumerate())
}
4 => {
let result_ptr_cast = env
.builder
.build_bitcast(
pointer,
record_type.ptr_type(AddressSpace::Generic),
"to_unnamed",
)
.into_pointer_value();
builder
.build_load(result_ptr_cast, "load_utf8_validate_bytes_result")
.into_struct_value()
}
_ => unreachable!(),
}
}
/// Str.fromUtf8 : List U8, { count : Nat, start : Nat } -> { a : Bool, b : Str, c : Nat, d : I8 }
pub fn str_from_utf8_range<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
@ -268,7 +335,6 @@ pub fn str_from_utf8_range<'a, 'ctx, 'env>(
count_and_start: StructValue<'ctx>,
) -> BasicValueEnum<'ctx> {
let builder = env.builder;
let ctx = env.context;
let result_type = env.module.get_struct_type("str.FromUtf8Result").unwrap();
let result_ptr = builder.build_alloca(result_type, "alloca_utf8_validate_bytes_result");
@ -293,26 +359,7 @@ pub fn str_from_utf8_range<'a, 'ctx, 'env>(
bitcode::STR_FROM_UTF8_RANGE,
);
let record_type = env.context.struct_type(
&[
super::convert::zig_str_type(env).into(),
env.ptr_int().into(),
env.context.bool_type().into(),
ctx.i8_type().into(),
],
false,
);
let result_ptr_cast = env
.builder
.build_bitcast(
result_ptr,
record_type.ptr_type(AddressSpace::Generic),
"to_unnamed",
)
.into_pointer_value();
builder.build_load(result_ptr_cast, "load_utf8_validate_bytes_result")
decode_from_utf8_result(env, result_ptr).into()
}
/// Str.fromUtf8 : List U8 -> { a : Bool, b : Str, c : Nat, d : I8 }
@ -322,7 +369,6 @@ pub fn str_from_utf8<'a, 'ctx, 'env>(
original_wrapper: StructValue<'ctx>,
) -> BasicValueEnum<'ctx> {
let builder = env.builder;
let ctx = env.context;
let result_type = env.module.get_struct_type("str.FromUtf8Result").unwrap();
let result_ptr = builder.build_alloca(result_type, "alloca_utf8_validate_bytes_result");
@ -341,26 +387,7 @@ pub fn str_from_utf8<'a, 'ctx, 'env>(
bitcode::STR_FROM_UTF8,
);
let record_type = env.context.struct_type(
&[
super::convert::zig_str_type(env).into(),
env.ptr_int().into(),
env.context.bool_type().into(),
ctx.i8_type().into(),
],
false,
);
let result_ptr_cast = env
.builder
.build_bitcast(
result_ptr,
record_type.ptr_type(AddressSpace::Generic),
"to_unnamed",
)
.into_pointer_value();
builder.build_load(result_ptr_cast, "load_utf8_validate_bytes_result")
decode_from_utf8_result(env, result_ptr).into()
}
/// Str.fromInt : Int -> Str