forked from M-Labs/nac3
nac3core/artiq: fix tuple representation
This commit is contained in:
parent
000b128551
commit
10d623e36f
|
@ -849,9 +849,7 @@ impl InnerResolver {
|
||||||
super::CompileError::new_err(format!("Error getting element {}: {}", i, e)))).collect();
|
super::CompileError::new_err(format!("Error getting element {}: {}", i, e)))).collect();
|
||||||
let val = val?.unwrap();
|
let val = val?.unwrap();
|
||||||
let val = ctx.ctx.const_struct(&val, false);
|
let val = ctx.ctx.const_struct(&val, false);
|
||||||
let global = ctx.module.add_global(ty, Some(AddressSpace::Generic), &id_str);
|
Ok(Some(val.into()))
|
||||||
global.set_initializer(&val);
|
|
||||||
Ok(Some(global.as_pointer_value().into()))
|
|
||||||
} else if ty_id == self.primitive_ids.option {
|
} else if ty_id == self.primitive_ids.option {
|
||||||
if id == self.primitive_ids.none {
|
if id == self.primitive_ids.none {
|
||||||
// for option type, just a null ptr, whose type needs to be casted in codegen
|
// for option type, just a null ptr, whose type needs to be casted in codegen
|
||||||
|
|
|
@ -957,28 +957,22 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
||||||
None => {
|
None => {
|
||||||
let resolver = ctx.resolver.clone();
|
let resolver = ctx.resolver.clone();
|
||||||
let val = resolver.get_symbol_value(*id, ctx).unwrap();
|
let val = resolver.get_symbol_value(*id, ctx).unwrap();
|
||||||
// if is tuple, need to deref it to handle tuple as value
|
|
||||||
// if is option, need to cast pointer to handle None
|
// if is option, need to cast pointer to handle None
|
||||||
match (
|
match (
|
||||||
&*ctx.unifier.get_ty(expr.custom.unwrap()),
|
&*ctx.unifier.get_ty(expr.custom.unwrap()),
|
||||||
resolver
|
val.to_basic_value_enum(ctx, generator)?
|
||||||
.get_symbol_value(*id, ctx)
|
|
||||||
.unwrap()
|
|
||||||
.to_basic_value_enum(ctx, generator)?,
|
|
||||||
) {
|
) {
|
||||||
(TypeEnum::TTuple { .. }, BasicValueEnum::PointerValue(ptr)) => {
|
|
||||||
ctx.builder.build_load(ptr, "tup_val").into()
|
|
||||||
}
|
|
||||||
(TypeEnum::TObj { obj_id, params, .. }, BasicValueEnum::PointerValue(ptr))
|
(TypeEnum::TObj { obj_id, params, .. }, BasicValueEnum::PointerValue(ptr))
|
||||||
if *obj_id == ctx.primitives.option.get_obj_id(&ctx.unifier) => {
|
if *obj_id == ctx.primitives.option.get_obj_id(&ctx.unifier) =>
|
||||||
let actual_ptr_ty = ctx.get_llvm_type(
|
{
|
||||||
generator,
|
let actual_ptr_ty = ctx.get_llvm_type(
|
||||||
*params.iter().next().unwrap().1,
|
generator,
|
||||||
)
|
*params.iter().next().unwrap().1,
|
||||||
.ptr_type(AddressSpace::Generic);
|
)
|
||||||
ctx.builder.build_bitcast(ptr, actual_ptr_ty, "option_ptr_cast").into()
|
.ptr_type(AddressSpace::Generic);
|
||||||
}
|
ctx.builder.build_bitcast(ptr, actual_ptr_ty, "option_ptr_cast").into()
|
||||||
_ => val,
|
}
|
||||||
|
val => val.1.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1026,20 +1020,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
||||||
.map_or_else(Err, |v| v.unwrap().to_basic_value_enum(ctx, generator))
|
.map_or_else(Err, |v| v.unwrap().to_basic_value_enum(ctx, generator))
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
let element_ty = element_val.iter().map(BasicValueEnum::get_type).collect_vec();
|
ctx.ctx.const_struct(&element_val, false).into()
|
||||||
let tuple_ty = ctx.ctx.struct_type(&element_ty, false);
|
|
||||||
let tuple_ptr = ctx.builder.build_alloca(tuple_ty, "tuple");
|
|
||||||
for (i, v) in element_val.into_iter().enumerate() {
|
|
||||||
unsafe {
|
|
||||||
let ptr = ctx.builder.build_in_bounds_gep(
|
|
||||||
tuple_ptr,
|
|
||||||
&[zero, int32.const_int(i as u64, false)],
|
|
||||||
"ptr",
|
|
||||||
);
|
|
||||||
ctx.builder.build_store(ptr, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.builder.build_load(tuple_ptr, "tup_val").into()
|
|
||||||
}
|
}
|
||||||
ExprKind::Attribute { value, attr, .. } => {
|
ExprKind::Attribute { value, attr, .. } => {
|
||||||
// note that we would handle class methods directly in calls
|
// note that we would handle class methods directly in calls
|
||||||
|
|
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
typedef::{Type, Unifier},
|
typedef::{Type, Unifier},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use inkwell::values::{BasicValueEnum, FloatValue, IntValue, PointerValue};
|
use inkwell::values::{BasicValueEnum, FloatValue, IntValue, PointerValue, StructValue};
|
||||||
use itertools::{chain, izip};
|
use itertools::{chain, izip};
|
||||||
use nac3parser::ast::{Expr, Location, StrRef};
|
use nac3parser::ast::{Expr, Location, StrRef};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
@ -106,6 +106,12 @@ impl<'ctx> From<FloatValue<'ctx>> for ValueEnum<'ctx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'ctx> From<StructValue<'ctx>> for ValueEnum<'ctx> {
|
||||||
|
fn from(v: StructValue<'ctx>) -> Self {
|
||||||
|
ValueEnum::Dynamic(v.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'ctx> ValueEnum<'ctx> {
|
impl<'ctx> ValueEnum<'ctx> {
|
||||||
pub fn to_basic_value_enum<'a>(
|
pub fn to_basic_value_enum<'a>(
|
||||||
self,
|
self,
|
||||||
|
|
Loading…
Reference in New Issue