WIP: add new opcodes to Air and AirTree and update parts of codegen to handle the new pair type
This commit is contained in:
parent
9e78f0fc2a
commit
f950ae7d3d
|
@ -1091,6 +1091,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo: constr_tipo,
|
tipo: constr_tipo,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
// TODO: Implement Pair pattern
|
||||||
if tipo.is_bool() {
|
if tipo.is_bool() {
|
||||||
assert!(props.kind.is_expect());
|
assert!(props.kind.is_expect());
|
||||||
|
|
||||||
|
@ -1364,12 +1365,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
msg_func.clone(),
|
msg_func.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let anon_func_body = AirTree::tuple_access(
|
let anon_func_body = AirTree::pair_access(
|
||||||
vec![fst_name, snd_name],
|
Some(fst_name),
|
||||||
|
Some(snd_name),
|
||||||
inner_list_type.clone(),
|
inner_list_type.clone(),
|
||||||
AirTree::local_var(&pair_name, inner_list_type.clone()),
|
AirTree::local_var(&pair_name, inner_list_type.clone()),
|
||||||
msg_func.clone(),
|
msg_func.clone(),
|
||||||
msg_func.is_some(),
|
true,
|
||||||
AirTree::let_assignment("_", expect_fst, expect_snd),
|
AirTree::let_assignment("_", expect_fst, expect_snd),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1512,16 +1514,17 @@ impl<'a> CodeGenerator<'a> {
|
||||||
msg_func.clone(),
|
msg_func.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let tuple_access = AirTree::tuple_access(
|
let pair_access = AirTree::pair_access(
|
||||||
vec![fst_name, snd_name],
|
Some(fst_name.clone()),
|
||||||
|
Some(snd_name.clone()),
|
||||||
tipo.clone(),
|
tipo.clone(),
|
||||||
AirTree::local_var(&pair_name, tipo.clone()),
|
AirTree::local_var(&pair_name, tipo.clone()),
|
||||||
msg_func.clone(),
|
msg_func.clone(),
|
||||||
msg_func.is_some(),
|
true,
|
||||||
AirTree::let_assignment("_", expect_fst, expect_snd),
|
AirTree::let_assignment("_", expect_fst, expect_snd),
|
||||||
);
|
);
|
||||||
|
|
||||||
AirTree::let_assignment(&pair_name, value, tuple_access)
|
AirTree::let_assignment(&pair_name, value, pair_access)
|
||||||
} else if tipo.is_tuple() {
|
} else if tipo.is_tuple() {
|
||||||
let tuple_inner_types = tipo.get_inner_types();
|
let tuple_inner_types = tipo.get_inner_types();
|
||||||
|
|
||||||
|
@ -1799,6 +1802,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match &mut props.specific_clause {
|
match &mut props.specific_clause {
|
||||||
|
// TODO: Implement PairClause and PairClauseGuard
|
||||||
SpecificClause::ConstrClause => {
|
SpecificClause::ConstrClause => {
|
||||||
let data_type = lookup_data_type_by_tipo(&self.data_types, subject_tipo);
|
let data_type = lookup_data_type_by_tipo(&self.data_types, subject_tipo);
|
||||||
|
|
||||||
|
@ -3845,7 +3849,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
DefaultFunction::MkCons | DefaultFunction::MkPairData => {
|
DefaultFunction::MkCons | DefaultFunction::MkPairData => {
|
||||||
unimplemented!(
|
unimplemented!(
|
||||||
"MkCons and MkPairData should be handled by an anon function or using [] or ( a, b, .., z).\n"
|
"MkCons and MkPairData should be handled by an anon function or using [] or ( a, b, .., z) or Pair {{fst:a, snd: b}}.\n"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -4792,31 +4796,49 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.apply(next_clause.delay());
|
.apply(next_clause.delay());
|
||||||
}
|
}
|
||||||
|
|
||||||
if tipo.is_pair() {
|
for (index, name) in indices.iter() {
|
||||||
for (index, name) in indices.iter() {
|
term = term.lambda(name.clone()).apply(builder::known_data_to_type(
|
||||||
if name == "_" {
|
Term::head_list()
|
||||||
continue;
|
.apply(Term::var(subject_name.clone()).repeat_tail_list(*index)),
|
||||||
}
|
&tuple_types[*index].clone(),
|
||||||
let builtin = if *index == 0 {
|
));
|
||||||
Term::fst_pair()
|
|
||||||
} else {
|
|
||||||
Term::snd_pair()
|
|
||||||
};
|
|
||||||
|
|
||||||
term = term.lambda(name).apply(builder::known_data_to_type(
|
|
||||||
builtin.apply(Term::var(subject_name.clone())),
|
|
||||||
&tuple_types[*index].clone(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (index, name) in indices.iter() {
|
|
||||||
term = term.lambda(name.clone()).apply(builder::known_data_to_type(
|
|
||||||
Term::head_list()
|
|
||||||
.apply(Term::var(subject_name.clone()).repeat_tail_list(*index)),
|
|
||||||
&tuple_types[*index].clone(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some(term)
|
||||||
|
}
|
||||||
|
Air::PairClause {
|
||||||
|
subject_tipo: tipo,
|
||||||
|
complex_clause,
|
||||||
|
subject_name,
|
||||||
|
fst_name,
|
||||||
|
snd_name,
|
||||||
|
} => {
|
||||||
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
let next_clause = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
let pair_types = tipo.get_inner_types();
|
||||||
|
|
||||||
|
if complex_clause {
|
||||||
|
term = term
|
||||||
|
.lambda("__other_clauses_delayed")
|
||||||
|
.apply(next_clause.delay());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(fst) = fst_name {
|
||||||
|
term = term.lambda(fst).apply(builder::known_data_to_type(
|
||||||
|
Term::fst_pair().apply(Term::var(subject_name.clone())),
|
||||||
|
&pair_types[0].clone(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(snd) = snd_name {
|
||||||
|
term = term.lambda(snd).apply(builder::known_data_to_type(
|
||||||
|
Term::snd_pair().apply(Term::var(subject_name.clone())),
|
||||||
|
&pair_types[1].clone(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
Some(term)
|
Some(term)
|
||||||
}
|
}
|
||||||
Air::ClauseGuard {
|
Air::ClauseGuard {
|
||||||
|
@ -4913,31 +4935,40 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let tuple_types = tipo.get_inner_types();
|
let tuple_types = tipo.get_inner_types();
|
||||||
|
|
||||||
if tuple_types.len() == 2 {
|
for (index, name) in indices.iter() {
|
||||||
for (index, name) in indices.iter() {
|
term = term.lambda(name.clone()).apply(builder::known_data_to_type(
|
||||||
if name == "_" {
|
Term::head_list()
|
||||||
continue;
|
.apply(Term::var(subject_name.clone()).repeat_tail_list(*index)),
|
||||||
}
|
&tuple_types[*index].clone(),
|
||||||
let builtin = if *index == 0 {
|
));
|
||||||
Term::fst_pair()
|
|
||||||
} else {
|
|
||||||
Term::snd_pair()
|
|
||||||
};
|
|
||||||
|
|
||||||
term = term.lambda(name).apply(builder::known_data_to_type(
|
|
||||||
builtin.apply(Term::var(subject_name.clone())),
|
|
||||||
&tuple_types[*index].clone(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (index, name) in indices.iter() {
|
|
||||||
term = term.lambda(name.clone()).apply(builder::known_data_to_type(
|
|
||||||
Term::head_list()
|
|
||||||
.apply(Term::var(subject_name.clone()).repeat_tail_list(*index)),
|
|
||||||
&tuple_types[*index].clone(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some(term)
|
||||||
|
}
|
||||||
|
Air::PairGuard {
|
||||||
|
subject_tipo: tipo,
|
||||||
|
subject_name,
|
||||||
|
fst_name,
|
||||||
|
snd_name,
|
||||||
|
} => {
|
||||||
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
let tuple_types = tipo.get_inner_types();
|
||||||
|
|
||||||
|
if let Some(fst) = fst_name {
|
||||||
|
term = term.lambda(fst).apply(builder::known_data_to_type(
|
||||||
|
Term::fst_pair().apply(Term::var(subject_name.clone())),
|
||||||
|
&tuple_types[0].clone(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(snd) = snd_name {
|
||||||
|
term = term.lambda(snd).apply(builder::known_data_to_type(
|
||||||
|
Term::snd_pair().apply(Term::var(subject_name.clone())),
|
||||||
|
&tuple_types[1].clone(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
Some(term)
|
Some(term)
|
||||||
}
|
}
|
||||||
Air::Finally => {
|
Air::Finally => {
|
||||||
|
@ -5094,34 +5125,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
if constants.len() == args.len() {
|
if constants.len() == args.len() {
|
||||||
let data_constants = builder::convert_constants_to_data(constants);
|
let data_constants = builder::convert_constants_to_data(constants);
|
||||||
|
|
||||||
if count == 2 {
|
let term = Term::Constant(
|
||||||
let term = Term::Constant(
|
UplcConstant::ProtoList(UplcType::Data, data_constants).into(),
|
||||||
UplcConstant::ProtoPair(
|
);
|
||||||
UplcType::Data,
|
|
||||||
UplcType::Data,
|
|
||||||
data_constants[0].clone().into(),
|
|
||||||
data_constants[1].clone().into(),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
Some(term)
|
|
||||||
} else {
|
|
||||||
let term = Term::Constant(
|
|
||||||
UplcConstant::ProtoList(UplcType::Data, data_constants).into(),
|
|
||||||
);
|
|
||||||
Some(term)
|
|
||||||
}
|
|
||||||
} else if count == 2 {
|
|
||||||
let term = Term::mk_pair_data()
|
|
||||||
.apply(builder::convert_type_to_data(
|
|
||||||
args[0].clone(),
|
|
||||||
&tuple_sub_types[0],
|
|
||||||
))
|
|
||||||
.apply(builder::convert_type_to_data(
|
|
||||||
args[1].clone(),
|
|
||||||
&tuple_sub_types[1],
|
|
||||||
));
|
|
||||||
|
|
||||||
Some(term)
|
Some(term)
|
||||||
} else {
|
} else {
|
||||||
let mut term = Term::empty_list();
|
let mut term = Term::empty_list();
|
||||||
|
@ -5133,6 +5139,38 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Some(term)
|
Some(term)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Air::Pair { tipo } => {
|
||||||
|
let fst = arg_stack.pop().unwrap();
|
||||||
|
let snd = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
match (extract_constant(&fst), extract_constant(&snd)) {
|
||||||
|
(Some(fst), Some(snd)) => {
|
||||||
|
let term = Term::Constant(
|
||||||
|
UplcConstant::ProtoPair(
|
||||||
|
UplcType::Data,
|
||||||
|
UplcType::Data,
|
||||||
|
fst.clone(),
|
||||||
|
snd.clone(),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
Some(term)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let term = Term::mk_pair_data()
|
||||||
|
.apply(builder::convert_type_to_data(
|
||||||
|
fst,
|
||||||
|
&tipo.get_inner_types()[0],
|
||||||
|
))
|
||||||
|
.apply(builder::convert_type_to_data(
|
||||||
|
snd,
|
||||||
|
&tipo.get_inner_types()[1],
|
||||||
|
));
|
||||||
|
|
||||||
|
Some(term)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Air::RecordUpdate {
|
Air::RecordUpdate {
|
||||||
highest_index,
|
highest_index,
|
||||||
indices,
|
indices,
|
||||||
|
@ -5261,67 +5299,75 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let mut term = arg_stack.pop().unwrap();
|
let mut term = arg_stack.pop().unwrap();
|
||||||
let list_id = self.id_gen.next();
|
let list_id = self.id_gen.next();
|
||||||
|
|
||||||
if tipo.is_pair() {
|
let mut id_list = vec![];
|
||||||
assert!(names.len() == 2);
|
id_list.push(list_id);
|
||||||
|
|
||||||
if names[1] != "_" {
|
names.iter().for_each(|_| {
|
||||||
term = term.lambda(names[1].clone()).apply(if is_expect {
|
id_list.push(self.id_gen.next());
|
||||||
convert_data_to_type(
|
});
|
||||||
Term::snd_pair().apply(Term::var(format!("__tuple_{list_id}"))),
|
|
||||||
&inner_types[1],
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
known_data_to_type(
|
|
||||||
Term::snd_pair().apply(Term::var(format!("__tuple_{list_id}"))),
|
|
||||||
&inner_types[1],
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if names[0] != "_" {
|
let names_types = names
|
||||||
term = term.lambda(names[0].clone()).apply(if is_expect {
|
.into_iter()
|
||||||
convert_data_to_type(
|
.zip(inner_types)
|
||||||
Term::fst_pair().apply(Term::var(format!("__tuple_{list_id}"))),
|
.zip(id_list)
|
||||||
&inner_types[0],
|
.map(|((name, tipo), id)| (name, tipo, id))
|
||||||
)
|
.collect_vec();
|
||||||
} else {
|
|
||||||
known_data_to_type(
|
|
||||||
Term::fst_pair().apply(Term::var(format!("__tuple_{list_id}"))),
|
|
||||||
&inner_types[0],
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
term = term.lambda(format!("__tuple_{list_id}")).apply(value);
|
term = builder::list_access_to_uplc(
|
||||||
|
&names_types,
|
||||||
|
false,
|
||||||
|
term,
|
||||||
|
false,
|
||||||
|
is_expect.into(),
|
||||||
|
error_term,
|
||||||
|
)
|
||||||
|
.apply(value);
|
||||||
|
|
||||||
Some(term)
|
Some(term)
|
||||||
} else {
|
}
|
||||||
let mut id_list = vec![];
|
Air::PairAccessor {
|
||||||
id_list.push(list_id);
|
fst,
|
||||||
|
snd,
|
||||||
|
tipo,
|
||||||
|
is_expect,
|
||||||
|
} => {
|
||||||
|
let inner_types = tipo.get_inner_types();
|
||||||
|
let value = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
names.iter().for_each(|_| {
|
let mut term = arg_stack.pop().unwrap();
|
||||||
id_list.push(self.id_gen.next());
|
let list_id = self.id_gen.next();
|
||||||
|
|
||||||
|
if let Some(name) = snd {
|
||||||
|
term = term.lambda(name).apply(if is_expect {
|
||||||
|
convert_data_to_type(
|
||||||
|
Term::snd_pair().apply(Term::var(format!("__pair_{list_id}"))),
|
||||||
|
&inner_types[1],
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
known_data_to_type(
|
||||||
|
Term::snd_pair().apply(Term::var(format!("__pair_{list_id}"))),
|
||||||
|
&inner_types[1],
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let names_types = names
|
|
||||||
.into_iter()
|
|
||||||
.zip(inner_types)
|
|
||||||
.zip(id_list)
|
|
||||||
.map(|((name, tipo), id)| (name, tipo, id))
|
|
||||||
.collect_vec();
|
|
||||||
|
|
||||||
term = builder::list_access_to_uplc(
|
|
||||||
&names_types,
|
|
||||||
false,
|
|
||||||
term,
|
|
||||||
false,
|
|
||||||
is_expect.into(),
|
|
||||||
error_term,
|
|
||||||
)
|
|
||||||
.apply(value);
|
|
||||||
|
|
||||||
Some(term)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(name) = fst {
|
||||||
|
term = term.lambda(name).apply(if is_expect {
|
||||||
|
convert_data_to_type(
|
||||||
|
Term::fst_pair().apply(Term::var(format!("__pair_{list_id}"))),
|
||||||
|
&inner_types[0],
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
known_data_to_type(
|
||||||
|
Term::fst_pair().apply(Term::var(format!("__pair_{list_id}"))),
|
||||||
|
&inner_types[0],
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
term = term.lambda(format!("__pair_{list_id}")).apply(value);
|
||||||
|
|
||||||
|
Some(term)
|
||||||
}
|
}
|
||||||
Air::Trace { .. } => {
|
Air::Trace { .. } => {
|
||||||
let text = arg_stack.pop().unwrap();
|
let text = arg_stack.pop().unwrap();
|
||||||
|
|
|
@ -51,6 +51,9 @@ pub enum Air {
|
||||||
tipo: Rc<Type>,
|
tipo: Rc<Type>,
|
||||||
count: usize,
|
count: usize,
|
||||||
},
|
},
|
||||||
|
Pair {
|
||||||
|
tipo: Rc<Type>,
|
||||||
|
},
|
||||||
Void,
|
Void,
|
||||||
Var {
|
Var {
|
||||||
constructor: ValueConstructor,
|
constructor: ValueConstructor,
|
||||||
|
@ -136,6 +139,13 @@ pub enum Air {
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
complex_clause: bool,
|
complex_clause: bool,
|
||||||
},
|
},
|
||||||
|
PairClause {
|
||||||
|
subject_tipo: Rc<Type>,
|
||||||
|
subject_name: String,
|
||||||
|
fst_name: Option<String>,
|
||||||
|
snd_name: Option<String>,
|
||||||
|
complex_clause: bool,
|
||||||
|
},
|
||||||
ClauseGuard {
|
ClauseGuard {
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
subject_tipo: Rc<Type>,
|
subject_tipo: Rc<Type>,
|
||||||
|
@ -151,6 +161,12 @@ pub enum Air {
|
||||||
indices: IndexSet<(usize, String)>,
|
indices: IndexSet<(usize, String)>,
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
},
|
},
|
||||||
|
PairGuard {
|
||||||
|
subject_tipo: Rc<Type>,
|
||||||
|
subject_name: String,
|
||||||
|
fst_name: Option<String>,
|
||||||
|
snd_name: Option<String>,
|
||||||
|
},
|
||||||
Finally,
|
Finally,
|
||||||
// If
|
// If
|
||||||
If {
|
If {
|
||||||
|
@ -190,6 +206,13 @@ pub enum Air {
|
||||||
tipo: Rc<Type>,
|
tipo: Rc<Type>,
|
||||||
is_expect: bool,
|
is_expect: bool,
|
||||||
},
|
},
|
||||||
|
// Tuple Access
|
||||||
|
PairAccessor {
|
||||||
|
fst: Option<String>,
|
||||||
|
snd: Option<String>,
|
||||||
|
tipo: Rc<Type>,
|
||||||
|
is_expect: bool,
|
||||||
|
},
|
||||||
// Misc.
|
// Misc.
|
||||||
ErrorTerm {
|
ErrorTerm {
|
||||||
tipo: Rc<Type>,
|
tipo: Rc<Type>,
|
||||||
|
|
|
@ -1852,6 +1852,7 @@ pub fn air_holds_msg(air: &Air) -> bool {
|
||||||
|
|
||||||
Air::FieldsExpose { is_expect, .. }
|
Air::FieldsExpose { is_expect, .. }
|
||||||
| Air::TupleAccessor { is_expect, .. }
|
| Air::TupleAccessor { is_expect, .. }
|
||||||
|
| Air::PairAccessor { is_expect, .. }
|
||||||
| Air::CastFromData { is_expect, .. } => *is_expect,
|
| Air::CastFromData { is_expect, .. } => *is_expect,
|
||||||
|
|
||||||
Air::ListAccessor { expect_level, .. } => {
|
Air::ListAccessor { expect_level, .. } => {
|
||||||
|
|
|
@ -162,6 +162,13 @@ pub enum AirTree {
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
then: Box<AirTree>,
|
then: Box<AirTree>,
|
||||||
},
|
},
|
||||||
|
PairGuard {
|
||||||
|
subject_tipo: Rc<Type>,
|
||||||
|
subject_name: String,
|
||||||
|
fst_name: Option<String>,
|
||||||
|
snd_name: Option<String>,
|
||||||
|
then: Box<AirTree>,
|
||||||
|
},
|
||||||
// Field Access
|
// Field Access
|
||||||
FieldsExpose {
|
FieldsExpose {
|
||||||
indices: Vec<(usize, String, Rc<Type>)>,
|
indices: Vec<(usize, String, Rc<Type>)>,
|
||||||
|
@ -195,6 +202,16 @@ pub enum AirTree {
|
||||||
msg: Option<AirMsg>,
|
msg: Option<AirMsg>,
|
||||||
then: Box<AirTree>,
|
then: Box<AirTree>,
|
||||||
},
|
},
|
||||||
|
// Pair Access
|
||||||
|
PairAccessor {
|
||||||
|
fst: Option<String>,
|
||||||
|
snd: Option<String>,
|
||||||
|
tipo: Rc<Type>,
|
||||||
|
is_expect: bool,
|
||||||
|
msg: Option<AirMsg>,
|
||||||
|
pair: Box<AirTree>,
|
||||||
|
then: Box<AirTree>,
|
||||||
|
},
|
||||||
// Misc.
|
// Misc.
|
||||||
FieldsEmpty {
|
FieldsEmpty {
|
||||||
constr: Box<AirTree>,
|
constr: Box<AirTree>,
|
||||||
|
@ -237,6 +254,11 @@ pub enum AirTree {
|
||||||
tipo: Rc<Type>,
|
tipo: Rc<Type>,
|
||||||
items: Vec<AirTree>,
|
items: Vec<AirTree>,
|
||||||
},
|
},
|
||||||
|
Pair {
|
||||||
|
tipo: Rc<Type>,
|
||||||
|
fst: Box<AirTree>,
|
||||||
|
snd: Box<AirTree>,
|
||||||
|
},
|
||||||
Void,
|
Void,
|
||||||
Var {
|
Var {
|
||||||
constructor: ValueConstructor,
|
constructor: ValueConstructor,
|
||||||
|
@ -320,6 +342,16 @@ pub enum AirTree {
|
||||||
otherwise: Box<AirTree>,
|
otherwise: Box<AirTree>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
PairClause {
|
||||||
|
subject_tipo: Rc<Type>,
|
||||||
|
subject_name: String,
|
||||||
|
fst_name: Option<String>,
|
||||||
|
snd_name: Option<String>,
|
||||||
|
complex_clause: bool,
|
||||||
|
then: Box<AirTree>,
|
||||||
|
otherwise: Box<AirTree>,
|
||||||
|
},
|
||||||
|
|
||||||
Finally {
|
Finally {
|
||||||
pattern: Box<AirTree>,
|
pattern: Box<AirTree>,
|
||||||
then: Box<AirTree>,
|
then: Box<AirTree>,
|
||||||
|
@ -363,20 +395,25 @@ impl AirTree {
|
||||||
value: value.to_string(),
|
value: value.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn string(value: impl ToString) -> AirTree {
|
pub fn string(value: impl ToString) -> AirTree {
|
||||||
AirTree::String {
|
AirTree::String {
|
||||||
value: value.to_string(),
|
value: value.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn byte_array(bytes: Vec<u8>) -> AirTree {
|
pub fn byte_array(bytes: Vec<u8>) -> AirTree {
|
||||||
AirTree::ByteArray { bytes }
|
AirTree::ByteArray { bytes }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn curve(point: Curve) -> AirTree {
|
pub fn curve(point: Curve) -> AirTree {
|
||||||
AirTree::CurvePoint { point }
|
AirTree::CurvePoint { point }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bool(value: bool) -> AirTree {
|
pub fn bool(value: bool) -> AirTree {
|
||||||
AirTree::Bool { value }
|
AirTree::Bool { value }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list(mut items: Vec<AirTree>, tipo: Rc<Type>, tail: Option<AirTree>) -> AirTree {
|
pub fn list(mut items: Vec<AirTree>, tipo: Rc<Type>, tail: Option<AirTree>) -> AirTree {
|
||||||
if let Some(tail) = tail {
|
if let Some(tail) = tail {
|
||||||
items.push(tail);
|
items.push(tail);
|
||||||
|
@ -394,12 +431,23 @@ impl AirTree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tuple(items: Vec<AirTree>, tipo: Rc<Type>) -> AirTree {
|
pub fn tuple(items: Vec<AirTree>, tipo: Rc<Type>) -> AirTree {
|
||||||
AirTree::Tuple { tipo, items }
|
AirTree::Tuple { tipo, items }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pair(fst: AirTree, snd: AirTree, tipo: Rc<Type>) -> AirTree {
|
||||||
|
AirTree::Pair {
|
||||||
|
tipo,
|
||||||
|
fst: fst.into(),
|
||||||
|
snd: snd.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn void() -> AirTree {
|
pub fn void() -> AirTree {
|
||||||
AirTree::Void
|
AirTree::Void
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn var(
|
pub fn var(
|
||||||
constructor: ValueConstructor,
|
constructor: ValueConstructor,
|
||||||
name: impl ToString,
|
name: impl ToString,
|
||||||
|
@ -411,6 +459,7 @@ impl AirTree {
|
||||||
variant_name: variant_name.to_string(),
|
variant_name: variant_name.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn local_var(name: impl ToString, tipo: Rc<Type>) -> AirTree {
|
pub fn local_var(name: impl ToString, tipo: Rc<Type>) -> AirTree {
|
||||||
AirTree::Var {
|
AirTree::Var {
|
||||||
constructor: ValueConstructor::public(
|
constructor: ValueConstructor::public(
|
||||||
|
@ -423,6 +472,7 @@ impl AirTree {
|
||||||
variant_name: "".to_string(),
|
variant_name: "".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call(func: AirTree, tipo: Rc<Type>, args: Vec<AirTree>) -> AirTree {
|
pub fn call(func: AirTree, tipo: Rc<Type>, args: Vec<AirTree>) -> AirTree {
|
||||||
AirTree::Call {
|
AirTree::Call {
|
||||||
tipo,
|
tipo,
|
||||||
|
@ -453,6 +503,7 @@ impl AirTree {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn define_cyclic_func(
|
pub fn define_cyclic_func(
|
||||||
func_name: impl ToString,
|
func_name: impl ToString,
|
||||||
module_name: impl ToString,
|
module_name: impl ToString,
|
||||||
|
@ -468,15 +519,18 @@ impl AirTree {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn anon_func(params: Vec<String>, func_body: AirTree) -> AirTree {
|
pub fn anon_func(params: Vec<String>, func_body: AirTree) -> AirTree {
|
||||||
AirTree::Fn {
|
AirTree::Fn {
|
||||||
params,
|
params,
|
||||||
func_body: func_body.into(),
|
func_body: func_body.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn builtin(func: DefaultFunction, tipo: Rc<Type>, args: Vec<AirTree>) -> AirTree {
|
pub fn builtin(func: DefaultFunction, tipo: Rc<Type>, args: Vec<AirTree>) -> AirTree {
|
||||||
AirTree::Builtin { func, tipo, args }
|
AirTree::Builtin { func, tipo, args }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn binop(
|
pub fn binop(
|
||||||
op: BinOp,
|
op: BinOp,
|
||||||
tipo: Rc<Type>,
|
tipo: Rc<Type>,
|
||||||
|
@ -492,12 +546,14 @@ impl AirTree {
|
||||||
argument_tipo,
|
argument_tipo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unop(op: UnOp, arg: AirTree) -> AirTree {
|
pub fn unop(op: UnOp, arg: AirTree) -> AirTree {
|
||||||
AirTree::UnOp {
|
AirTree::UnOp {
|
||||||
op,
|
op,
|
||||||
arg: arg.into(),
|
arg: arg.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn let_assignment(name: impl ToString, value: AirTree, then: AirTree) -> AirTree {
|
pub fn let_assignment(name: impl ToString, value: AirTree, then: AirTree) -> AirTree {
|
||||||
AirTree::Let {
|
AirTree::Let {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
|
@ -505,6 +561,7 @@ impl AirTree {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cast_from_data(value: AirTree, tipo: Rc<Type>, msg: Option<AirMsg>) -> AirTree {
|
pub fn cast_from_data(value: AirTree, tipo: Rc<Type>, msg: Option<AirMsg>) -> AirTree {
|
||||||
AirTree::CastFromData {
|
AirTree::CastFromData {
|
||||||
tipo,
|
tipo,
|
||||||
|
@ -512,12 +569,14 @@ impl AirTree {
|
||||||
msg,
|
msg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cast_to_data(value: AirTree, tipo: Rc<Type>) -> AirTree {
|
pub fn cast_to_data(value: AirTree, tipo: Rc<Type>) -> AirTree {
|
||||||
AirTree::CastToData {
|
AirTree::CastToData {
|
||||||
tipo,
|
tipo,
|
||||||
value: value.into(),
|
value: value.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assert_constr_index(
|
pub fn assert_constr_index(
|
||||||
constr_index: usize,
|
constr_index: usize,
|
||||||
constr: AirTree,
|
constr: AirTree,
|
||||||
|
@ -531,6 +590,7 @@ impl AirTree {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assert_bool(
|
pub fn assert_bool(
|
||||||
is_true: bool,
|
is_true: bool,
|
||||||
value: AirTree,
|
value: AirTree,
|
||||||
|
@ -544,6 +604,7 @@ impl AirTree {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn when(
|
pub fn when(
|
||||||
subject_name: impl ToString,
|
subject_name: impl ToString,
|
||||||
tipo: Rc<Type>,
|
tipo: Rc<Type>,
|
||||||
|
@ -559,6 +620,7 @@ impl AirTree {
|
||||||
clauses: clauses.into(),
|
clauses: clauses.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clause(
|
pub fn clause(
|
||||||
subject_name: impl ToString,
|
subject_name: impl ToString,
|
||||||
pattern: AirTree,
|
pattern: AirTree,
|
||||||
|
@ -576,6 +638,7 @@ impl AirTree {
|
||||||
otherwise: otherwise.into(),
|
otherwise: otherwise.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_clause(
|
pub fn list_clause(
|
||||||
tail_name: impl ToString,
|
tail_name: impl ToString,
|
||||||
subject_tipo: Rc<Type>,
|
subject_tipo: Rc<Type>,
|
||||||
|
@ -593,6 +656,7 @@ impl AirTree {
|
||||||
otherwise: otherwise.into(),
|
otherwise: otherwise.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tuple_clause(
|
pub fn tuple_clause(
|
||||||
subject_name: impl ToString,
|
subject_name: impl ToString,
|
||||||
subject_tipo: Rc<Type>,
|
subject_tipo: Rc<Type>,
|
||||||
|
@ -612,12 +676,34 @@ impl AirTree {
|
||||||
otherwise: otherwise.into(),
|
otherwise: otherwise.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pair_clause(
|
||||||
|
subject_name: impl ToString,
|
||||||
|
subject_tipo: Rc<Type>,
|
||||||
|
fst_name: Option<String>,
|
||||||
|
snd_name: Option<String>,
|
||||||
|
then: AirTree,
|
||||||
|
otherwise: AirTree,
|
||||||
|
complex_clause: bool,
|
||||||
|
) -> AirTree {
|
||||||
|
AirTree::PairClause {
|
||||||
|
subject_tipo,
|
||||||
|
subject_name: subject_name.to_string(),
|
||||||
|
fst_name,
|
||||||
|
snd_name,
|
||||||
|
complex_clause,
|
||||||
|
then: then.into(),
|
||||||
|
otherwise: otherwise.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn wrap_clause(then: AirTree, otherwise: AirTree) -> AirTree {
|
pub fn wrap_clause(then: AirTree, otherwise: AirTree) -> AirTree {
|
||||||
AirTree::WrapClause {
|
AirTree::WrapClause {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
otherwise: otherwise.into(),
|
otherwise: otherwise.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clause_guard(
|
pub fn clause_guard(
|
||||||
subject_name: impl ToString,
|
subject_name: impl ToString,
|
||||||
pattern: AirTree,
|
pattern: AirTree,
|
||||||
|
@ -631,6 +717,7 @@ impl AirTree {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_clause_guard(
|
pub fn list_clause_guard(
|
||||||
tail_name: impl ToString,
|
tail_name: impl ToString,
|
||||||
subject_tipo: Rc<Type>,
|
subject_tipo: Rc<Type>,
|
||||||
|
@ -646,6 +733,7 @@ impl AirTree {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tuple_clause_guard(
|
pub fn tuple_clause_guard(
|
||||||
subject_name: impl ToString,
|
subject_name: impl ToString,
|
||||||
subject_tipo: Rc<Type>,
|
subject_tipo: Rc<Type>,
|
||||||
|
@ -659,12 +747,30 @@ impl AirTree {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pair_clause_guard(
|
||||||
|
subject_name: impl ToString,
|
||||||
|
subject_tipo: Rc<Type>,
|
||||||
|
fst_name: Option<String>,
|
||||||
|
snd_name: Option<String>,
|
||||||
|
then: AirTree,
|
||||||
|
) -> AirTree {
|
||||||
|
AirTree::PairGuard {
|
||||||
|
subject_name: subject_name.to_string(),
|
||||||
|
subject_tipo,
|
||||||
|
fst_name,
|
||||||
|
snd_name,
|
||||||
|
then: then.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn finally(pattern: AirTree, then: AirTree) -> AirTree {
|
pub fn finally(pattern: AirTree, then: AirTree) -> AirTree {
|
||||||
AirTree::Finally {
|
AirTree::Finally {
|
||||||
pattern: pattern.into(),
|
pattern: pattern.into(),
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn if_branches(
|
pub fn if_branches(
|
||||||
mut branches: Vec<(AirTree, AirTree)>,
|
mut branches: Vec<(AirTree, AirTree)>,
|
||||||
tipo: Rc<Type>,
|
tipo: Rc<Type>,
|
||||||
|
@ -691,6 +797,7 @@ impl AirTree {
|
||||||
|
|
||||||
final_if
|
final_if
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_constr(tag: usize, tipo: Rc<Type>, args: Vec<AirTree>) -> AirTree {
|
pub fn create_constr(tag: usize, tipo: Rc<Type>, args: Vec<AirTree>) -> AirTree {
|
||||||
AirTree::Constr { tag, tipo, args }
|
AirTree::Constr { tag, tipo, args }
|
||||||
}
|
}
|
||||||
|
@ -710,6 +817,7 @@ impl AirTree {
|
||||||
args,
|
args,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn index_access(function_name: String, tipo: Rc<Type>, list_of_fields: AirTree) -> AirTree {
|
pub fn index_access(function_name: String, tipo: Rc<Type>, list_of_fields: AirTree) -> AirTree {
|
||||||
AirTree::cast_from_data(
|
AirTree::cast_from_data(
|
||||||
AirTree::call(
|
AirTree::call(
|
||||||
|
@ -740,6 +848,7 @@ impl AirTree {
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fields_expose(
|
pub fn fields_expose(
|
||||||
indices: Vec<(usize, String, Rc<Type>)>,
|
indices: Vec<(usize, String, Rc<Type>)>,
|
||||||
record: AirTree,
|
record: AirTree,
|
||||||
|
@ -775,6 +884,7 @@ impl AirTree {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_expose(
|
pub fn list_expose(
|
||||||
tail_head_names: Vec<(String, String)>,
|
tail_head_names: Vec<(String, String)>,
|
||||||
tail: Option<(String, String)>,
|
tail: Option<(String, String)>,
|
||||||
|
@ -788,6 +898,7 @@ impl AirTree {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tuple_access(
|
pub fn tuple_access(
|
||||||
names: Vec<String>,
|
names: Vec<String>,
|
||||||
tipo: Rc<Type>,
|
tipo: Rc<Type>,
|
||||||
|
@ -805,6 +916,27 @@ impl AirTree {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pair_access(
|
||||||
|
fst: Option<String>,
|
||||||
|
snd: Option<String>,
|
||||||
|
tipo: Rc<Type>,
|
||||||
|
pair: AirTree,
|
||||||
|
msg: Option<AirMsg>,
|
||||||
|
is_expect: bool,
|
||||||
|
then: AirTree,
|
||||||
|
) -> AirTree {
|
||||||
|
AirTree::PairAccessor {
|
||||||
|
fst,
|
||||||
|
snd,
|
||||||
|
tipo,
|
||||||
|
is_expect,
|
||||||
|
msg,
|
||||||
|
pair: pair.into(),
|
||||||
|
then: then.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn pair_index(index: usize, tipo: Rc<Type>, tuple: AirTree) -> AirTree {
|
pub fn pair_index(index: usize, tipo: Rc<Type>, tuple: AirTree) -> AirTree {
|
||||||
AirTree::cast_from_data(
|
AirTree::cast_from_data(
|
||||||
AirTree::builtin(
|
AirTree::builtin(
|
||||||
|
@ -820,9 +952,11 @@ impl AirTree {
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error(tipo: Rc<Type>, validator: bool) -> AirTree {
|
pub fn error(tipo: Rc<Type>, validator: bool) -> AirTree {
|
||||||
AirTree::ErrorTerm { tipo, validator }
|
AirTree::ErrorTerm { tipo, validator }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trace(msg: AirTree, tipo: Rc<Type>, then: AirTree) -> AirTree {
|
pub fn trace(msg: AirTree, tipo: Rc<Type>, then: AirTree) -> AirTree {
|
||||||
AirTree::Trace {
|
AirTree::Trace {
|
||||||
tipo,
|
tipo,
|
||||||
|
@ -840,6 +974,7 @@ impl AirTree {
|
||||||
pub fn no_op(then: AirTree) -> AirTree {
|
pub fn no_op(then: AirTree) -> AirTree {
|
||||||
AirTree::NoOp { then: then.into() }
|
AirTree::NoOp { then: then.into() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fields_empty(constr: AirTree, msg: Option<AirMsg>, then: AirTree) -> AirTree {
|
pub fn fields_empty(constr: AirTree, msg: Option<AirMsg>, then: AirTree) -> AirTree {
|
||||||
AirTree::FieldsEmpty {
|
AirTree::FieldsEmpty {
|
||||||
constr: constr.into(),
|
constr: constr.into(),
|
||||||
|
@ -847,6 +982,7 @@ impl AirTree {
|
||||||
then: then.into(),
|
then: then.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_empty(list: AirTree, msg: Option<AirMsg>, then: AirTree) -> AirTree {
|
pub fn list_empty(list: AirTree, msg: Option<AirMsg>, then: AirTree) -> AirTree {
|
||||||
AirTree::ListEmpty {
|
AirTree::ListEmpty {
|
||||||
list: list.into(),
|
list: list.into(),
|
||||||
|
@ -1058,6 +1194,21 @@ impl AirTree {
|
||||||
});
|
});
|
||||||
then.create_air_vec(air_vec);
|
then.create_air_vec(air_vec);
|
||||||
}
|
}
|
||||||
|
AirTree::PairGuard {
|
||||||
|
subject_tipo,
|
||||||
|
subject_name,
|
||||||
|
fst_name,
|
||||||
|
snd_name,
|
||||||
|
then,
|
||||||
|
} => {
|
||||||
|
air_vec.push(Air::PairGuard {
|
||||||
|
subject_tipo: subject_tipo.clone(),
|
||||||
|
subject_name: subject_name.clone(),
|
||||||
|
fst_name: fst_name.clone(),
|
||||||
|
snd_name: snd_name.clone(),
|
||||||
|
});
|
||||||
|
then.create_air_vec(air_vec);
|
||||||
|
}
|
||||||
AirTree::FieldsExpose {
|
AirTree::FieldsExpose {
|
||||||
indices,
|
indices,
|
||||||
record,
|
record,
|
||||||
|
@ -1134,6 +1285,29 @@ impl AirTree {
|
||||||
tuple.create_air_vec(air_vec);
|
tuple.create_air_vec(air_vec);
|
||||||
then.create_air_vec(air_vec);
|
then.create_air_vec(air_vec);
|
||||||
}
|
}
|
||||||
|
AirTree::PairAccessor {
|
||||||
|
fst,
|
||||||
|
snd,
|
||||||
|
tipo,
|
||||||
|
is_expect,
|
||||||
|
msg,
|
||||||
|
pair,
|
||||||
|
then,
|
||||||
|
} => {
|
||||||
|
air_vec.push(Air::PairAccessor {
|
||||||
|
fst: fst.clone(),
|
||||||
|
snd: snd.clone(),
|
||||||
|
tipo: tipo.clone(),
|
||||||
|
is_expect: *is_expect,
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(msg) = msg {
|
||||||
|
msg.to_air_tree().create_air_vec(air_vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
pair.create_air_vec(air_vec);
|
||||||
|
then.create_air_vec(air_vec);
|
||||||
|
}
|
||||||
AirTree::FieldsEmpty { constr, msg, then } => {
|
AirTree::FieldsEmpty { constr, msg, then } => {
|
||||||
air_vec.push(Air::FieldsEmpty);
|
air_vec.push(Air::FieldsEmpty);
|
||||||
|
|
||||||
|
@ -1189,6 +1363,11 @@ impl AirTree {
|
||||||
item.create_air_vec(air_vec);
|
item.create_air_vec(air_vec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AirTree::Pair { tipo, fst, snd } => {
|
||||||
|
air_vec.push(Air::Pair { tipo: tipo.clone() });
|
||||||
|
fst.create_air_vec(air_vec);
|
||||||
|
snd.create_air_vec(air_vec);
|
||||||
|
}
|
||||||
AirTree::Void => air_vec.push(Air::Void),
|
AirTree::Void => air_vec.push(Air::Void),
|
||||||
AirTree::Var {
|
AirTree::Var {
|
||||||
constructor,
|
constructor,
|
||||||
|
@ -1334,6 +1513,25 @@ impl AirTree {
|
||||||
then.create_air_vec(air_vec);
|
then.create_air_vec(air_vec);
|
||||||
otherwise.create_air_vec(air_vec);
|
otherwise.create_air_vec(air_vec);
|
||||||
}
|
}
|
||||||
|
AirTree::PairClause {
|
||||||
|
subject_tipo,
|
||||||
|
subject_name,
|
||||||
|
fst_name,
|
||||||
|
snd_name,
|
||||||
|
complex_clause,
|
||||||
|
then,
|
||||||
|
otherwise,
|
||||||
|
} => {
|
||||||
|
air_vec.push(Air::PairClause {
|
||||||
|
subject_tipo: subject_tipo.clone(),
|
||||||
|
subject_name: subject_name.clone(),
|
||||||
|
fst_name: fst_name.clone(),
|
||||||
|
snd_name: snd_name.clone(),
|
||||||
|
complex_clause: *complex_clause,
|
||||||
|
});
|
||||||
|
then.create_air_vec(air_vec);
|
||||||
|
otherwise.create_air_vec(air_vec);
|
||||||
|
}
|
||||||
AirTree::Finally { pattern, then } => {
|
AirTree::Finally { pattern, then } => {
|
||||||
air_vec.push(Air::Finally);
|
air_vec.push(Air::Finally);
|
||||||
pattern.create_air_vec(air_vec);
|
pattern.create_air_vec(air_vec);
|
||||||
|
@ -1398,6 +1596,7 @@ impl AirTree {
|
||||||
AirTree::CurvePoint { point } => point.tipo(),
|
AirTree::CurvePoint { point } => point.tipo(),
|
||||||
AirTree::List { tipo, .. }
|
AirTree::List { tipo, .. }
|
||||||
| AirTree::Tuple { tipo, .. }
|
| AirTree::Tuple { tipo, .. }
|
||||||
|
| AirTree::Pair { tipo, .. }
|
||||||
| AirTree::Call { tipo, .. }
|
| AirTree::Call { tipo, .. }
|
||||||
| AirTree::Builtin { tipo, .. }
|
| AirTree::Builtin { tipo, .. }
|
||||||
| AirTree::BinOp { tipo, .. }
|
| AirTree::BinOp { tipo, .. }
|
||||||
|
@ -1420,6 +1619,7 @@ impl AirTree {
|
||||||
| AirTree::ListClause { then, .. }
|
| AirTree::ListClause { then, .. }
|
||||||
| AirTree::WrapClause { then, .. }
|
| AirTree::WrapClause { then, .. }
|
||||||
| AirTree::TupleClause { then, .. }
|
| AirTree::TupleClause { then, .. }
|
||||||
|
| AirTree::PairClause { then, .. }
|
||||||
| AirTree::Finally { then, .. }
|
| AirTree::Finally { then, .. }
|
||||||
| AirTree::Let { then, .. }
|
| AirTree::Let { then, .. }
|
||||||
| AirTree::DefineFunc { then, .. }
|
| AirTree::DefineFunc { then, .. }
|
||||||
|
@ -1429,10 +1629,12 @@ impl AirTree {
|
||||||
| AirTree::ClauseGuard { then, .. }
|
| AirTree::ClauseGuard { then, .. }
|
||||||
| AirTree::ListClauseGuard { then, .. }
|
| AirTree::ListClauseGuard { then, .. }
|
||||||
| AirTree::TupleGuard { then, .. }
|
| AirTree::TupleGuard { then, .. }
|
||||||
|
| AirTree::PairGuard { then, .. }
|
||||||
| AirTree::FieldsExpose { then, .. }
|
| AirTree::FieldsExpose { then, .. }
|
||||||
| AirTree::ListAccessor { then, .. }
|
| AirTree::ListAccessor { then, .. }
|
||||||
| AirTree::ListExpose { then, .. }
|
| AirTree::ListExpose { then, .. }
|
||||||
| AirTree::TupleAccessor { then, .. }
|
| AirTree::TupleAccessor { then, .. }
|
||||||
|
| AirTree::PairAccessor { then, .. }
|
||||||
| AirTree::FieldsEmpty { then, .. }
|
| AirTree::FieldsEmpty { then, .. }
|
||||||
| AirTree::ListEmpty { then, .. }
|
| AirTree::ListEmpty { then, .. }
|
||||||
| AirTree::NoOp { then } => then.return_type(),
|
| AirTree::NoOp { then } => then.return_type(),
|
||||||
|
@ -1525,7 +1727,8 @@ impl AirTree {
|
||||||
tree_path.push(current_depth, depth_index);
|
tree_path.push(current_depth, depth_index);
|
||||||
let mut tuple_then_index = None;
|
let mut tuple_then_index = None;
|
||||||
|
|
||||||
// Assignments/Statements get traversed here
|
// Assignments'/Statements' values get traversed here
|
||||||
|
// Then the body under these assignments/statements get traversed later on
|
||||||
match self {
|
match self {
|
||||||
AirTree::Let { value, .. } => {
|
AirTree::Let { value, .. } => {
|
||||||
value.do_traverse_tree_with(
|
value.do_traverse_tree_with(
|
||||||
|
@ -1592,6 +1795,15 @@ impl AirTree {
|
||||||
apply_with_func_last,
|
apply_with_func_last,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
AirTree::PairAccessor { pair, .. } => {
|
||||||
|
pair.do_traverse_tree_with(
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next_number(),
|
||||||
|
with,
|
||||||
|
apply_with_func_last,
|
||||||
|
);
|
||||||
|
}
|
||||||
AirTree::FieldsEmpty { constr, .. } => {
|
AirTree::FieldsEmpty { constr, .. } => {
|
||||||
constr.do_traverse_tree_with(
|
constr.do_traverse_tree_with(
|
||||||
tree_path,
|
tree_path,
|
||||||
|
@ -1629,7 +1841,49 @@ impl AirTree {
|
||||||
apply_with_func_last,
|
apply_with_func_last,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {}
|
AirTree::PairClause { otherwise, .. } => {
|
||||||
|
tuple_then_index = Some(index_count.next_number());
|
||||||
|
otherwise.do_traverse_tree_with(
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next_number(),
|
||||||
|
with,
|
||||||
|
apply_with_func_last,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
AirTree::DefineFunc { .. }
|
||||||
|
| AirTree::DefineCyclicFuncs { .. }
|
||||||
|
| AirTree::ListClauseGuard { .. }
|
||||||
|
| AirTree::TupleGuard { .. }
|
||||||
|
| AirTree::PairGuard { .. }
|
||||||
|
| AirTree::ListExpose { .. }
|
||||||
|
| AirTree::NoOp { .. }
|
||||||
|
| AirTree::Int { .. }
|
||||||
|
| AirTree::String { .. }
|
||||||
|
| AirTree::ByteArray { .. }
|
||||||
|
| AirTree::CurvePoint { .. }
|
||||||
|
| AirTree::Bool { .. }
|
||||||
|
| AirTree::List { .. }
|
||||||
|
| AirTree::Tuple { .. }
|
||||||
|
| AirTree::Pair { .. }
|
||||||
|
| AirTree::Void
|
||||||
|
| AirTree::Var { .. }
|
||||||
|
| AirTree::Call { .. }
|
||||||
|
| AirTree::Fn { .. }
|
||||||
|
| AirTree::Builtin { .. }
|
||||||
|
| AirTree::BinOp { .. }
|
||||||
|
| AirTree::UnOp { .. }
|
||||||
|
| AirTree::CastFromData { .. }
|
||||||
|
| AirTree::CastToData { .. }
|
||||||
|
| AirTree::Clause { .. }
|
||||||
|
| AirTree::ListClause { .. }
|
||||||
|
| AirTree::WrapClause { .. }
|
||||||
|
| AirTree::Finally { .. }
|
||||||
|
| AirTree::If { .. }
|
||||||
|
| AirTree::Constr { .. }
|
||||||
|
| AirTree::RecordUpdate { .. }
|
||||||
|
| AirTree::ErrorTerm { .. }
|
||||||
|
| AirTree::Trace { .. } => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !apply_with_func_last {
|
if !apply_with_func_last {
|
||||||
|
@ -1645,11 +1899,13 @@ impl AirTree {
|
||||||
| AirTree::FieldsExpose { then, .. }
|
| AirTree::FieldsExpose { then, .. }
|
||||||
| AirTree::ListAccessor { then, .. }
|
| AirTree::ListAccessor { then, .. }
|
||||||
| AirTree::TupleAccessor { then, .. }
|
| AirTree::TupleAccessor { then, .. }
|
||||||
|
| AirTree::PairAccessor { then, .. }
|
||||||
| AirTree::FieldsEmpty { then, .. }
|
| AirTree::FieldsEmpty { then, .. }
|
||||||
| AirTree::ListEmpty { then, .. }
|
| AirTree::ListEmpty { then, .. }
|
||||||
| AirTree::ListExpose { then, .. }
|
| AirTree::ListExpose { then, .. }
|
||||||
| AirTree::ListClauseGuard { then, .. }
|
| AirTree::ListClauseGuard { then, .. }
|
||||||
| AirTree::TupleGuard { then, .. }
|
| AirTree::TupleGuard { then, .. }
|
||||||
|
| AirTree::PairGuard { then, .. }
|
||||||
| AirTree::NoOp { then } => {
|
| AirTree::NoOp { then } => {
|
||||||
then.do_traverse_tree_with(
|
then.do_traverse_tree_with(
|
||||||
tree_path,
|
tree_path,
|
||||||
|
@ -1681,6 +1937,19 @@ impl AirTree {
|
||||||
apply_with_func_last,
|
apply_with_func_last,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
AirTree::PairClause { then, .. } => {
|
||||||
|
let Some(index) = tuple_then_index else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
then.do_traverse_tree_with(
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index,
|
||||||
|
with,
|
||||||
|
apply_with_func_last,
|
||||||
|
);
|
||||||
|
}
|
||||||
AirTree::List { items, .. } => {
|
AirTree::List { items, .. } => {
|
||||||
for item in items {
|
for item in items {
|
||||||
item.do_traverse_tree_with(
|
item.do_traverse_tree_with(
|
||||||
|
@ -1703,6 +1972,23 @@ impl AirTree {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AirTree::Pair { fst, snd, .. } => {
|
||||||
|
fst.do_traverse_tree_with(
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next_number(),
|
||||||
|
with,
|
||||||
|
apply_with_func_last,
|
||||||
|
);
|
||||||
|
|
||||||
|
snd.do_traverse_tree_with(
|
||||||
|
tree_path,
|
||||||
|
current_depth + 1,
|
||||||
|
index_count.next_number(),
|
||||||
|
with,
|
||||||
|
apply_with_func_last,
|
||||||
|
);
|
||||||
|
}
|
||||||
AirTree::Call { func, args, .. } => {
|
AirTree::Call { func, args, .. } => {
|
||||||
func.do_traverse_tree_with(
|
func.do_traverse_tree_with(
|
||||||
tree_path,
|
tree_path,
|
||||||
|
@ -2071,6 +2357,13 @@ impl AirTree {
|
||||||
panic!("Tree Path index outside tree children nodes")
|
panic!("Tree Path index outside tree children nodes")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AirTree::PairGuard { then, .. } => {
|
||||||
|
if *index == 0 {
|
||||||
|
then.as_mut().do_find_air_tree_node(tree_path_iter)
|
||||||
|
} else {
|
||||||
|
panic!("Tree Path index outside tree children nodes")
|
||||||
|
}
|
||||||
|
}
|
||||||
AirTree::FieldsExpose { record, then, .. } => {
|
AirTree::FieldsExpose { record, then, .. } => {
|
||||||
if *index == 0 {
|
if *index == 0 {
|
||||||
record.as_mut().do_find_air_tree_node(tree_path_iter)
|
record.as_mut().do_find_air_tree_node(tree_path_iter)
|
||||||
|
@ -2105,6 +2398,15 @@ impl AirTree {
|
||||||
panic!("Tree Path index outside tree children nodes")
|
panic!("Tree Path index outside tree children nodes")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AirTree::PairAccessor { pair, then, .. } => {
|
||||||
|
if *index == 0 {
|
||||||
|
pair.as_mut().do_find_air_tree_node(tree_path_iter)
|
||||||
|
} else if *index == 1 {
|
||||||
|
then.as_mut().do_find_air_tree_node(tree_path_iter)
|
||||||
|
} else {
|
||||||
|
panic!("Tree Path index outside tree children nodes")
|
||||||
|
}
|
||||||
|
}
|
||||||
AirTree::NoOp { then } => {
|
AirTree::NoOp { then } => {
|
||||||
if *index == 0 {
|
if *index == 0 {
|
||||||
then.as_mut().do_find_air_tree_node(tree_path_iter)
|
then.as_mut().do_find_air_tree_node(tree_path_iter)
|
||||||
|
@ -2112,8 +2414,7 @@ impl AirTree {
|
||||||
panic!("Tree Path index outside tree children nodes")
|
panic!("Tree Path index outside tree children nodes")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AirTree::DefineFunc { .. } => unreachable!(),
|
AirTree::DefineFunc { .. } | AirTree::DefineCyclicFuncs { .. } => unreachable!(),
|
||||||
AirTree::DefineCyclicFuncs { .. } => unreachable!(),
|
|
||||||
AirTree::FieldsEmpty { constr, then, .. } => {
|
AirTree::FieldsEmpty { constr, then, .. } => {
|
||||||
if *index == 0 {
|
if *index == 0 {
|
||||||
constr.as_mut().do_find_air_tree_node(tree_path_iter)
|
constr.as_mut().do_find_air_tree_node(tree_path_iter)
|
||||||
|
@ -2140,6 +2441,15 @@ impl AirTree {
|
||||||
.expect("Tree Path index outside tree children nodes");
|
.expect("Tree Path index outside tree children nodes");
|
||||||
item.do_find_air_tree_node(tree_path_iter)
|
item.do_find_air_tree_node(tree_path_iter)
|
||||||
}
|
}
|
||||||
|
AirTree::Pair { fst, snd, .. } => {
|
||||||
|
if *index == 0 {
|
||||||
|
fst.as_mut().do_find_air_tree_node(tree_path_iter)
|
||||||
|
} else if *index == 1 {
|
||||||
|
snd.as_mut().do_find_air_tree_node(tree_path_iter)
|
||||||
|
} else {
|
||||||
|
panic!("Tree Path index outside tree children nodes")
|
||||||
|
}
|
||||||
|
}
|
||||||
AirTree::Call { func, args, .. } => {
|
AirTree::Call { func, args, .. } => {
|
||||||
children_nodes.push(func.as_mut());
|
children_nodes.push(func.as_mut());
|
||||||
children_nodes.extend(args.iter_mut());
|
children_nodes.extend(args.iter_mut());
|
||||||
|
@ -2243,6 +2553,17 @@ impl AirTree {
|
||||||
panic!("Tree Path index outside tree children nodes")
|
panic!("Tree Path index outside tree children nodes")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AirTree::PairClause {
|
||||||
|
then, otherwise, ..
|
||||||
|
} => {
|
||||||
|
if *index == 0 {
|
||||||
|
then.as_mut().do_find_air_tree_node(tree_path_iter)
|
||||||
|
} else if *index == 1 {
|
||||||
|
otherwise.as_mut().do_find_air_tree_node(tree_path_iter)
|
||||||
|
} else {
|
||||||
|
panic!("Tree Path index outside tree children nodes")
|
||||||
|
}
|
||||||
|
}
|
||||||
AirTree::Finally { pattern, then } => {
|
AirTree::Finally { pattern, then } => {
|
||||||
if *index == 0 {
|
if *index == 0 {
|
||||||
pattern.as_mut().do_find_air_tree_node(tree_path_iter)
|
pattern.as_mut().do_find_air_tree_node(tree_path_iter)
|
||||||
|
@ -2291,7 +2612,15 @@ impl AirTree {
|
||||||
panic!("Tree Path index outside tree children nodes")
|
panic!("Tree Path index outside tree children nodes")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
|
||||||
|
AirTree::Int { .. }
|
||||||
|
| AirTree::String { .. }
|
||||||
|
| AirTree::ByteArray { .. }
|
||||||
|
| AirTree::CurvePoint { .. }
|
||||||
|
| AirTree::Bool { .. }
|
||||||
|
| AirTree::Void
|
||||||
|
| AirTree::Var { .. }
|
||||||
|
| AirTree::ErrorTerm { .. } => {
|
||||||
panic!("A tree node with no children was encountered with a longer tree path.")
|
panic!("A tree node with no children was encountered with a longer tree path.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -453,6 +453,12 @@ impl Type {
|
||||||
Self::Var { tipo, .. } => tipo.borrow().get_inner_types(),
|
Self::Var { tipo, .. } => tipo.borrow().get_inner_types(),
|
||||||
_ => vec![],
|
_ => vec![],
|
||||||
}
|
}
|
||||||
|
} else if self.is_pair() {
|
||||||
|
match self {
|
||||||
|
Self::Pair { fst, snd, .. } => vec![fst.clone(), snd.clone()],
|
||||||
|
Self::Var { tipo, .. } => tipo.borrow().get_inner_types(),
|
||||||
|
_ => vec![],
|
||||||
|
}
|
||||||
} else if matches!(self.get_uplc_type(), UplcType::Data) {
|
} else if matches!(self.get_uplc_type(), UplcType::Data) {
|
||||||
match self {
|
match self {
|
||||||
Type::App { args, .. } => args.clone(),
|
Type::App { args, .. } => args.clone(),
|
||||||
|
|
Loading…
Reference in New Issue