feat: debruijn conversions and binder
Co-authored-by: Kasey White <kwhitemsg@gmail.com>
This commit is contained in:
parent
2ad630de90
commit
2f51b23e7e
|
@ -1,5 +1,5 @@
|
||||||
use uplc::{
|
use uplc::{
|
||||||
ast::{NamedDeBruijn, Program},
|
ast::{DeBruijn, NamedDeBruijn, Program},
|
||||||
parser,
|
parser,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,11 +12,12 @@ fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
let program = parser::program(&code)?;
|
let program = parser::program(&code)?;
|
||||||
|
|
||||||
|
println!("\nName:");
|
||||||
println!("{:#?}", program);
|
println!("{:#?}", program);
|
||||||
|
|
||||||
let flat_bytes = program.to_flat()?;
|
let flat_bytes = program.to_flat()?;
|
||||||
|
|
||||||
print!("flat bits: ");
|
print!("\nflat bits:\n");
|
||||||
|
|
||||||
for byte in flat_bytes {
|
for byte in flat_bytes {
|
||||||
print!("{:08b} ", byte);
|
print!("{:08b} ", byte);
|
||||||
|
@ -24,9 +25,35 @@ fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
let program: Program<NamedDeBruijn> = program.try_into().unwrap();
|
let program_nd: Program<NamedDeBruijn> = program.try_into().unwrap();
|
||||||
|
|
||||||
println!("{:#?}", program);
|
println!("\nNamed De Bruijn:");
|
||||||
|
println!("{:#?}", program_nd);
|
||||||
|
|
||||||
|
let flat_bytes = program_nd.to_flat()?;
|
||||||
|
|
||||||
|
print!("\nflat bits:\n");
|
||||||
|
|
||||||
|
for byte in flat_bytes {
|
||||||
|
print!("{:08b} ", byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
|
||||||
|
let program_d: Program<DeBruijn> = program_nd.into();
|
||||||
|
|
||||||
|
println!("\nDe Bruijn:");
|
||||||
|
println!("{:#?}", program_d);
|
||||||
|
|
||||||
|
let flat_bytes = program_d.to_flat()?;
|
||||||
|
|
||||||
|
print!("\nflat bits:\n");
|
||||||
|
|
||||||
|
for byte in flat_bytes {
|
||||||
|
print!("{:08b} ", byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
(program 11.22.33
|
(program 11.22.33
|
||||||
(lam x (lam x y))
|
(lam x (lam x x))
|
||||||
)
|
)
|
|
@ -88,6 +88,12 @@ pub struct NamedDeBruijn {
|
||||||
#[derive(Debug, Clone, PartialEq, Copy)]
|
#[derive(Debug, Clone, PartialEq, Copy)]
|
||||||
pub struct DeBruijn(usize);
|
pub struct DeBruijn(usize);
|
||||||
|
|
||||||
|
impl DeBruijn {
|
||||||
|
pub fn new(index: usize) -> Self {
|
||||||
|
DeBruijn(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<usize> for DeBruijn {
|
impl From<usize> for DeBruijn {
|
||||||
fn from(i: usize) -> Self {
|
fn from(i: usize) -> Self {
|
||||||
DeBruijn(i)
|
DeBruijn(i)
|
||||||
|
@ -126,17 +132,6 @@ impl TryFrom<Program<Name>> for Program<NamedDeBruijn> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<Program<NamedDeBruijn>> for Program<Name> {
|
|
||||||
type Error = String;
|
|
||||||
|
|
||||||
fn try_from(value: Program<NamedDeBruijn>) -> Result<Self, Self::Error> {
|
|
||||||
Ok(Program::<Name> {
|
|
||||||
version: value.version,
|
|
||||||
term: value.term.try_into()?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Term<Name>> for Term<NamedDeBruijn> {
|
impl TryFrom<Term<Name>> for Term<NamedDeBruijn> {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
|
|
||||||
|
@ -153,6 +148,42 @@ impl TryFrom<Term<Name>> for Term<NamedDeBruijn> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Program<Name>> for Program<DeBruijn> {
|
||||||
|
type Error = String;
|
||||||
|
|
||||||
|
fn try_from(value: Program<Name>) -> Result<Self, Self::Error> {
|
||||||
|
Ok(Program::<DeBruijn> {
|
||||||
|
version: value.version,
|
||||||
|
term: value.term.try_into()?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Term<Name>> for Term<DeBruijn> {
|
||||||
|
type Error = String;
|
||||||
|
|
||||||
|
fn try_from(value: Term<Name>) -> Result<Self, <Term<DeBruijn> as TryFrom<Term<Name>>>::Error> {
|
||||||
|
let mut converter = Converter::new();
|
||||||
|
|
||||||
|
let term = converter
|
||||||
|
.name_to_debruijn(value)
|
||||||
|
.map_err(|err| err.to_string())?;
|
||||||
|
|
||||||
|
Ok(term)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Program<NamedDeBruijn>> for Program<Name> {
|
||||||
|
type Error = String;
|
||||||
|
|
||||||
|
fn try_from(value: Program<NamedDeBruijn>) -> Result<Self, Self::Error> {
|
||||||
|
Ok(Program::<Name> {
|
||||||
|
version: value.version,
|
||||||
|
term: value.term.try_into()?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TryFrom<Term<NamedDeBruijn>> for Term<Name> {
|
impl TryFrom<Term<NamedDeBruijn>> for Term<Name> {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
|
|
||||||
|
@ -168,3 +199,64 @@ impl TryFrom<Term<NamedDeBruijn>> for Term<Name> {
|
||||||
Ok(term)
|
Ok(term)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Program<NamedDeBruijn>> for Program<DeBruijn> {
|
||||||
|
fn from(value: Program<NamedDeBruijn>) -> Self {
|
||||||
|
Program::<DeBruijn> {
|
||||||
|
version: value.version,
|
||||||
|
term: value.term.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Term<NamedDeBruijn>> for Term<DeBruijn> {
|
||||||
|
fn from(value: Term<NamedDeBruijn>) -> Self {
|
||||||
|
let mut converter = Converter::new();
|
||||||
|
|
||||||
|
converter.named_debruijn_to_debruijn(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Program<DeBruijn>> for Program<Name> {
|
||||||
|
type Error = String;
|
||||||
|
|
||||||
|
fn try_from(value: Program<DeBruijn>) -> Result<Self, Self::Error> {
|
||||||
|
Ok(Program::<Name> {
|
||||||
|
version: value.version,
|
||||||
|
term: value.term.try_into()?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Term<DeBruijn>> for Term<Name> {
|
||||||
|
type Error = String;
|
||||||
|
|
||||||
|
fn try_from(
|
||||||
|
value: Term<DeBruijn>,
|
||||||
|
) -> Result<Self, <Term<Name> as TryFrom<Term<DeBruijn>>>::Error> {
|
||||||
|
let mut converter = Converter::new();
|
||||||
|
|
||||||
|
let term = converter
|
||||||
|
.debruijn_to_name(value)
|
||||||
|
.map_err(|err| err.to_string())?;
|
||||||
|
|
||||||
|
Ok(term)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Program<DeBruijn>> for Program<NamedDeBruijn> {
|
||||||
|
fn from(value: Program<DeBruijn>) -> Self {
|
||||||
|
Program::<NamedDeBruijn> {
|
||||||
|
version: value.version,
|
||||||
|
term: value.term.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Term<DeBruijn>> for Term<NamedDeBruijn> {
|
||||||
|
fn from(value: Term<DeBruijn>) -> Self {
|
||||||
|
let mut converter = Converter::new();
|
||||||
|
|
||||||
|
converter.debruijn_to_named_debruijn(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,20 +5,20 @@ use crate::ast::{DeBruijn, Name, NamedDeBruijn, Term, Unique};
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
struct Level(usize);
|
struct Level(usize);
|
||||||
|
|
||||||
pub(crate) struct Converter {
|
pub struct Converter {
|
||||||
current_level: Level,
|
current_level: Level,
|
||||||
levels: Vec<HashMap<Unique, Level>>,
|
levels: Vec<HashMap<Unique, Level>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Converter {
|
impl Converter {
|
||||||
pub(crate) fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Converter {
|
Converter {
|
||||||
current_level: Level(0),
|
current_level: Level(0),
|
||||||
levels: vec![HashMap::new()],
|
levels: vec![HashMap::new()],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn name_to_named_debruijn(
|
pub fn name_to_named_debruijn(
|
||||||
&mut self,
|
&mut self,
|
||||||
term: Term<Name>,
|
term: Term<Name>,
|
||||||
) -> anyhow::Result<Term<NamedDeBruijn>> {
|
) -> anyhow::Result<Term<NamedDeBruijn>> {
|
||||||
|
@ -65,13 +65,97 @@ impl Converter {
|
||||||
Ok(converted_term)
|
Ok(converted_term)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn named_debruijn_to_name(
|
pub fn name_to_debruijn(&mut self, term: Term<Name>) -> anyhow::Result<Term<DeBruijn>> {
|
||||||
|
let converted_term = match term {
|
||||||
|
Term::Var(Name { unique, .. }) => Term::Var(self.get_index(unique)?),
|
||||||
|
Term::Delay(term) => Term::Delay(Box::new(self.name_to_debruijn(*term)?)),
|
||||||
|
Term::Lambda {
|
||||||
|
parameter_name,
|
||||||
|
body,
|
||||||
|
} => {
|
||||||
|
self.declare_unique(parameter_name.unique);
|
||||||
|
|
||||||
|
let name = self.get_index(parameter_name.unique)?;
|
||||||
|
|
||||||
|
self.start_scope();
|
||||||
|
|
||||||
|
let body = self.name_to_debruijn(*body)?;
|
||||||
|
|
||||||
|
self.end_scope();
|
||||||
|
|
||||||
|
Term::Lambda {
|
||||||
|
parameter_name: name,
|
||||||
|
body: Box::new(body),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Term::Apply { function, argument } => Term::Apply {
|
||||||
|
function: Box::new(self.name_to_debruijn(*function)?),
|
||||||
|
argument: Box::new(self.name_to_debruijn(*argument)?),
|
||||||
|
},
|
||||||
|
Term::Constant(constant) => Term::Constant(constant),
|
||||||
|
Term::Force(term) => Term::Force(Box::new(self.name_to_debruijn(*term)?)),
|
||||||
|
Term::Error => Term::Error,
|
||||||
|
Term::Builtin(builtin) => Term::Builtin(builtin),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(converted_term)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn named_debruijn_to_name(
|
||||||
&mut self,
|
&mut self,
|
||||||
_term: Term<NamedDeBruijn>,
|
_term: Term<NamedDeBruijn>,
|
||||||
) -> anyhow::Result<Term<Name>> {
|
) -> anyhow::Result<Term<Name>> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn named_debruijn_to_debruijn(&mut self, term: Term<NamedDeBruijn>) -> Term<DeBruijn> {
|
||||||
|
match term {
|
||||||
|
Term::Var(name) => Term::Var(name.into()),
|
||||||
|
Term::Delay(term) => Term::Delay(Box::new(self.named_debruijn_to_debruijn(*term))),
|
||||||
|
Term::Lambda {
|
||||||
|
parameter_name,
|
||||||
|
body,
|
||||||
|
} => Term::Lambda {
|
||||||
|
parameter_name: parameter_name.into(),
|
||||||
|
body: Box::new(self.named_debruijn_to_debruijn(*body)),
|
||||||
|
},
|
||||||
|
Term::Apply { function, argument } => Term::Apply {
|
||||||
|
function: Box::new(self.named_debruijn_to_debruijn(*function)),
|
||||||
|
argument: Box::new(self.named_debruijn_to_debruijn(*argument)),
|
||||||
|
},
|
||||||
|
Term::Constant(constant) => Term::Constant(constant),
|
||||||
|
Term::Force(term) => Term::Force(Box::new(self.named_debruijn_to_debruijn(*term))),
|
||||||
|
Term::Error => Term::Error,
|
||||||
|
Term::Builtin(builtin) => Term::Builtin(builtin),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn debruijn_to_name(&mut self, _term: Term<DeBruijn>) -> anyhow::Result<Term<Name>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn debruijn_to_named_debruijn(&mut self, term: Term<DeBruijn>) -> Term<NamedDeBruijn> {
|
||||||
|
match term {
|
||||||
|
Term::Var(name) => Term::Var(name.into()),
|
||||||
|
Term::Delay(term) => Term::Delay(Box::new(self.debruijn_to_named_debruijn(*term))),
|
||||||
|
Term::Lambda {
|
||||||
|
parameter_name,
|
||||||
|
body,
|
||||||
|
} => Term::Lambda {
|
||||||
|
parameter_name: parameter_name.into(),
|
||||||
|
body: Box::new(self.debruijn_to_named_debruijn(*body)),
|
||||||
|
},
|
||||||
|
Term::Apply { function, argument } => Term::Apply {
|
||||||
|
function: Box::new(self.debruijn_to_named_debruijn(*function)),
|
||||||
|
argument: Box::new(self.debruijn_to_named_debruijn(*argument)),
|
||||||
|
},
|
||||||
|
Term::Constant(constant) => Term::Constant(constant),
|
||||||
|
Term::Force(term) => Term::Force(Box::new(self.debruijn_to_named_debruijn(*term))),
|
||||||
|
Term::Error => Term::Error,
|
||||||
|
Term::Builtin(builtin) => Term::Builtin(builtin),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_index(&mut self, unique: Unique) -> anyhow::Result<DeBruijn> {
|
fn get_index(&mut self, unique: Unique) -> anyhow::Result<DeBruijn> {
|
||||||
for scope in self.levels.iter().rev() {
|
for scope in self.levels.iter().rev() {
|
||||||
if let Some(found_level) = scope.get(&unique) {
|
if let Some(found_level) = scope.get(&unique) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use flat::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Constant, Name, Program, Term, Unique},
|
ast::{Constant, DeBruijn, Name, NamedDeBruijn, Program, Term, Unique},
|
||||||
builtins::DefaultFunction,
|
builtins::DefaultFunction,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,11 +15,16 @@ const BUILTIN_TAG_WIDTH: u32 = 7;
|
||||||
const CONST_TAG_WIDTH: u32 = 4;
|
const CONST_TAG_WIDTH: u32 = 4;
|
||||||
const TERM_TAG_WIDTH: u32 = 4;
|
const TERM_TAG_WIDTH: u32 = 4;
|
||||||
|
|
||||||
impl<'b, T> Flat<'b> for Program<T> where T: Encode + Decode<'b> {}
|
pub trait Binder<'b>: Encode + Decode<'b> {
|
||||||
|
fn binder_encode(&self, e: &mut Encoder) -> Result<(), String>;
|
||||||
|
fn binder_decode(d: &mut Decoder) -> Result<Self, String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b, T> Flat<'b> for Program<T> where T: Binder<'b> {}
|
||||||
|
|
||||||
impl<'b, T> Program<T>
|
impl<'b, T> Program<T>
|
||||||
where
|
where
|
||||||
T: Encode + Decode<'b>,
|
T: Binder<'b>,
|
||||||
{
|
{
|
||||||
// convenient so that people don't need to depend on the flat crate
|
// convenient so that people don't need to depend on the flat crate
|
||||||
// directly to call programs flat function
|
// directly to call programs flat function
|
||||||
|
@ -36,7 +41,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Encode> Encode for Program<T> {
|
impl<'b, T> Encode for Program<T>
|
||||||
|
where
|
||||||
|
T: Binder<'b>,
|
||||||
|
{
|
||||||
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
||||||
let (major, minor, patch) = self.version;
|
let (major, minor, patch) = self.version;
|
||||||
|
|
||||||
|
@ -52,7 +60,7 @@ impl<T: Encode> Encode for Program<T> {
|
||||||
|
|
||||||
impl<'b, T> Decode<'b> for Program<T>
|
impl<'b, T> Decode<'b> for Program<T>
|
||||||
where
|
where
|
||||||
T: Decode<'b>,
|
T: Binder<'b>,
|
||||||
{
|
{
|
||||||
fn decode(d: &mut Decoder) -> Result<Self, String> {
|
fn decode(d: &mut Decoder) -> Result<Self, String> {
|
||||||
let version = (usize::decode(d)?, usize::decode(d)?, usize::decode(d)?);
|
let version = (usize::decode(d)?, usize::decode(d)?, usize::decode(d)?);
|
||||||
|
@ -61,7 +69,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Encode> Encode for Term<T> {
|
impl<'b, T> Encode for Term<T>
|
||||||
|
where
|
||||||
|
T: Binder<'b>,
|
||||||
|
{
|
||||||
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
||||||
match self {
|
match self {
|
||||||
Term::Var(name) => {
|
Term::Var(name) => {
|
||||||
|
@ -77,7 +88,7 @@ impl<T: Encode> Encode for Term<T> {
|
||||||
body,
|
body,
|
||||||
} => {
|
} => {
|
||||||
encode_term_tag(2, e)?;
|
encode_term_tag(2, e)?;
|
||||||
parameter_name.encode(e)?;
|
parameter_name.binder_encode(e)?;
|
||||||
body.encode(e)?;
|
body.encode(e)?;
|
||||||
}
|
}
|
||||||
Term::Apply { function, argument } => {
|
Term::Apply { function, argument } => {
|
||||||
|
@ -112,14 +123,14 @@ impl<T: Encode> Encode for Term<T> {
|
||||||
|
|
||||||
impl<'b, T> Decode<'b> for Term<T>
|
impl<'b, T> Decode<'b> for Term<T>
|
||||||
where
|
where
|
||||||
T: Decode<'b>,
|
T: Binder<'b>,
|
||||||
{
|
{
|
||||||
fn decode(d: &mut Decoder) -> Result<Self, String> {
|
fn decode(d: &mut Decoder) -> Result<Self, String> {
|
||||||
match decode_term_tag(d)? {
|
match decode_term_tag(d)? {
|
||||||
0 => Ok(Term::Var(T::decode(d)?)),
|
0 => Ok(Term::Var(T::decode(d)?)),
|
||||||
1 => Ok(Term::Delay(Box::new(Term::decode(d)?))),
|
1 => Ok(Term::Delay(Box::new(Term::decode(d)?))),
|
||||||
2 => Ok(Term::Lambda {
|
2 => Ok(Term::Lambda {
|
||||||
parameter_name: T::decode(d)?,
|
parameter_name: T::binder_decode(d)?,
|
||||||
body: Box::new(Term::decode(d)?),
|
body: Box::new(Term::decode(d)?),
|
||||||
}),
|
}),
|
||||||
3 => Ok(Term::Apply {
|
3 => Ok(Term::Apply {
|
||||||
|
@ -198,7 +209,7 @@ impl<'b> Decode<'b> for Unique {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encode for Name {
|
impl Encode for Name {
|
||||||
fn encode(&self, e: &mut flat::en::Encoder) -> Result<(), String> {
|
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
||||||
self.text.encode(e)?;
|
self.text.encode(e)?;
|
||||||
self.unique.encode(e)?;
|
self.unique.encode(e)?;
|
||||||
|
|
||||||
|
@ -215,8 +226,77 @@ impl<'b> Decode<'b> for Name {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'b> Binder<'b> for Name {
|
||||||
|
fn binder_encode(&self, e: &mut Encoder) -> Result<(), String> {
|
||||||
|
self.encode(e)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn binder_decode(d: &mut Decoder) -> Result<Self, String> {
|
||||||
|
Name::decode(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encode for NamedDeBruijn {
|
||||||
|
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
||||||
|
self.text.encode(e)?;
|
||||||
|
self.index.encode(e)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b> Decode<'b> for NamedDeBruijn {
|
||||||
|
fn decode(d: &mut Decoder) -> Result<Self, String> {
|
||||||
|
Ok(NamedDeBruijn {
|
||||||
|
text: String::decode(d)?,
|
||||||
|
index: DeBruijn::decode(d)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b> Binder<'b> for NamedDeBruijn {
|
||||||
|
fn binder_encode(&self, e: &mut Encoder) -> Result<(), String> {
|
||||||
|
self.text.encode(e)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn binder_decode(d: &mut Decoder) -> Result<Self, String> {
|
||||||
|
Ok(NamedDeBruijn {
|
||||||
|
text: String::decode(d)?,
|
||||||
|
index: DeBruijn::new(0),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encode for DeBruijn {
|
||||||
|
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
||||||
|
usize::from(*self).encode(e)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b> Decode<'b> for DeBruijn {
|
||||||
|
fn decode(d: &mut Decoder) -> Result<Self, String> {
|
||||||
|
Ok(usize::decode(d)?.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b> Binder<'b> for DeBruijn {
|
||||||
|
fn binder_encode(&self, _: &mut Encoder) -> Result<(), String> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn binder_decode(_d: &mut Decoder) -> Result<Self, String> {
|
||||||
|
Ok(DeBruijn::new(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Encode for DefaultFunction {
|
impl Encode for DefaultFunction {
|
||||||
fn encode(&self, e: &mut flat::en::Encoder) -> Result<(), String> {
|
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
||||||
e.bits(BUILTIN_TAG_WIDTH as i64, self.clone() as u8);
|
e.bits(BUILTIN_TAG_WIDTH as i64, self.clone() as u8);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in New Issue