fixes: tuple clauses, zero args funcs, list clause named pattern
List Clauses patterns handle var cases Fixed Tuple Clauses issue with last clause not being a tuple Redid how zero arg functions and dependencies are handled. Tough one lol
This commit is contained in:
parent
23bf101e08
commit
32b0200966
|
@ -31,6 +31,7 @@ pub struct FuncComponents {
|
|||
pub dependencies: Vec<FunctionAccessKey>,
|
||||
pub args: Vec<String>,
|
||||
pub recursive: bool,
|
||||
pub defined_by_zero_arg: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, Debug, PartialEq, Hash)]
|
||||
|
@ -1862,8 +1863,7 @@ pub fn handle_func_dependencies_ir(
|
|||
dependency_vec.reverse();
|
||||
|
||||
while let Some(dependency) = dependency_vec.pop() {
|
||||
if (defined_functions.contains_key(&dependency) && !funt_comp.args.is_empty())
|
||||
|| func_components.get(&dependency).is_none()
|
||||
if defined_functions.contains_key(&dependency) || func_components.get(&dependency).is_none()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -1874,31 +1874,27 @@ pub fn handle_func_dependencies_ir(
|
|||
if get_common_ancestor(dep_scope, func_scope) == func_scope.to_vec()
|
||||
|| funt_comp.args.is_empty()
|
||||
{
|
||||
// we handle zero arg functions and their dependencies in a unique way
|
||||
if !depend_comp.args.is_empty() {
|
||||
let mut recursion_ir = vec![];
|
||||
handle_recursion_ir(&dependency, depend_comp, &mut recursion_ir);
|
||||
let mut recursion_ir = vec![];
|
||||
handle_recursion_ir(&dependency, depend_comp, &mut recursion_ir);
|
||||
|
||||
let mut temp_ir = vec![Air::DefineFunc {
|
||||
scope: func_scope.to_vec(),
|
||||
func_name: dependency.function_name.clone(),
|
||||
module_name: dependency.module_name.clone(),
|
||||
params: depend_comp.args.clone(),
|
||||
recursive: depend_comp.recursive,
|
||||
variant_name: dependency.variant_name.clone(),
|
||||
}];
|
||||
let mut temp_ir = vec![Air::DefineFunc {
|
||||
scope: func_scope.to_vec(),
|
||||
func_name: dependency.function_name.clone(),
|
||||
module_name: dependency.module_name.clone(),
|
||||
params: depend_comp.args.clone(),
|
||||
recursive: depend_comp.recursive,
|
||||
variant_name: dependency.variant_name.clone(),
|
||||
}];
|
||||
|
||||
temp_ir.append(&mut recursion_ir);
|
||||
temp_ir.append(&mut recursion_ir);
|
||||
|
||||
temp_ir.append(dependencies_ir);
|
||||
temp_ir.append(dependencies_ir);
|
||||
|
||||
*dependencies_ir = temp_ir;
|
||||
if get_common_ancestor(dep_scope, func_scope) == func_scope.to_vec() {
|
||||
defined_functions.insert(dependency, ());
|
||||
}
|
||||
*dependencies_ir = temp_ir;
|
||||
if get_common_ancestor(dep_scope, func_scope) == func_scope.to_vec() {
|
||||
defined_functions.insert(dependency, ());
|
||||
}
|
||||
} else {
|
||||
// Dependency will need to be defined somewhere in the main body
|
||||
} else if depend_comp.args.is_empty() {
|
||||
to_be_defined.insert(dependency, ());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -411,7 +411,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
|
||||
final_scope.push(self.id_gen.next());
|
||||
|
||||
if !matches!(clause_properties, ClauseProperties::TupleClause { .. }) {
|
||||
if !matches!(last_pattern, Pattern::Tuple { .. }) {
|
||||
pattern_vec.push(Air::Finally {
|
||||
scope: final_scope.clone(),
|
||||
});
|
||||
|
@ -773,8 +773,14 @@ impl<'a> CodeGenerator<'a> {
|
|||
let current_clause_index =
|
||||
if let Pattern::List { elements, .. } = &clause.pattern[0] {
|
||||
elements.len()
|
||||
} else if let Pattern::Assign { pattern, .. } = &clause.pattern[0] {
|
||||
if let Pattern::List { elements, .. } = pattern.as_ref() {
|
||||
elements.len()
|
||||
} else {
|
||||
unreachable!("{:#?}", pattern)
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
unreachable!("{:#?}", &clause.pattern[0])
|
||||
};
|
||||
|
||||
let prev_index = *current_index;
|
||||
|
@ -801,6 +807,14 @@ impl<'a> CodeGenerator<'a> {
|
|||
&clauses[index + 1].pattern[0]
|
||||
{
|
||||
elements.len()
|
||||
} else if let Pattern::Assign { pattern, .. } =
|
||||
&clauses[index + 1].pattern[0]
|
||||
{
|
||||
if let Pattern::List { elements, .. } = pattern.as_ref() {
|
||||
elements.len()
|
||||
} else {
|
||||
unreachable!("{:#?}", pattern)
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
|
@ -2755,33 +2769,55 @@ impl<'a> CodeGenerator<'a> {
|
|||
|
||||
let recursion_func_map = IndexMap::new();
|
||||
|
||||
self.define_recurse_ir(
|
||||
self.define_ir_recurse(
|
||||
ir_stack,
|
||||
&mut func_components,
|
||||
&mut func_index_map,
|
||||
recursion_func_map,
|
||||
false,
|
||||
);
|
||||
|
||||
let mut final_func_dep_ir = IndexMap::new();
|
||||
let mut zero_arg_defined_functions = IndexMap::new();
|
||||
let mut to_be_defined = IndexMap::new();
|
||||
|
||||
let mut dependency_map = IndexMap::new();
|
||||
let mut dependency_vec = vec![];
|
||||
|
||||
let mut func_keys = func_components.keys().cloned().collect_vec();
|
||||
let mut func_keys = func_components
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter(|(_, val)| !val.defined_by_zero_arg)
|
||||
.map(|(key, val)| (key, val.defined_by_zero_arg))
|
||||
.collect_vec();
|
||||
|
||||
// deal with function dependencies by sorting order in which we iter over them.
|
||||
while let Some(function) = func_keys.pop() {
|
||||
let funct_comp = func_components.get(&function).unwrap();
|
||||
if dependency_map.contains_key(&function) {
|
||||
dependency_map.shift_remove(&function);
|
||||
let funct_comp = func_components.get(&function.0).unwrap();
|
||||
if dependency_map.contains_key(&function.0) {
|
||||
dependency_map.shift_remove(&function.0);
|
||||
}
|
||||
dependency_map.insert(function, ());
|
||||
func_keys.extend(funct_comp.dependencies.clone().into_iter());
|
||||
dependency_map.insert(function.0, function.1);
|
||||
func_keys.extend(
|
||||
funct_comp
|
||||
.dependencies
|
||||
.iter()
|
||||
.map(|key| {
|
||||
(
|
||||
key.clone(),
|
||||
func_components.get(key).unwrap().defined_by_zero_arg,
|
||||
)
|
||||
})
|
||||
.collect_vec(),
|
||||
);
|
||||
}
|
||||
|
||||
dependency_vec.extend(dependency_map.keys().cloned());
|
||||
dependency_vec.extend(
|
||||
dependency_map
|
||||
.iter()
|
||||
.filter(|(_, defined_in_zero_arg)| !**defined_in_zero_arg)
|
||||
.map(|(key, _)| key.clone())
|
||||
.collect_vec(),
|
||||
);
|
||||
|
||||
for func in dependency_vec {
|
||||
if self.defined_functions.contains_key(&func) {
|
||||
|
@ -2808,6 +2844,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
// since zero arg functions are run at compile time we need to pull all deps
|
||||
// note anon functions are not included in the above. They exist in a function anyway
|
||||
let mut defined_functions = IndexMap::new();
|
||||
|
||||
// deal with function dependencies in zero arg functions
|
||||
handle_func_dependencies_ir(
|
||||
&mut dep_ir,
|
||||
|
@ -2816,7 +2853,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
&mut defined_functions,
|
||||
&func_index_map,
|
||||
func_scope,
|
||||
&mut IndexMap::new(),
|
||||
&mut to_be_defined,
|
||||
);
|
||||
|
||||
let mut final_zero_arg_ir = dep_ir;
|
||||
|
@ -2827,18 +2864,33 @@ impl<'a> CodeGenerator<'a> {
|
|||
self.zero_arg_functions.insert(func, final_zero_arg_ir);
|
||||
// zero arg functions don't contain the dependencies since they are pre-evaluated
|
||||
// As such we add functions to defined only after dependencies for all other functions are calculated
|
||||
for (key, val) in defined_functions.into_iter() {
|
||||
zero_arg_defined_functions.insert(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle functions that are used in zero arg funcs but also used by the validator
|
||||
// or a func used by the validator
|
||||
for (key, val) in zero_arg_defined_functions.into_iter() {
|
||||
if !to_be_defined.contains_key(&key) {
|
||||
self.defined_functions.insert(key, val);
|
||||
}
|
||||
while let Some(func) = to_be_defined.pop() {
|
||||
let mut dep_ir = vec![];
|
||||
let mut defined_functions = IndexMap::new();
|
||||
// deal with function dependencies in zero arg functions
|
||||
|
||||
let funt_comp = func_components.get(&func.0).unwrap();
|
||||
let func_scope = func_index_map.get(&func.0).unwrap();
|
||||
|
||||
handle_func_dependencies_ir(
|
||||
&mut dep_ir,
|
||||
funt_comp,
|
||||
&func_components,
|
||||
&mut defined_functions,
|
||||
&func_index_map,
|
||||
func_scope,
|
||||
&mut to_be_defined,
|
||||
);
|
||||
|
||||
let mut final_zero_arg_ir = dep_ir;
|
||||
final_zero_arg_ir.extend(funt_comp.ir.clone());
|
||||
|
||||
self.convert_opaque_type_to_inner_ir(&mut final_zero_arg_ir);
|
||||
|
||||
self.zero_arg_functions.insert(func.0, final_zero_arg_ir);
|
||||
}
|
||||
|
||||
for (index, ir) in ir_stack.clone().into_iter().enumerate().rev() {
|
||||
|
@ -2850,6 +2902,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
get_common_ancestor(&func.1, &ir.scope()) == ir.scope()
|
||||
&& !self.defined_functions.contains_key(&func.0)
|
||||
&& !self.zero_arg_functions.contains_key(&func.0)
|
||||
&& !(*dependency_map.get(&func.0).unwrap())
|
||||
})
|
||||
.collect_vec();
|
||||
|
||||
|
@ -2894,14 +2947,15 @@ impl<'a> CodeGenerator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn define_recurse_ir(
|
||||
fn define_ir_recurse(
|
||||
&mut self,
|
||||
ir_stack: &mut [Air],
|
||||
func_components: &mut IndexMap<FunctionAccessKey, FuncComponents>,
|
||||
func_index_map: &mut IndexMap<FunctionAccessKey, Vec<u64>>,
|
||||
mut recursion_func_map: IndexMap<FunctionAccessKey, ()>,
|
||||
in_zero_arg_func: bool,
|
||||
) {
|
||||
self.process_define_ir(ir_stack, func_components, func_index_map);
|
||||
self.define_ir_processor(ir_stack, func_components, func_index_map, in_zero_arg_func);
|
||||
|
||||
let mut recursion_func_map_to_add = recursion_func_map.clone();
|
||||
|
||||
|
@ -2910,6 +2964,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
|
||||
let function_components = func_components.get_mut(func).unwrap();
|
||||
let mut function_ir = function_components.ir.clone();
|
||||
let in_zero_arg = function_components.args.is_empty() || in_zero_arg_func;
|
||||
let mut skip = false;
|
||||
|
||||
for ir in function_ir.clone() {
|
||||
|
@ -2965,18 +3020,22 @@ impl<'a> CodeGenerator<'a> {
|
|||
|
||||
let mut inner_func_index_map = IndexMap::new();
|
||||
|
||||
self.define_recurse_ir(
|
||||
self.define_ir_recurse(
|
||||
&mut function_ir,
|
||||
&mut inner_func_components,
|
||||
&mut inner_func_index_map,
|
||||
recursion_func_map.clone(),
|
||||
in_zero_arg,
|
||||
);
|
||||
|
||||
function_components.ir = function_ir;
|
||||
|
||||
//now unify
|
||||
for item in inner_func_components {
|
||||
if !func_components.contains_key(&item.0) {
|
||||
if let Some(entry) = func_components.get_mut(&item.0) {
|
||||
entry.defined_by_zero_arg =
|
||||
entry.defined_by_zero_arg && item.1.defined_by_zero_arg
|
||||
} else {
|
||||
func_components.insert(item.0, item.1);
|
||||
}
|
||||
}
|
||||
|
@ -2992,11 +3051,12 @@ impl<'a> CodeGenerator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn process_define_ir(
|
||||
fn define_ir_processor(
|
||||
&mut self,
|
||||
ir_stack: &mut [Air],
|
||||
func_components: &mut IndexMap<FunctionAccessKey, FuncComponents>,
|
||||
func_index_map: &mut IndexMap<FunctionAccessKey, Vec<u64>>,
|
||||
in_zero_arg_func: bool,
|
||||
) {
|
||||
let mut to_be_defined_map: IndexMap<FunctionAccessKey, Vec<u64>> = IndexMap::new();
|
||||
for (index, ir) in ir_stack.to_vec().iter().enumerate().rev() {
|
||||
|
@ -3172,6 +3232,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
dependencies: func_calls.keys().cloned().collect_vec(),
|
||||
recursive,
|
||||
args,
|
||||
defined_by_zero_arg: in_zero_arg_func,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
|
||||
[[requirements]]
|
||||
name = "aiken-lang/stdlib"
|
||||
version = "cf89161cbcd5e2c9519e7ea5d61986473b708179"
|
||||
version = "3b47c89006e7580c2213370d7426ed2a38d2836e"
|
||||
source = "github"
|
||||
|
||||
[[packages]]
|
||||
name = "aiken-lang/stdlib"
|
||||
version = "cf89161cbcd5e2c9519e7ea5d61986473b708179"
|
||||
version = "3b47c89006e7580c2213370d7426ed2a38d2836e"
|
||||
requirements = []
|
||||
source = "github"
|
||||
|
|
|
@ -2,5 +2,5 @@ name = "aiken-lang/acceptance_test_055"
|
|||
version = "0.0.0"
|
||||
|
||||
dependencies = [
|
||||
{ name = "aiken-lang/stdlib", version="cf89161cbcd5e2c9519e7ea5d61986473b708179", source = "github" },
|
||||
{ name = "aiken-lang/stdlib", version="3b47c89006e7580c2213370d7426ed2a38d2836e", source = "github" },
|
||||
]
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
use aiken/bytearray
|
||||
use aiken/dict
|
||||
use aiken/hash.{Hash, Sha2_256, sha2_256}
|
||||
use aiken/interval.{Interval, IntervalBound, PositiveInfinity}
|
||||
use aiken/interval.{between, intersection, is_empty, strictly_between}
|
||||
use aiken/list
|
||||
use aiken/string
|
||||
use aiken/transaction.{
|
||||
InlineDatum, Input, Output, OutputReference, Transaction, TransactionId,
|
||||
}
|
||||
use aiken/transaction/credential.{
|
||||
Address, PublicKeyCredential, ScriptCredential, StakeCredential,
|
||||
}
|
||||
use aiken/transaction/value
|
||||
use aiken/transaction.{InlineDatum}
|
||||
|
||||
// MerkleTree in Aiken (ported from: https://github.com/input-output-hk/hydra/blob/master/plutus-merkle-tree/src/Plutus/MerkleTree.hs)
|
||||
|
||||
|
@ -74,83 +67,27 @@ test foo() {
|
|||
size(mt) == 3
|
||||
}
|
||||
|
||||
// const keyhash = #"010203040506"
|
||||
|
||||
// const scripthash = #"060504030201"
|
||||
|
||||
// pub fn keyhash_address(with_stake_credential: Option<StakeCredential>) {
|
||||
// Address {
|
||||
// payment_credential: PublicKeyCredential(keyhash),
|
||||
// stake_credential: with_stake_credential,
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub fn scripthash_address(with_stake_credential: Option<StakeCredential>) {
|
||||
// Address {
|
||||
// payment_credential: ScriptCredential(scripthash),
|
||||
// stake_credential: with_stake_credential,
|
||||
// }
|
||||
// }
|
||||
|
||||
// type SampleData {
|
||||
// a: Int,
|
||||
// b: ByteArray,
|
||||
// }
|
||||
|
||||
// pub fn tx_1() -> Transaction {
|
||||
// let sample_datum = SampleData { a: 1, b: #"01" }
|
||||
// // let sample_data: Data = sample_datum
|
||||
// let tx =
|
||||
// Transaction {
|
||||
// inputs: [
|
||||
// Input {
|
||||
// output_reference: OutputReference {
|
||||
// transaction_id: TransactionId { hash: #"" },
|
||||
// output_index: 0,
|
||||
// },
|
||||
// output: Output {
|
||||
// address: scripthash_address(None),
|
||||
// value: value.zero(),
|
||||
// datum: InlineDatum(sample_datum),
|
||||
// reference_script: None,
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// reference_inputs: [],
|
||||
// outputs: [
|
||||
// Output {
|
||||
// address: keyhash_address(None),
|
||||
// value: value.from_lovelace(10000),
|
||||
// datum: InlineDatum(sample_datum),
|
||||
// reference_script: None,
|
||||
// },
|
||||
// ],
|
||||
// fee: value.zero(),
|
||||
// mint: value.from_asset(#"000000", #"00", -1),
|
||||
// certificates: [],
|
||||
// withdrawals: dict.new(),
|
||||
// validity_range: Interval {
|
||||
// lower_bound: IntervalBound {
|
||||
// bound_type: PositiveInfinity,
|
||||
// is_inclusive: True,
|
||||
// },
|
||||
// upper_bound: IntervalBound {
|
||||
// bound_type: PositiveInfinity,
|
||||
// is_inclusive: True,
|
||||
// },
|
||||
// },
|
||||
// extra_signatories: [keyhash],
|
||||
// redeemers: dict.new(),
|
||||
// datums: dict.new(),
|
||||
// id: TransactionId { hash: #"" },
|
||||
// }
|
||||
// tx
|
||||
// }
|
||||
|
||||
// test some_test2() {
|
||||
// tx_1() == tx_1()
|
||||
// }
|
||||
|
||||
test some_test1() {
|
||||
InlineDatum(Void) == InlineDatum(Void)
|
||||
}
|
||||
|
||||
test intersection_3() {
|
||||
let iv1 = between(0, 1)
|
||||
let iv2 = strictly_between(1, 2)
|
||||
intersection(iv1, iv2)
|
||||
|> is_empty
|
||||
}
|
||||
|
||||
const fooz = #"666f6f"
|
||||
|
||||
const bar = #"626172"
|
||||
|
||||
fn fixture_1() {
|
||||
dict.new()
|
||||
|> dict.insert(fooz, 42, bytearray.compare)
|
||||
|> dict.insert(bar, 14, bytearray.compare)
|
||||
}
|
||||
|
||||
test union_1() {
|
||||
dict.union(fixture_1(), dict.new(), bytearray.compare) == fixture_1()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue