feat: more debruijn stuff
This commit is contained in:
parent
f8edb5d519
commit
946937f945
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
(program 11.22.33
|
||||
(con integer 11)
|
||||
(lam x x)
|
||||
)
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(¶meter_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),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue