feat: get program ready for debruijn
This commit is contained in:
		
							parent
							
								
									c7037ff8d9
								
							
						
					
					
						commit
						83d6b5243e
					
				|  | @ -1,31 +1,31 @@ | ||||||
| use crate::builtins::DefaultFunction; | use crate::builtins::DefaultFunction; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone, PartialEq)] | #[derive(Debug, Clone, PartialEq)] | ||||||
| pub struct Program { | pub struct Program<T> { | ||||||
|     pub version: (usize, usize, usize), |     pub version: (usize, usize, usize), | ||||||
|     pub term: Term, |     pub term: Term<T>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone, PartialEq)] | #[derive(Debug, Clone, PartialEq)] | ||||||
| pub enum Term { | pub enum Term<T> { | ||||||
|     // tag: 0
 |     // tag: 0
 | ||||||
|     Var(Name), |     Var(T), | ||||||
|     // tag: 1
 |     // tag: 1
 | ||||||
|     Delay(Box<Term>), |     Delay(Box<Term<T>>), | ||||||
|     // tag: 2
 |     // tag: 2
 | ||||||
|     Lambda { |     Lambda { | ||||||
|         parameter_name: Name, |         parameter_name: T, | ||||||
|         body: Box<Term>, |         body: Box<Term<T>>, | ||||||
|     }, |     }, | ||||||
|     // tag: 3
 |     // tag: 3
 | ||||||
|     Apply { |     Apply { | ||||||
|         function: Box<Term>, |         function: Box<Term<T>>, | ||||||
|         argument: Box<Term>, |         argument: Box<Term<T>>, | ||||||
|     }, |     }, | ||||||
|     // tag: 4
 |     // tag: 4
 | ||||||
|     Constant(Constant), |     Constant(Constant), | ||||||
|     // tag: 5
 |     // tag: 5
 | ||||||
|     Force(Box<Term>), |     Force(Box<Term<T>>), | ||||||
|     // tag: 6
 |     // tag: 6
 | ||||||
|     Error, |     Error, | ||||||
|     // tag: 7
 |     // tag: 7
 | ||||||
|  | @ -53,3 +53,12 @@ pub struct Name { | ||||||
|     pub text: String, |     pub text: String, | ||||||
|     pub unique: isize, |     pub unique: isize, | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, PartialEq)] | ||||||
|  | pub struct NamedDeBruijn { | ||||||
|  |     pub text: String, | ||||||
|  |     pub index: isize, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, PartialEq)] | ||||||
|  | pub struct DeBruijn(isize); | ||||||
|  |  | ||||||
|  | @ -15,9 +15,12 @@ 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> Flat<'b> for Program {} | impl<'b, T> Flat<'b> for Program<T> where T: Encode + Decode<'b> {} | ||||||
| 
 | 
 | ||||||
