feat: more debruijn stuff

This commit is contained in:
rvcas 2022-06-03 22:00:16 -04:00
parent f8edb5d519
commit 946937f945
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
5 changed files with 118 additions and 42 deletions

View File

@ -1,4 +1,7 @@
use uplc::parser;
use uplc::{
ast::{NamedDeBruijn, Program},
parser,
};
use neptune::Cli;
@ -13,13 +16,17 @@ fn main() -> anyhow::Result<()> {
let flat_bytes = program.to_flat()?;
print!("flat bits: ");
for byte in flat_bytes {
print!("{:08b} ", byte);
}
println!();
println!("{}", program.flat_hex()?);
let program: Program<NamedDeBruijn> = program.try_into().unwrap();
println!("{:#?}", program);
Ok(())
}

View File

@ -1,3 +1,3 @@
(program 11.22.33
(con integer 11)
(lam x x)
)

View File

@ -6,17 +6,6 @@ pub struct Program<T> {
pub term: Term<T>,
}
impl TryFrom<Program<Name>> for Program<NamedDeBruijn> {
type Error = String;
fn try_from(value: Program<Name>) -> Result<Self, Self::Error> {
Ok(Program::<NamedDeBruijn> {
version: value.version,
term: value.term.try_into()?,
})
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum Term<T> {
// tag: 0
@ -43,22 +32,6 @@ pub enum Term<T> {
Builtin(DefaultFunction),
}
impl TryFrom<Term<Name>> for Term<NamedDeBruijn> {
type Error = String;
fn try_from(
value: Term<Name>,
) -> Result<Self, <Term<NamedDeBruijn> as TryFrom<Term<Name>>>::Error> {
let mut converter = Converter::new();
let term = converter
.name_to_named_debruijn(value)
.map_err(|err| err.to_string())?;
Ok(term)
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum Constant {
// tag: 0
@ -141,3 +114,57 @@ impl From<DeBruijn> for NamedDeBruijn {
}
}
}
impl TryFrom<Program<Name>> for Program<NamedDeBruijn> {
type Error = String;
fn try_from(value: Program<Name>) -> Result<Self, Self::Error> {
Ok(Program::<NamedDeBruijn> {
version: value.version,
term: value.term.try_into()?,
})
}
}
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> {
type Error = String;
fn try_from(
value: Term<Name>,
) -> Result<Self, <Term<NamedDeBruijn> as TryFrom<Term<Name>>>::Error> {
let mut converter = Converter::new();
let term = converter
.name_to_named_debruijn(value)
.map_err(|err| err.to_string())?;
Ok(term)
}
}
impl TryFrom<Term<NamedDeBruijn>> for Term<Name> {
type Error = String;
fn try_from(
value: Term<NamedDeBruijn>,
) -> Result<Self, <Term<Name> as TryFrom<Term<NamedDeBruijn>>>::Error> {
let mut converter = Converter::new();
let term = converter
.named_debruijn_to_name(value)
.map_err(|err| err.to_string())?;
Ok(term)
}
}

View File

@ -2,6 +2,7 @@ use std::collections::HashMap;
use crate::ast::{DeBruijn, Name, NamedDeBruijn, Term, Unique};
#[derive(Debug, Copy, Clone)]
struct Level(u64);
pub(crate) struct Converter {
@ -31,7 +32,21 @@ impl Converter {
parameter_name,
body,
} => {
todo!()
self.declare_unique(parameter_name.unique);
let index = self.get_index(parameter_name.unique)?;
let name = NamedDeBruijn {
text: parameter_name.text,
index,
};
self.with_scope();
Term::Lambda {
parameter_name: name,
body: Box::new(self.name_to_named_debruijn(*body)?),
}
}
Term::Apply { function, argument } => Term::Apply {
function: Box::new(self.name_to_named_debruijn(*function)?),
@ -46,7 +61,10 @@ impl Converter {
Ok(converted_term)
}
pub(crate) fn named_debruijn_to_name(&mut self, term: Term<NamedDeBruijn>) -> Term<Name> {
pub(crate) fn named_debruijn_to_name(
&mut self,
_term: Term<NamedDeBruijn>,
) -> anyhow::Result<Term<Name>> {
todo!()
}
@ -59,4 +77,12 @@ impl Converter {
anyhow::bail!("Free unique: {}", isize::from(unique));
}
}
fn declare_unique(&mut self, unique: Unique) {
self.levels.insert(unique, self.current_level);
}
fn with_scope(&mut self) {
self.current_level = Level(self.current_level.0 + 1);
}
}

View File

@ -102,6 +102,7 @@ where
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
opaque!(no_partial(choice((
attempt(var()),
attempt(delay()),
attempt(lambda()),
attempt(apply()),
@ -112,6 +113,21 @@ where
))))
}
fn var<Input>() -> impl Parser<StateStream<Input>, Output = Term<Name>>
where
Input: Stream<Token = char>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
(many1(alpha_num()), spaces()).map_input(
|(text, _): (String, _), input: &mut StateStream<Input>| {
Term::Var(Name {
unique: input.state.intern(&text),
text,
})
},
)
}
fn delay<Input>() -> impl Parser<StateStream<Input>, Output = Term<Name>>
where
Input: Stream<Token = char>,
@ -147,21 +163,21 @@ where
Input: Stream<Token = char>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
let name = many1(alpha_num()).map_input(|text: String, input: &mut StateStream<Input>| Name {
unique: input.state.intern(&text),
text,
});
between(
token('('),
token(')'),
string("lam")
.with(skip_many1(space()))
.with((many1(alpha_num()), skip_many1(space()), term()))
.map_input(
|(parameter_name, _, term): (String, _, Term<Name>), input| Term::Lambda {
parameter_name: Name {
unique: input.state.intern(&parameter_name),
text: parameter_name,
},
body: Box::new(term),
},
),
.with((name, skip_many1(space()), term()))
.map(|(parameter_name, _, term)| Term::Lambda {
parameter_name,
body: Box::new(term),
}),
)
}