From 1a15440d24cf2243f5b38f1c7e2069ee7ad3f8d3 Mon Sep 17 00:00:00 2001 From: microproofs Date: Thu, 24 Oct 2024 01:06:21 -0400 Subject: [PATCH] Checkpoint for today --- crates/aiken-lang/src/gen_uplc.rs | 100 +++++++++++++++++- .../src/gen_uplc/stick_break_set.rs | 56 +++++++--- 2 files changed, 135 insertions(+), 21 deletions(-) diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index 52af1a0c..e4d267da 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -45,7 +45,7 @@ use builder::{ unknown_data_to_type, DISCARDED, }; -use decision_tree::{get_tipo_by_path, Assigned, DecisionTree, TreeGen}; +use decision_tree::{get_tipo_by_path, Assigned, CaseTest, DecisionTree, TreeGen}; use indexmap::IndexMap; use interner::AirInterner; use itertools::Itertools; @@ -2495,17 +2495,102 @@ impl<'a> CodeGenerator<'a> { let y = AirTree::when( test_subject_name, - Type::void(), + return_tipo.clone(), current_tipo.clone(), AirTree::local_var(current_subject_name, current_tipo.clone()), clauses, ); - let x = builtins_to_add.to_air(prev_subject_name, prev_tipo, y); + let x = builtins_to_add.to_air( + &mut self.special_functions, + prev_subject_name, + prev_tipo, + y, + ); x } - DecisionTree::ListSwitch { .. } => todo!(), + DecisionTree::ListSwitch { + path, + cases, + tail_cases, + default, + } => { + println!("PATH IS {:#?}", path); + //Current path to test + let current_tipo = get_tipo_by_path(subject_tipo.clone(), &path); + let builtins_path = Builtins::new_from_path(subject_tipo.clone(), path); + let current_subject_name = if builtins_path.is_empty() { + subject_name.clone() + } else { + format!("{}_{}", subject_name, builtins_path.to_string()) + }; + + println!("Current IS {:#?}", builtins_path); + + // Transition process from previous to current + let builtins_to_add = stick_set.diff_union_builtins(builtins_path.clone()); + + println!("TO ADD IS {:#?}", builtins_to_add); + + // Previous path to apply the transition process too + let prev_builtins = Builtins { + vec: builtins_path.vec[0..(builtins_path.len() - builtins_to_add.len())] + .to_vec(), + }; + + println!("PREV IS {:#?}", prev_builtins); + + let prev_subject_name = if prev_builtins.is_empty() { + subject_name.clone() + } else { + format!("{}_{}", subject_name, prev_builtins.to_string()) + }; + let prev_tipo = prev_builtins + .vec + .last() + .map_or(subject_tipo.clone(), |last| last.tipo()); + + let longest_list_pattern = cases.iter().chain(tail_cases.iter()).fold( + 0, + |longest, (case, _)| match case { + CaseTest::List(i) | CaseTest::ListWithTail(i) => { + if longest > *i { + *i + } else { + longest + } + } + _ => unreachable!(), + }, + ); + + let (builtin_path, last_pattern) = if tail_cases.is_empty() { + (Builtins::new(), *default.unwrap()) + } else { + let (case, tree) = tail_cases.first().unwrap(); + + ( + builtins_path + .clone() + .merge(Builtins::new_from_list_case(case.clone())), + tree.clone(), + ) + }; + + let last_pattern = self.handle_decision_tree( + subject_name, + subject_tipo.clone(), + return_tipo.clone(), + module_build_name, + last_pattern, + stick_set.clone(), + ); + + (0..longest_list_pattern).fold(last_pattern, |_, _| todo!()); + + todo!() + } DecisionTree::HoistedLeaf(name, args) => { let air_args = args .iter() @@ -2567,7 +2652,12 @@ impl<'a> CodeGenerator<'a> { acc, ); - let thing = builtins_to_add.to_air(prev_subject_name, prev_tipo, assignment); + let thing = builtins_to_add.to_air( + &mut self.special_functions, + prev_subject_name, + prev_tipo, + assignment, + ); thing }) diff --git a/crates/aiken-lang/src/gen_uplc/stick_break_set.rs b/crates/aiken-lang/src/gen_uplc/stick_break_set.rs index 7366a25a..e3983205 100644 --- a/crates/aiken-lang/src/gen_uplc/stick_break_set.rs +++ b/crates/aiken-lang/src/gen_uplc/stick_break_set.rs @@ -1,12 +1,13 @@ use std::rc::Rc; use itertools::Itertools; -use uplc::builtins::DefaultFunction; +use uplc::{builder::CONSTR_FIELDS_EXPOSER, builtins::DefaultFunction}; use crate::expr::Type; use super::{ - decision_tree::{get_tipo_by_path, Path}, + builder::CodeGenSpecialFuncs, + decision_tree::{get_tipo_by_path, CaseTest, Path}, tree::AirTree, }; @@ -14,7 +15,7 @@ use super::{ pub enum Builtin { HeadList(Rc), TailList, - UnConstr, + UnConstrFields, FstPair(Rc), SndPair(Rc), } @@ -24,7 +25,7 @@ impl PartialEq for Builtin { match (self, other) { (Builtin::HeadList(_), Builtin::HeadList(_)) => true, (Builtin::TailList, Builtin::TailList) => true, - (Builtin::UnConstr, Builtin::UnConstr) => true, + (Builtin::UnConstrFields, Builtin::UnConstrFields) => true, (Builtin::SndPair(_), Builtin::SndPair(_)) => true, _ => false, } @@ -34,7 +35,7 @@ impl PartialEq for Builtin { impl Eq for Builtin {} impl Builtin { - fn to_air_call(self, arg: AirTree) -> AirTree { + fn to_air_call(self, special_funcs: &mut CodeGenSpecialFuncs, arg: AirTree) -> AirTree { match self { Builtin::HeadList(t) => AirTree::builtin(DefaultFunction::HeadList, t, vec![arg]), Builtin::TailList => AirTree::builtin( @@ -42,11 +43,12 @@ impl Builtin { Type::list(Type::data()), vec![arg], ), - Builtin::UnConstr => AirTree::builtin( - DefaultFunction::UnConstrData, - Type::pair(Type::int(), Type::list(Type::data())), + Builtin::UnConstrFields => AirTree::call( + special_funcs.use_function_tree(CONSTR_FIELDS_EXPOSER.to_string()), + Type::list(Type::data()), vec![arg], ), + Builtin::FstPair(t) => AirTree::builtin(DefaultFunction::FstPair, t, vec![arg]), Builtin::SndPair(t) => AirTree::builtin(DefaultFunction::SndPair, t, vec![arg]), } @@ -57,7 +59,7 @@ impl Builtin { Builtin::HeadList(t) => t.clone(), Builtin::TailList => Type::list(Type::data()), - Builtin::UnConstr => Type::pair(Type::int(), Type::list(Type::data())), + Builtin::UnConstrFields => Type::list(Type::data()), Builtin::FstPair(t) => t.clone(), Builtin::SndPair(t) => t.clone(), @@ -70,7 +72,7 @@ impl ToString for Builtin { match self { Builtin::HeadList(_) => "head".to_string(), Builtin::TailList => "tail".to_string(), - Builtin::UnConstr => "unconstr".to_string(), + Builtin::UnConstrFields => "unconstrfields".to_string(), Builtin::FstPair(_) => "fst".to_string(), Builtin::SndPair(_) => "snd".to_string(), } @@ -87,6 +89,20 @@ impl Builtins { Builtins { vec: vec![] } } + pub fn new_from_list_case(case: CaseTest) -> Self { + Self { + vec: match case { + CaseTest::List(i) | CaseTest::ListWithTail(i) => { + (0..i).fold(vec![], |mut acc, _index| { + acc.push(Builtin::TailList); + acc + }) + } + _ => unreachable!(), + }, + } + } + pub fn new_from_path(subject_tipo: Rc, path: Vec) -> Self { Self { vec: path @@ -124,10 +140,7 @@ impl Builtins { (builtins, rebuilt_path) } Path::Constr(_rc, i) => { - builtins.extend([ - Builtin::UnConstr, - Builtin::SndPair(Type::list(Type::data())), - ]); + builtins.push(Builtin::UnConstrFields); for _ in 0..i { builtins.push(Builtin::TailList); @@ -162,7 +175,18 @@ impl Builtins { self.vec.is_empty() } - pub fn to_air(self, prev_name: String, subject_tipo: Rc, then: AirTree) -> AirTree { + pub fn merge(mut self, other: Self) -> Self { + self.vec.extend(other.vec); + self + } + + pub fn to_air( + self, + special_funcs: &mut CodeGenSpecialFuncs, + prev_name: String, + subject_tipo: Rc, + then: AirTree, + ) -> AirTree { let (_, _, name_builtins) = self.vec.into_iter().fold( (prev_name, subject_tipo, vec![]), |(prev_name, prev_tipo, mut acc), item| { @@ -180,7 +204,7 @@ impl Builtins { .rfold(then, |then, (prev_name, prev_tipo, next_name, builtin)| { AirTree::let_assignment( next_name, - builtin.to_air_call(AirTree::local_var(prev_name, prev_tipo)), + builtin.to_air_call(special_funcs, AirTree::local_var(prev_name, prev_tipo)), then, ) })