From 10d623e36ff6b5b7452a98ed4f7322c137afea15 Mon Sep 17 00:00:00 2001 From: ychenfo Date: Sun, 27 Mar 2022 02:23:22 +0800 Subject: [PATCH] nac3core/artiq: fix tuple representation --- nac3artiq/src/symbol_resolver.rs | 4 +-- nac3core/src/codegen/expr.rs | 43 +++++++++----------------------- nac3core/src/symbol_resolver.rs | 8 +++++- 3 files changed, 20 insertions(+), 35 deletions(-) diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index 213c12d3..999f4f91 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -849,9 +849,7 @@ impl InnerResolver { super::CompileError::new_err(format!("Error getting element {}: {}", i, e)))).collect(); let val = val?.unwrap(); let val = ctx.ctx.const_struct(&val, false); - let global = ctx.module.add_global(ty, Some(AddressSpace::Generic), &id_str); - global.set_initializer(&val); - Ok(Some(global.as_pointer_value().into())) + Ok(Some(val.into())) } else if ty_id == self.primitive_ids.option { if id == self.primitive_ids.none { // for option type, just a null ptr, whose type needs to be casted in codegen diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 6c3a09b9..9657dad0 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -957,28 +957,22 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( None => { let resolver = ctx.resolver.clone(); 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 match ( &*ctx.unifier.get_ty(expr.custom.unwrap()), - resolver - .get_symbol_value(*id, ctx) - .unwrap() - .to_basic_value_enum(ctx, generator)?, + val.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)) - if *obj_id == ctx.primitives.option.get_obj_id(&ctx.unifier) => { - let actual_ptr_ty = ctx.get_llvm_type( - generator, - *params.iter().next().unwrap().1, - ) - .ptr_type(AddressSpace::Generic); - ctx.builder.build_bitcast(ptr, actual_ptr_ty, "option_ptr_cast").into() - } - _ => val, + if *obj_id == ctx.primitives.option.get_obj_id(&ctx.unifier) => + { + let actual_ptr_ty = ctx.get_llvm_type( + generator, + *params.iter().next().unwrap().1, + ) + .ptr_type(AddressSpace::Generic); + ctx.builder.build_bitcast(ptr, actual_ptr_ty, "option_ptr_cast").into() + } + 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)) }) .collect::, _>>()?; - let element_ty = element_val.iter().map(BasicValueEnum::get_type).collect_vec(); - 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() + ctx.ctx.const_struct(&element_val, false).into() } ExprKind::Attribute { value, attr, .. } => { // note that we would handle class methods directly in calls diff --git a/nac3core/src/symbol_resolver.rs b/nac3core/src/symbol_resolver.rs index b8fc9f27..6f92ee47 100644 --- a/nac3core/src/symbol_resolver.rs +++ b/nac3core/src/symbol_resolver.rs @@ -14,7 +14,7 @@ use crate::{ typedef::{Type, Unifier}, }, }; -use inkwell::values::{BasicValueEnum, FloatValue, IntValue, PointerValue}; +use inkwell::values::{BasicValueEnum, FloatValue, IntValue, PointerValue, StructValue}; use itertools::{chain, izip}; use nac3parser::ast::{Expr, Location, StrRef}; use parking_lot::RwLock; @@ -106,6 +106,12 @@ impl<'ctx> From> for ValueEnum<'ctx> { } } +impl<'ctx> From> for ValueEnum<'ctx> { + fn from(v: StructValue<'ctx>) -> Self { + ValueEnum::Dynamic(v.into()) + } +} + impl<'ctx> ValueEnum<'ctx> { pub fn to_basic_value_enum<'a>( self,