feat: add map support and tuple deconstruction in let

This commit is contained in:
Kasey White 2022-12-08 05:08:11 -05:00 committed by Lucas
parent 26d2a95618
commit 80a9b7b36a
4 changed files with 699 additions and 172 deletions

View File

@ -219,6 +219,12 @@ pub enum Air {
scope: Vec<u64>, scope: Vec<u64>,
value: Box<Self>, value: Box<Self>,
}, },
TupleAccessor {
scope: Vec<u64>,
names: Vec<String>,
tipo: Arc<Type>,
},
} }
impl Air { impl Air {
@ -255,7 +261,8 @@ impl Air {
| Air::Todo { scope, .. } | Air::Todo { scope, .. }
| Air::Record { scope, .. } | Air::Record { scope, .. }
| Air::RecordUpdate { scope, .. } | Air::RecordUpdate { scope, .. }
| Air::Negate { scope, .. } => scope.to_vec(), | Air::Negate { scope, .. }
| Air::TupleAccessor { scope, .. } => scope.to_vec(),
} }
} }
} }

View File

@ -142,6 +142,8 @@ impl Type {
} if "List" == name && module.is_empty() => { } if "List" == name && module.is_empty() => {
if let Type::Tuple { elems } = &*args[0] { if let Type::Tuple { elems } = &*args[0] {
elems.len() == 2 elems.len() == 2
} else if let Type::Var { tipo } = &*args[0] {
matches!(tipo.borrow().get_uplc_type(), UplcType::Pair(_, _))
} else { } else {
false false
} }
@ -385,6 +387,13 @@ impl TypeVar {
_ => vec![], _ => vec![],
} }
} }
pub fn get_uplc_type(&self) -> UplcType {
match self {
Self::Link { tipo } => tipo.get_uplc_type(),
_ => unreachable!(),
}
}
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]

View File

