Merge branch 'main' into waalge/bump-cargo2nix
This commit is contained in:
commit
6817510e2d
|
@ -6,6 +6,12 @@
|
||||||
|
|
||||||
- **aiken**: new command `blueprint convert`
|
- **aiken**: new command `blueprint convert`
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **aiken-lang**: block `Data` and `String` from unifying when casting
|
||||||
|
- **aiken-lang**: remove ability for a type with many variants with matching field labels and types to support field access
|
||||||
|
- **aiken-project**: tests filtering with `-m` during check now happens in `Project::collect_tests`
|
||||||
|
|
||||||
## [v0.0.29] - 2023-MM-DD
|
## [v0.0.29] - 2023-MM-DD
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -117,6 +117,11 @@ pub enum Air {
|
||||||
constr_index: usize,
|
constr_index: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
AssertBool {
|
||||||
|
scope: Vec<u64>,
|
||||||
|
is_true: bool,
|
||||||
|
},
|
||||||
|
|
||||||
// When
|
// When
|
||||||
When {
|
When {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
|
@ -268,6 +273,7 @@ impl Air {
|
||||||
| Air::UnWrapData { scope, .. }
|
| Air::UnWrapData { scope, .. }
|
||||||
| Air::WrapData { scope, .. }
|
| Air::WrapData { scope, .. }
|
||||||
| Air::AssertConstr { scope, .. }
|
| Air::AssertConstr { scope, .. }
|
||||||
|
| Air::AssertBool { scope, .. }
|
||||||
| Air::When { scope, .. }
|
| Air::When { scope, .. }
|
||||||
| Air::Clause { scope, .. }
|
| Air::Clause { scope, .. }
|
||||||
| Air::ListClause { scope, .. }
|
| Air::ListClause { scope, .. }
|
||||||
|
@ -375,6 +381,7 @@ impl Air {
|
||||||
| Air::Let { .. }
|
| Air::Let { .. }
|
||||||
| Air::WrapClause { .. }
|
| Air::WrapClause { .. }
|
||||||
| Air::AssertConstr { .. }
|
| Air::AssertConstr { .. }
|
||||||
|
| Air::AssertBool { .. }
|
||||||
| Air::Finally { .. }
|
| Air::Finally { .. }
|
||||||
| Air::FieldsExpose { .. } => None,
|
| Air::FieldsExpose { .. } => None,
|
||||||
|
|
||||||
|
|
|
@ -1200,7 +1200,7 @@ pub fn find_and_replace_generics(tipo: &mut Arc<Type>, mono_types: &IndexMap<u64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_generics_and_type(tipo: &Type, param: &Type) -> Vec<(u64, Arc<Type>)> {
|
pub fn get_generic_id_and_type(tipo: &Type, param: &Type) -> Vec<(u64, Arc<Type>)> {
|
||||||
let mut generics_ids = vec![];
|
let mut generics_ids = vec![];
|
||||||
|
|
||||||
if let Some(id) = tipo.get_generic() {
|
if let Some(id) = tipo.get_generic() {
|
||||||
|
@ -1213,7 +1213,7 @@ pub fn get_generics_and_type(tipo: &Type, param: &Type) -> Vec<(u64, Arc<Type>)>
|
||||||
.iter()
|
.iter()
|
||||||
.zip(param.get_inner_types().iter())
|
.zip(param.get_inner_types().iter())
|
||||||
{
|
{
|
||||||
generics_ids.append(&mut get_generics_and_type(tipo, param_type));
|
generics_ids.append(&mut get_generic_id_and_type(tipo, param_type));
|
||||||
}
|
}
|
||||||
generics_ids
|
generics_ids
|
||||||
}
|
}
|
||||||
|
@ -1990,7 +1990,7 @@ pub fn replace_opaque_type(t: &mut Arc<Type>, data_types: IndexMap<DataTypeKey,
|
||||||
|
|
||||||
for (tipo, param) in new_type_fields.iter().zip(t.arg_types().unwrap()) {
|
for (tipo, param) in new_type_fields.iter().zip(t.arg_types().unwrap()) {
|
||||||
let mut map = mono_types.into_iter().collect_vec();
|
let mut map = mono_types.into_iter().collect_vec();
|
||||||
map.append(&mut get_generics_and_type(tipo, ¶m));
|
map.append(&mut get_generic_id_and_type(tipo, ¶m));
|
||||||
mono_types = map.into_iter().collect();
|
mono_types = map.into_iter().collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,7 @@ impl<'a> Environment<'a> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(fields))
|
Ok(Some(fields))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1289,6 +1290,7 @@ impl<'a> Environment<'a> {
|
||||||
&& !(t1.is_unbound() || t2.is_unbound())
|
&& !(t1.is_unbound() || t2.is_unbound())
|
||||||
&& !(t1.is_function() || t2.is_function())
|
&& !(t1.is_function() || t2.is_function())
|
||||||
&& !(t1.is_generic() || t2.is_generic())
|
&& !(t1.is_generic() || t2.is_generic())
|
||||||
|
&& !(t1.is_string() || t2.is_string())
|
||||||
{
|
{
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -1779,44 +1781,22 @@ fn get_compatible_record_fields<A>(
|
||||||
) -> Vec<(usize, &str, &Annotation)> {
|
) -> Vec<(usize, &str, &Annotation)> {
|
||||||
let mut compatible = vec![];
|
let mut compatible = vec![];
|
||||||
|
|
||||||
|
if constructors.len() > 1 {
|
||||||
|
return compatible;
|
||||||
|
}
|
||||||
|
|
||||||
let first = match constructors.get(0) {
|
let first = match constructors.get(0) {
|
||||||
Some(first) => first,
|
Some(first) => first,
|
||||||
None => return compatible,
|
None => return compatible,
|
||||||
};
|
};
|
||||||
|
|
||||||
'next_argument: for (index, first_argument) in first.arguments.iter().enumerate() {
|
for (index, first_argument) in first.arguments.iter().enumerate() {
|
||||||
// Fields without labels do not have accessors
|
// Fields without labels do not have accessors
|
||||||
let label = match first_argument.label.as_ref() {
|
let label = match first_argument.label.as_ref() {
|
||||||
Some(label) => label.as_str(),
|
Some(label) => label.as_str(),
|
||||||
None => continue 'next_argument,
|
None => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check each variant to see if they have an field in the same position
|
|
||||||
// with the same label and the same type
|
|
||||||
for constructor in constructors.iter().skip(1) {
|
|
||||||
// The field must exist in all variants
|
|
||||||
let argument = match constructor.arguments.get(index) {
|
|
||||||
Some(argument) => argument,
|
|
||||||
None => continue 'next_argument,
|
|
||||||
};
|
|
||||||
|
|
||||||
// The labels must be the same
|
|
||||||
if argument.label != first_argument.label {
|
|
||||||
continue 'next_argument;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The types must be the same
|
|
||||||
if !argument
|
|
||||||
.annotation
|
|
||||||
.is_logically_equal(&first_argument.annotation)
|
|
||||||
{
|
|
||||||
continue 'next_argument;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The previous loop did not find any incompatible fields in the other
|
|
||||||
// variants so this field is compatible across variants and we should
|
|
||||||
// generate an accessor for it.
|
|
||||||
compatible.push((index, label, &first_argument.annotation))
|
compatible.push((index, label, &first_argument.annotation))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -264,8 +264,9 @@ You can use '{discard}' and numbers to distinguish between similar names.
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I saw a {} fields in a context where there should be {}.\n",
|
"I saw {} field{} in a context where there should be {}.\n",
|
||||||
given.if_supports_color(Stdout, |s| s.purple()),
|
given.if_supports_color(Stdout, |s| s.purple()),
|
||||||
|
if *given <= 1 { "" } else { "s"},
|
||||||
expected.if_supports_color(Stdout, |s| s.purple()),
|
expected.if_supports_color(Stdout, |s| s.purple()),
|
||||||
)]
|
)]
|
||||||
#[diagnostic(url("https://aiken-lang.org/language-tour/custom-types"))]
|
#[diagnostic(url("https://aiken-lang.org/language-tour/custom-types"))]
|
||||||
|
@ -744,7 +745,7 @@ Perhaps, try the following:
|
||||||
#[diagnostic(code("unknown::record_field"))]
|
#[diagnostic(code("unknown::record_field"))]
|
||||||
#[diagnostic(help(
|
#[diagnostic(help(
|
||||||
"{}",
|
"{}",
|
||||||
suggest_neighbor(label, fields.iter(), "Did you forget to make it public?")
|
suggest_neighbor(label, fields.iter(), "Did you forget to make it public?\n\nAlso record access is only supported on types with one constructor.")
|
||||||
))]
|
))]
|
||||||
UnknownRecordField {
|
UnknownRecordField {
|
||||||
#[label]
|
#[label]
|
||||||
|
|
|
@ -26,7 +26,7 @@ use crate::{
|
||||||
builder::{
|
builder::{
|
||||||
check_replaceable_opaque_type, check_when_pattern_needs, constants_ir,
|
check_replaceable_opaque_type, check_when_pattern_needs, constants_ir,
|
||||||
convert_constants_to_data, convert_data_to_type, convert_type_to_data, get_common_ancestor,
|
convert_constants_to_data, convert_data_to_type, convert_type_to_data, get_common_ancestor,
|
||||||
get_generics_and_type, handle_clause_guard, handle_func_dependencies_ir,
|
get_generic_id_and_type, handle_clause_guard, handle_func_dependencies_ir,
|
||||||
handle_recursion_ir, list_access_to_uplc, lookup_data_type_by_tipo, monomorphize,
|
handle_recursion_ir, list_access_to_uplc, lookup_data_type_by_tipo, monomorphize,
|
||||||
rearrange_clauses, replace_opaque_type, wrap_validator_args, AssignmentProperties,
|
rearrange_clauses, replace_opaque_type, wrap_validator_args, AssignmentProperties,
|
||||||
ClauseProperties, DataTypeKey, FuncComponents, FunctionAccessKey,
|
ClauseProperties, DataTypeKey, FuncComponents, FunctionAccessKey,
|
||||||
|
@ -2056,66 +2056,78 @@ impl<'a> CodeGenerator<'a> {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
check_last_item: false,
|
check_last_item: false,
|
||||||
});
|
});
|
||||||
} else {
|
} else if !tipo.is_bool() {
|
||||||
pattern_vec.push(Air::Let {
|
pattern_vec.push(Air::Let {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(assignment_properties.kind, AssignmentKind::Expect) {
|
match assignment_properties.kind {
|
||||||
let data_type =
|
AssignmentKind::Let => {
|
||||||
lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
|
pattern_vec.append(values);
|
||||||
|
}
|
||||||
|
AssignmentKind::Expect => {
|
||||||
|
if tipo.is_bool() {
|
||||||
|
pattern_vec.push(Air::AssertBool {
|
||||||
|
scope,
|
||||||
|
is_true: constr_name == "True",
|
||||||
|
});
|
||||||
|
|
||||||
let (index, _) = data_type
|
pattern_vec.append(values);
|
||||||
.constructors
|
} else {
|
||||||
.iter()
|
let data_type =
|
||||||
.enumerate()
|
lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap();
|
||||||
.find(|(_, constr)| &constr.name == constr_name)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let constr_name = format!("__{}_{}", constr_name, self.id_gen.next());
|
let (index, _) = data_type
|
||||||
|
.constructors
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.find(|(_, constr)| &constr.name == constr_name)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
pattern_vec.push(Air::Let {
|
let constr_name = format!("__{}_{}", constr_name, self.id_gen.next());
|
||||||
scope: scope.clone(),
|
|
||||||
name: constr_name.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.append(values);
|
pattern_vec.push(Air::Let {
|
||||||
|
scope: scope.clone(),
|
||||||
|
name: constr_name.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
let mut scope = scope;
|
pattern_vec.append(values);
|
||||||
scope.push(self.id_gen.next());
|
|
||||||
|
|
||||||
pattern_vec.push(Air::AssertConstr {
|
let mut scope = scope;
|
||||||
scope: scope.clone(),
|
scope.push(self.id_gen.next());
|
||||||
constr_index: index,
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.push(Air::Var {
|
pattern_vec.push(Air::AssertConstr {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
constructor: ValueConstructor::public(
|
constr_index: index,
|
||||||
tipo.clone().into(),
|
});
|
||||||
ValueConstructorVariant::LocalVariable {
|
|
||||||
location: Span::empty(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
name: constr_name.clone(),
|
|
||||||
variant_name: String::new(),
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.push(Air::Var {
|
pattern_vec.push(Air::Var {
|
||||||
scope,
|
scope: scope.clone(),
|
||||||
constructor: ValueConstructor::public(
|
constructor: ValueConstructor::public(
|
||||||
tipo.clone().into(),
|
tipo.clone().into(),
|
||||||
ValueConstructorVariant::LocalVariable {
|
ValueConstructorVariant::LocalVariable {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
name: constr_name,
|
name: constr_name.clone(),
|
||||||
variant_name: String::new(),
|
variant_name: String::new(),
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
pattern_vec.append(values);
|
pattern_vec.push(Air::Var {
|
||||||
|
scope,
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
tipo.clone().into(),
|
||||||
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name: constr_name,
|
||||||
|
variant_name: String::new(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pattern_vec.append(&mut nested_pattern);
|
pattern_vec.append(&mut nested_pattern);
|
||||||
|
@ -3275,18 +3287,24 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let param_types = constructor.tipo.arg_types().unwrap();
|
let param_types = constructor.tipo.arg_types().unwrap();
|
||||||
|
|
||||||
let mut mono_types: IndexMap<u64, Arc<Type>> = IndexMap::new();
|
let mut mono_types: IndexMap<u64, Arc<Type>> = IndexMap::new();
|
||||||
|
let mut map = mono_types.into_iter().collect_vec();
|
||||||
|
|
||||||
for (index, arg) in function.arguments.iter().enumerate() {
|
for (index, arg) in function.arguments.iter().enumerate() {
|
||||||
if arg.tipo.is_generic() {
|
if arg.tipo.is_generic() {
|
||||||
let mut map = mono_types.into_iter().collect_vec();
|
|
||||||
let param_type = ¶m_types[index];
|
let param_type = ¶m_types[index];
|
||||||
|
|
||||||
map.append(&mut get_generics_and_type(&arg.tipo, param_type));
|
map.append(&mut get_generic_id_and_type(&arg.tipo, param_type));
|
||||||
|
|
||||||
mono_types = map.into_iter().collect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if function.return_type.is_generic() {
|
||||||
|
if let Type::Fn { ret, .. } = &*constructor.tipo {
|
||||||
|
map.append(&mut get_generic_id_and_type(&function.return_type, ret))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mono_types = map.into_iter().collect();
|
||||||
|
|
||||||
let (variant_name, func_ir) =
|
let (variant_name, func_ir) =
|
||||||
monomorphize(func_ir, mono_types, &constructor.tipo);
|
monomorphize(func_ir, mono_types, &constructor.tipo);
|
||||||
|
|
||||||
|
@ -3347,23 +3365,32 @@ impl<'a> CodeGenerator<'a> {
|
||||||
} else if let (Some(function), Type::Fn { .. }) =
|
} else if let (Some(function), Type::Fn { .. }) =
|
||||||
(function, &*tipo)
|
(function, &*tipo)
|
||||||
{
|
{
|
||||||
|
let param_types = tipo.arg_types().unwrap();
|
||||||
|
|
||||||
let mut mono_types: IndexMap<u64, Arc<Type>> =
|
let mut mono_types: IndexMap<u64, Arc<Type>> =
|
||||||
IndexMap::new();
|
IndexMap::new();
|
||||||
|
let mut map = mono_types.into_iter().collect_vec();
|
||||||
let param_types = tipo.arg_types().unwrap();
|
|
||||||
|
|
||||||
for (index, arg) in function.arguments.iter().enumerate() {
|
for (index, arg) in function.arguments.iter().enumerate() {
|
||||||
if arg.tipo.is_generic() {
|
if arg.tipo.is_generic() {
|
||||||
let mut map = mono_types.into_iter().collect_vec();
|
let param_type = ¶m_types[index];
|
||||||
map.append(&mut get_generics_and_type(
|
|
||||||
&arg.tipo,
|
|
||||||
¶m_types[index],
|
|
||||||
));
|
|
||||||
|
|
||||||
mono_types = map.into_iter().collect();
|
map.append(&mut get_generic_id_and_type(
|
||||||
|
&arg.tipo, param_type,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if function.return_type.is_generic() {
|
||||||
|
if let Type::Fn { ret, .. } = &*constructor.tipo {
|
||||||
|
map.append(&mut get_generic_id_and_type(
|
||||||
|
&function.return_type,
|
||||||
|
ret,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mono_types = map.into_iter().collect();
|
||||||
let mut func_ir = vec![];
|
let mut func_ir = vec![];
|
||||||
|
|
||||||
self.build_ir(&function.body, &mut func_ir, scope.to_vec());
|
self.build_ir(&function.body, &mut func_ir, scope.to_vec());
|
||||||
|
@ -4310,7 +4337,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
arg_vec.push(arg_stack.pop().unwrap());
|
arg_vec.push(arg_stack.pop().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
for arg in arg_vec.iter() {
|
for (index, arg) in arg_vec.into_iter().enumerate() {
|
||||||
|
let arg = if matches!(func, DefaultFunction::ChooseData) && index > 0 {
|
||||||
|
Term::Delay(arg.into())
|
||||||
|
} else {
|
||||||
|
arg
|
||||||
|
};
|
||||||
term = apply_wrap(term, arg.clone());
|
term = apply_wrap(term, arg.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4425,6 +4457,58 @@ impl<'a> CodeGenerator<'a> {
|
||||||
DefaultFunction::MkCons => {
|
DefaultFunction::MkCons => {
|
||||||
unimplemented!("Use brackets instead.");
|
unimplemented!("Use brackets instead.");
|
||||||
}
|
}
|
||||||
|
DefaultFunction::IfThenElse
|
||||||
|
| DefaultFunction::ChooseList
|
||||||
|
| DefaultFunction::Trace => unimplemented!("{func:#?}"),
|
||||||
|
DefaultFunction::ChooseData => {
|
||||||
|
let temp_vars = (0..func.arity())
|
||||||
|
.into_iter()
|
||||||
|
.map(|_| format!("__item_{}", self.id_gen.next()))
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
if count == 0 {
|
||||||
|
for (index, temp_var) in temp_vars.iter().enumerate() {
|
||||||
|
term = apply_wrap(
|
||||||
|
term,
|
||||||
|
if index > 0 {
|
||||||
|
Term::Delay(
|
||||||
|
Term::Var(
|
||||||
|
Name {
|
||||||
|
text: temp_var.clone(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Term::Var(
|
||||||
|
Name {
|
||||||
|
text: temp_var.clone(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
term = term.force_wrap();
|
||||||
|
|
||||||
|
if count == 0 {
|
||||||
|
for temp_var in temp_vars.into_iter().rev() {
|
||||||
|
term = Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: temp_var,
|
||||||
|
unique: 0.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
body: term.into(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
|
@ -4828,7 +4912,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Term::Builtin(DefaultFunction::Trace).force_wrap(),
|
Term::Builtin(DefaultFunction::Trace).force_wrap(),
|
||||||
Term::Constant(
|
Term::Constant(
|
||||||
UplcConstant::String(
|
UplcConstant::String(
|
||||||
"Asserted on incorrect constructor variant.".to_string(),
|
"Expected on incorrect constructor variant.".to_string(),
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
|
@ -4851,6 +4935,31 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
|
Air::AssertBool { is_true, .. } => {
|
||||||
|
let value = arg_stack.pop().unwrap();
|
||||||
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
let error_term = apply_wrap(
|
||||||
|
apply_wrap(
|
||||||
|
Term::Builtin(DefaultFunction::Trace).force_wrap(),
|
||||||
|
Term::Constant(
|
||||||
|
UplcConstant::String(
|
||||||
|
"Expected on incorrect boolean variant.".to_string(),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Term::Delay(Term::Error.into()),
|
||||||
|
)
|
||||||
|
.force_wrap();
|
||||||
|
|
||||||
|
if is_true {
|
||||||
|
term = delayed_if_else(value, term, error_term);
|
||||||
|
} else {
|
||||||
|
term = delayed_if_else(value, error_term, term);
|
||||||
|
}
|
||||||
|
arg_stack.push(term);
|
||||||
|
}
|
||||||
Air::When {
|
Air::When {
|
||||||
subject_name, tipo, ..
|
subject_name, tipo, ..
|
||||||
} => {
|
} => {
|
||||||
|
|
|
@ -250,36 +250,22 @@ impl Annotated<Schema> {
|
||||||
Err(Error::new(ErrorContext::UnboundTypeVariable, type_info))
|
Err(Error::new(ErrorContext::UnboundTypeVariable, type_info))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Type::Tuple { elems } => match &elems[..] {
|
Type::Tuple { elems } => {
|
||||||
[left, right] => {
|
let elems = elems
|
||||||
let left = Annotated::from_type(modules, left, type_parameters)?
|
.iter()
|
||||||
.into_data(left)
|
.map(|e| {
|
||||||
.map_err(|e| e.backtrack(type_info))?;
|
Annotated::from_type(modules, e, type_parameters)
|
||||||
let right = Annotated::from_type(modules, right, type_parameters)?
|
.and_then(|s| s.into_data(e).map(|s| s.annotated))
|
||||||
.into_data(right)
|
|
||||||
.map_err(|e| e.backtrack(type_info))?;
|
|
||||||
Ok(Schema::Data(Data::List(Items::Many(vec![
|
|
||||||
left.annotated,
|
|
||||||
right.annotated,
|
|
||||||
])))
|
|
||||||
.into())
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
let elems = elems
|
|
||||||
.iter()
|
|
||||||
.map(|e| {
|
|
||||||
Annotated::from_type(modules, e, type_parameters)
|
|
||||||
.and_then(|s| s.into_data(e).map(|s| s.annotated))
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<_>, _>>()
|
|
||||||
.map_err(|e| e.backtrack(type_info))?;
|
|
||||||
Ok(Annotated {
|
|
||||||
title: Some("Tuple".to_owned()),
|
|
||||||
description: None,
|
|
||||||
annotated: Schema::Data(Data::List(Items::Many(elems))),
|
|
||||||
})
|
})
|
||||||
}
|
.collect::<Result<Vec<_>, _>>()
|
||||||
},
|
.map_err(|e| e.backtrack(type_info))?;
|
||||||
|
|
||||||
|
Ok(Annotated {
|
||||||
|
title: Some("Tuple".to_owned()),
|
||||||
|
description: None,
|
||||||
|
annotated: Schema::Data(Data::List(Items::Many(elems))),
|
||||||
|
})
|
||||||
|
}
|
||||||
Type::Fn { .. } => Err(Error::new(ErrorContext::UnexpectedFunction, type_info)),
|
Type::Fn { .. } => Err(Error::new(ErrorContext::UnexpectedFunction, type_info)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -470,6 +470,7 @@ mod test {
|
||||||
"title": "test_module.spend",
|
"title": "test_module.spend",
|
||||||
"hash": "3c6766e7a36df2aa13c0e9e6e071317ed39d05f405771c4f1a81c6cc",
|
"hash": "3c6766e7a36df2aa13c0e9e6e071317ed39d05f405771c4f1a81c6cc",
|
||||||
"datum": {
|
"datum": {
|
||||||
|
"title": "Tuple",
|
||||||
"schema": {
|
"schema": {
|
||||||
"dataType": "list",
|
"dataType": "list",
|
||||||
"items": [
|
"items": [
|
||||||
|
|
|
@ -575,22 +575,40 @@ fn new_timestamp() -> Duration {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_modules_prefix(modules: &[DocLink]) -> String {
|
fn find_modules_prefix(modules: &[DocLink]) -> String {
|
||||||
modules
|
do_find_modules_prefix("", modules)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_find_modules_prefix(current_prefix: &str, modules: &[DocLink]) -> String {
|
||||||
|
let prefix = modules
|
||||||
.iter()
|
.iter()
|
||||||
.fold(None, |previous_prefix, module| {
|
.fold(None, |previous_prefix, module| {
|
||||||
let prefix = module
|
let name = module.name.strip_prefix(current_prefix).unwrap_or_default();
|
||||||
.name
|
let name = if name.starts_with('/') {
|
||||||
.split('/')
|
name.strip_prefix('/').unwrap_or_default()
|
||||||
.next()
|
} else {
|
||||||
.unwrap_or_default()
|
name
|
||||||
.to_string();
|
};
|
||||||
|
|
||||||
|
let prefix = name.split('/').next().unwrap_or_default().to_string();
|
||||||
|
|
||||||
match previous_prefix {
|
match previous_prefix {
|
||||||
None if prefix != module.name => Some(prefix),
|
None if prefix != module.name => Some(prefix),
|
||||||
Some(..) if Some(prefix) == previous_prefix => previous_prefix,
|
Some(..) if Some(prefix) == previous_prefix => previous_prefix,
|
||||||
_ => Some(String::new()),
|
_ => Some(String::new()),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap_or_default()
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
if prefix.is_empty() {
|
||||||
|
current_prefix.to_string()
|
||||||
|
} else {
|
||||||
|
let mut current_prefix = current_prefix.to_owned();
|
||||||
|
if !current_prefix.is_empty() {
|
||||||
|
current_prefix.push('/');
|
||||||
|
}
|
||||||
|
current_prefix.push_str(&prefix);
|
||||||
|
do_find_modules_prefix(¤t_prefix, modules)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -602,7 +620,7 @@ fn find_modules_prefix_test() {
|
||||||
name: "aiken/list".to_string(),
|
name: "aiken/list".to_string(),
|
||||||
path: String::new()
|
path: String::new()
|
||||||
}]),
|
}]),
|
||||||
"aiken".to_string()
|
"aiken/list".to_string()
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -620,7 +638,7 @@ fn find_modules_prefix_test() {
|
||||||
path: String::new()
|
path: String::new()
|
||||||
},
|
},
|
||||||
DocLink {
|
DocLink {
|
||||||
name: "aiken/byte_array".to_string(),
|
name: "aiken/bytearray".to_string(),
|
||||||
path: String::new(),
|
path: String::new(),
|
||||||
}
|
}
|
||||||
]),
|
]),
|
||||||
|
@ -634,7 +652,56 @@ fn find_modules_prefix_test() {
|
||||||
path: String::new()
|
path: String::new()
|
||||||
},
|
},
|
||||||
DocLink {
|
DocLink {
|
||||||
name: "foo/byte_array".to_string(),
|
name: "foo/bytearray".to_string(),
|
||||||
|
path: String::new(),
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
"".to_string()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn find_modules_prefix_test_2() {
|
||||||
|
assert_eq!(
|
||||||
|
find_modules_prefix(&[
|
||||||
|
DocLink {
|
||||||
|
name: "aiken/trees/bst".to_string(),
|
||||||
|
path: String::new()
|
||||||
|
},
|
||||||
|
DocLink {
|
||||||
|
name: "aiken/trees/mt".to_string(),
|
||||||
|
path: String::new(),
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
"aiken/trees".to_string()
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
find_modules_prefix(&[
|
||||||
|
DocLink {
|
||||||
|
name: "aiken/trees/bst".to_string(),
|
||||||
|
path: String::new()
|
||||||
|
},
|
||||||
|
DocLink {
|
||||||
|
name: "aiken/trees/mt".to_string(),
|
||||||
|
path: String::new(),
|
||||||
|
},
|
||||||
|
DocLink {
|
||||||
|
name: "aiken/sequences".to_string(),
|
||||||
|
path: String::new(),
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
"aiken".to_string()
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
find_modules_prefix(&[
|
||||||
|
DocLink {
|
||||||
|
name: "aiken".to_string(),
|
||||||
|
path: String::new()
|
||||||
|
},
|
||||||
|
DocLink {
|
||||||
|
name: "aiken/prelude".to_string(),
|
||||||
path: String::new(),
|
path: String::new(),
|
||||||
}
|
}
|
||||||
]),
|
]),
|
||||||
|
|
|
@ -175,7 +175,10 @@ where
|
||||||
let doc_files = docs::generate_all(
|
let doc_files = docs::generate_all(
|
||||||
&self.root,
|
&self.root,
|
||||||
&self.config,
|
&self.config,
|
||||||
self.checked_modules.values().collect(),
|
self.checked_modules
|
||||||
|
.values()
|
||||||
|
.filter(|CheckedModule { package, .. }| package == &self.config.name.to_string())
|
||||||
|
.collect(),
|
||||||
);
|
);
|
||||||
|
|
||||||
for file in doc_files {
|
for file in doc_files {
|
||||||
|
@ -288,13 +291,13 @@ where
|
||||||
verbose,
|
verbose,
|
||||||
exact_match,
|
exact_match,
|
||||||
} => {
|
} => {
|
||||||
let tests = self.collect_tests(verbose)?;
|
let tests = self.collect_tests(verbose, match_tests, exact_match)?;
|
||||||
|
|
||||||
if !tests.is_empty() {
|
if !tests.is_empty() {
|
||||||
self.event_listener.handle_event(Event::RunningTests);
|
self.event_listener.handle_event(Event::RunningTests);
|
||||||
}
|
}
|
||||||
|
|
||||||
let results = self.eval_scripts(tests, match_tests, exact_match);
|
let results = self.eval_scripts(tests);
|
||||||
|
|
||||||
let errors: Vec<Error> = results
|
let errors: Vec<Error> = results
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -586,20 +589,84 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_tests(&mut self, verbose: bool) -> Result<Vec<Script>, Error> {
|
fn collect_tests(
|
||||||
|
&mut self,
|
||||||
|
verbose: bool,
|
||||||
|
match_tests: Option<Vec<String>>,
|
||||||
|
exact_match: bool,
|
||||||
|
) -> Result<Vec<Script>, Error> {
|
||||||
let mut scripts = Vec::new();
|
let mut scripts = Vec::new();
|
||||||
for module in self.checked_modules.values() {
|
|
||||||
if module.package != self.config.name.to_string() {
|
let match_tests = match_tests.map(|mt| {
|
||||||
|
mt.into_iter()
|
||||||
|
.map(|match_test| {
|
||||||
|
let mut match_split_dot = match_test.split('.');
|
||||||
|
|
||||||
|
let match_module = if match_test.contains('.') || match_test.contains('/') {
|
||||||
|
match_split_dot.next().unwrap_or("")
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
|
let match_names = match_split_dot.next().map(|names| {
|
||||||
|
let names = names.replace(&['{', '}'][..], "");
|
||||||
|
|
||||||
|
let names_split_comma = names.split(',');
|
||||||
|
|
||||||
|
names_split_comma.map(str::to_string).collect()
|
||||||
|
});
|
||||||
|
|
||||||
|
(match_module.to_string(), match_names)
|
||||||
|
})
|
||||||
|
.collect::<Vec<(String, Option<Vec<String>>)>>()
|
||||||
|
});
|
||||||
|
|
||||||
|
for checked_module in self.checked_modules.values() {
|
||||||
|
if checked_module.package != self.config.name.to_string() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for def in module.ast.definitions() {
|
|
||||||
|
for def in checked_module.ast.definitions() {
|
||||||
if let Definition::Test(func) = def {
|
if let Definition::Test(func) = def {
|
||||||
scripts.push((module.input_path.clone(), module.name.clone(), func))
|
if let Some(match_tests) = &match_tests {
|
||||||
|
let is_match = match_tests.iter().any(|(module, names)| {
|
||||||
|
let matched_module =
|
||||||
|
module.is_empty() || checked_module.name.contains(module);
|
||||||
|
|
||||||
|
let matched_name = match names {
|
||||||
|
None => true,
|
||||||
|
Some(names) => names.iter().any(|name| {
|
||||||
|
if exact_match {
|
||||||
|
name == &func.name
|
||||||
|
} else {
|
||||||
|
func.name.contains(name)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
matched_module && matched_name
|
||||||
|
});
|
||||||
|
|
||||||
|
if is_match {
|
||||||
|
scripts.push((
|
||||||
|
checked_module.input_path.clone(),
|
||||||
|
checked_module.name.clone(),
|
||||||
|
func,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scripts.push((
|
||||||
|
checked_module.input_path.clone(),
|
||||||
|
checked_module.name.clone(),
|
||||||
|
func,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut programs = Vec::new();
|
let mut programs = Vec::new();
|
||||||
|
|
||||||
for (input_path, module_name, func_def) in scripts {
|
for (input_path, module_name, func_def) in scripts {
|
||||||
let Function {
|
let Function {
|
||||||
arguments,
|
arguments,
|
||||||
|
@ -660,12 +727,7 @@ where
|
||||||
Ok(programs)
|
Ok(programs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_scripts(
|
fn eval_scripts(&self, scripts: Vec<Script>) -> Vec<EvalInfo> {
|
||||||
&self,
|
|
||||||
scripts: Vec<Script>,
|
|
||||||
match_tests: Option<Vec<String>>,
|
|
||||||
exact_match: bool,
|
|
||||||
) -> Vec<EvalInfo> {
|
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
// TODO: in the future we probably just want to be able to
|
// TODO: in the future we probably just want to be able to
|
||||||
|
@ -675,55 +737,6 @@ where
|
||||||
cpu: i64::MAX,
|
cpu: i64::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let scripts = if let Some(match_tests) = match_tests {
|
|
||||||
let match_tests: Vec<(&str, Option<Vec<String>>)> = match_tests
|
|
||||||
.iter()
|
|
||||||
.map(|match_test| {
|
|
||||||
let mut match_split_dot = match_test.split('.');
|
|
||||||
|
|
||||||
let match_module = if match_test.contains('.') || match_test.contains('/') {
|
|
||||||
match_split_dot.next().unwrap_or("")
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
};
|
|
||||||
|
|
||||||
let match_names = match_split_dot.next().map(|names| {
|
|
||||||
let names = names.replace(&['{', '}'][..], "");
|
|
||||||
|
|
||||||
let names_split_comma = names.split(',');
|
|
||||||
|
|
||||||
names_split_comma.map(str::to_string).collect()
|
|
||||||
});
|
|
||||||
|
|
||||||
(match_module, match_names)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
scripts
|
|
||||||
.into_iter()
|
|
||||||
.filter(|script| -> bool {
|
|
||||||
match_tests.iter().any(|(module, names)| {
|
|
||||||
let matched_module = module == &"" || script.module.contains(module);
|
|
||||||
|
|
||||||
let matched_name = match names {
|
|
||||||
None => true,
|
|
||||||
Some(names) => names.iter().any(|name| {
|
|
||||||
if exact_match {
|
|
||||||
name == &script.name
|
|
||||||
} else {
|
|
||||||
script.name.contains(name)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
matched_module && matched_name
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect::<Vec<Script>>()
|
|
||||||
} else {
|
|
||||||
scripts
|
|
||||||
};
|
|
||||||
|
|
||||||
scripts
|
scripts
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|script| {
|
.map(|script| {
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
# This file was generated by Aiken
|
||||||
|
# You typically do not need to edit this file
|
||||||
|
|
||||||
|
requirements = []
|
||||||
|
packages = []
|
|
@ -0,0 +1,3 @@
|
||||||
|
name = 'aiken-lang/acceptance_test_065'
|
||||||
|
version = '0.0.0'
|
||||||
|
description = ''
|
|
@ -0,0 +1,49 @@
|
||||||
|
use aiken/builtin
|
||||||
|
|
||||||
|
type MyData {
|
||||||
|
Integer(Int)
|
||||||
|
Bytes(ByteArray)
|
||||||
|
}
|
||||||
|
|
||||||
|
test foo() {
|
||||||
|
inspect(42) == Integer(42) && inspect(#"ff") == Bytes(#"ff")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inspect(data: Data) -> MyData {
|
||||||
|
expect result: MyData =
|
||||||
|
builtin.choose_data(
|
||||||
|
data,
|
||||||
|
inspect_constr(data),
|
||||||
|
inspect_map(data),
|
||||||
|
inspect_list(data),
|
||||||
|
inspect_integer(data),
|
||||||
|
inspect_bytearray(data),
|
||||||
|
)
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inspect_constr(_data: Data) -> Data {
|
||||||
|
todo
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inspect_map(_data: Data) -> Data {
|
||||||
|
todo
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inspect_list(_data: Data) -> Data {
|
||||||
|
todo
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inspect_integer(data: Data) -> Data {
|
||||||
|
let result: Data =
|
||||||
|
builtin.un_i_data(data)
|
||||||
|
|> Integer
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inspect_bytearray(data: Data) -> Data {
|
||||||
|
let result: Data =
|
||||||
|
builtin.un_b_data(data)
|
||||||
|
|> Bytes
|
||||||
|
result
|
||||||
|
}
|
|
@ -164,8 +164,8 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compiledCode": "59030501000032323232323232323232322225333006323232323232323232533300f3370e002900009925130090021533300f3370e0029001099191919299980999b87001480084c8c8cccc8888c8c8c8c8c9289812000980b19299980e99b8748000c080dd500088008a9980fa492a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e0016330120070033022001301432533301b3370e9000180f1baa0011001153301d49012a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163300f005001300d48901ff00010001012005301b001300d00214a0602a6ea8004cc028c02c03120023017001300900213232323253330133370e0029001099191999911119191919192513024001301632533301d3370e900018101baa0011001153301f49012a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e0016330120070033022001301432533301b3370e9000180f1baa0011001153301d49012a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163300f005001300d48901ff00010001012005301b001300d00214a0602a6ea8004cc028c02c031200230170013009002301137540026600c600e0129000119ba548000cc04ccdd2a4004660266ea40052f5c06602666e9520024bd7025eb8088cc010dd6198031803998031803801240009002119baf3300730080014800000888cc00cdd6198029803198029803001240009000119baf3300630073300630070014800920000023001001222533301000213374a900125eb804c8c94ccc034c00c0084cdd2a40006602600497ae013330050050010033014003301200222323330010014800000c888cccc030cdc3802001009919980200219b8000348008c0540040048c02cdd50008a4c2c6002002444a666012004293099802980098058011998018019806001000ab9a5736ae7155ceaab9e5573eae815d0aba201",
|
"compiledCode": "59030501000032323232323232323232322225333006323232323232323232533300f3370e002900009925130090021533300f3370e0029001099191919299980999b87001480084c8c8cccc8888c8c8c8c8c9289812000980b19299980e99b8748000c080dd500088008a9980fa492a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e0016330120070033022001301432533301b3370e9000180f1baa0011001153301d49012a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163300f005001300d48901ff00010001012005301b001300d00214a0602a6ea8004cc028c02c03120023017001300900213232323253330133370e0029001099191999911119191919192513024001301632533301d3370e900018101baa0011001153301f49012a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e0016330120070033022001301432533301b3370e9000180f1baa0011001153301d49012a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163300f005001300d48901ff00010001012005301b001300d00214a0602a6ea8004cc028c02c031200230170013009002301137540026600c600e0129000119ba548000cc04ccdd2a4004660266ea40052f5c06602666e9520024bd7025eb8088cc010dd6198031803998031803801240009002119baf3300730080014800000888cc00cdd6198029803198029803001240009000119baf3300630073300630070014800920000023001001222533301000213374a900125eb804c8c94ccc034c00c0084cdd2a40006602600497ae013330050050010033014003301200222323330010014800000c888cccc030cdc3802001009919980200219b8000348008c0540040048c02cdd50008a4c2c6002002444a666012004293099802980098058011998018019806001000ab9a5736ae7155ceaab9e5573eae815d0aba201",
|
||||||
"hash": "c95b3842362b77afec21773b7c0b1f09e61bf5e4c58b685533e6d342"
|
"hash": "b79dffa847f2b9a55cb6cee2bd6057251f45e6a252587c7f6f3545d0"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
# This file was generated by Aiken
|
||||||
|
# You typically do not need to edit this file
|
||||||
|
|
||||||
|
[[requirements]]
|
||||||
|
name = "aiken-lang/stdlib"
|
||||||
|
version = "main"
|
||||||
|
source = "github"
|
||||||
|
|
||||||
|
[[packages]]
|
||||||
|
name = "aiken-lang/stdlib"
|
||||||
|
version = "main"
|
||||||
|
requirements = []
|
||||||
|
source = "github"
|
|
@ -0,0 +1,7 @@
|
||||||
|
name = "aiken-lang/acceptance_test_074"
|
||||||
|
version = "0.0.0"
|
||||||
|
|
||||||
|
[[dependencies]]
|
||||||
|
name = 'aiken-lang/stdlib'
|
||||||
|
version = 'main'
|
||||||
|
source = 'github'
|
|
@ -0,0 +1,282 @@
|
||||||
|
use aiken/bytearray.{from_string}
|
||||||
|
use aiken/hash.{Hash, Sha2_256, sha2_256}
|
||||||
|
use aiken/list
|
||||||
|
use aiken/option.{choice, is_none}
|
||||||
|
|
||||||
|
/// Variant of MerkleTree with only hash but without actual value
|
||||||
|
pub type MerkleTree<a> {
|
||||||
|
Empty
|
||||||
|
Leaf { hash: Hash<Sha2_256, ByteArray> }
|
||||||
|
Node {
|
||||||
|
hash: Hash<Sha2_256, ByteArray>,
|
||||||
|
left: MerkleTree<a>,
|
||||||
|
right: MerkleTree<a>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Proof =
|
||||||
|
List<ProofItem>
|
||||||
|
|
||||||
|
pub type ProofItem {
|
||||||
|
Left { hash: Hash<Sha2_256, ByteArray> }
|
||||||
|
Right { hash: Hash<Sha2_256, ByteArray> }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function returning a hash of a given Merkle Tree element
|
||||||
|
pub fn root_hash(self: MerkleTree<a>) -> Hash<Sha2_256, ByteArray> {
|
||||||
|
when self is {
|
||||||
|
Empty -> #""
|
||||||
|
Leaf { hash } -> hash
|
||||||
|
Node { hash, .. } -> hash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Function atests whether two Merkle Tress are equal, this is the case when their root hashes match.
|
||||||
|
pub fn is_equal(left: MerkleTree<a>, right: MerkleTree<a>) -> Bool {
|
||||||
|
root_hash(left) == root_hash(right)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Function returns a total numbers of leaves in the tree.
|
||||||
|
pub fn size(self: MerkleTree<a>) -> Int {
|
||||||
|
when self is {
|
||||||
|
Empty -> 0
|
||||||
|
Leaf{..} -> 1
|
||||||
|
Node { left, right, .. } -> size(left) + size(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn combine_hash(
|
||||||
|
left: Hash<Sha2_256, a>,
|
||||||
|
right: Hash<Sha2_256, a>,
|
||||||
|
) -> Hash<Sha2_256, a> {
|
||||||
|
sha2_256(bytearray.concat(left, right))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Function that returns whether merkle tree has any elements
|
||||||
|
pub fn is_empty(self: MerkleTree<a>) -> Bool {
|
||||||
|
when self is {
|
||||||
|
Empty -> True
|
||||||
|
_ -> False
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_proof(
|
||||||
|
self: MerkleTree<a>,
|
||||||
|
item_hash: Hash<Sha2_256, ByteArray>,
|
||||||
|
proof: Proof,
|
||||||
|
serialise_fn: fn(a) -> ByteArray,
|
||||||
|
) -> Option<Proof> {
|
||||||
|
when self is {
|
||||||
|
Empty -> None
|
||||||
|
Leaf { hash } ->
|
||||||
|
if hash == item_hash {
|
||||||
|
Some(proof)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
Node { left, right, .. } -> {
|
||||||
|
let rh = root_hash(right)
|
||||||
|
let lh = root_hash(left)
|
||||||
|
let go_left: Option<Proof> =
|
||||||
|
do_proof(
|
||||||
|
left,
|
||||||
|
item_hash,
|
||||||
|
list.push(proof, Right { hash: rh }),
|
||||||
|
serialise_fn,
|
||||||
|
)
|
||||||
|
let go_right: Option<Proof> =
|
||||||
|
do_proof(
|
||||||
|
right,
|
||||||
|
item_hash,
|
||||||
|
list.push(proof, Left { hash: lh }),
|
||||||
|
serialise_fn,
|
||||||
|
)
|
||||||
|
choice([go_left, go_right])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a membership 'Proof' from an element and a 'MerkleTree'. Returns
|
||||||
|
/// 'None' if the element isn't a member of the tree to begin with.
|
||||||
|
/// Note function will return Some([]) in case root of the tree is also it's only one and only element
|
||||||
|
pub fn get_proof(
|
||||||
|
self: MerkleTree<a>,
|
||||||
|
item: a,
|
||||||
|
serialise_fn: fn(a) -> ByteArray,
|
||||||
|
) -> Option<Proof> {
|
||||||
|
let empty: Proof = []
|
||||||
|
|
||||||
|
do_proof(self, sha2_256(serialise_fn(item)), empty, serialise_fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_from_list(
|
||||||
|
items: List<a>,
|
||||||
|
len: Int,
|
||||||
|
serialise_fn: fn(a) -> ByteArray,
|
||||||
|
) -> MerkleTree<a> {
|
||||||
|
when items is {
|
||||||
|
[] -> Empty
|
||||||
|
[item] -> {
|
||||||
|
let hashed_item = sha2_256(serialise_fn(item))
|
||||||
|
Leaf { hash: hashed_item }
|
||||||
|
}
|
||||||
|
all -> {
|
||||||
|
let cutoff: Int = len / 2
|
||||||
|
let left =
|
||||||
|
all
|
||||||
|
|> list.take(cutoff)
|
||||||
|
|> do_from_list(cutoff, serialise_fn)
|
||||||
|
let right =
|
||||||
|
all
|
||||||
|
|> list.drop(cutoff)
|
||||||
|
|> do_from_list(len - cutoff, serialise_fn)
|
||||||
|
let hash = combine_hash(root_hash(left), root_hash(right))
|
||||||
|
Node { hash, left, right }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a 'MerkleTree' from a list of elements.
|
||||||
|
/// Note that, while this operation is doable on-chain, it is expensive and
|
||||||
|
/// preferably done off-chain.
|
||||||
|
pub fn from_list(
|
||||||
|
items: List<a>,
|
||||||
|
serialise_fn: fn(a) -> ByteArray,
|
||||||
|
) -> MerkleTree<a> {
|
||||||
|
do_from_list(items, list.length(items), serialise_fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_from_hashes_list(
|
||||||
|
items: List<Hash<Sha2_256, a>>,
|
||||||
|
len: Int,
|
||||||
|
) -> MerkleTree<a> {
|
||||||
|
when items is {
|
||||||
|
[] -> Empty
|
||||||
|
[hashed_item] -> Leaf { hash: hashed_item }
|
||||||
|
all -> {
|
||||||
|
let cutoff: Int = len / 2
|
||||||
|
let left =
|
||||||
|
all
|
||||||
|
|> list.take(cutoff)
|
||||||
|
|> do_from_hashes_list(cutoff)
|
||||||
|
let right =
|
||||||
|
all
|
||||||
|
|> list.drop(cutoff)
|
||||||
|
|> do_from_hashes_list(len - cutoff)
|
||||||
|
let hash = combine_hash(root_hash(left), root_hash(right))
|
||||||
|
Node { hash, left, right }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a 'MerkleTree' from a list of hashes.
|
||||||
|
/// Note that, while this operation is doable on-chain, it is expensive and
|
||||||
|
/// preferably done off-chain.
|
||||||
|
pub fn from_hashes_list(items: List<Hash<Sha2_256, a>>) -> MerkleTree<a> {
|
||||||
|
do_from_hashes_list(items, list.length(items))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether a hashed element is part of a 'MerkleTree' using only its root hash
|
||||||
|
// and a 'Proof'. The proof is guaranteed to be in log(n) of the size of the
|
||||||
|
// tree, which is why we are interested in such data-structure in the first
|
||||||
|
// place.
|
||||||
|
pub fn member_from_hash(
|
||||||
|
item_hash: Hash<Sha2_256, a>,
|
||||||
|
root_hash: Hash<Sha2_256, a>,
|
||||||
|
proof: Proof,
|
||||||
|
serialise_fn: fn(a) -> ByteArray,
|
||||||
|
) -> Bool {
|
||||||
|
when proof is {
|
||||||
|
[] -> root_hash == item_hash
|
||||||
|
[head, ..tail] ->
|
||||||
|
when head is {
|
||||||
|
Left { hash: l } ->
|
||||||
|
member_from_hash(
|
||||||
|
combine_hash(l, item_hash),
|
||||||
|
root_hash,
|
||||||
|
tail,
|
||||||
|
serialise_fn,
|
||||||
|
)
|
||||||
|
Right { hash: r } ->
|
||||||
|
member_from_hash(
|
||||||
|
combine_hash(item_hash, r),
|
||||||
|
root_hash,
|
||||||
|
tail,
|
||||||
|
serialise_fn,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether an element is part of a 'MerkleTree' using only its root hash
|
||||||
|
// and a 'Proof'.
|
||||||
|
pub fn member(
|
||||||
|
item: a,
|
||||||
|
root_hash: Hash<Sha2_256, ByteArray>,
|
||||||
|
proof: Proof,
|
||||||
|
serialise_fn: fn(a) -> ByteArray,
|
||||||
|
) -> Bool {
|
||||||
|
let item_hash = sha2_256(serialise_fn(item))
|
||||||
|
member_from_hash(item_hash, root_hash, proof, serialise_fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn member_from_tree(
|
||||||
|
tree: MerkleTree<a>,
|
||||||
|
item: a,
|
||||||
|
serialise_fn: fn(a) -> ByteArray,
|
||||||
|
) -> Bool {
|
||||||
|
let proof: Option<Proof> = get_proof(tree, item, serialise_fn)
|
||||||
|
let rh = root_hash(tree)
|
||||||
|
|
||||||
|
when proof is {
|
||||||
|
Some(p) -> member(item, rh, p, serialise_fn)
|
||||||
|
None -> False
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// needed only for tests
|
||||||
|
fn create_string_item_serialise_fn() -> fn(String) -> ByteArray {
|
||||||
|
fn(x: String) { from_string(x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
test from_hashes_list_5() {
|
||||||
|
let dog = @"dog"
|
||||||
|
let cat = @"cat"
|
||||||
|
let mouse = @"mouse"
|
||||||
|
let horse = @"horse"
|
||||||
|
|
||||||
|
let serialise_fn = create_string_item_serialise_fn()
|
||||||
|
|
||||||
|
let items = [dog, cat, mouse, horse]
|
||||||
|
let hashes_items = list.map(items, fn(item) { sha2_256(serialise_fn(item)) })
|
||||||
|
|
||||||
|
let mt = from_hashes_list(hashes_items)
|
||||||
|
|
||||||
|
let left_node_hash =
|
||||||
|
sha2_256(
|
||||||
|
bytearray.concat(sha2_256(serialise_fn(dog)), sha2_256(serialise_fn(cat))),
|
||||||
|
)
|
||||||
|
let right_node_hash =
|
||||||
|
sha2_256(
|
||||||
|
bytearray.concat(
|
||||||
|
sha2_256(serialise_fn(mouse)),
|
||||||
|
sha2_256(serialise_fn(horse)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
let root_hash = sha2_256(bytearray.concat(left_node_hash, right_node_hash))
|
||||||
|
|
||||||
|
Node {
|
||||||
|
hash: root_hash,
|
||||||
|
left: Node {
|
||||||
|
hash: left_node_hash,
|
||||||
|
left: Leaf { hash: sha2_256(serialise_fn(dog)) },
|
||||||
|
right: Leaf { hash: sha2_256(serialise_fn(cat)) },
|
||||||
|
},
|
||||||
|
right: Node {
|
||||||
|
hash: right_node_hash,
|
||||||
|
left: Leaf { hash: sha2_256(serialise_fn(mouse)) },
|
||||||
|
right: Leaf { hash: sha2_256(serialise_fn(horse)) },
|
||||||
|
},
|
||||||
|
} == mt
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
# This file was generated by Aiken
|
||||||
|
# You typically do not need to edit this file
|
||||||
|
|
||||||
|
requirements = []
|
||||||
|
packages = []
|
|
@ -0,0 +1,3 @@
|
||||||
|
name = 'aiken-lang/acceptance_test_076'
|
||||||
|
version = '0.0.0'
|
||||||
|
description = ''
|
|
@ -0,0 +1,5 @@
|
||||||
|
test expect_positive() {
|
||||||
|
let val = 5
|
||||||
|
expect True = val > 0
|
||||||
|
True
|
||||||
|
}
|
|
@ -6,45 +6,19 @@
|
||||||
},
|
},
|
||||||
"validators": [
|
"validators": [
|
||||||
{
|
{
|
||||||
"title": "basic.spend",
|
"title": "deploy.spend",
|
||||||
"datum": {
|
"datum": {
|
||||||
"title": "Unit",
|
"title": "Data",
|
||||||
"description": "The nullary constructor.",
|
"description": "Any Plutus data.",
|
||||||
"schema": {
|
"schema": {}
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"dataType": "constructor",
|
|
||||||
"index": 0,
|
|
||||||
"fields": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"redeemer": {
|
|
||||||
"title": "Unit",
|
|
||||||
"description": "The nullary constructor.",
|
|
||||||
"schema": {
|
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"dataType": "constructor",
|
|
||||||
"index": 0,
|
|
||||||
"fields": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"compiledCode": "5904600100003232323232323232323222253330063232323232300200132323232323233015333010323330113375e660146016002900b26126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff004a0944cc024c02802d20004c0103d87a80004c0103d879800033015333010323253330123370e002900109919299980a19baf3300d300e00148001300126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff0013370e6eb4cc034c038005200248000528180c80098060010b18099baa00133009300a00b48009300103d87a80004c0103d8798000330153330103232533301600116132533301700113232300c001330193330143375e6e98dd5998069807000a40046e98c0152080a8d6b9074c0103d87a80004c0103d8798000330193330143375e6601a601c6601a601c002900024000980122d8799f581c11111111111111111111111111111111111111111111111111111111ff004c0103d87a80004c0103d879800033019333014323253330163370e0029000099250301000214a2602e6ea8004cc034c038cc034c038005200048009300103d87a80004c0103d8798000330193330143375e6601a601c002900219ba5480012f5c098103d87a80004c0103d8798000330193330143375e6601a601c002900319ba5480092f5c098103d87a80004c0103d87980004bd70180c8010b180c8009bac3300a300b00148010cc024c02802d20004c0103d87a80004c0103d879800033015333010323375e6e98dd5998051805800a400c6e98c009205433009300a00b4800130103d87a80004c0103d87980004bd7011999111919000999991111999805002001801000a5eb7bdb180010004020cccc8888cccc03001000c0080052f5bded8c000400200e9101004881000013001001222225333016004133017337606ea400cdd300125eb7bdb1804c8c8c8c94ccc058cdd79980280380099ba5480012f5c026603666ec0dd48039ba6006008153330163371e00e00226603666ec0dd48039ba600600313301b337606ea4004dd3001199998048048018038030029bae30170033756602e004603400a603000844a66601c66e400080044cdd2a400097ae01533300e3371e004002266e9520024bd70099ba5480112f5c0600200244444a66602600826602866ec0dd48019ba80024bd6f7b630099191919299980999baf330050070013374a900025eb804cc060cdd81ba9007375000c0102a66602666e3c01c0044cc060cdd81ba9007375000c00626603066ec0dd48009ba800233333009009003007006005375c60280066eb4c050008c05c014c054010c004004894ccc0380045288991929998060010998020020008a5030120023370e900118061baa301000122323330010014800000c888cccc030cdc3802001009119980200219b8000348008c0500040048c028dd50008a4c2c6002002444a666010004293099802980098050011998018019805801000ab9a5736aae7555cf2ab9f5740ae855d101",
|
|
||||||
"hash": "42428cc55092a182161081f528491b8ec1fbd908c40eca9069c4d1be"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": "mint.mint",
|
|
||||||
"redeemer": {
|
"redeemer": {
|
||||||
"title": "Data",
|
"title": "Data",
|
||||||
"description": "Any Plutus data.",
|
"description": "Any Plutus data.",
|
||||||
"schema": {}
|
"schema": {}
|
||||||
},
|
},
|
||||||
"compiledCode": "590488010000323232323232323232323222533300532323232323001003300100122533300f00114a226464a6660180042660080080022940c04c008cdc3a4004601a6ea8c044004cc034ccc01cc8c8c8c8c8c8c94ccc04cc0580084c8c8cdc78018009bae3016001300932533300f3370e900018091baa0011001153301149012a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163300830090034800854cc0412401364c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2069742065787065637465640016375c602800264646464600c00200200264640026644660100040020029110000137566600c600e6600c600e00290002401000e600200244a666020002297ae01323232323301537520026600c00c0066eb8c04400cdd59808801180a0011809000980080091129998078010a5eb7bdb1804c8c8c8c94ccc038cdc7802800880189980a19bb037520026e98008ccc01c01c00c014dd718080019bab3010002301300330110024c103d87a80004c0103d87980003300d333007323232323322323232323253330123370e00290010b0991919b87001483c850dd6980d0009806801180a1baa001332233008002001001488103666f6f0033223233223253330153370e00290010801099190009bab301d00130100033017375400400297adef6c6033223300b002001002001375666012601400690040009bae30150013008533300d3370e900018081baa0021002153300f49012a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e001633005300600748008cc014c01801d20003001001222533301100213374a900125eb804c8c8c8c94ccc040cdc7802800899ba548000cc058dd400125eb804ccc01c01c00c014dd718090019bad3012002301500330130023001001222533300f00213374a900125eb804c8c8c8c94ccc038cdc7802800899ba548000cc050dd300125eb804ccc01c01c00c014dd718080019bab3010002301300330110024c103d87a80004c0103d87980003300d3330073232323233223232533300f3375e006002266e1cc8c018004dd5998049805198049805002240009009240042940c054004c020c94ccc038cdc3a400060226ea8004400454cc0412412a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e001633223300700200137566600e60106600e60100049000240246600e6010004900100380418008009129998080008a400026466e0120023300300300130130013001001222533300f00213374a900125eb804c8c8c8c94ccc038cdd7802800899ba548000cc0500092f5c0266600e00e00600a6020006602000460260066022004980103d87a80004c0103d87980004bd701119199800800a4000006444666601666e1c0100080488ccc010010cdc0001a40046028002002460146ea8004526163001001222533300900214984cc014c004c02c008ccc00c00cc0300080055cd2b9b5738aae7555cf2ab9f5740ae855d11",
|
"compiledCode": "5903e101000032323232323232323232322225333006323232323230020013301033300a32323375e0040026601893260103d87980000074c103d87a80004c0103d87980003301033300a32323232323232330123253330123370e002900009919299980c980e0010a4c2a6602c921364c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2069742065787065637465640016375a603400260180042a660289212b436f6e73747220696e64657820646964206e6f74206d6174636820616e7920747970652076617269616e74001630143754002a66602266ebd30106d8799f182aff0000113370e64600a00200690020a50301700130093253330103370e900018099baa0011001153301249012a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163322330060020010013237280026ecd30106d8799f182aff0037566600e60106600e6010012900024028600200244a6660260022900009919b8048008cc00c00c004c058004c0040048894ccc0480084cdd2a400497ae013232323253330113371e00a002266e952000330170024bd7009998038038018029bae30130033013002301600330140024c0103d87a80004c0103d87980003301033300a32533301000116132533301100116132323232533301032323009001330173330113375e660146016002900226126d87a9f5820fcaa61fb85676101d9e3398a484674e71c45c3fd41b492682f3b0054f4cf3273ff004c0103d87a80004c0103d8798000330173330113375e6601460160029003260122d8799f581ce37db487fbd58c45d059bcbf5cd6b1604d3bec16cf888f1395a4ebc4ff004c0103d87a80004c0103d87980004bd700010991918048009980b99980899baf3300a300b3300a300b0014800120024c012ad8799fd8799fd8799f581c66666666666666666666666666666666666666666666666666666666ffffff004c0103d87a80004c0103d879800033017333011323253330133370e0029002099251300d00216301537540026601460160029002260103d87a80004c0103d87980004bd700008a50301600430150041630140013013001375866006600866006600800a900024008980103d87a80004c0103d87980004bd7018008009129998078008a5113232533300c00213300400400114a0602600466e1d2002300d3754602200244646660020029000001911199980619b870040020132333004004337000069001180a800800918059baa001149858c0040048894ccc0240085261330053001300b002333003003300c0020015734ae6d5ce2ab9d5573caae7d5d02ba15745",
|
||||||
"hash": "dbc571e23778572680144ee7065334ab9545cc8111da1ea5dc85ac44"
|
"hash": "3326c651fce284b443e23da9cc6f5864a1e496f2fc7774799fb897f9"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "withdrawals.spend",
|
"title": "withdrawals.spend",
|
||||||
|
@ -78,19 +52,45 @@
|
||||||
"hash": "6917ce2313801b854e38507b68d2c61afd70fca721804235e4760056"
|
"hash": "6917ce2313801b854e38507b68d2c61afd70fca721804235e4760056"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "deploy.spend",
|
"title": "mint.mint",
|
||||||
"datum": {
|
|
||||||
"title": "Data",
|
|
||||||
"description": "Any Plutus data.",
|
|
||||||
"schema": {}
|
|
||||||
},
|
|
||||||
"redeemer": {
|
"redeemer": {
|
||||||
"title": "Data",
|
"title": "Data",
|
||||||
"description": "Any Plutus data.",
|
"description": "Any Plutus data.",
|
||||||
"schema": {}
|
"schema": {}
|
||||||
},
|
},
|
||||||
"compiledCode": "5903e101000032323232323232323232322225333006323232323230020013301033300a32323375e0040026601893260103d87980000074c103d87a80004c0103d87980003301033300a32323232323232330123253330123370e002900009919299980c980e0010a4c2a6602c921364c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2069742065787065637465640016375a603400260180042a660289212b436f6e73747220696e64657820646964206e6f74206d6174636820616e7920747970652076617269616e74001630143754002a66602266ebd30106d8799f182aff0000113370e64600a00200690020a50301700130093253330103370e900018099baa0011001153301249012a4173736572746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163322330060020010013237280026ecd30106d8799f182aff0037566600e60106600e6010012900024028600200244a6660260022900009919b8048008cc00c00c004c058004c0040048894ccc0480084cdd2a400497ae013232323253330113371e00a002266e952000330170024bd7009998038038018029bae30130033013002301600330140024c0103d87a80004c0103d87980003301033300a32533301000116132533301100116132323232533301032323009001330173330113375e660146016002900226126d87a9f5820fcaa61fb85676101d9e3398a484674e71c45c3fd41b492682f3b0054f4cf3273ff004c0103d87a80004c0103d8798000330173330113375e6601460160029003260122d8799f581ce37db487fbd58c45d059bcbf5cd6b1604d3bec16cf888f1395a4ebc4ff004c0103d87a80004c0103d87980004bd700010991918048009980b99980899baf3300a300b3300a300b0014800120024c012ad8799fd8799fd8799f581c66666666666666666666666666666666666666666666666666666666ffffff004c0103d87a80004c0103d879800033017333011323253330133370e0029002099251300d00216301537540026601460160029002260103d87a80004c0103d87980004bd700008a50301600430150041630140013013001375866006600866006600800a900024008980103d87a80004c0103d87980004bd7018008009129998078008a5113232533300c00213300400400114a0602600466e1d2002300d3754602200244646660020029000001911199980619b870040020132333004004337000069001180a800800918059baa001149858c0040048894ccc0240085261330053001300b002333003003300c0020015734ae6d5ce2ab9d5573caae7d5d02ba15745",
|
"compiledCode": "590488010000323232323232323232323222533300532323232323001003300100122533300f00114a226464a6660180042660080080022940c04c008cdc3a4004601a6ea8c044004cc034ccc01cc8c8c8c8c8c8c94ccc04cc0580084c8c8cdc78018009bae3016001300932533300f3370e900018091baa0011001153301149012a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e00163300830090034800854cc0412401364c6973742f5475706c652f436f6e73747220636f6e7461696e73206d6f7265206974656d73207468616e2069742065787065637465640016375c602800264646464600c00200200264640026644660100040020029110000137566600c600e6600c600e00290002401000e600200244a666020002297ae01323232323301537520026600c00c0066eb8c04400cdd59808801180a0011809000980080091129998078010a5eb7bdb1804c8c8c8c94ccc038cdc7802800880189980a19bb037520026e98008ccc01c01c00c014dd718080019bab3010002301300330110024c103d87a80004c0103d87980003300d333007323232323322323232323253330123370e00290010b0991919b87001483c850dd6980d0009806801180a1baa001332233008002001001488103666f6f0033223233223253330153370e00290010801099190009bab301d00130100033017375400400297adef6c6033223300b002001002001375666012601400690040009bae30150013008533300d3370e900018081baa0021002153300f49012a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e001633005300600748008cc014c01801d20003001001222533301100213374a900125eb804c8c8c8c94ccc040cdc7802800899ba548000cc058dd400125eb804ccc01c01c00c014dd718090019bad3012002301500330130023001001222533300f00213374a900125eb804c8c8c8c94ccc038cdc7802800899ba548000cc050dd300125eb804ccc01c01c00c014dd718080019bab3010002301300330110024c103d87a80004c0103d87980003300d3330073232323233223232533300f3375e006002266e1cc8c018004dd5998049805198049805002240009009240042940c054004c020c94ccc038cdc3a400060226ea8004400454cc0412412a4578706563746564206f6e20696e636f727265637420636f6e7374727563746f722076617269616e742e001633223300700200137566600e60106600e60100049000240246600e6010004900100380418008009129998080008a400026466e0120023300300300130130013001001222533300f00213374a900125eb804c8c8c8c94ccc038cdd7802800899ba548000cc0500092f5c0266600e00e00600a6020006602000460260066022004980103d87a80004c0103d87980004bd701119199800800a4000006444666601666e1c0100080488ccc010010cdc0001a40046028002002460146ea8004526163001001222533300900214984cc014c004c02c008ccc00c00cc0300080055cd2b9b5738aae7555cf2ab9f5740ae855d11",
|
||||||
"hash": "6bfde537ea8bcb1b566489979896ecc8f88c6edb2f791a4197e2d51f"
|
"hash": "4621310698e9ee7830df98d79551eb5672cdee04247e28c8e1c1d494"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "basic.spend",
|
||||||
|
"datum": {
|
||||||
|
"title": "Unit",
|
||||||
|
"description": "The nullary constructor.",
|
||||||
|
"schema": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"dataType": "constructor",
|
||||||
|
"index": 0,
|
||||||
|
"fields": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"redeemer": {
|
||||||
|
"title": "Unit",
|
||||||
|
"description": "The nullary constructor.",
|
||||||
|
"schema": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"dataType": "constructor",
|
||||||
|
"index": 0,
|
||||||
|
"fields": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"compiledCode": "59046f0100003232323232323232323222253330063232323232300200132323232323233015333010323330113375e660146016002900b26126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff004a0944cc024c02802d20004c0103d87a80004c0103d879800033015333010323253330123370e002900109919299980a19baf3300d300e00148001300126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff0013370e6eb4cc034c038005200248000528180c80098060010b18099baa00133009300a00b48009300103d87a80004c0103d8798000330153330103232533301600116132533301700113232300c001330193330143375e6e98dd5998069807000a40046e98c0152080a8d6b9074c0103d87a80004c0103d8798000330193330143375e6601a601c6601a601c002900024000980122d8799f581c11111111111111111111111111111111111111111111111111111111ff004c0103d87a80004c0103d879800033019333014323253330163370e0029000099250301000214a2602e6ea8004cc034c038cc034c038005200048009300103d87a80004c0103d8798000330193330143375e6601a601c002900219ba5480012f5c098103d87a80004c0103d8798000330193330143375e6601a601c002900319ba5480092f5c098103d87a80004c0103d87980004bd70180c8010b180c8009bac3300a300b00148010cc024c02802d20004c0103d87a80004c0103d879800033015333010323375e6e98dd5998051805800a400c6e98c009205433009300a00b4800130103d87a80004c0103d87980004bd701199911299980999b870014800052f5bded8c02646400266664444666601400800600400297adef6c6000400100833332222333300c0040030020014bd6f7b630001000803a45004881000013001001222225333016004133017337606ea400cdd300125eb7bdb1804c8c8c8c94ccc058cdd79980280380099ba5480012f5c026603666ec0dd48039ba6006008153330163371e00e00226603666ec0dd48039ba600600313301b337606ea4004dd3001199998048048018038030029bae30170033756602e004603400a603000844a66601c66e400080044cdd2a400097ae01533300e3371e004002266e9520024bd70099ba5480112f5c0600200244444a66602600826602866ec0dd48019ba80024bd6f7b630099191919299980999baf330050070013374a900025eb804cc060cdd81ba9007375000c0102a66602666e3c01c0044cc060cdd81ba9007375000c00626603066ec0dd48009ba800233333009009003007006005375c60280066eb4c050008c05c014c054010c004004894ccc0380045288991929998060010998020020008a5030120023370e900118061baa301000122323330010014800000c888cccc030cdc3802001009119980200219b8000348008c0500040048c028dd50008a4c2c6002002444a666010004293099802980098050011998018019805801000ab9a5736aae7555cf2ab9f5740ae855d101",
|
||||||
|
"hash": "911eb2bc725e7a51670338f2a12102785984d2569fa75b6ba4054c49"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Loading…
Reference in New Issue