| impl Program { | impl<'b, T> Program<T> | ||||||
|  | where | ||||||
|  |     T: Encode + Decode<'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
 | ||||||
|     pub fn to_flat(&self) -> anyhow::Result<Vec<u8>> { |     pub fn to_flat(&self) -> anyhow::Result<Vec<u8>> { | ||||||
|  | @ -33,7 +36,7 @@ impl Program { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Encode for Program { | impl<T: Encode> Encode for Program<T> { | ||||||
|     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; | ||||||
| 
 | 
 | ||||||
|  | @ -47,7 +50,10 @@ impl Encode for Program { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'b> Decode<'b> for Program { | impl<'b, T> Decode<'b> for Program<T> | ||||||
|  | where | ||||||
|  |     T: Decode<'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)?); | ||||||
|         let term = Term::decode(d)?; |         let term = Term::decode(d)?; | ||||||
|  | @ -55,7 +61,7 @@ impl<'b> Decode<'b> for Program { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Encode for Term { | impl<T: Encode> Encode for Term<T> { | ||||||
|     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) => { | ||||||
|  | @ -104,13 +110,16 @@ impl Encode for Term { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'b> Decode<'b> for Term { | impl<'b, T> Decode<'b> for Term<T> | ||||||
|  | where | ||||||
|  |     T: Decode<'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(Name::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: Name::decode(d)?, |                 parameter_name: T::decode(d)?, | ||||||
|                 body: Box::new(Term::decode(d)?), |                 body: Box::new(Term::decode(d)?), | ||||||
|             }), |             }), | ||||||
|             3 => Ok(Term::Apply { |             3 => Ok(Term::Apply { | ||||||
|  | @ -255,11 +264,13 @@ pub fn decode_constant_tag(d: &mut Decoder) -> Result<u8, String> { | ||||||
| mod test { | mod test { | ||||||
|     use flat::Flat; |     use flat::Flat; | ||||||
| 
 | 
 | ||||||
|  |     use crate::ast::Name; | ||||||
|  | 
 | ||||||
|     use super::{Constant, Program, Term}; |     use super::{Constant, Program, Term}; | ||||||
| 
 | 
 | ||||||
|     #[test] |     #[test] | ||||||
|     fn flat_encode_integer() { |     fn flat_encode_integer() { | ||||||
|         let program = Program { |         let program = Program::<Name> { | ||||||
|             version: (11, 22, 33), |             version: (11, 22, 33), | ||||||
|             term: Term::Constant(Constant::Integer(11)), |             term: Term::Constant(Constant::Integer(11)), | ||||||
|         }; |         }; | ||||||
|  | @ -283,7 +294,7 @@ mod test { | ||||||
|             term: Term::Constant(Constant::Integer(11)), |             term: Term::Constant(Constant::Integer(11)), | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         let actual_program: Program = Program::unflat(&flat_encoded).unwrap(); |         let actual_program: Program<Name> = Program::unflat(&flat_encoded).unwrap(); | ||||||
| 
 | 
 | ||||||
|         assert_eq!(actual_program, expected_program) |         assert_eq!(actual_program, expected_program) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -43,7 +43,7 @@ impl ParserState { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn program(src: &str) -> anyhow::Result<Program> { | pub fn program(src: &str) -> anyhow::Result<Program<Name>> { | ||||||
|     let mut parser = program_(); |     let mut parser = program_(); | ||||||
| 
 | 
 | ||||||
|     let result = parser.parse(state::Stream { |     let result = parser.parse(state::Stream { | ||||||
|  | @ -57,7 +57,7 @@ pub fn program(src: &str) -> anyhow::Result<Program> { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn program_<Input>() -> impl Parser<StateStream<Input>, Output = Program> | fn program_<Input>() -> impl Parser<StateStream<Input>, Output = Program<Name>> | ||||||
| where | where | ||||||
|     Input: Stream<Token = char>, |     Input: Stream<Token = char>, | ||||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, |     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||||
|  | @ -93,7 +93,7 @@ where | ||||||
|         ) |         ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn term<Input>() -> impl Parser<StateStream<Input>, Output = Term> | fn term<Input>() -> impl Parser<StateStream<Input>, Output = Term<Name>> | ||||||
| where | where | ||||||
|     Input: Stream<Token = char>, |     Input: Stream<Token = char>, | ||||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, |     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||||
|  | @ -109,7 +109,7 @@ where | ||||||
|     )))) |     )))) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn delay<Input>() -> impl Parser<StateStream<Input>, Output = Term> | fn delay<Input>() -> impl Parser<StateStream<Input>, Output = Term<Name>> | ||||||
| where | where | ||||||
|     Input: Stream<Token = char>, |     Input: Stream<Token = char>, | ||||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, |     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||||
|  | @ -124,7 +124,7 @@ where | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn force<Input>() -> impl Parser<StateStream<Input>, Output = Term> | fn force<Input>() -> impl Parser<StateStream<Input>, Output = Term<Name>> | ||||||
| where | where | ||||||
|     Input: Stream<Token = char>, |     Input: Stream<Token = char>, | ||||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, |     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||||
|  | @ -139,7 +139,7 @@ where | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn lambda<Input>() -> impl Parser<StateStream<Input>, Output = Term> | fn lambda<Input>() -> impl Parser<StateStream<Input>, Output = Term<Name>> | ||||||
| where | where | ||||||
|     Input: Stream<Token = char>, |     Input: Stream<Token = char>, | ||||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, |     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||||
|  | @ -151,7 +151,7 @@ where | ||||||
|             .with(skip_many1(space())) |             .with(skip_many1(space())) | ||||||
|             .with((many1(alpha_num()), skip_many1(space()), term())) |             .with((many1(alpha_num()), skip_many1(space()), term())) | ||||||
|             .map_input( |             .map_input( | ||||||
|                 |(parameter_name, _, term): (String, _, Term), input| Term::Lambda { |                 |(parameter_name, _, term): (String, _, Term<Name>), input| Term::Lambda { | ||||||
|                     parameter_name: Name { |                     parameter_name: Name { | ||||||
|                         unique: input.state.intern(¶meter_name), |                         unique: input.state.intern(¶meter_name), | ||||||
|                         text: parameter_name, |                         text: parameter_name, | ||||||
|  | @ -162,7 +162,7 @@ where | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn apply<Input>() -> impl Parser<StateStream<Input>, Output = Term> | fn apply<Input>() -> impl Parser<StateStream<Input>, Output = Term<Name>> | ||||||
| where | where | ||||||
|     Input: Stream<Token = char>, |     Input: Stream<Token = char>, | ||||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, |     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||||
|  | @ -177,7 +177,7 @@ where | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn builtin<Input>() -> impl Parser<StateStream<Input>, Output = Term> | fn builtin<Input>() -> impl Parser<StateStream<Input>, Output = Term<Name>> | ||||||
| where | where | ||||||
|     Input: Stream<Token = char>, |     Input: Stream<Token = char>, | ||||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, |     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||||
|  | @ -194,7 +194,7 @@ where | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn error<Input>() -> impl Parser<StateStream<Input>, Output = Term> | fn error<Input>() -> impl Parser<StateStream<Input>, Output = Term<Name>> | ||||||
| where | where | ||||||
|     Input: Stream<Token = char>, |     Input: Stream<Token = char>, | ||||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, |     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||||
|  | @ -208,7 +208,7 @@ where | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn constant<Input>() -> impl Parser<StateStream<Input>, Output = Term> | fn constant<Input>() -> impl Parser<StateStream<Input>, Output = Term<Name>> | ||||||
| where | where | ||||||
|     Input: Stream<Token = char>, |     Input: Stream<Token = char>, | ||||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, |     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 rvcas
						rvcas