feat: start debruijn conversion
Co-authored-by: Kasey White <kwhitemsg@gmail.com>
This commit is contained in:
		
							parent
							
								
									83d6b5243e
								
							
						
					
					
						commit
						f8edb5d519
					
				|  | @ -1,4 +1,4 @@ | ||||||
| use crate::builtins::DefaultFunction; | use crate::{builtins::DefaultFunction, debruijn::Converter}; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone, PartialEq)] | #[derive(Debug, Clone, PartialEq)] | ||||||
| pub struct Program<T> { | pub struct Program<T> { | ||||||
|  | @ -6,6 +6,17 @@ pub struct Program<T> { | ||||||
|     pub term: Term<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)] | #[derive(Debug, Clone, PartialEq)] | ||||||
| pub enum Term<T> { | pub enum Term<T> { | ||||||
|     // tag: 0
 |     // tag: 0
 | ||||||
|  | @ -32,6 +43,22 @@ pub enum Term<T> { | ||||||
|     Builtin(DefaultFunction), |     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)] | #[derive(Debug, Clone, PartialEq)] | ||||||
| pub enum Constant { | pub enum Constant { | ||||||
|     // tag: 0
 |     // tag: 0
 | ||||||
|  | @ -51,14 +78,66 @@ pub enum Constant { | ||||||
| #[derive(Debug, Clone, PartialEq)] | #[derive(Debug, Clone, PartialEq)] | ||||||
| pub struct Name { | pub struct Name { | ||||||
|     pub text: String, |     pub text: String, | ||||||
|     pub unique: isize, |     pub unique: Unique, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, PartialEq, Copy, Eq, Hash)] | ||||||
|  | pub struct Unique(isize); | ||||||
|  | 
 | ||||||
|  | impl Unique { | ||||||
|  |     pub fn new(unique: isize) -> Self { | ||||||
|  |         Unique(unique) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn increment(&mut self) { | ||||||
|  |         self.0 += 1; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl From<isize> for Unique { | ||||||
|  |     fn from(i: isize) -> Self { | ||||||
|  |         Unique(i) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl From<Unique> for isize { | ||||||
|  |     fn from(d: Unique) -> Self { | ||||||
|  |         d.0 | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone, PartialEq)] | #[derive(Debug, Clone, PartialEq)] | ||||||
| pub struct NamedDeBruijn { | pub struct NamedDeBruijn { | ||||||
|     pub text: String, |     pub text: String, | ||||||
|     pub index: isize, |     pub index: DeBruijn, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone, PartialEq)] | #[derive(Debug, Clone, PartialEq, Copy)] | ||||||
| pub struct DeBruijn(isize); | pub struct DeBruijn(u64); | ||||||
|  | 
 | ||||||
|  | impl From<u64> for DeBruijn { | ||||||
|  |     fn from(i: u64) -> Self { | ||||||
|  |         DeBruijn(i) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl From<DeBruijn> for u64 { | ||||||
|  |     fn from(d: DeBruijn) -> Self { | ||||||
|  |         d.0 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl From<NamedDeBruijn> for DeBruijn { | ||||||
|  |     fn from(n: NamedDeBruijn) -> Self { | ||||||
|  |         n.index | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl From<DeBruijn> for NamedDeBruijn { | ||||||
|  |     fn from(index: DeBruijn) -> Self { | ||||||
|  |         NamedDeBruijn { | ||||||
|  |             text: String::from("i"), | ||||||
|  |             index, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,62 @@ | ||||||
|  | use std::collections::HashMap; | ||||||
|  | 
 | ||||||
|  | use crate::ast::{DeBruijn, Name, NamedDeBruijn, Term, Unique}; | ||||||
|  | 
 | ||||||
|  | struct Level(u64); | ||||||
|  | 
 | ||||||
|  | pub(crate) struct Converter { | ||||||
|  |     current_level: Level, | ||||||
|  |     levels: HashMap<Unique, Level>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Converter { | ||||||
|  |     pub(crate) fn new() -> Self { | ||||||
|  |         Converter { | ||||||
|  |             current_level: Level(0), | ||||||
|  |             levels: HashMap::new(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub(crate) fn name_to_named_debruijn( | ||||||
|  |         &mut self, | ||||||
|  |         term: Term<Name>, | ||||||
|  |     ) -> anyhow::Result<Term<NamedDeBruijn>> { | ||||||
|  |         let converted_term = match term { | ||||||
|  |             Term::Var(Name { text, unique }) => Term::Var(NamedDeBruijn { | ||||||
|  |                 text, | ||||||
|  |                 index: self.get_index(unique)?, | ||||||
|  |             }), | ||||||
|  |             Term::Delay(term) => Term::Delay(Box::new(self.name_to_named_debruijn(*term)?)), | ||||||
|  |             Term::Lambda { | ||||||
|  |                 parameter_name, | ||||||
|  |                 body, | ||||||
|  |             } => { | ||||||
|  |                 todo!() | ||||||
|  |             } | ||||||
|  |             Term::Apply { function, argument } => Term::Apply { | ||||||
|  |                 function: Box::new(self.name_to_named_debruijn(*function)?), | ||||||
|  |                 argument: Box::new(self.name_to_named_debruijn(*argument)?), | ||||||
|  |             }, | ||||||
|  |             Term::Constant(constant) => Term::Constant(constant), | ||||||
|  |             Term::Force(term) => Term::Force(Box::new(self.name_to_named_debruijn(*term)?)), | ||||||
|  |             Term::Error => Term::Error, | ||||||
|  |             Term::Builtin(builtin) => Term::Builtin(builtin), | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         Ok(converted_term) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub(crate) fn named_debruijn_to_name(&mut self, term: Term<NamedDeBruijn>) -> Term<Name> { | ||||||
|  |         todo!() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_index(&mut self, unique: Unique) -> anyhow::Result<DeBruijn> { | ||||||
|  |         if let Some(found_level) = self.levels.get(&unique) { | ||||||
|  |             let index = self.current_level.0 - found_level.0; | ||||||
|  | 
 | ||||||
|  |             Ok(index.into()) | ||||||
|  |         } else { | ||||||
|  |             anyhow::bail!("Free unique: {}", isize::from(unique)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -7,7 +7,7 @@ use flat::{ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     ast::{Constant, Name, Program, Term}, |     ast::{Constant, Name, Program, Term, Unique}, | ||||||
|     builtins::DefaultFunction, |     builtins::DefaultFunction, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -183,6 +183,20 @@ impl<'b> Decode<'b> for Constant { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl Encode for Unique { | ||||||
|  |     fn encode(&self, e: &mut Encoder) -> Result<(), String> { | ||||||
|  |         isize::from(*self).encode(e)?; | ||||||
|  | 
 | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'b> Decode<'b> for Unique { | ||||||
|  |     fn decode(d: &mut Decoder) -> Result<Self, String> { | ||||||
|  |         Ok(isize::decode(d)?.into()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| impl Encode for Name { | impl Encode for Name { | ||||||
|     fn encode(&self, e: &mut flat::en::Encoder) -> Result<(), String> { |     fn encode(&self, e: &mut flat::en::Encoder) -> Result<(), String> { | ||||||
|         self.text.encode(e)?; |         self.text.encode(e)?; | ||||||
|  | @ -196,7 +210,7 @@ impl<'b> Decode<'b> for Name { | ||||||
|     fn decode(d: &mut Decoder) -> Result<Self, String> { |     fn decode(d: &mut Decoder) -> Result<Self, String> { | ||||||
|         Ok(Name { |         Ok(Name { | ||||||
|             text: String::decode(d)?, |             text: String::decode(d)?, | ||||||
|             unique: isize::decode(d)?, |             unique: Unique::decode(d)?, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| pub mod ast; | pub mod ast; | ||||||
| pub mod builtins; | pub mod builtins; | ||||||
|  | mod debruijn; | ||||||
| mod flat; | mod flat; | ||||||
| pub mod parser; | pub mod parser; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,13 +12,13 @@ use combine::{ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     ast::{Constant, Name, Program, Term}, |     ast::{Constant, Name, Program, Term, Unique}, | ||||||
|     builtins::DefaultFunction, |     builtins::DefaultFunction, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct ParserState { | struct ParserState { | ||||||
|     identifiers: HashMap<String, isize>, |     identifiers: HashMap<String, Unique>, | ||||||
|     current_unique: isize, |     current: Unique, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type StateStream<Input> = state::Stream<Input, ParserState>; | type StateStream<Input> = state::Stream<Input, ParserState>; | ||||||
|  | @ -27,17 +27,20 @@ impl ParserState { | ||||||
|     fn new() -> Self { |     fn new() -> Self { | ||||||
|         ParserState { |         ParserState { | ||||||
|             identifiers: HashMap::new(), |             identifiers: HashMap::new(), | ||||||
|             current_unique: 0, |             current: Unique::new(0), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn intern(&mut self, text: &str) -> isize { |     fn intern(&mut self, text: &str) -> Unique { | ||||||
|         if let Some(u) = self.identifiers.get(text) { |         if let Some(u) = self.identifiers.get(text) { | ||||||
|             *u |             *u | ||||||
|         } else { |         } else { | ||||||
|             let unique = self.current_unique; |             let unique = self.current; | ||||||
|  | 
 | ||||||
|             self.identifiers.insert(text.to_string(), unique); |             self.identifiers.insert(text.to_string(), unique); | ||||||
|             self.current_unique += 1; | 
 | ||||||
|  |             self.current.increment(); | ||||||
|  | 
 | ||||||
|             unique |             unique | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 rvcas
						rvcas