From 3484e484a96037c8ad70d103a12bab598f3264cf Mon Sep 17 00:00:00 2001 From: rvcas Date: Fri, 6 May 2022 01:17:47 -0400 Subject: [PATCH] feat: parse apply --- example/plutus-core | 2 +- src/parser.rs | 136 +++++++++++++++++++++++++------------------- 2 files changed, 77 insertions(+), 61 deletions(-) diff --git a/example/plutus-core b/example/plutus-core index aa257de7..76f101ea 100644 --- a/example/plutus-core +++ b/example/plutus-core @@ -1,3 +1,3 @@ (program 1.0.0 [(lam x (con integer 4)) (con bool False)] -) +) \ No newline at end of file diff --git a/src/parser.rs b/src/parser.rs index 24936aeb..45e13464 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,14 +1,17 @@ use combine::{ attempt, between, choice, many1, parser::char::{alpha_num, digit, hex_digit, space, spaces, string}, - skip_many1, token, EasyParser, ParseError, Parser, Stream, + skip_many1, + stream::position, + token, EasyParser, ParseError, Parser, Stream, }; use crate::ast::{Constant, Program, Term}; pub fn program(src: &str) -> anyhow::Result { let mut parser = program_(); - let result = parser.easy_parse(src); + + let result = parser.easy_parse(position::Stream::new(src)); match result { Ok((program, _)) => Ok(program), @@ -16,19 +19,20 @@ pub fn program(src: &str) -> anyhow::Result { } } -pub fn program_() -> impl Parser +fn program_() -> impl Parser where Input: Stream, Input::Error: ParseError, { - let prog = string("program") - .with(spaces()) - .with((version(), spaces(), term()).map(|(version, _, term)| Program { version, term })); + let prog = string("program").with(spaces()).with( + (version(), skip_many1(space()), term().skip(spaces())) + .map(|(version, _, term)| Program { version, term }), + ); between(token('('), token(')'), prog).skip(spaces()) } -pub fn version() -> impl Parser +fn version() -> impl Parser where Input: Stream, Input::Error: ParseError, @@ -47,25 +51,18 @@ where ) } -pub fn term() -> impl Parser +fn term() -> impl Parser where Input: Stream, Input::Error: ParseError, { choice(( - attempt(between(token('['), token(']'), apply())), - attempt(between( - token('('), - token(')'), - choice(( - attempt(delay()), - attempt(lambda()), - attempt(constant()), - attempt(force()), - )), - )), + attempt(delay()), + attempt(lambda()), + attempt(apply()), + attempt(constant()), + attempt(force()), )) - .skip(spaces()) } parser! { @@ -76,72 +73,91 @@ parser! { } } -pub fn delay() -> impl Parser +fn delay() -> impl Parser where Input: Stream, Input::Error: ParseError, { - string("delay") - .with(skip_many1(space())) - .with(term_()) - .map(|term| Term::Delay(Box::new(term))) + between( + token('('), + token(')'), + string("delay") + .with(skip_many1(space())) + .with(term_()) + .map(|term| Term::Delay(Box::new(term))), + ) } -pub fn force() -> impl Parser +fn force() -> impl Parser where Input: Stream, Input::Error: ParseError, { - string("force") - .with(skip_many1(space())) - .with(term_()) - .map(|term| Term::Force(Box::new(term))) + between( + token('('), + token(')'), + string("force") + .with(skip_many1(space())) + .with(term_()) + .map(|term| Term::Force(Box::new(term))), + ) } -pub fn lambda() -> impl Parser +fn lambda() -> impl Parser where Input: Stream, Input::Error: ParseError, { - string("lam") - .with(skip_many1(space())) - .with((many1(alpha_num()), skip_many1(space()), term_())) - .map(|(parameter_name, _, term)| Term::Lambda { - parameter_name, - body: Box::new(term), - }) + between( + token('('), + token(')'), + string("lam") + .with(skip_many1(space())) + .with((many1(alpha_num()), skip_many1(space()), term_())) + .map(|(parameter_name, _, term)| Term::Lambda { + parameter_name, + body: Box::new(term), + }), + ) } -pub fn apply() -> impl Parser +fn apply() -> impl Parser where Input: Stream, Input::Error: ParseError, { - println!("daid"); - (term_(), skip_many1(space()), term_()).map(|(function, _, argument)| Term::Apply { - function: Box::new(function), - argument: Box::new(argument), - }) + between( + token('['), + token(']'), + (term_().skip(skip_many1(space())), term_()).map(|(function, argument)| Term::Apply { + function: Box::new(function), + argument: Box::new(argument), + }), + ) } -pub fn constant() -> impl Parser +fn constant() -> impl Parser where Input: Stream, Input::Error: ParseError, { - string("con") - .with(skip_many1(space())) - .with(choice(( - attempt(constant_integer()), - attempt(constant_bytestring()), - attempt(constant_string()), - attempt(constant_unit()), - attempt(constant_bool()), - ))) - .map(Term::Constant) + between( + token('('), + token(')'), + string("con") + .with(skip_many1(space())) + .with(choice(( + attempt(constant_integer()), + attempt(constant_bytestring()), + attempt(constant_string()), + attempt(constant_unit()), + attempt(constant_bool()), + ))) + .map(Term::Constant), + ) } -pub fn constant_integer() -> impl Parser +fn constant_integer() -> impl Parser where Input: Stream, Input::Error: ParseError, @@ -152,7 +168,7 @@ where .map(|d: String| Constant::Integer(d.parse::().unwrap())) } -pub fn constant_bytestring() -> impl Parser +fn constant_bytestring() -> impl Parser where Input: Stream, Input::Error: ParseError, @@ -164,7 +180,7 @@ where .map(|b: String| Constant::ByteString(hex::decode(b).unwrap())) } -pub fn constant_string() -> impl Parser +fn constant_string() -> impl Parser where Input: Stream, Input::Error: ParseError, @@ -175,7 +191,7 @@ where .map(Constant::String) } -pub fn constant_unit() -> impl Parser +fn constant_unit() -> impl Parser where Input: Stream, Input::Error: ParseError, @@ -186,7 +202,7 @@ where .map(|_| Constant::Unit) } -pub fn constant_bool() -> impl Parser +fn constant_bool() -> impl Parser where Input: Stream, Input::Error: ParseError,