@ -1112,7 +1112,9 @@ impl<'a> CodeGenerator<'a> {
Pattern::Constructor { .. } => { Pattern::Constructor { .. } => {
self.pattern_ir(pattern, pattern_vec, value_vec, tipo, scope); self.pattern_ir(pattern, pattern_vec, value_vec, tipo, scope);
} }
Pattern::Tuple { .. } => todo!(), Pattern::Tuple { .. } => {
self.pattern_ir(pattern, pattern_vec, value_vec, tipo, scope);
}
} }
} }
@ -1368,7 +1370,55 @@ impl<'a> CodeGenerator<'a> {
pattern_vec.append(values); pattern_vec.append(values);
pattern_vec.append(&mut nested_pattern); pattern_vec.append(&mut nested_pattern);
} }
Pattern::Tuple { .. } => todo!(), Pattern::Tuple { elems, .. } => {
let mut elements_vec = vec![];
let mut names = vec![];
for element in elems {
match element {
Pattern::Var { name, .. } => {
names.push(name.clone());
}
a @ Pattern::List { .. } => {
let mut var_vec = vec![];
let item_name = format!("list_item_id_{}", self.id_gen.next());
names.push(item_name.clone());
var_vec.push(Air::Var {
constructor: ValueConstructor::public(
Type::App {
public: true,
module: String::new(),
name: String::new(),
args: vec![],
}
.into(),
ValueConstructorVariant::LocalVariable {
location: Span::empty(),
},
),
name: item_name,
scope: scope.clone(),
});
self.pattern_ir(
a,
&mut elements_vec,
&mut var_vec,
&tipo.get_inner_type()[0],
scope.clone(),
);
}
_ => todo!(),
}
}
pattern_vec.push(Air::TupleAccessor {
names,
scope,
tipo: tipo.clone().into(),
});
pattern_vec.append(values);
pattern_vec.append(&mut elements_vec);
}
} }
} }
@ -1556,27 +1606,69 @@ impl<'a> CodeGenerator<'a> {
let list_type = tipo.get_inner_type()[0].clone(); let list_type = tipo.get_inner_type()[0].clone();
if constants.len() == args.len() && !tail { if constants.len() == args.len() && !tail {
let list = Term::Constant(UplcConstant::ProtoList( let list = if tipo.is_map() {
let mut convert_keys = vec![];
let mut convert_values = vec![];
for constant in constants {
match constant {
UplcConstant::ProtoPair(_, _, fst, snd) => {
convert_keys.push(*fst);
convert_values.push(*snd);
}
_ => unreachable!(),
}
}
convert_keys = convert_constants_to_data(convert_keys);
convert_values = convert_constants_to_data(convert_values);
Term::Constant(UplcConstant::ProtoList(
UplcType::Pair(UplcType::Data.into(), UplcType::Data.into()),
convert_keys
.into_iter()
.zip(convert_values.into_iter())
.map(|(key, value)| {
UplcConstant::ProtoPair(
UplcType::Data,
UplcType::Data,
key.into(),
value.into(),
)
})
.collect_vec(),
))
} else {
Term::Constant(UplcConstant::ProtoList(
UplcType::Data, UplcType::Data,
convert_constants_to_data(constants), convert_constants_to_data(constants),
)); ))
};
arg_stack.push(list); arg_stack.push(list);
} else { } else {
let mut term = if tail { let mut term = if tail {
arg_stack.pop().unwrap() arg_stack.pop().unwrap()
} else if tipo.is_map() {
Term::Constant(UplcConstant::ProtoList(
UplcType::Pair(UplcType::Data.into(), UplcType::Data.into()),
vec![],
))
} else { } else {
Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![])) Term::Constant(UplcConstant::ProtoList(UplcType::Data, vec![]))
}; };
for arg in args { for arg in args {
let list_item = if tipo.is_map() {
arg
} else {
convert_type_to_data(arg, &list_type)
};
term = Term::Apply { term = Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Force( function: Term::Force(
Term::Builtin(DefaultFunction::MkCons).force_wrap().into(), Term::Builtin(DefaultFunction::MkCons).force_wrap().into(),
) )
.into(), .into(),
argument: convert_type_to_data(arg, &list_type).into(), argument: list_item.into(),
} }
.into(), .into(),
argument: term.into(), argument: term.into(),
@ -1600,7 +1692,40 @@ impl<'a> CodeGenerator<'a> {
let current_index = 0; let current_index = 0;
let (first_name, names) = names.split_first().unwrap(); let (first_name, names) = names.split_first().unwrap();
let list_id = self.id_gen.next();
let head_list = if tipo.is_map() {
Term::Apply {
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into())
.into(),
argument: Term::Var(Name {
text: format!("__list_{}", list_id),
unique: 0.into(),
})
.into(),
}
} else {
convert_data_to_type(
Term::Apply {
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into())
.into(),
argument: Term::Var(Name {
text: format!("__list_{}", list_id),
unique: 0.into(),
})
.into(),
},
&tipo.get_inner_type()[0],
)
};
term = Term::Apply { term = Term::Apply {
function: Term::Lambda {
parameter_name: Name {
text: format!("__list_{}", list_id),
unique: 0.into(),
},
body: Term::Apply {
function: Term::Lambda { function: Term::Lambda {
parameter_name: Name { parameter_name: Name {
text: first_name.clone(), text: first_name.clone(),
@ -1613,7 +1738,7 @@ impl<'a> CodeGenerator<'a> {
tail, tail,
current_index, current_index,
term, term,
&tipo.get_inner_type()[0], &tipo,
) )
.into(), .into(),
argument: Term::Apply { argument: Term::Apply {
@ -1621,22 +1746,23 @@ impl<'a> CodeGenerator<'a> {
Term::Builtin(DefaultFunction::TailList).into(), Term::Builtin(DefaultFunction::TailList).into(),
) )
.into(), .into(),
argument: value.clone().into(), argument: Term::Var(Name {
text: format!("__list_{}", list_id),
unique: 0.into(),
})
.into(),
} }
.into(), .into(),
} }
.into(), .into(),
} }
.into(), .into(),
argument: convert_data_to_type( argument: head_list.into(),
Term::Apply { }
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into()) .into(),
}
.into(), .into(),
argument: value.into(), argument: value.into(),
},
&tipo.get_inner_type()[0],
)
.into(),
}; };
arg_stack.push(term); arg_stack.push(term);
@ -1649,8 +1775,6 @@ impl<'a> CodeGenerator<'a> {
} => { } => {
let mut term = arg_stack.pop().unwrap(); let mut term = arg_stack.pop().unwrap();
let list_type = tipo.get_inner_type()[0].clone();
if let Some((tail_var, tail_name)) = tail { if let Some((tail_var, tail_name)) = tail {
term = Term::Apply { term = Term::Apply {
function: Term::Lambda { function: Term::Lambda {
@ -1672,7 +1796,34 @@ impl<'a> CodeGenerator<'a> {
.into(), .into(),
}; };
} }
for (tail_var, head_name) in tail_head_names.into_iter().rev() { for (tail_var, head_name) in tail_head_names.into_iter().rev() {
let head_list = if tipo.is_map() {
Term::Apply {
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into())
.into(),
argument: Term::Var(Name {
text: tail_var,
unique: 0.into(),
})
.into(),
}
} else {
convert_data_to_type(
Term::Apply {
function: Term::Force(
Term::Builtin(DefaultFunction::HeadList).into(),
)
.into(),
argument: Term::Var(Name {
text: tail_var,
unique: 0.into(),
})
.into(),
},
&tipo.get_inner_type()[0],
)
};
term = Term::Apply { term = Term::Apply {
function: Term::Lambda { function: Term::Lambda {
parameter_name: Name { parameter_name: Name {
@ -1682,20 +1833,7 @@ impl<'a> CodeGenerator<'a> {
body: term.into(), body: term.into(),
} }
.into(), .into(),
argument: convert_data_to_type( argument: head_list.into(),
Term::Apply {
function: Term::Builtin(DefaultFunction::HeadList)
.force_wrap()
.into(),
argument: Term::Var(Name {
text: tail_var,
unique: 0.into(),
})
.into(),
},
&list_type,
)
.into(),
}; };
} }
@ -1729,19 +1867,14 @@ impl<'a> CodeGenerator<'a> {
let left = arg_stack.pop().unwrap(); let left = arg_stack.pop().unwrap();
let right = arg_stack.pop().unwrap(); let right = arg_stack.pop().unwrap();
let default_builtin = match tipo.deref() { let default_builtin = if tipo.is_int() {
Type::App { name, .. } => { DefaultFunction::EqualsInteger
if name == "Int" { } else if tipo.is_string() {
Term::Builtin(DefaultFunction::EqualsInteger) DefaultFunction::EqualsString
} else if name == "String" { } else if tipo.is_bytearray() {
Term::Builtin(DefaultFunction::EqualsString) DefaultFunction::EqualsByteString
} else if name == "ByteArray" {
Term::Builtin(DefaultFunction::EqualsByteString)
} else { } else {
Term::Builtin(DefaultFunction::EqualsData) DefaultFunction::EqualsData
}
}
_ => unreachable!(),
}; };
let term = match name { let term = match name {
@ -1778,16 +1911,13 @@ impl<'a> CodeGenerator<'a> {
} }
.force_wrap(), .force_wrap(),
BinOp::Eq => { BinOp::Eq => {
match tipo.deref() { if tipo.is_bool() {
Type::App { name, .. } => {
if name == "Bool" {
let term = Term::Force( let term = Term::Force(
Term::Apply { Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Force( function: Term::Force(
Term::Builtin(DefaultFunction::IfThenElse) Term::Builtin(DefaultFunction::IfThenElse).into(),
.into(),
) )
.into(), .into(),
argument: left.into(), argument: left.into(),
@ -1801,24 +1931,18 @@ impl<'a> CodeGenerator<'a> {
function: Term::Apply { function: Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Force( function: Term::Force(
Term::Builtin( Term::Builtin(DefaultFunction::IfThenElse)
DefaultFunction::IfThenElse,
)
.into(), .into(),
) )
.into(), .into(),
argument: right.into(), argument: right.into(),
} }
.into(), .into(),
argument: Term::Constant( argument: Term::Constant(UplcConstant::Bool(false))
UplcConstant::Bool(false),
)
.into(), .into(),
} }
.into(), .into(),
argument: Term::Constant(UplcConstant::Bool( argument: Term::Constant(UplcConstant::Bool(true))
true,
))
.into(), .into(),
} }
.into(), .into(),
@ -1830,10 +1954,106 @@ impl<'a> CodeGenerator<'a> {
arg_stack.push(term); arg_stack.push(term);
return; return;
} else if tipo.is_map() {
let term = Term::Apply {
function: Term::Apply {
function: default_builtin.into(),
argument: Term::Apply {
function: DefaultFunction::MapData.into(),
argument: left.into(),
} }
.into(),
} }
_ => unreachable!(), .into(),
argument: Term::Apply {
function: DefaultFunction::MapData.into(),
argument: right.into(),
}
.into(),
}; };
arg_stack.push(term);
return;
} else if tipo.is_tuple()
&& matches!(tipo.get_uplc_type(), UplcType::Pair(_, _))
{
let term = Term::Apply {
function: Term::Apply {
function: default_builtin.into(),
argument: Term::Apply {
function: DefaultFunction::MapData.into(),
argument: Term::Apply {
function: Term::Apply {
function: Term::Builtin(DefaultFunction::MkCons)
.force_wrap()
.into(),
argument: left.into(),
}
.into(),
argument: Term::Constant(UplcConstant::ProtoList(
UplcType::Pair(
UplcType::Data.into(),
UplcType::Data.into(),
),
vec![],
))
.into(),
}
.into(),
}
.into(),
}
.into(),
argument: Term::Apply {
function: DefaultFunction::MapData.into(),
argument: Term::Apply {
function: Term::Apply {
function: Term::Builtin(DefaultFunction::MkCons)
.force_wrap()
.into(),
argument: right.into(),
}
.into(),
argument: Term::Constant(UplcConstant::ProtoList(
UplcType::Pair(
UplcType::Data.into(),
UplcType::Data.into(),
),
vec![],
))
.into(),
}
.into(),
}
.into(),
};
arg_stack.push(term);
return;
} else if tipo.is_list()
|| matches!(tipo.get_uplc_type(), UplcType::List(_))
{
let term = Term::Apply {
function: Term::Apply {
function: default_builtin.into(),
argument: Term::Apply {
function: DefaultFunction::ListData.into(),
argument: left.into(),
}
.into(),
}
.into(),
argument: Term::Apply {
function: default_builtin.into(),
argument: Term::Apply {
function: DefaultFunction::ListData.into(),
argument: right.into(),
}
.into(),
}
.into(),
};
arg_stack.push(term);
return;
}
Term::Apply { Term::Apply {
function: Term::Apply { function: Term::Apply {
@ -1845,16 +2065,13 @@ impl<'a> CodeGenerator<'a> {
} }
} }
BinOp::NotEq => { BinOp::NotEq => {
match tipo.deref() { if tipo.is_bool() {
Type::App { name, .. } => {
if name == "Bool" {
let term = Term::Force( let term = Term::Force(
Term::Apply { Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Force( function: Term::Force(
Term::Builtin(DefaultFunction::IfThenElse) Term::Builtin(DefaultFunction::IfThenElse).into(),
.into(),
) )
.into(), .into(),
argument: left.into(), argument: left.into(),
@ -1874,15 +2091,13 @@ impl<'a> CodeGenerator<'a> {
argument: right.clone().into(), argument: right.clone().into(),
} }
.into(), .into(),
argument: Term::Constant( argument: Term::Constant(UplcConstant::Bool(
UplcConstant::Bool(false), false,
) ))
.into(), .into(),
} }
.into(), .into(),
argument: Term::Constant( argument: Term::Constant(UplcConstant::Bool(true))
UplcConstant::Bool(true),
)
.into(), .into(),
} }
.into(), .into(),
@ -1897,10 +2112,133 @@ impl<'a> CodeGenerator<'a> {
arg_stack.push(term); arg_stack.push(term);
return; return;
} else if tipo.is_map() {
let term = Term::Apply {
function: Term::Apply {
function: Term::Apply {
function: Term::Builtin(DefaultFunction::IfThenElse)
.force_wrap()
.into(),
argument: Term::Apply {
function: Term::Apply {
function: default_builtin.into(),
argument: Term::Apply {
function: DefaultFunction::MapData.into(),
argument: left.into(),
} }
.into(),
} }
_ => unreachable!(), .into(),
argument: Term::Apply {
function: DefaultFunction::MapData.into(),
argument: right.into(),
}
.into(),
}
.into(),
}
.into(),
argument: Term::Constant(UplcConstant::Bool(false)).into(),
}
.into(),
argument: Term::Constant(UplcConstant::Bool(true)).into(),
}; };
arg_stack.push(term);
return;
} else if tipo.is_tuple()
&& matches!(tipo.get_uplc_type(), UplcType::Pair(_, _))
{
// let term = Term::Apply {
// function: Term::Apply {
// function: default_builtin.into(),
// argument: Term::Apply {
// function: DefaultFunction::MapData.into(),
// argument: Term::Apply {
// function: Term::Apply {
// function: Term::Builtin(DefaultFunction::MkCons)
// .force_wrap()
// .into(),
// argument: left.into(),
// }
// .into(),
// argument: Term::Constant(UplcConstant::ProtoList(
// UplcType::Pair(
// UplcType::Data.into(),
// UplcType::Data.into(),
// ),
// vec![],
// ))
// .into(),
// }
// .into(),
// }
// .into(),
// }
// .into(),
// argument: Term::Apply {
// function: Term::Apply {
// function: Term::Builtin(DefaultFunction::MkCons)
// .force_wrap()
// .into(),
// argument: right.into(),
// }
// .into(),
// argument: Term::Constant(UplcConstant::ProtoList(
// UplcType::Pair(
// UplcType::Data.into(),
// UplcType::Data.into(),
// ),
// vec![],
// ))
// .into(),
// }
// .into(),
// };
// arg_stack.push(term);
// return;
todo!()
} else if tipo.is_list()
|| matches!(tipo.get_uplc_type(), UplcType::List(_))
{
let term = Term::Apply {
function: Term::Apply {
function: Term::Apply {
function: Term::Builtin(DefaultFunction::IfThenElse)
.force_wrap()
.into(),
argument: Term::Apply {
function: Term::Apply {
function: default_builtin.into(),
argument: Term::Apply {
function: DefaultFunction::ListData.into(),
argument: left.into(),
}
.into(),
}
.into(),
argument: Term::Apply {
function: default_builtin.into(),
argument: Term::Apply {
function: DefaultFunction::ListData.into(),
argument: right.into(),
}
.into(),
}
.into(),
}
.into(),
}
.into(),
argument: Term::Constant(UplcConstant::Bool(false)).into(),
}
.into(),
argument: Term::Constant(UplcConstant::Bool(true)).into(),
};
arg_stack.push(term);
return;
}
Term::Apply { Term::Apply {
function: Term::Apply { function: Term::Apply {
function: Term::Apply { function: Term::Apply {
@ -2736,6 +3074,153 @@ impl<'a> CodeGenerator<'a> {
Air::Record { .. } => todo!(), Air::Record { .. } => todo!(),
Air::RecordUpdate { .. } => todo!(), Air::RecordUpdate { .. } => todo!(),
Air::Negate { .. } => todo!(), Air::Negate { .. } => todo!(),
Air::TupleAccessor { tipo, names, .. } => {
let value = arg_stack.pop().unwrap();
let mut term = arg_stack.pop().unwrap();
let list_id = self.id_gen.next();
if names.len() == 2 {
term = Term::Apply {
function: Term::Lambda {
parameter_name: Name {
text: format!("__tuple_{}", list_id),
unique: 0.into(),
},
body: Term::Apply {
function: Term::Lambda {
parameter_name: Name {
text: names[0].clone(),
unique: 0.into(),
},
body: Term::Apply {
function: Term::Lambda {
parameter_name: Name {
text: names[1].clone(),
unique: 0.into(),
},
body: term.into(),
}
.into(),
argument: Term::Apply {
function: Term::Builtin(DefaultFunction::SndPair)
.force_wrap()
.force_wrap()
.into(),
argument: Term::Var(Name {
text: format!("__tuple_{}", list_id),
unique: 0.into(),
})
.into(),
}
.into(),
}
.into(),
}
.into(),
argument: Term::Apply {
function: Term::Builtin(DefaultFunction::FstPair)
.force_wrap()
.force_wrap()
.into(),
argument: Term::Var(Name {
text: format!("__tuple_{}", list_id),
unique: 0.into(),
})
.into(),
}
.into(),
}
.into(),
}
.into(),
argument: value.into(),
};
} else {
let mut id_list = vec![];
for _ in 0..names.len() {
id_list.push(self.id_gen.next());
}
let current_index = 0;
let (first_name, names) = names.split_first().unwrap();
let head_list = if tipo.is_map() {
Term::Apply {
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into())
.into(),
argument: Term::Var(Name {
text: format!("__tuple_{}", list_id),
unique: 0.into(),
})
.into(),
}
} else {
convert_data_to_type(
Term::Apply {
function: Term::Force(
Term::Builtin(DefaultFunction::HeadList).into(),
)
.into(),
argument: Term::Var(Name {
text: format!("__tuple_{}", list_id),
unique: 0.into(),
})
.into(),
},
&tipo.get_inner_type()[0],
)
};
term = Term::Apply {
function: Term::Lambda {
parameter_name: Name {
text: format!("__tuple_{}", list_id),
unique: 0.into(),
},
body: Term::Apply {
function: Term::Lambda {
parameter_name: Name {
text: first_name.clone(),
unique: 0.into(),
},
body: Term::Apply {
function: list_access_to_uplc(
names,
&id_list,
false,
current_index,
term,
&tipo,
)
.into(),
argument: Term::Apply {
function: Term::Force(
Term::Builtin(DefaultFunction::TailList).into(),
)
.into(),
argument: Term::Var(Name {
text: format!("__tuple_{}", list_id),
unique: 0.into(),
})
.into(),
}
.into(),
}
.into(),
}
.into(),
argument: head_list.into(),
}
.into(),
}
.into(),
argument: value.into(),
};
}
arg_stack.push(term);
}
} }
} }
@ -3066,7 +3551,7 @@ fn convert_constants_to_data(constants: Vec<UplcConstant>) -> Vec<UplcConstant>
})), })),
UplcConstant::ProtoList(_, _) => todo!(), UplcConstant::ProtoList(_, _) => todo!(),
UplcConstant::ProtoPair(_, _, _, _) => todo!(), UplcConstant::ProtoPair(_, _, _, _) => todo!(),
UplcConstant::Data(_) => todo!(), d @ UplcConstant::Data(_) => d,
_ => unreachable!(), _ => unreachable!(),
}; };
new_constants.push(constant); new_constants.push(constant);
@ -3172,6 +3657,29 @@ fn list_access_to_uplc(
) -> Term<Name> { ) -> Term<Name> {
let (first, names) = names.split_first().unwrap(); let (first, names) = names.split_first().unwrap();
let head_list = if tipo.is_map() {
Term::Apply {
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into()).into(),
argument: Term::Var(Name {
text: format!("tail_index_{}_{}", current_index, id_list[current_index]),
unique: 0.into(),
})
.into(),
}
} else {
convert_data_to_type(
Term::Apply {
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into()).into(),
argument: Term::Var(Name {
text: format!("tail_index_{}_{}", current_index, id_list[current_index]),
unique: 0.into(),
})
.into(),
},
&tipo.clone().get_inner_type()[0],
)
};
if names.len() == 1 && tail { if names.len() == 1 && tail {
Term::Lambda { Term::Lambda {
parameter_name: Name { parameter_name: Name {
@ -3210,22 +3718,7 @@ fn list_access_to_uplc(
.into(), .into(),
} }
.into(), .into(),
argument: convert_data_to_type( argument: head_list.into(),
Term::Apply {
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into())
.into(),
argument: Term::Var(Name {
text: format!(
"tail_index_{}_{}",
current_index, id_list[current_index]
),
unique: 0.into(),
})
.into(),
},
&Arc::new(tipo.clone()),
)
.into(),
} }
.into(), .into(),
} }
@ -3295,15 +3788,7 @@ fn list_access_to_uplc(
.into(), .into(),
} }
.into(), .into(),
argument: Term::Apply { argument: head_list.into(),
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into()).into(),
argument: Term::Var(Name {
text: format!("tail_index_{}_{}", current_index, id_list[current_index]),
unique: 0.into(),
})
.into(),
}
.into(),
} }
.into(), .into(),
} }
@ -3697,6 +4182,26 @@ fn convert_data_to_type(term: Term<Name>, field_type: &Arc<Type>) -> Term<Name>
}, },
_ => unreachable!(), _ => unreachable!(),
} }
} else if field_type.is_bool() {
Term::Apply {
function: Term::Apply {
function: Term::Builtin(DefaultFunction::EqualsInteger).into(),
argument: Term::Constant(UplcConstant::Integer(1)).into(),
}
.into(),
argument: Term::Apply {
function: Term::Builtin(DefaultFunction::FstPair)
.force_wrap()
.force_wrap()
.into(),
argument: Term::Apply {
function: Term::Builtin(DefaultFunction::UnConstrData).into(),
argument: term.into(),
}
.into(),
}
.into(),
}
} else { } else {
term term
} }

View File

@ -1,7 +1,13 @@
use sample use sample
pub fn spend(datum: sample.Datum, rdmr: sample.Redeemer, _ctx: Nil) -> Bool { pub fn spend(datum: sample.Datum, rdmr: sample.Redeemer, _ctx: Nil) -> Bool {
let x = #(datum, rdmr, #[244]) let x = #(datum, #[244])
datum.random == rdmr.signer let y = [#(#[222], #[222]), #(#[233], #[52])]
let [z, f, ..g] = y
let #(a, b) = x
z == #(#[222], #[222])
} }