From 9864a3fe31bcec461c48386773e69135a5358e59 Mon Sep 17 00:00:00 2001 From: Kasey White Date: Fri, 4 Nov 2022 05:18:06 -0400 Subject: [PATCH] figured out the recursion based uplc terms to get item from a list --- crates/lang/src/uplc.rs | 235 +++++++++++++++++++++++++++- examples/sample/src/scripts/swap.ak | 3 +- 2 files changed, 235 insertions(+), 3 deletions(-) diff --git a/crates/lang/src/uplc.rs b/crates/lang/src/uplc.rs index eaee5d56..f76becf0 100644 --- a/crates/lang/src/uplc.rs +++ b/crates/lang/src/uplc.rs @@ -107,6 +107,239 @@ impl<'a> CodeGenerator<'a> { let mut term = self.recurse_code_gen(&body, ScopeLevels::new()); + // Apply constr exposer to top level. + term = Term::Apply { + function: Term::Lambda { + parameter_name: Name { + text: "constr_fields_exposer".to_string(), + unique: 0.into(), + }, + body: term.into(), + } + .into(), + argument: Term::Lambda { + parameter_name: Name { + text: "constr_var".to_string(), + unique: 0.into(), + }, + body: Term::Apply { + function: Term::Builtin(DefaultFunction::UnListData).into(), + argument: Term::Apply { + function: Term::Builtin(DefaultFunction::SndPair).into(), + argument: Term::Apply { + function: Term::Builtin(DefaultFunction::UnConstrData).into(), + argument: Term::Var(Name { + text: "constr_var".to_string(), + unique: 0.into(), + }) + .into(), + } + .into(), + } + .into(), + } + .into(), + } + .into(), + }; + + //Apply constr arg getter to top level. + + term = Term::Apply { + function: Term::Lambda { + parameter_name: Name { + text: "constr_field_get_arg".to_string(), + unique: 0.into(), + }, + body: term.into(), + } + .into(), + argument: Term::Lambda { + parameter_name: Name { + text: "constr_list".to_string(), + unique: 0.into(), + }, + body: Term::Lambda { + parameter_name: Name { + text: "arg_number".to_string(), + unique: 0.into(), + }, + body: Term::Apply { + function: Term::Lambda { + parameter_name: Name { + text: "recurse".to_string(), + unique: 0.into(), + }, + body: Term::Apply { + function: Term::Apply { + function: Term::Apply { + function: Term::Var(Name { + text: "recurse".to_string(), + unique: 0.into(), + }) + .into(), + argument: Term::Var(Name { + text: "recurse".to_string(), + unique: 0.into(), + }) + .into(), + } + .into(), + + // Start recursive with index 0 of list + argument: Term::Constant(Constant::Integer(0.into())).into(), + } + .into(), + argument: Term::Var(Name { + text: "constr_list".to_string(), + unique: 0.into(), + }) + .into(), + } + .into(), + } + .into(), + + argument: Term::Lambda { + parameter_name: Name { + text: "self_recursor".to_string(), + unique: 0.into(), + }, + body: Term::Lambda { + parameter_name: Name { + text: "current_arg_number".to_string(), + unique: 0.into(), + }, + body: Term::Lambda { + parameter_name: Name { + text: "list_of_constr_args".to_string(), + unique: 0.into(), + }, + body: Term::Apply { + function: Term::Apply { + function: Term::Apply { + function: Term::Apply { + function: Term::Force( + Term::Builtin(DefaultFunction::IfThenElse) + .into(), + ) + .into(), + argument: Term::Apply { + function: Term::Apply { + function: Term::Builtin( + DefaultFunction::EqualsInteger, + ) + .into(), + argument: Term::Var(Name { + text: "arg_number".to_string(), + unique: 0.into(), + }) + .into(), + } + .into(), + argument: Term::Var(Name { + text: "current_arg_number".to_string(), + unique: 0.into(), + }) + .into(), + } + .into(), + } + .into(), + argument: Term::Force( + Term::Builtin(DefaultFunction::HeadList).into(), + ) + .into(), + } + .into(), + argument: Term::Lambda { + parameter_name: Name { + text: "current_list_of_constr_args".to_string(), + unique: 0.into(), + }, + body: Term::Apply { + function: Term::Apply { + function: Term::Apply { + function: Term::Var(Name { + text: "self_recursor".to_string(), + unique: 0.into(), + }) + .into(), + argument: Term::Var(Name { + text: "self_recursor".to_string(), + unique: 0.into(), + }) + .into(), + } + .into(), + + argument: Term::Apply { + function: Term::Apply { + function: Term::Builtin( + DefaultFunction::AddInteger, + ) + .into(), + argument: Term::Var(Name { + text: "current_arg_number" + .to_string(), + unique: 0.into(), + }) + .into(), + } + .into(), + argument: Term::Constant( + Constant::Integer(1.into()), + ) + .into(), + } + .into(), + } + .into(), + + argument: Term::Apply { + function: Term::Force( + Term::Builtin( + DefaultFunction::TailList, + ) + .into(), + ) + .into(), + + argument: Term::Var(Name { + text: "current_list_of_constr_args" + .to_string(), + unique: 0.into(), + }) + .into(), + } + .into(), + } + .into(), + } + .into(), + } + .into(), + argument: Term::Var(Name { + text: "list_of_constr_args".to_string(), + unique: 0.into(), + }) + .into(), + } + .into(), + } + .into(), + } + .into(), + } + .into(), + } + .into(), + } + .into(), + } + .into(), + }; + for arg in arguments.iter().rev() { term = Term::Lambda { parameter_name: uplc::ast::Name { @@ -859,7 +1092,7 @@ impl<'a> CodeGenerator<'a> { // TODO: Find proper scope for this function if at all. argument: Term::Apply { function: Term::Var(Name { - text: "constr_field_exposer".to_string(), + text: "constr_fields_exposer".to_string(), unique: 0.into(), }) .into(), diff --git a/examples/sample/src/scripts/swap.ak b/examples/sample/src/scripts/swap.ak index ec5e0fc3..c0fc0f3d 100644 --- a/examples/sample/src/scripts/swap.ak +++ b/examples/sample/src/scripts/swap.ak @@ -9,11 +9,10 @@ pub type Redeemer { pub fn spend(datum: sample.Datum, rdmr: Redeemer, ctx: spend.ScriptContext) -> Bool { - let dat = sample.Datum{..} + let y = 2 let x = 1 let a = datum.something - let e = dat.something let b = 2 b == 1 }