feat: some code gen improvements
* fix assert on pattern Var * fix tuple index unwrapping closes #334 * allow wrapping when casting with let * allow wrapping when casting via function call
This commit is contained in:
parent
6053e76f6f
commit
86ca466807
|
@ -106,6 +106,11 @@ pub enum Air {
|
|||
tipo: Arc<Type>,
|
||||
},
|
||||
|
||||
WrapData {
|
||||
scope: Vec<u64>,
|
||||
tipo: Arc<Type>,
|
||||
},
|
||||
|
||||
AssertConstr {
|
||||
scope: Vec<u64>,
|
||||
constr_index: usize,
|
||||
|
@ -268,6 +273,7 @@ impl Air {
|
|||
| Air::UnOp { scope, .. }
|
||||
| Air::Let { scope, .. }
|
||||
| Air::UnWrapData { scope, .. }
|
||||
| Air::WrapData { scope, .. }
|
||||
| Air::AssertConstr { scope, .. }
|
||||
| Air::When { scope, .. }
|
||||
| Air::Clause { scope, .. }
|
||||
|
@ -339,6 +345,15 @@ impl Air {
|
|||
}
|
||||
.into(),
|
||||
),
|
||||
Air::WrapData { .. } => Some(
|
||||
Type::App {
|
||||
public: true,
|
||||
module: String::new(),
|
||||
name: "Data".to_string(),
|
||||
args: vec![],
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
Air::Var { constructor, .. } => Some(constructor.tipo.clone()),
|
||||
Air::List { tipo, .. }
|
||||
| Air::Tuple { tipo, .. }
|
||||
|
|
|
@ -53,7 +53,7 @@ pub struct FunctionAccessKey {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AssignmentProperties {
|
||||
pub value_is_data: bool,
|
||||
pub value_type: Arc<Type>,
|
||||
pub kind: AssignmentKind,
|
||||
}
|
||||
|
||||
|
@ -1220,6 +1220,15 @@ pub fn monomorphize(
|
|||
needs_variant = true;
|
||||
}
|
||||
}
|
||||
Air::WrapData { scope, tipo } => {
|
||||
if tipo.is_generic() {
|
||||
let mut tipo = tipo.clone();
|
||||
find_generics_to_replace(&mut tipo, &generic_types);
|
||||
|
||||
new_air[index] = Air::WrapData { scope, tipo };
|
||||
needs_variant = true;
|
||||
}
|
||||
}
|
||||
Air::When {
|
||||
scope,
|
||||
tipo,
|
||||
|
|
|
@ -255,12 +255,22 @@ impl<'a> CodeGenerator<'a> {
|
|||
scope_fun.push(self.id_gen.next());
|
||||
self.build_ir(fun, ir_stack, scope_fun);
|
||||
|
||||
for arg in args {
|
||||
if let Some(fun_arg_types) = fun.tipo().arg_types() {
|
||||
for (arg, func_type) in args.iter().zip(fun_arg_types) {
|
||||
let mut scope = scope.clone();
|
||||
scope.push(self.id_gen.next());
|
||||
|
||||
if func_type.is_data() && !arg.value.tipo().is_data() {
|
||||
ir_stack.push(Air::WrapData {
|
||||
scope: scope.clone(),
|
||||
tipo: arg.value.tipo(),
|
||||
})
|
||||
}
|
||||
|
||||
self.build_ir(&arg.value, ir_stack, scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
TypedExpr::BinOp {
|
||||
name, left, right, ..
|
||||
} => {
|
||||
|
@ -292,8 +302,6 @@ impl<'a> CodeGenerator<'a> {
|
|||
let mut value_scope = scope.clone();
|
||||
value_scope.push(self.id_gen.next());
|
||||
|
||||
let value_is_data = value.tipo().is_data();
|
||||
|
||||
self.build_ir(value, &mut value_vec, value_scope);
|
||||
|
||||
self.assignment_ir(
|
||||
|
@ -302,7 +310,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
&mut value_vec,
|
||||
tipo,
|
||||
AssignmentProperties {
|
||||
value_is_data,
|
||||
value_type: value.tipo(),
|
||||
kind: *kind,
|
||||
},
|
||||
scope,
|
||||
|
@ -333,7 +341,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
&mut subject_vec,
|
||||
&subject.tipo(),
|
||||
AssignmentProperties {
|
||||
value_is_data: false,
|
||||
value_type: clauses[0].then.tipo(),
|
||||
kind: AssignmentKind::Let,
|
||||
},
|
||||
scope,
|
||||
|
@ -1514,7 +1522,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
assignment_properties: AssignmentProperties,
|
||||
scope: Vec<u64>,
|
||||
) {
|
||||
if assignment_properties.value_is_data && !tipo.is_data() && !pattern.is_discard() {
|
||||
if assignment_properties.value_type.is_data() && !tipo.is_data() && !pattern.is_discard() {
|
||||
value_vec.insert(
|
||||
0,
|
||||
Air::UnWrapData {
|
||||
|
@ -1523,6 +1531,15 @@ impl<'a> CodeGenerator<'a> {
|
|||
},
|
||||
);
|
||||
}
|
||||
if !assignment_properties.value_type.is_data() && tipo.is_data() && !pattern.is_discard() {
|
||||
value_vec.insert(
|
||||
0,
|
||||
Air::WrapData {
|
||||
scope: scope.clone(),
|
||||
tipo: assignment_properties.value_type.clone(),
|
||||
},
|
||||
)
|
||||
}
|
||||
match pattern {
|
||||
Pattern::Int { .. } | Pattern::String { .. } => unreachable!(),
|
||||
Pattern::Var { name, .. } => {
|
||||
|
@ -1534,7 +1551,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
pattern_vec.append(value_vec);
|
||||
|
||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||
&& assignment_properties.value_is_data
|
||||
&& assignment_properties.value_type.is_data()
|
||||
&& !tipo.is_data()
|
||||
{
|
||||
let mut assert_vec = vec![];
|
||||
|
@ -1560,7 +1577,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
}
|
||||
list @ Pattern::List { .. } => {
|
||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||
&& assignment_properties.value_is_data
|
||||
&& assignment_properties.value_type.is_data()
|
||||
&& !tipo.is_data()
|
||||
{
|
||||
self.recursive_assert_pattern(
|
||||
|
@ -1585,7 +1602,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
// TODO: Check constr for assert on all cases
|
||||
constr @ Pattern::Constructor { .. } => {
|
||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||
&& assignment_properties.value_is_data
|
||||
&& assignment_properties.value_type.is_data()
|
||||
&& !tipo.is_data()
|
||||
{
|
||||
self.recursive_assert_pattern(
|
||||
|
@ -1609,7 +1626,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
}
|
||||
tuple @ Pattern::Tuple { .. } => {
|
||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||
&& assignment_properties.value_is_data
|
||||
&& assignment_properties.value_type.is_data()
|
||||
&& !tipo.is_data()
|
||||
{
|
||||
self.recursive_assert_pattern(
|
||||
|
@ -1831,11 +1848,6 @@ impl<'a> CodeGenerator<'a> {
|
|||
Pattern::Int { .. } => unreachable!(),
|
||||
Pattern::String { .. } => unreachable!(),
|
||||
Pattern::Var { name, .. } => {
|
||||
pattern_vec.push(Air::Let {
|
||||
scope: scope.clone(),
|
||||
name: name.clone(),
|
||||
});
|
||||
|
||||
pattern_vec.append(value_vec);
|
||||
|
||||
self.recursive_assert_tipo(tipo, pattern_vec, name, scope);
|
||||
|
@ -2426,7 +2438,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
let list_name = format!("__list_{id}");
|
||||
|
||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||
&& assignment_properties.value_is_data
|
||||
&& assignment_properties.value_type.is_data()
|
||||
&& !tipo.is_data()
|
||||
{
|
||||
self.recursive_assert_pattern(
|
||||
|
@ -2479,7 +2491,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
let constr_name = format!("{constr_name}_{id}");
|
||||
|
||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||
&& assignment_properties.value_is_data
|
||||
&& assignment_properties.value_type.is_data()
|
||||
&& !tipo.is_data()
|
||||
{
|
||||
self.recursive_assert_pattern(
|
||||
|
@ -2528,7 +2540,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
let tuple_name = format!("__tuple_name_{id}");
|
||||
|
||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||
&& assignment_properties.value_is_data
|
||||
&& assignment_properties.value_type.is_data()
|
||||
&& !tipo.is_data()
|
||||
{
|
||||
self.recursive_assert_pattern(
|
||||
|
@ -3459,6 +3471,15 @@ impl<'a> CodeGenerator<'a> {
|
|||
tipo: replaced_type,
|
||||
};
|
||||
}
|
||||
Air::WrapData { scope, tipo } => {
|
||||
let mut replaced_type = tipo.clone();
|
||||
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||
|
||||
ir_stack[index] = Air::WrapData {
|
||||
scope,
|
||||
tipo: replaced_type,
|
||||
};
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -4361,6 +4382,13 @@ impl<'a> CodeGenerator<'a> {
|
|||
|
||||
arg_stack.push(term);
|
||||
}
|
||||
Air::WrapData { tipo, .. } => {
|
||||
let mut term = arg_stack.pop().unwrap();
|
||||
|
||||
term = convert_type_to_data(term, &tipo);
|
||||
|
||||
arg_stack.push(term);
|
||||
}
|
||||
Air::AssertConstr { constr_index, .. } => {
|
||||
let constr = arg_stack.pop().unwrap();
|
||||
|
||||
|
@ -5388,7 +5416,8 @@ impl<'a> CodeGenerator<'a> {
|
|||
}
|
||||
} else {
|
||||
self.needs_field_access = true;
|
||||
term = apply_wrap(
|
||||
term = convert_data_to_type(
|
||||
apply_wrap(
|
||||
apply_wrap(
|
||||
Term::Var(
|
||||
Name {
|
||||
|
@ -5400,6 +5429,8 @@ impl<'a> CodeGenerator<'a> {
|
|||
term,
|
||||
),
|
||||
Term::Constant(UplcConstant::Integer(tuple_index as i128).into()),
|
||||
),
|
||||
&tipo.get_inner_types()[tuple_index],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue