feat: most of the constants and better space skipping
This commit is contained in:
		
							parent
							
								
									6fdcd7012d
								
							
						
					
					
						commit
						b3318e5f24
					
				|  | @ -107,6 +107,12 @@ dependencies = [ | |||
|  "libc", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "hex" | ||||
| version = "0.4.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "indexmap" | ||||
| version = "1.8.1" | ||||
|  | @ -142,6 +148,7 @@ dependencies = [ | |||
|  "anyhow", | ||||
|  "clap", | ||||
|  "combine", | ||||
|  "hex", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  |  | |||
|  | @ -9,3 +9,4 @@ edition = "2021" | |||
| anyhow = "1.0.57" | ||||
| clap = { version = "3.1.14", features = ["derive"] } | ||||
| combine = "4.6.4" | ||||
| hex = "0.4.3" | ||||
|  |  | |||
|  | @ -1,3 +1,3 @@ | |||
| (program 1.0.0 | ||||
|     (con integer 4) | ||||
|     (con bool False) | ||||
| ) | ||||
|  | @ -1,14 +1,14 @@ | |||
| use combine::{ | ||||
|     between, many1, | ||||
|     parser::char::{digit, spaces, string}, | ||||
|     token, ParseError, Parser, Stream, | ||||
|     attempt, between, choice, many1, | ||||
|     parser::char::{alpha_num, digit, hex_digit, space, spaces, string}, | ||||
|     skip_many1, token, EasyParser, ParseError, Parser, Stream, | ||||
| }; | ||||
| 
 | ||||
| use crate::ast::{Constant, Program, Term}; | ||||
| 
 | ||||
| pub fn program(src: &str) -> anyhow::Result<Program> { | ||||
|     let mut parser = program_(); | ||||
|     let result = parser.parse(src); | ||||
|     let result = parser.easy_parse(src); | ||||
| 
 | ||||
|     match result { | ||||
|         Ok((program, _)) => Ok(program), | ||||
|  | @ -52,7 +52,12 @@ where | |||
|     Input: Stream<Token = char>, | ||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||
| { | ||||
|     between(token('('), token(')'), constant().or(delay())).skip(spaces()) | ||||
|     between( | ||||
|         token('('), | ||||
|         token(')'), | ||||
|         choice((attempt(constant()), attempt(delay()), attempt(force()))), | ||||
|     ) | ||||
|     .skip(spaces()) | ||||
| } | ||||
| 
 | ||||
| parser! { | ||||
|  | @ -69,19 +74,36 @@ where | |||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||
| { | ||||
|     string("delay") | ||||
|         .skip(spaces()) | ||||
|         .with(skip_many1(space())) | ||||
|         .with(term_()) | ||||
|         .map(|term| Term::Delay(Box::new(term))) | ||||
| } | ||||
| 
 | ||||
| pub fn force<Input>() -> impl Parser<Input, Output = Term> | ||||
| where | ||||
|     Input: Stream<Token = char>, | ||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||
| { | ||||
|     string("force") | ||||
|         .with(skip_many1(space())) | ||||
|         .with(term_()) | ||||
|         .map(|term| Term::Force(Box::new(term))) | ||||
| } | ||||
| 
 | ||||
| pub fn constant<Input>() -> impl Parser<Input, Output = Term> | ||||
| where | ||||
|     Input: Stream<Token = char>, | ||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||
| { | ||||
|     string("con") | ||||
|         .skip(spaces()) | ||||
|         .with(constant_integer().or(unit()).or(constant_bool())) | ||||
|         .with(skip_many1(space())) | ||||
|         .with(choice(( | ||||
|             attempt(constant_integer()), | ||||
|             attempt(constant_bytestring()), | ||||
|             attempt(constant_string()), | ||||
|             attempt(constant_unit()), | ||||
|             attempt(constant_bool()), | ||||
|         ))) | ||||
|         .map(Term::Constant) | ||||
| } | ||||
| 
 | ||||
|  | @ -91,33 +113,56 @@ where | |||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||
| { | ||||
|     string("integer") | ||||
|         .skip(spaces()) | ||||
|         .with(skip_many1(space())) | ||||
|         .with(many1(digit())) | ||||
|         .map(|d: String| Constant::Integer(d.parse::<i64>().unwrap())) | ||||
| } | ||||
| 
 | ||||
| pub fn constant_bytestring<Input>() -> impl Parser<Input, Output = Constant> | ||||
| where | ||||
|     Input: Stream<Token = char>, | ||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||
| { | ||||
|     string("bytestring") | ||||
|         .with(skip_many1(space())) | ||||
|         .with(token('#')) | ||||
|         .with(many1(hex_digit())) | ||||
|         .map(|b: String| Constant::ByteString(hex::decode(b).unwrap())) | ||||
| } | ||||
| 
 | ||||
| pub fn constant_string<Input>() -> impl Parser<Input, Output = Constant> | ||||
| where | ||||
|     Input: Stream<Token = char>, | ||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||
| { | ||||
|     string("string") | ||||
|         .with(skip_many1(space())) | ||||
|         .with(between(token('"'), token('"'), many1(alpha_num()))) | ||||
|         .map(Constant::String) | ||||
| } | ||||
| 
 | ||||
| pub fn constant_unit<Input>() -> impl Parser<Input, Output = Constant> | ||||
| where | ||||
|     Input: Stream<Token = char>, | ||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||
| { | ||||
|     string("unit") | ||||
|         .with(skip_many1(space())) | ||||
|         .with(string("()")) | ||||
|         .map(|_| Constant::Unit) | ||||
| } | ||||
| 
 | ||||
| pub fn constant_bool<Input>() -> impl Parser<Input, Output = Constant> | ||||
| where | ||||
|     Input: Stream<Token = char>, | ||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||
| { | ||||
|     string("bool") | ||||
|         .skip(spaces()) | ||||
|         .with(skip_many1(space())) | ||||
|         .with(string("True").or(string("False"))) | ||||
|         .map(|b| Constant::Bool(b == "True")) | ||||
| } | ||||
| 
 | ||||
| pub fn unit<Input>() -> impl Parser<Input, Output = Constant> | ||||
| where | ||||
|     Input: Stream<Token = char>, | ||||
|     Input::Error: ParseError<Input::Token, Input::Range, Input::Position>, | ||||
| { | ||||
|     string("unit") | ||||
|         .skip(spaces()) | ||||
|         .with(string("()")) | ||||
|         .map(|_| Constant::Unit) | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod test { | ||||
|     use combine::Parser; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 rvcas
						rvcas