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>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
WrapData {
|
||||||
|
scope: Vec<u64>,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
},
|
||||||
|
|
||||||
AssertConstr {
|
AssertConstr {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
constr_index: usize,
|
constr_index: usize,
|
||||||
|
@ -268,6 +273,7 @@ impl Air {
|
||||||
| Air::UnOp { scope, .. }
|
| Air::UnOp { scope, .. }
|
||||||
| Air::Let { scope, .. }
|
| Air::Let { scope, .. }
|
||||||
| Air::UnWrapData { scope, .. }
|
| Air::UnWrapData { scope, .. }
|
||||||
|
| Air::WrapData { scope, .. }
|
||||||
| Air::AssertConstr { scope, .. }
|
| Air::AssertConstr { scope, .. }
|
||||||
| Air::When { scope, .. }
|
| Air::When { scope, .. }
|
||||||
| Air::Clause { scope, .. }
|
| Air::Clause { scope, .. }
|
||||||
|
@ -339,6 +345,15 @@ impl Air {
|
||||||
}
|
}
|
||||||
.into(),
|
.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::Var { constructor, .. } => Some(constructor.tipo.clone()),
|
||||||
Air::List { tipo, .. }
|
Air::List { tipo, .. }
|
||||||
| Air::Tuple { tipo, .. }
|
| Air::Tuple { tipo, .. }
|
||||||
|
|
|
@ -53,7 +53,7 @@ pub struct FunctionAccessKey {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct AssignmentProperties {
|
pub struct AssignmentProperties {
|
||||||
pub value_is_data: bool,
|
pub value_type: Arc<Type>,
|
||||||
pub kind: AssignmentKind,
|
pub kind: AssignmentKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1220,6 +1220,15 @@ pub fn monomorphize(
|
||||||
needs_variant = true;
|
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 {
|
Air::When {
|
||||||
scope,
|
scope,
|
||||||
tipo,
|
tipo,
|
||||||
|
|
|
@ -255,10 +255,20 @@ impl<'a> CodeGenerator<'a> {
|
||||||
scope_fun.push(self.id_gen.next());
|
scope_fun.push(self.id_gen.next());
|
||||||
self.build_ir(fun, ir_stack, scope_fun);
|
self.build_ir(fun, ir_stack, scope_fun);
|
||||||
|
|
||||||
for arg in args {
|
if let Some(fun_arg_types) = fun.tipo().arg_types() {
|
||||||
let mut scope = scope.clone();
|
for (arg, func_type) in args.iter().zip(fun_arg_types) {
|
||||||
scope.push(self.id_gen.next());
|
let mut scope = scope.clone();
|
||||||
self.build_ir(&arg.value, ir_stack, scope);
|
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 {
|
TypedExpr::BinOp {
|
||||||
|
@ -292,8 +302,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let mut value_scope = scope.clone();
|
let mut value_scope = scope.clone();
|
||||||
value_scope.push(self.id_gen.next());
|
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.build_ir(value, &mut value_vec, value_scope);
|
||||||
|
|
||||||
self.assignment_ir(
|
self.assignment_ir(
|
||||||
|
@ -302,7 +310,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&mut value_vec,
|
&mut value_vec,
|
||||||
tipo,
|
tipo,
|
||||||
AssignmentProperties {
|
AssignmentProperties {
|
||||||
value_is_data,
|
value_type: value.tipo(),
|
||||||
kind: *kind,
|
kind: *kind,
|
||||||
},
|
},
|
||||||
scope,
|
scope,
|
||||||
|
@ -333,7 +341,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&mut subject_vec,
|
&mut subject_vec,
|
||||||
&subject.tipo(),
|
&subject.tipo(),
|
||||||
AssignmentProperties {
|
AssignmentProperties {
|
||||||
value_is_data: false,
|
value_type: clauses[0].then.tipo(),
|
||||||
kind: AssignmentKind::Let,
|
kind: AssignmentKind::Let,
|
||||||
},
|
},
|
||||||
scope,
|
scope,
|
||||||
|
@ -1514,7 +1522,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
assignment_properties: AssignmentProperties,
|
assignment_properties: AssignmentProperties,
|
||||||
scope: Vec<u64>,
|
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(
|
value_vec.insert(
|
||||||
0,
|
0,
|
||||||
Air::UnWrapData {
|
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 {
|
match pattern {
|
||||||
Pattern::Int { .. } | Pattern::String { .. } => unreachable!(),
|
Pattern::Int { .. } | Pattern::String { .. } => unreachable!(),
|
||||||
Pattern::Var { name, .. } => {
|
Pattern::Var { name, .. } => {
|
||||||
|
@ -1534,7 +1551,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern_vec.append(value_vec);
|
pattern_vec.append(value_vec);
|
||||||
|
|
||||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||||
&& assignment_properties.value_is_data
|
&& assignment_properties.value_type.is_data()
|
||||||
&& !tipo.is_data()
|
&& !tipo.is_data()
|
||||||
{
|
{
|
||||||
let mut assert_vec = vec![];
|
let mut assert_vec = vec![];
|
||||||
|
@ -1560,7 +1577,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
list @ Pattern::List { .. } => {
|
list @ Pattern::List { .. } => {
|
||||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||||
&& assignment_properties.value_is_data
|
&& assignment_properties.value_type.is_data()
|
||||||
&& !tipo.is_data()
|
&& !tipo.is_data()
|
||||||
{
|
{
|
||||||
self.recursive_assert_pattern(
|
self.recursive_assert_pattern(
|
||||||
|
@ -1585,7 +1602,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
// TODO: Check constr for assert on all cases
|
// TODO: Check constr for assert on all cases
|
||||||
constr @ Pattern::Constructor { .. } => {
|
constr @ Pattern::Constructor { .. } => {
|
||||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||||
&& assignment_properties.value_is_data
|
&& assignment_properties.value_type.is_data()
|
||||||
&& !tipo.is_data()
|
&& !tipo.is_data()
|
||||||
{
|
{
|
||||||
self.recursive_assert_pattern(
|
self.recursive_assert_pattern(
|
||||||
|
@ -1609,7 +1626,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
tuple @ Pattern::Tuple { .. } => {
|
tuple @ Pattern::Tuple { .. } => {
|
||||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||||
&& assignment_properties.value_is_data
|
&& assignment_properties.value_type.is_data()
|
||||||
&& !tipo.is_data()
|
&& !tipo.is_data()
|
||||||
{
|
{
|
||||||
self.recursive_assert_pattern(
|
self.recursive_assert_pattern(
|
||||||
|
@ -1831,11 +1848,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Pattern::Int { .. } => unreachable!(),
|
Pattern::Int { .. } => unreachable!(),
|
||||||
Pattern::String { .. } => unreachable!(),
|
Pattern::String { .. } => unreachable!(),
|
||||||
Pattern::Var { name, .. } => {
|
Pattern::Var { name, .. } => {
|
||||||
pattern_vec.push(Air::Let {
|
|
||||||
scope: scope.clone(),
|
|
||||||
name: name.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.append(value_vec);
|
pattern_vec.append(value_vec);
|
||||||
|
|
||||||
self.recursive_assert_tipo(tipo, pattern_vec, name, scope);
|
self.recursive_assert_tipo(tipo, pattern_vec, name, scope);
|
||||||
|
@ -2426,7 +2438,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let list_name = format!("__list_{id}");
|
let list_name = format!("__list_{id}");
|
||||||
|
|
||||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||||
&& assignment_properties.value_is_data
|
&& assignment_properties.value_type.is_data()
|
||||||
&& !tipo.is_data()
|
&& !tipo.is_data()
|
||||||
{
|
{
|
||||||
self.recursive_assert_pattern(
|
self.recursive_assert_pattern(
|
||||||
|
@ -2479,7 +2491,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let constr_name = format!("{constr_name}_{id}");
|
let constr_name = format!("{constr_name}_{id}");
|
||||||
|
|
||||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||||
&& assignment_properties.value_is_data
|
&& assignment_properties.value_type.is_data()
|
||||||
&& !tipo.is_data()
|
&& !tipo.is_data()
|
||||||
{
|
{
|
||||||
self.recursive_assert_pattern(
|
self.recursive_assert_pattern(
|
||||||
|
@ -2528,7 +2540,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let tuple_name = format!("__tuple_name_{id}");
|
let tuple_name = format!("__tuple_name_{id}");
|
||||||
|
|
||||||
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
if matches!(assignment_properties.kind, AssignmentKind::Assert)
|
||||||
&& assignment_properties.value_is_data
|
&& assignment_properties.value_type.is_data()
|
||||||
&& !tipo.is_data()
|
&& !tipo.is_data()
|
||||||
{
|
{
|
||||||
self.recursive_assert_pattern(
|
self.recursive_assert_pattern(
|
||||||
|
@ -3459,6 +3471,15 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo: replaced_type,
|
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);
|
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, .. } => {
|
Air::AssertConstr { constr_index, .. } => {
|
||||||
let constr = arg_stack.pop().unwrap();
|
let constr = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
@ -5388,18 +5416,21 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.needs_field_access = true;
|
self.needs_field_access = true;
|
||||||
term = apply_wrap(
|
term = convert_data_to_type(
|
||||||
apply_wrap(
|
apply_wrap(
|
||||||
Term::Var(
|
apply_wrap(
|
||||||
Name {
|
Term::Var(
|
||||||
text: CONSTR_GET_FIELD.to_string(),
|
Name {
|
||||||
unique: 0.into(),
|
text: CONSTR_GET_FIELD.to_string(),
|
||||||
}
|
unique: 0.into(),
|
||||||
.into(),
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
term,
|
||||||
),
|
),
|
||||||
term,
|
Term::Constant(UplcConstant::Integer(tuple_index as i128).into()),
|
||||||
),
|
),
|
||||||
Term::Constant(UplcConstant::Integer(tuple_index as i128).into()),
|
&tipo.get_inner_types()[tuple_index],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue