checkpoint
This commit is contained in:
parent
b7d506a8db
commit
a08c615da4
|
@ -140,8 +140,8 @@ pub enum Air {
|
||||||
TupleClause {
|
TupleClause {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
indices: HashSet<(u64, String)>,
|
indices: HashSet<(usize, String)>,
|
||||||
predefined_indices: HashSet<(u64, String)>,
|
predefined_indices: HashSet<(usize, String)>,
|
||||||
subject_name: String,
|
subject_name: String,
|
||||||
count: usize,
|
count: usize,
|
||||||
complex_clause: bool,
|
complex_clause: bool,
|
||||||
|
|
|
@ -69,7 +69,7 @@ pub enum ClauseProperties {
|
||||||
needs_constr_var: bool,
|
needs_constr_var: bool,
|
||||||
is_complex_clause: bool,
|
is_complex_clause: bool,
|
||||||
original_subject_name: String,
|
original_subject_name: String,
|
||||||
defined_tuple_indices: HashSet<(u64, String)>,
|
defined_tuple_indices: HashSet<(usize, String)>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
use std::{collections::HashMap, ops::Deref, sync::Arc, vec};
|
use std::{
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
ops::Deref,
|
||||||
|
sync::Arc,
|
||||||
|
vec,
|
||||||
|
};
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use uplc::{
|
use uplc::{
|
||||||
ast::{
|
ast::{
|
||||||
builder::{
|
builder::{
|
||||||
self, choose_list, constr_index_exposer, delayed_choose_list, delayed_if_else, if_else,
|
self, apply_wrap, choose_list, constr_index_exposer, delayed_choose_list,
|
||||||
CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD,
|
delayed_if_else, if_else, CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD,
|
||||||
},
|
},
|
||||||
Constant as UplcConstant, Name, NamedDeBruijn, Program, Term, Type as UplcType,
|
Constant as UplcConstant, Name, NamedDeBruijn, Program, Term, Type as UplcType,
|
||||||
},
|
},
|
||||||
|
@ -81,9 +86,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let scope = vec![self.id_gen.next()];
|
let scope = vec![self.id_gen.next()];
|
||||||
|
|
||||||
self.build_ir(&body, &mut ir_stack, scope);
|
self.build_ir(&body, &mut ir_stack, scope);
|
||||||
|
println!("{ir_stack:#?}");
|
||||||
|
|
||||||
self.define_ir(&mut ir_stack);
|
self.define_ir(&mut ir_stack);
|
||||||
|
|
||||||
|
println!("{ir_stack:#?}");
|
||||||
let mut term = self.uplc_code_gen(&mut ir_stack);
|
let mut term = self.uplc_code_gen(&mut ir_stack);
|
||||||
|
|
||||||
if self.needs_field_access {
|
if self.needs_field_access {
|
||||||
|
@ -113,6 +120,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
version: (1, 0, 0),
|
version: (1, 0, 0),
|
||||||
term,
|
term,
|
||||||
};
|
};
|
||||||
|
println!("{}", program.to_pretty());
|
||||||
|
|
||||||
let mut interner = Interner::new();
|
let mut interner = Interner::new();
|
||||||
|
|
||||||
|
@ -772,7 +780,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern,
|
pattern,
|
||||||
pattern_vec,
|
pattern_vec,
|
||||||
values,
|
values,
|
||||||
clause_properties.clone(),
|
clause_properties,
|
||||||
tipo,
|
tipo,
|
||||||
scope,
|
scope,
|
||||||
);
|
);
|
||||||
|
@ -837,7 +845,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern,
|
pattern,
|
||||||
pattern_vec,
|
pattern_vec,
|
||||||
&mut new_vec,
|
&mut new_vec,
|
||||||
clause_properties.clone(),
|
clause_properties,
|
||||||
tipo,
|
tipo,
|
||||||
scope,
|
scope,
|
||||||
);
|
);
|
||||||
|
@ -847,7 +855,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern,
|
pattern,
|
||||||
pattern_vec,
|
pattern_vec,
|
||||||
&mut vec![],
|
&mut vec![],
|
||||||
clause_properties.clone(),
|
clause_properties,
|
||||||
tipo,
|
tipo,
|
||||||
scope,
|
scope,
|
||||||
);
|
);
|
||||||
|
@ -864,7 +872,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern,
|
pattern,
|
||||||
pattern_vec,
|
pattern_vec,
|
||||||
&mut vec![],
|
&mut vec![],
|
||||||
clause_properties.clone(),
|
clause_properties,
|
||||||
tipo,
|
tipo,
|
||||||
scope,
|
scope,
|
||||||
);
|
);
|
||||||
|
@ -879,11 +887,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern: &Pattern<tipo::PatternConstructor, Arc<tipo::Type>>,
|
pattern: &Pattern<tipo::PatternConstructor, Arc<tipo::Type>>,
|
||||||
pattern_vec: &mut Vec<Air>,
|
pattern_vec: &mut Vec<Air>,
|
||||||
values: &mut Vec<Air>,
|
values: &mut Vec<Air>,
|
||||||
clause_properties: ClauseProperties,
|
clause_properties: &mut ClauseProperties,
|
||||||
tipo: &Type,
|
tipo: &Type,
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
) {
|
) {
|
||||||
let mut clause_properties = clause_properties;
|
|
||||||
match pattern {
|
match pattern {
|
||||||
Pattern::Int { .. } => todo!(),
|
Pattern::Int { .. } => todo!(),
|
||||||
Pattern::String { .. } => todo!(),
|
Pattern::String { .. } => todo!(),
|
||||||
|
@ -1011,6 +1018,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
type_map.insert(label, field_type);
|
type_map.insert(label, field_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("TYPE MAP IS {type_map:#?}");
|
||||||
|
println!("Type args are {:#?}", tipo.arg_types());
|
||||||
|
println!("ARGUMENTS ARE {:#?}", arguments);
|
||||||
|
|
||||||
let arguments_index = arguments
|
let arguments_index = arguments
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|item| {
|
.filter_map(|item| {
|
||||||
|
@ -1023,7 +1034,15 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let var_name = self.nested_pattern_ir_and_label(
|
let var_name = self.nested_pattern_ir_and_label(
|
||||||
&item.value,
|
&item.value,
|
||||||
&mut nested_pattern,
|
&mut nested_pattern,
|
||||||
type_map.get(&label).unwrap(),
|
type_map.get(&label).unwrap_or(
|
||||||
|
&Type::App {
|
||||||
|
public: true,
|
||||||
|
module: "".to_string(),
|
||||||
|
name: "Discard".to_string(),
|
||||||
|
args: vec![],
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
scope.clone(),
|
scope.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1088,7 +1107,83 @@ 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 names = vec![];
|
||||||
|
let mut nested_pattern = vec![];
|
||||||
|
let items_type = &tipo.get_inner_types();
|
||||||
|
|
||||||
|
for (index, element) in elems.iter().enumerate() {
|
||||||
|
let name = self.nested_pattern_ir_and_label(
|
||||||
|
element,
|
||||||
|
&mut nested_pattern,
|
||||||
|
&items_type[index],
|
||||||
|
scope.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
names.push((name.unwrap_or_else(|| "_".to_string()), index))
|
||||||
|
}
|
||||||
|
let mut defined_indices = match clause_properties.clone() {
|
||||||
|
ClauseProperties::TupleClause {
|
||||||
|
defined_tuple_indices,
|
||||||
|
..
|
||||||
|
} => defined_tuple_indices,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut previous_defined_names = vec![];
|
||||||
|
for (name, index) in names.clone() {
|
||||||
|
if let Some(defined_index) = defined_indices
|
||||||
|
.iter()
|
||||||
|
.find(|(defined_index, _)| *defined_index as usize == index)
|
||||||
|
{
|
||||||
|
previous_defined_names.push(defined_index.clone());
|
||||||
|
} else {
|
||||||
|
defined_indices.insert((index, name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("DEFINED INDICES ARE {:#?}", defined_indices);
|
||||||
|
|
||||||
|
for (index, name) in previous_defined_names {
|
||||||
|
let new_name = names
|
||||||
|
.iter()
|
||||||
|
.find(|(_, current_index)| *current_index == index)
|
||||||
|
.map(|(new_name, _)| new_name)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let pattern_type = &tipo.get_inner_types()[index];
|
||||||
|
|
||||||
|
pattern_vec.push(Air::Lam {
|
||||||
|
scope: scope.clone(),
|
||||||
|
name: new_name.clone(),
|
||||||
|
});
|
||||||
|
pattern_vec.push(Air::Var {
|
||||||
|
scope: scope.clone(),
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
pattern_type.clone(),
|
||||||
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name,
|
||||||
|
variant_name: String::new(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
match clause_properties {
|
||||||
|
ClauseProperties::TupleClause {
|
||||||
|
defined_tuple_indices,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
*defined_tuple_indices = defined_indices;
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("CLAUSE PROPERTIES IS NOW {:#?}", clause_properties);
|
||||||
|
|
||||||
|
pattern_vec.append(&mut nested_pattern);
|
||||||
|
pattern_vec.append(values);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1347,6 +1442,50 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
Some(constr_var_name)
|
Some(constr_var_name)
|
||||||
}
|
}
|
||||||
|
a @ Pattern::Tuple { elems, .. } => {
|
||||||
|
let item_name = format!("__tuple_item_id_{}", self.id_gen.next());
|
||||||
|
|
||||||
|
let mut clause_properties = ClauseProperties::TupleClause {
|
||||||
|
clause_var_name: item_name.clone(),
|
||||||
|
needs_constr_var: false,
|
||||||
|
is_complex_clause: false,
|
||||||
|
original_subject_name: item_name.clone(),
|
||||||
|
defined_tuple_indices: HashSet::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut inner_pattern_vec = vec![];
|
||||||
|
|
||||||
|
self.when_ir(
|
||||||
|
a,
|
||||||
|
&mut inner_pattern_vec,
|
||||||
|
&mut vec![],
|
||||||
|
pattern_type,
|
||||||
|
&mut clause_properties,
|
||||||
|
scope.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let defined_indices = match clause_properties.clone() {
|
||||||
|
ClauseProperties::TupleClause {
|
||||||
|
defined_tuple_indices,
|
||||||
|
..
|
||||||
|
} => defined_tuple_indices,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
pattern_vec.push(Air::TupleClause {
|
||||||
|
scope: scope.clone(),
|
||||||
|
tipo: pattern_type.clone(),
|
||||||
|
indices: defined_indices,
|
||||||
|
predefined_indices: HashSet::new(),
|
||||||
|
subject_name: clause_properties.original_subject_name().to_string(),
|
||||||
|
count: elems.len(),
|
||||||
|
complex_clause: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
pattern_vec.append(&mut inner_pattern_vec);
|
||||||
|
|
||||||
|
Some(item_name)
|
||||||
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3867,7 +4006,7 @@ 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 head_list = if tipo.is_map() {
|
let head_list = convert_data_to_type(
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into())
|
function: Term::Force(Term::Builtin(DefaultFunction::HeadList).into())
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -3876,23 +4015,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
unique: 0.into(),
|
unique: 0.into(),
|
||||||
})
|
})
|
||||||
.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_types()[0],
|
&tipo.get_inner_types()[0],
|
||||||
)
|
);
|
||||||
};
|
|
||||||
|
|
||||||
term = Term::Apply {
|
term = Term::Apply {
|
||||||
function: Term::Lambda {
|
function: Term::Lambda {
|
||||||
|
@ -3977,7 +4102,35 @@ impl<'a> CodeGenerator<'a> {
|
||||||
arg_stack.push(Term::Error)
|
arg_stack.push(Term::Error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::TupleClause { .. } => todo!(),
|
Air::TupleClause {
|
||||||
|
tipo,
|
||||||
|
indices,
|
||||||
|
predefined_indices,
|
||||||
|
subject_name,
|
||||||
|
complex_clause,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
let tuple_types = tipo.get_inner_types();
|
||||||
|
|
||||||
|
if tuple_types.len() == 2 {
|
||||||
|
for (index, name) in indices.iter() {
|
||||||
|
if *index == 0 {
|
||||||
|
// apply_wrap(
|
||||||
|
// Term::Builtin(DefaultFunction::FstPair)
|
||||||
|
// .force_wrap()
|
||||||
|
// .force_wrap(),
|
||||||
|
// Term::Var(Name {
|
||||||
|
// text: subject_name.clone(),
|
||||||
|
// unique: 0.into(),
|
||||||
|
// }),
|
||||||
|
// )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,10 @@ impl<T> Term<T> {
|
||||||
pub fn force_wrap(self) -> Self {
|
pub fn force_wrap(self) -> Self {
|
||||||
Term::Force(self.into())
|
Term::Force(self.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delay_wrap(self) -> Self {
|
||||||
|
Term::Delay(self.into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Display for Term<T>
|
impl<'a, T> Display for Term<T>
|
||||||
|
|
|
@ -6,7 +6,14 @@ pub const CONSTR_FIELDS_EXPOSER: &str = "__constr_fields_exposer";
|
||||||
pub const CONSTR_INDEX_EXPOSER: &str = "__constr_index_exposer";
|
pub const CONSTR_INDEX_EXPOSER: &str = "__constr_index_exposer";
|
||||||
pub const CONSTR_GET_FIELD: &str = "__constr_get_field";
|
pub const CONSTR_GET_FIELD: &str = "__constr_get_field";
|
||||||
|
|
||||||
pub fn final_wrapper<T>(term: Term<T>) -> Term<T> {
|
pub fn apply_wrap(function: Term<Name>, arg: Term<Name>) -> Term<Name> {
|
||||||
|
Term::Apply {
|
||||||
|
function: function.into(),
|
||||||
|
argument: arg.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn final_wrapper(term: Term<Name>) -> Term<Name> {
|
||||||
Term::Force(
|
Term::Force(
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
function: Term::Apply {
|
function: Term::Apply {
|
||||||
|
@ -350,3 +357,15 @@ pub fn choose_list(
|
||||||
argument: else_term.into(),
|
argument: else_term.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn repeat_tail_list(term: Term<Name>, repeat: usize) -> Term<Name> {
|
||||||
|
let mut term = term;
|
||||||
|
|
||||||
|
for _ in 0..repeat {
|
||||||
|
term = Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::TailList).force_wrap().into(),
|
||||||
|
argument: term.into(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
term
|
||||||
|
}
|
||||||
|
|
|
@ -12,16 +12,36 @@ pub type Redeemer {
|
||||||
msg: ByteArray,
|
msg: ByteArray,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spend(datum: Datum, redeemer: Redeemer, context: ScriptContext) -> Bool {
|
pub type Dummy {
|
||||||
|
Mannequin {
|
||||||
|
hands: ByteArray,
|
||||||
|
feet: Int,
|
||||||
|
}
|
||||||
|
Doll {
|
||||||
|
hands: ByteArray,
|
||||||
|
datum: Datum,
|
||||||
|
feet: Int,
|
||||||
|
}
|
||||||
|
Puppet {
|
||||||
|
hands: ByteArray,
|
||||||
|
dummy: Dummy,
|
||||||
|
}
|
||||||
|
Statue {
|
||||||
|
hands: ByteArray,
|
||||||
|
boots: ByteArray,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spend(datum: Datum, redeemer: Redeemer, context: Dummy) -> Bool {
|
||||||
let must_say_hello = string.from_bytearray(redeemer.msg) == "Hello, World!"
|
let must_say_hello = string.from_bytearray(redeemer.msg) == "Hello, World!"
|
||||||
|
let must_be_signed = #(1, datum, #(redeemer.msg, context ))
|
||||||
|
// context.transaction.extra_signatories
|
||||||
|
// |> list.any(fn(vk) { vk == datum.owner })
|
||||||
|
|
||||||
let must_be_signed =
|
when must_be_signed is {
|
||||||
context.transaction.extra_signatories
|
#(a, b, #(c, Mannequin{ feet, ..})) -> feet == 2
|
||||||
|> list.any(fn(vk) { vk == datum.owner })
|
_ -> False
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
must_say_hello && must_be_signed
|
|
||||||
}
|
|
||||||
|
|
||||||
test foo() {
|
|
||||||
1 + 1 == 2
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue