diff --git a/crates/uplc/src/ast.rs b/crates/uplc/src/ast.rs index 2aaf408f..04702b39 100644 --- a/crates/uplc/src/ast.rs +++ b/crates/uplc/src/ast.rs @@ -96,6 +96,33 @@ pub struct NamedDeBruijn { pub index: DeBruijn, } +#[derive(Debug, Clone, PartialEq)] +pub struct FakeNamedDeBruijn(NamedDeBruijn); + +impl From for FakeNamedDeBruijn { + fn from(d: DeBruijn) -> Self { + FakeNamedDeBruijn(d.into()) + } +} + +impl From for DeBruijn { + fn from(d: FakeNamedDeBruijn) -> Self { + d.0.into() + } +} + +impl From for NamedDeBruijn { + fn from(d: FakeNamedDeBruijn) -> Self { + d.0 + } +} + +impl From for FakeNamedDeBruijn { + fn from(d: NamedDeBruijn) -> Self { + FakeNamedDeBruijn(d) + } +} + #[derive(Debug, Clone, PartialEq, Copy)] pub struct DeBruijn(usize); @@ -218,6 +245,23 @@ impl From> for Term { } } +impl From> for Program { + fn from(value: Program) -> Self { + Program:: { + version: value.version, + term: value.term.into(), + } + } +} + +impl From> for Term { + fn from(value: Term) -> Self { + let mut converter = Converter::new(); + + converter.named_debruijn_to_fake_named_debruijn(value) + } +} + impl TryFrom> for Program { type Error = debruijn::Error; @@ -257,3 +301,20 @@ impl From> for Term { converter.debruijn_to_named_debruijn(value) } } + +impl From> for Program { + fn from(value: Program) -> Self { + Program:: { + version: value.version, + term: value.term.into(), + } + } +} + +impl From> for Term { + fn from(value: Term) -> Self { + let mut converter = Converter::new(); + + converter.fake_named_debruijn_to_named_debruijn(value) + } +} diff --git a/crates/uplc/src/debruijn.rs b/crates/uplc/src/debruijn.rs index f37a6a6b..3216e9f4 100644 --- a/crates/uplc/src/debruijn.rs +++ b/crates/uplc/src/debruijn.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use thiserror::Error; -use crate::ast::{DeBruijn, Name, NamedDeBruijn, Term, Unique}; +use crate::ast::{DeBruijn, FakeNamedDeBruijn, Name, NamedDeBruijn, Term, Unique}; #[derive(Debug, Copy, Clone)] struct Level(usize); @@ -164,6 +164,64 @@ impl Converter { } } + pub fn fake_named_debruijn_to_named_debruijn( + &mut self, + term: Term, + ) -> Term { + match term { + Term::Var(name) => Term::Var(name.into()), + Term::Delay(term) => { + Term::Delay(Box::new(self.fake_named_debruijn_to_named_debruijn(*term))) + } + Term::Lambda { + parameter_name, + body, + } => Term::Lambda { + parameter_name: parameter_name.into(), + body: Box::new(self.fake_named_debruijn_to_named_debruijn(*body)), + }, + Term::Apply { function, argument } => Term::Apply { + function: Box::new(self.fake_named_debruijn_to_named_debruijn(*function)), + argument: Box::new(self.fake_named_debruijn_to_named_debruijn(*argument)), + }, + Term::Constant(constant) => Term::Constant(constant), + Term::Force(term) => { + Term::Force(Box::new(self.fake_named_debruijn_to_named_debruijn(*term))) + } + Term::Error => Term::Error, + Term::Builtin(builtin) => Term::Builtin(builtin), + } + } + + pub fn named_debruijn_to_fake_named_debruijn( + &mut self, + term: Term, + ) -> Term { + match term { + Term::Var(name) => Term::Var(name.into()), + Term::Delay(term) => { + Term::Delay(Box::new(self.named_debruijn_to_fake_named_debruijn(*term))) + } + Term::Lambda { + parameter_name, + body, + } => Term::Lambda { + parameter_name: parameter_name.into(), + body: Box::new(self.named_debruijn_to_fake_named_debruijn(*body)), + }, + Term::Apply { function, argument } => Term::Apply { + function: Box::new(self.named_debruijn_to_fake_named_debruijn(*function)), + argument: Box::new(self.named_debruijn_to_fake_named_debruijn(*argument)), + }, + Term::Constant(constant) => Term::Constant(constant), + Term::Force(term) => { + Term::Force(Box::new(self.named_debruijn_to_fake_named_debruijn(*term))) + } + Term::Error => Term::Error, + Term::Builtin(builtin) => Term::Builtin(builtin), + } + } + fn get_index(&mut self, unique: Unique) -> Result { for scope in self.levels.iter().rev() { if let Some(found_level) = scope.get(&unique) { diff --git a/crates/uplc/src/flat.rs b/crates/uplc/src/flat.rs index c422c18d..8e7ada8a 100644 --- a/crates/uplc/src/flat.rs +++ b/crates/uplc/src/flat.rs @@ -5,7 +5,7 @@ use flat::{ }; use crate::{ - ast::{Constant, DeBruijn, Name, NamedDeBruijn, Program, Term, Unique}, + ast::{Constant, DeBruijn, FakeNamedDeBruijn, Name, NamedDeBruijn, Program, Term, Unique}, builtins::DefaultFunction, }; @@ -299,6 +299,36 @@ impl<'b> Binder<'b> for DeBruijn { } } +impl Encode for FakeNamedDeBruijn { + fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> { + let index: DeBruijn = self.clone().into(); + + index.encode(e)?; + + Ok(()) + } +} + +impl<'b> Decode<'b> for FakeNamedDeBruijn { + fn decode(d: &mut Decoder) -> Result { + let index = DeBruijn::decode(d)?; + + Ok(index.into()) + } +} + +impl<'b> Binder<'b> for FakeNamedDeBruijn { + fn binder_encode(&self, _: &mut Encoder) -> Result<(), en::Error> { + Ok(()) + } + + fn binder_decode(_d: &mut Decoder) -> Result { + let index = DeBruijn::new(0); + + Ok(index.into()) + } +} + impl Encode for DefaultFunction { fn encode(&self, e: &mut Encoder) -> Result<(), en::Error> { e.bits(BUILTIN_TAG_WIDTH as i64, *self as u8);