Add more complex test 40.

Add assert for when constr index is given
This commit is contained in:
Kasey White 2023-01-30 04:17:03 -05:00
parent 8c04ab093a
commit a638388747
3 changed files with 87 additions and 7 deletions

View File

@ -106,6 +106,11 @@ pub enum Air {
tipo: Arc<Type>,
},
AssertConstr {
scope: Vec<u64>,
constr_index: usize,
},
// When
When {
scope: Vec<u64>,
@ -263,6 +268,7 @@ impl Air {
| Air::UnOp { scope, .. }
| Air::Let { scope, .. }
| Air::UnWrapData { scope, .. }
| Air::AssertConstr { scope, .. }
| Air::When { scope, .. }
| Air::Clause { scope, .. }
| Air::ListClause { scope, .. }
@ -362,6 +368,7 @@ impl Air {
| Air::Fn { .. }
| Air::Let { .. }
| Air::WrapClause { .. }
| Air::AssertConstr { .. }
| Air::Finally { .. }
| Air::FieldsExpose { .. } => None,

View File

@ -1901,10 +1901,11 @@ impl<'a> CodeGenerator<'a> {
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
let data_type_constr = data_type
let (index, data_type_constr) = data_type
.constructors
.iter()
.find(|constr| &constr.name == constr_name)
.enumerate()
.find(|(_, constr)| &constr.name == constr_name)
.unwrap();
let mut type_map: IndexMap<usize, Arc<Type>> = IndexMap::new();
@ -1952,6 +1953,31 @@ impl<'a> CodeGenerator<'a> {
}
}
let constr_var = format!("__constr_{}", self.id_gen.next());
pattern_vec.push(Air::Let {
scope: scope.clone(),
name: constr_var.clone(),
});
pattern_vec.append(value_vec);
pattern_vec.push(Air::AssertConstr {
scope: scope.clone(),
constr_index: index,
});
pattern_vec.push(Air::Var {
scope: scope.clone(),
constructor: ValueConstructor::public(
tipo.clone(),
ValueConstructorVariant::LocalVariable {
location: Span::empty(),
},
),
name: constr_var.clone(),
variant_name: String::new(),
});
if !arguments_index.is_empty() {
pattern_vec.push(Air::FieldsExpose {
indices: final_args
@ -1961,12 +1987,22 @@ impl<'a> CodeGenerator<'a> {
(*index, var_name.clone(), field_type.clone())
})
.collect_vec(),
scope,
scope: scope.clone(),
check_last_item: true,
});
}
pattern_vec.append(value_vec);
pattern_vec.push(Air::Var {
scope,
constructor: ValueConstructor::public(
tipo.clone(),
ValueConstructorVariant::LocalVariable {
location: Span::empty(),
},
),
name: constr_var,
variant_name: String::new(),
});
}
pattern_vec.append(&mut nested_pattern);
}
@ -4234,6 +4270,36 @@ impl<'a> CodeGenerator<'a> {
arg_stack.push(term);
}
Air::AssertConstr { constr_index, .. } => {
let constr = arg_stack.pop().unwrap();
let mut term = arg_stack.pop().unwrap();
let error_term = apply_wrap(
apply_wrap(
Term::Builtin(DefaultFunction::Trace).force_wrap(),
Term::Constant(UplcConstant::String(
"Asserted on incorrect constructor variant.".to_string(),
)),
),
Term::Delay(Term::Error.into()),
)
.force_wrap();
term = delayed_if_else(
apply_wrap(
apply_wrap(
DefaultFunction::EqualsInteger.into(),
Term::Constant(UplcConstant::Integer(constr_index as i128)),
),
constr_index_exposer(constr),
),
term,
error_term,
);
arg_stack.push(term);
}
Air::When {
subject_name, tipo, ..
} => {

View File

@ -1,3 +1,9 @@
pub type Door{
angle: Int,
locked: Bool
}
pub type Car {
Honda { remote_connect: ByteArray, owner: ByteArray, wheels: Int }
Ford {
@ -5,18 +11,19 @@ pub type Car {
owner: ByteArray,
wheels: Int,
truck_bed_limit: Int,
car_doors: List<Door>
}
}
// test update_owner2_should_fail(){
// let initial_car: Data = Ford{remote_connect: #[], owner: #[], wheels: 4, truck_bed_limit: 10000}
// let initial_car: Data = Ford{remote_connect: #[], owner: #[], wheels: 4, truck_bed_limit: 10000, car_doors: []}
// assert Honda{ owner, ..}: Car = initial_car
// owner == #[]
// }
test update_owner1() {
let initial_car: Data =
Ford { remote_connect: #[], owner: #[], wheels: 4, truck_bed_limit: 10000 }
Ford { remote_connect: #[], owner: #[], wheels: 4, truck_bed_limit: 10000, car_doors: [] }
assert Ford { owner, .. }: Car = initial_car
owner == #[]
}