Merge remote-tracking branch 'origin/trunk' into array-wrappers

This commit is contained in:
Richard Feldman 2020-03-13 22:19:23 -04:00
commit 8d4331f903
41 changed files with 2057 additions and 723 deletions

View file

@ -284,6 +284,80 @@ pub fn build_expr<'a, 'ctx, 'env>(
BasicValueEnum::StructValue(struct_val.into_struct_value())
}
}
Struct { fields, .. } => {
let ctx = env.context;
let builder = env.builder;
// Sort the fields
let mut sorted_fields = Vec::with_capacity_in(fields.len(), env.arena);
for field in fields.iter() {
sorted_fields.push(field);
}
sorted_fields.sort_by_key(|k| &k.0);
// Determine types
let mut field_types = Vec::with_capacity_in(fields.len(), env.arena);
let mut field_vals = Vec::with_capacity_in(fields.len(), env.arena);
for (_, ref inner_expr) in sorted_fields.iter() {
let val = build_expr(env, &scope, parent, inner_expr, procs);
let field_type = match inner_expr {
Int(_) => BasicTypeEnum::IntType(ctx.i64_type()),
_ => panic!("I don't yet know how to get Inkwell type for {:?}", val),
};
field_types.push(field_type);
field_vals.push(val);
}
// Create the struct_type
let struct_type = ctx.struct_type(field_types.into_bump_slice(), false);
let mut struct_val = struct_type.const_zero().into();
// Insert field exprs into struct_val
for (index, field_val) in field_vals.into_iter().enumerate() {
struct_val = builder
.build_insert_value(struct_val, field_val, index as u32, "insert_field")
.unwrap();
}
BasicValueEnum::StructValue(struct_val.into_struct_value())
}
Access {
label,
field_layout,
struct_layout: Layout::Struct(fields),
record,
} => {
let builder = env.builder;
// Reconstruct struct layout
let mut reconstructed_struct_layout =
Vec::with_capacity_in(fields.len() + 1, env.arena);
for field in fields.iter() {
reconstructed_struct_layout.push(field.clone());
}
reconstructed_struct_layout.push((label.clone(), field_layout.clone()));
reconstructed_struct_layout.sort_by(|a, b| {
a.0.partial_cmp(&b.0)
.expect("TODO: failed to sort struct fields in crane access")
});
// Get index
let index = reconstructed_struct_layout
.iter()
.position(|(local_label, _)| local_label == label)
.unwrap() as u32; // TODO
// Get Struct val
let struct_val = build_expr(env, &scope, parent, record, procs).into_struct_value();
builder
.build_extract_value(struct_val, index, "field_access")
.unwrap()
}
_ => {
panic!("I don't yet know how to LLVM build {:?}", expr);
}
@ -576,35 +650,57 @@ fn call_with_args<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
) -> BasicValueEnum<'ctx> {
match symbol {
Symbol::NUM_ADD => {
Symbol::INT_ADD | Symbol::NUM_ADD => {
debug_assert!(args.len() == 2);
let int_val = env.builder.build_int_add(
args[0].into_int_value(),
args[1].into_int_value(),
"ADD_I64",
"add_i64",
);
BasicValueEnum::IntValue(int_val)
}
Symbol::NUM_SUB => {
Symbol::FLOAT_ADD => {
debug_assert!(args.len() == 2);
let float_val = env.builder.build_float_add(
args[0].into_float_value(),
args[1].into_float_value(),
"add_f64",
);
BasicValueEnum::FloatValue(float_val)
}
Symbol::INT_SUB | Symbol::NUM_SUB => {
debug_assert!(args.len() == 2);
let int_val = env.builder.build_int_sub(
args[0].into_int_value(),
args[1].into_int_value(),
"SUB_I64",
"sub_I64",
);
BasicValueEnum::IntValue(int_val)
}
Symbol::FLOAT_SUB => {
debug_assert!(args.len() == 2);
let float_val = env.builder.build_float_sub(
args[0].into_float_value(),
args[1].into_float_value(),
"sub_f64",
);
BasicValueEnum::FloatValue(float_val)
}
Symbol::NUM_MUL => {
debug_assert!(args.len() == 2);
let int_val = env.builder.build_int_mul(
args[0].into_int_value(),
args[1].into_int_value(),
"MUL_I64",
"mul_i64",
);
BasicValueEnum::IntValue(int_val)
@ -614,7 +710,7 @@ fn call_with_args<'a, 'ctx, 'env>(
let int_val = env
.builder
.build_int_neg(args[0].into_int_value(), "NEGATE_I64");
.build_int_neg(args[0].into_int_value(), "negate_i64");
BasicValueEnum::IntValue(int_val)
}