Few more places in codegen where we need to be able to deal with Pair records
This commit is contained in:
		
							parent
							
								
									26f68c2fb4
								
							
						
					
					
						commit
						3c332ca42a
					
				|  | @ -659,6 +659,12 @@ impl<'a> CodeGenerator<'a> { | ||||||
|                 } => { |                 } => { | ||||||
|                     if check_replaceable_opaque_type(&record.tipo(), &self.data_types) { |                     if check_replaceable_opaque_type(&record.tipo(), &self.data_types) { | ||||||
|                         self.build(record, module_build_name, &[]) |                         self.build(record, module_build_name, &[]) | ||||||
|  |                     } else if record.tipo().is_pair() { | ||||||
|  |                         AirTree::pair_index( | ||||||
|  |                             *index, | ||||||
|  |                             tipo.clone(), | ||||||
|  |                             self.build(record, module_build_name, &[]), | ||||||
|  |                         ) | ||||||
|                     } else { |                     } else { | ||||||
|                         let function_name = format!("__access_index_{}", *index); |                         let function_name = format!("__access_index_{}", *index); | ||||||
| 
 | 
 | ||||||
|  | @ -708,9 +714,22 @@ impl<'a> CodeGenerator<'a> { | ||||||
|                         field_map, |                         field_map, | ||||||
|                         .. |                         .. | ||||||
|                     } => { |                     } => { | ||||||
|  |                         let val_constructor = if tipo.is_pair() { | ||||||
|  |                             ValueConstructor::public( | ||||||
|  |                                 tipo.clone(), | ||||||
|  |                                 ValueConstructorVariant::Record { | ||||||
|  |                                     module: "".into(), | ||||||
|  |                                     name: name.clone(), | ||||||
|  |                                     field_map: field_map.clone(), | ||||||
|  |                                     arity: 2, | ||||||
|  |                                     location: Span::empty(), | ||||||
|  |                                     constructors_count: 1, | ||||||
|  |                                 }, | ||||||
|  |                             ) | ||||||
|  |                         } else { | ||||||
|                             let data_type = lookup_data_type_by_tipo(&self.data_types, tipo); |                             let data_type = lookup_data_type_by_tipo(&self.data_types, tipo); | ||||||
| 
 | 
 | ||||||
|                         let val_constructor = ValueConstructor::public( |                             ValueConstructor::public( | ||||||
|                                 tipo.clone(), |                                 tipo.clone(), | ||||||
|                                 ValueConstructorVariant::Record { |                                 ValueConstructorVariant::Record { | ||||||
|                                     name: name.clone(), |                                     name: name.clone(), | ||||||
|  | @ -724,7 +743,8 @@ impl<'a> CodeGenerator<'a> { | ||||||
|                                         .len() |                                         .len() | ||||||
|                                         as u16, |                                         as u16, | ||||||
|                                 }, |                                 }, | ||||||
|                         ); |                             ) | ||||||
|  |                         }; | ||||||
| 
 | 
 | ||||||
|                         AirTree::var(val_constructor, name, "") |                         AirTree::var(val_constructor, name, "") | ||||||
|                     } |                     } | ||||||
|  | @ -772,13 +792,6 @@ impl<'a> CodeGenerator<'a> { | ||||||
|                 TypedExpr::TupleIndex { |                 TypedExpr::TupleIndex { | ||||||
|                     index, tuple, tipo, .. |                     index, tuple, tipo, .. | ||||||
|                 } => { |                 } => { | ||||||
|                     if tuple.tipo().is_pair() { |  | ||||||
|                         AirTree::pair_index( |  | ||||||
|                             *index, |  | ||||||
|                             tipo.clone(), |  | ||||||
|                             self.build(tuple, module_build_name, &[]), |  | ||||||
|                         ) |  | ||||||
|                     } else { |  | ||||||
|                     let function_name = format!("__access_index_{}", *index); |                     let function_name = format!("__access_index_{}", *index); | ||||||
| 
 | 
 | ||||||
|                     if self.code_gen_functions.get(&function_name).is_none() { |                     if self.code_gen_functions.get(&function_name).is_none() { | ||||||
|  | @ -809,13 +822,45 @@ impl<'a> CodeGenerator<'a> { | ||||||
|                         self.build(tuple, module_build_name, &[]), |                         self.build(tuple, module_build_name, &[]), | ||||||
|                     ) |                     ) | ||||||
|                 } |                 } | ||||||
|                 } |  | ||||||
| 
 | 
 | ||||||
|                 TypedExpr::ErrorTerm { tipo, .. } => AirTree::error(tipo.clone(), false), |                 TypedExpr::ErrorTerm { tipo, .. } => AirTree::error(tipo.clone(), false), | ||||||
| 
 | 
 | ||||||
|                 TypedExpr::RecordUpdate { |                 TypedExpr::RecordUpdate { | ||||||
|                     tipo, spread, args, .. |                     tipo, spread, args, .. | ||||||
|                 } => { |                 } => { | ||||||
|  |                     if tipo.is_pair() { | ||||||
|  |                         assert!(args.len() == 1); | ||||||
|  | 
 | ||||||
|  |                         let Some(arg) = args.first() else { | ||||||
|  |                             unreachable!("Pair update with no arguments") | ||||||
|  |                         }; | ||||||
|  | 
 | ||||||
|  |                         let arg_val = self.build(&arg.value, module_build_name, &[]); | ||||||
|  | 
 | ||||||
|  |                         let other_pair = self.build(spread, module_build_name, &[]); | ||||||
|  | 
 | ||||||
|  |                         if arg.index == 0 { | ||||||
|  |                             AirTree::pair( | ||||||
|  |                                 arg_val, | ||||||
|  |                                 AirTree::pair_index( | ||||||
|  |                                     1, | ||||||
|  |                                     tipo.get_inner_types()[1].clone(), | ||||||
|  |                                     other_pair, | ||||||
|  |                                 ), | ||||||
|  |                                 tipo.clone(), | ||||||
|  |                             ) | ||||||
|  |                         } else { | ||||||
|  |                             AirTree::pair( | ||||||
|  |                                 AirTree::pair_index( | ||||||
|  |                                     0, | ||||||
|  |                                     tipo.get_inner_types()[0].clone(), | ||||||
|  |                                     other_pair, | ||||||
|  |                                 ), | ||||||
|  |                                 arg_val, | ||||||
|  |                                 tipo.clone(), | ||||||
|  |                             ) | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|                         let mut index_types = vec![]; |                         let mut index_types = vec![]; | ||||||
|                         let mut update_args = vec![]; |                         let mut update_args = vec![]; | ||||||
| 
 | 
 | ||||||
|  | @ -843,6 +888,7 @@ impl<'a> CodeGenerator<'a> { | ||||||
|                             update_args, |                             update_args, | ||||||
|                         ) |                         ) | ||||||
|                     } |                     } | ||||||
|  |                 } | ||||||
|                 TypedExpr::UnOp { value, op, .. } => { |                 TypedExpr::UnOp { value, op, .. } => { | ||||||
|                     AirTree::unop(*op, self.build(value, module_build_name, &[])) |                     AirTree::unop(*op, self.build(value, module_build_name, &[])) | ||||||
|                 } |                 } | ||||||
|  | @ -4195,6 +4241,7 @@ impl<'a> CodeGenerator<'a> { | ||||||
|                 ValueConstructorVariant::Record { |                 ValueConstructorVariant::Record { | ||||||
|                     name: constr_name, .. |                     name: constr_name, .. | ||||||
|                 } => { |                 } => { | ||||||
|  |                     // TODO handle pair
 | ||||||
|                     if constructor.tipo.is_bool() { |                     if constructor.tipo.is_bool() { | ||||||
|                         Some(Term::bool(constr_name == "True")) |                         Some(Term::bool(constr_name == "True")) | ||||||
|                     } else if constructor.tipo.is_void() { |                     } else if constructor.tipo.is_void() { | ||||||
|  |  | ||||||
|  | @ -937,7 +937,7 @@ impl AirTree { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn pair_index(index: usize, tipo: Rc<Type>, tuple: AirTree) -> AirTree { |     pub fn pair_index(index: u64, tipo: Rc<Type>, tuple: AirTree) -> AirTree { | ||||||
|         AirTree::cast_from_data( |         AirTree::cast_from_data( | ||||||
|             AirTree::builtin( |             AirTree::builtin( | ||||||
|                 if index == 0 { |                 if index == 0 { | ||||||
|  |  | ||||||
|  | @ -2994,7 +2994,238 @@ fn acceptance_test_28_unique_list() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[test] | #[test] | ||||||
| fn acceptance_test_29_union() { | fn acceptance_test_29_union_pair() { | ||||||
|  |     let src = r#" | ||||||
|  |       type Map<a,b> = List<Pair<a,b>> | ||||||
|  | 
 | ||||||
|  |       pub opaque type AssocList<key, value> { | ||||||
|  |         inner: Map<key, value>, | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       pub fn new() -> AssocList<key, value> { | ||||||
|  |         AssocList { inner: [] } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       pub fn from_list(xs: Map<key, value>) -> AssocList<key, value> { | ||||||
|  |         AssocList { inner: do_from_list(xs) } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       fn do_from_list(xs: Map<key, value>) -> Map<key, value> { | ||||||
|  |         when xs is { | ||||||
|  |           [] -> | ||||||
|  |             [] | ||||||
|  |           [Pair(k, v), ..rest] -> | ||||||
|  |             do_insert(do_from_list(rest), k, v) | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       pub fn insert( | ||||||
|  |         in m: AssocList<key, value>, | ||||||
|  |         key k: key, | ||||||
|  |         value v: value, | ||||||
|  |       ) -> AssocList<key, value> { | ||||||
|  |         AssocList { inner: do_insert(m.inner, k, v) } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       fn do_insert(elems: Map<key, value>, k: key, v: value) -> Map<key, value> { | ||||||
|  |         when elems is { | ||||||
|  |           [] -> | ||||||
|  |             [Pair(k, v)] | ||||||
|  |           [Pair(k2, v2), ..rest] -> | ||||||
|  |             if k == k2 { | ||||||
|  |               [Pair(k, v), ..rest] | ||||||
|  |             } else { | ||||||
|  |               [Pair(k2, v2), ..do_insert(rest, k, v)] | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       pub fn union( | ||||||
|  |         left: AssocList<key, value>, | ||||||
|  |         right: AssocList<key, value>, | ||||||
|  |       ) -> AssocList<key, value> { | ||||||
|  |         AssocList { inner: do_union(left.inner, right.inner) } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       fn do_union( | ||||||
|  |         left: Map<key, value>, | ||||||
|  |         right: Map<key, value>, | ||||||
|  |       ) -> Map<key, value> { | ||||||
|  |         when left is { | ||||||
|  |           [] -> | ||||||
|  |             right | ||||||
|  |           [Pair{fst: k, snd: v}, ..rest] -> | ||||||
|  |             do_union(rest, do_insert(right, k, v)) | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       fn fixture_1() { | ||||||
|  |         new() | ||||||
|  |           |> insert("foo", 42) | ||||||
|  |           |> insert("bar", 14) | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       test union_1() { | ||||||
|  |         union(fixture_1(), new()) == fixture_1() | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |     "#;
 | ||||||
|  | 
 | ||||||
|  |     assert_uplc( | ||||||
|  |         src, | ||||||
|  |         Term::equals_data() | ||||||
|  |             .apply( | ||||||
|  |                 Term::map_data().apply( | ||||||
|  |                     Term::var("union") | ||||||
|  |                         .lambda("union") | ||||||
|  |                         .apply( | ||||||
|  |                             Term::var("do_union") | ||||||
|  |                                 .apply(Term::var("left")) | ||||||
|  |                                 .apply(Term::var("right")) | ||||||
|  |                                 .lambda("right") | ||||||
|  |                                 .lambda("left"), | ||||||
|  |                         ) | ||||||
|  |                         .lambda("do_union") | ||||||
|  |                         .apply(Term::var("do_union").apply(Term::var("do_union"))) | ||||||
|  |                         .lambda("do_union") | ||||||
|  |                         .apply( | ||||||
|  |                             Term::var("left") | ||||||
|  |                                 .delayed_choose_list( | ||||||
|  |                                     Term::var("right"), | ||||||
|  |                                     Term::var("do_union") | ||||||
|  |                                         .apply(Term::var("do_union")) | ||||||
|  |                                         .apply(Term::var("rest")) | ||||||
|  |                                         .apply( | ||||||
|  |                                             Term::var("do_insert") | ||||||
|  |                                                 .apply(Term::var("right")) | ||||||
|  |                                                 .apply(Term::var("k")) | ||||||
|  |                                                 .apply(Term::var("v")), | ||||||
|  |                                         ) | ||||||
|  |                                         .lambda("v") | ||||||
|  |                                         .apply( | ||||||
|  |                                             Term::un_i_data() | ||||||
|  |                                                 .apply(Term::snd_pair().apply(Term::var("pair"))), | ||||||
|  |                                         ) | ||||||
|  |                                         .lambda("k") | ||||||
|  |                                         .apply( | ||||||
|  |                                             Term::un_b_data() | ||||||
|  |                                                 .apply(Term::fst_pair().apply(Term::var("pair"))), | ||||||
|  |                                         ) | ||||||
|  |                                         .lambda("rest") | ||||||
|  |                                         .apply(Term::tail_list().apply(Term::var("left"))) | ||||||
|  |                                         .lambda("pair") | ||||||
|  |                                         .apply(Term::head_list().apply(Term::var("left"))), | ||||||
|  |                                 ) | ||||||
|  |                                 .lambda("right") | ||||||
|  |                                 .lambda("left") | ||||||
|  |                                 .lambda("do_union"), | ||||||
|  |                         ) | ||||||
|  |                         .lambda("do_insert") | ||||||
|  |                         .apply( | ||||||
|  |                             Term::var("do_insert") | ||||||
|  |                                 .apply(Term::var("do_insert")) | ||||||
|  |                                 .apply(Term::var("elems")) | ||||||
|  |                                 .lambda("do_insert") | ||||||
|  |                                 .apply( | ||||||
|  |                                     Term::var("elems") | ||||||
|  |                                         .delayed_choose_list( | ||||||
|  |                                             Term::mk_cons() | ||||||
|  |                                                 .apply( | ||||||
|  |                                                     Term::mk_pair_data() | ||||||
|  |                                                         .apply(Term::b_data().apply(Term::var("k"))) | ||||||
|  |                                                         .apply( | ||||||
|  |                                                             Term::i_data().apply(Term::var("v")), | ||||||
|  |                                                         ), | ||||||
|  |                                                 ) | ||||||
|  |                                                 .apply(Term::empty_map()), | ||||||
|  |                                             Term::equals_bytestring() | ||||||
|  |                                                 .apply(Term::var("k")) | ||||||
|  |                                                 .apply(Term::var("k2")) | ||||||
|  |                                                 .delayed_if_then_else( | ||||||
|  |                                                     Term::mk_cons() | ||||||
|  |                                                         .apply( | ||||||
|  |                                                             Term::mk_pair_data() | ||||||
|  |                                                                 .apply( | ||||||
|  |                                                                     Term::b_data() | ||||||
|  |                                                                         .apply(Term::var("k")), | ||||||
|  |                                                                 ) | ||||||
|  |                                                                 .apply( | ||||||
|  |                                                                     Term::i_data() | ||||||
|  |                                                                         .apply(Term::var("v")), | ||||||
|  |                                                                 ), | ||||||
|  |                                                         ) | ||||||
|  |                                                         .apply(Term::var("rest")), | ||||||
|  |                                                     Term::mk_cons() | ||||||
|  |                                                         .apply( | ||||||
|  |                                                             Term::mk_pair_data() | ||||||
|  |                                                                 .apply( | ||||||
|  |                                                                     Term::b_data() | ||||||
|  |                                                                         .apply(Term::var("k2")), | ||||||
|  |                                                                 ) | ||||||
|  |                                                                 .apply( | ||||||
|  |                                                                     Term::i_data() | ||||||
|  |                                                                         .apply(Term::var("v2")), | ||||||
|  |                                                                 ), | ||||||
|  |                                                         ) | ||||||
|  |                                                         .apply( | ||||||
|  |                                                             Term::var("do_insert") | ||||||
|  |                                                                 .apply(Term::var("do_insert")) | ||||||
|  |                                                                 .apply(Term::var("rest")), | ||||||
|  |                                                         ), | ||||||
|  |                                                 ) | ||||||
|  |                                                 .lambda("v2") | ||||||
|  |                                                 .apply(Term::un_i_data().apply( | ||||||
|  |                                                     Term::snd_pair().apply(Term::var("pair")), | ||||||
|  |                                                 )) | ||||||
|  |                                                 .lambda("k2") | ||||||
|  |                                                 .apply(Term::un_b_data().apply( | ||||||
|  |                                                     Term::fst_pair().apply(Term::var("pair")), | ||||||
|  |                                                 )) | ||||||
|  |                                                 .lambda("rest") | ||||||
|  |                                                 .apply(Term::tail_list().apply(Term::var("elems"))) | ||||||
|  |                                                 .lambda("pair") | ||||||
|  |                                                 .apply(Term::head_list().apply(Term::var("elems"))), | ||||||
|  |                                         ) | ||||||
|  |                                         .lambda("elems") | ||||||
|  |                                         .lambda("do_insert"), | ||||||
|  |                                 ) | ||||||
|  |                                 .lambda("v") | ||||||
|  |                                 .lambda("k") | ||||||
|  |                                 .lambda("elems"), | ||||||
|  |                         ) | ||||||
|  |                         .apply(Term::map_values(vec![ | ||||||
|  |                             Constant::ProtoPair( | ||||||
|  |                                 Type::Data, | ||||||
|  |                                 Type::Data, | ||||||
|  |                                 Constant::Data(Data::bytestring("foo".as_bytes().to_vec())).into(), | ||||||
|  |                                 Constant::Data(Data::integer(42.into())).into(), | ||||||
|  |                             ), | ||||||
|  |                             Constant::ProtoPair( | ||||||
|  |                                 Type::Data, | ||||||
|  |                                 Type::Data, | ||||||
|  |                                 Constant::Data(Data::bytestring("bar".as_bytes().to_vec())).into(), | ||||||
|  |                                 Constant::Data(Data::integer(14.into())).into(), | ||||||
|  |                             ), | ||||||
|  |                         ])) | ||||||
|  |                         .apply(Term::empty_map()), | ||||||
|  |                 ), | ||||||
|  |             ) | ||||||
|  |             .apply(Term::data(Data::map(vec![ | ||||||
|  |                 ( | ||||||
|  |                     Data::bytestring("foo".as_bytes().to_vec()), | ||||||
|  |                     Data::integer(42.into()), | ||||||
|  |                 ), | ||||||
|  |                 ( | ||||||
|  |                     Data::bytestring("bar".as_bytes().to_vec()), | ||||||
|  |                     Data::integer(14.into()), | ||||||
|  |                 ), | ||||||
|  |             ]))), | ||||||
|  |         false, | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[test] | ||||||
|  | fn acceptance_test_29_union_tuple() { | ||||||
|     let src = r#" |     let src = r#" | ||||||
|       pub opaque type AssocList<key, value> { |       pub opaque type AssocList<key, value> { | ||||||
|         inner: List<(key, value)>, |         inner: List<(key, value)>, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 microproofs
						microproofs