diff --git a/crates/uplc/src/flat.rs b/crates/uplc/src/flat.rs index 51524a2f..c76e818c 100644 --- a/crates/uplc/src/flat.rs +++ b/crates/uplc/src/flat.rs @@ -144,8 +144,6 @@ impl Encode for &Constant { } // there is no char constant tag Constant::Char(c) => { - c.encode(e)?; - let mut b = [0; 4]; let s = c.encode_utf8(&mut b); diff --git a/crates/uplc/src/parser.rs b/crates/uplc/src/parser.rs index fb4aab63..8c3b07b7 100644 --- a/crates/uplc/src/parser.rs +++ b/crates/uplc/src/parser.rs @@ -2,10 +2,13 @@ use std::{collections::HashMap, str::FromStr}; use combine::{ attempt, between, choice, many1, - parser::char::{alpha_num, digit, hex_digit, space, spaces, string}, + parser::{ + char::{alpha_num, digit, hex_digit, space, spaces, string}, + combinator::no_partial, + }, skip_many1, - stream::position, - token, EasyParser, ParseError, Parser, Stream, + stream::{position, state}, + token, ParseError, Parser, Stream, }; use crate::{ @@ -18,6 +21,8 @@ struct ParserState { current_unique: isize, } +type StateStream = state::Stream; + impl ParserState { fn new() -> Self { ParserState { @@ -26,12 +31,12 @@ impl ParserState { } } - fn intern(&mut self, text: String) -> isize { - if let Some(u) = self.identifiers.get(&text) { + fn intern(&mut self, text: &str) -> isize { + if let Some(u) = self.identifiers.get(text) { *u } else { let unique = self.current_unique; - self.identifiers.insert(text, unique); + self.identifiers.insert(text.to_string(), unique); self.current_unique += 1; unique } @@ -39,10 +44,12 @@ impl ParserState { } pub fn program(src: &str) -> anyhow::Result { - let mut state = ParserState::new(); - let mut parser = program_(&mut state); + let mut parser = program_(); - let result = parser.easy_parse(position::Stream::new(src.trim())); + let result = parser.parse(state::Stream { + stream: position::Stream::new(src.trim()), + state: ParserState::new(), + }); match result { Ok((program, _)) => Ok(program), @@ -50,20 +57,20 @@ pub fn program(src: &str) -> anyhow::Result { } } -fn program_(state: &mut ParserState) -> impl Parser +fn program_() -> impl Parser, Output = Program> where Input: Stream, Input::Error: ParseError, { let prog = string("program").with(skip_many1(space())).with( - (version(), skip_many1(space()), term(state).skip(spaces())) + (version(), skip_many1(space()), term().skip(spaces())) .map(|(version, _, term)| Program { version, term }), ); between(token('('), token(')'), prog).skip(spaces()) } -fn version() -> impl Parser +fn version() -> impl Parser, Output = (usize, usize, usize)> where Input: Stream, Input::Error: ParseError, @@ -86,31 +93,23 @@ where ) } -fn term(state: &mut ParserState) -> impl Parser +fn term() -> impl Parser, Output = Term> where Input: Stream, Input::Error: ParseError, { - choice(( - attempt(delay(state)), - attempt(lambda(state)), - attempt(apply(state)), + opaque!(no_partial(choice(( + attempt(delay()), + attempt(lambda()), + attempt(apply()), attempt(constant()), - attempt(force(state)), + attempt(force()), attempt(error()), attempt(builtin()), - )) + )))) } -parser! { - fn term_[I](state: &mut ParserState)(I) -> Term - where [I: Stream] - { - term(state) - } -} - -fn delay(state: &mut ParserState) -> impl Parser +fn delay() -> impl Parser, Output = Term> where Input: Stream, Input::Error: ParseError, @@ -120,12 +119,12 @@ where token(')'), string("delay") .with(skip_many1(space())) - .with(term_(state)) + .with(term()) .map(|term| Term::Delay(Box::new(term))), ) } -fn force(state: &mut ParserState) -> impl Parser +fn force() -> impl Parser, Output = Term> where Input: Stream, Input::Error: ParseError, @@ -135,12 +134,12 @@ where token(')'), string("force") .with(skip_many1(space())) - .with(term_(state)) + .with(term()) .map(|term| Term::Force(Box::new(term))), ) } -fn lambda(state: &mut ParserState) -> impl Parser +fn lambda() -> impl Parser, Output = Term> where Input: Stream, Input::Error: ParseError, @@ -150,18 +149,20 @@ where token(')'), string("lam") .with(skip_many1(space())) - .with((many1(alpha_num()), skip_many1(space()), term_(state))) - .map(|(parameter_name, _, term)| Term::Lambda { - parameter_name: Name { - text: parameter_name, - unique: state.intern(parameter_name), + .with((many1(alpha_num()), skip_many1(space()), term())) + .map_input( + |(parameter_name, _, term): (String, _, Term), input| Term::Lambda { + parameter_name: Name { + unique: input.state.intern(¶meter_name), + text: parameter_name, + }, + body: Box::new(term), }, - body: Box::new(term), - }), + ), ) } -fn apply(state: &mut ParserState) -> impl Parser +fn apply() -> impl Parser, Output = Term> where Input: Stream, Input::Error: ParseError, @@ -169,16 +170,14 @@ where between( token('['), token(']'), - (term_(state).skip(skip_many1(space())), term_(state)).map(|(function, argument)| { - Term::Apply { - function: Box::new(function), - argument: Box::new(argument), - } + (term().skip(skip_many1(space())), term()).map(|(function, argument)| Term::Apply { + function: Box::new(function), + argument: Box::new(argument), }), ) } -pub fn builtin() -> impl Parser +fn builtin() -> impl Parser, Output = Term> where Input: Stream, Input::Error: ParseError, @@ -195,7 +194,7 @@ where ) } -pub fn error() -> impl Parser +fn error() -> impl Parser, Output = Term> where Input: Stream, Input::Error: ParseError, @@ -209,7 +208,7 @@ where ) } -pub fn constant() -> impl Parser +fn constant() -> impl Parser, Output = Term> where Input: Stream, Input::Error: ParseError, @@ -230,7 +229,7 @@ where ) } -fn constant_integer() -> impl Parser +fn constant_integer() -> impl Parser, Output = Constant> where Input: Stream, Input::Error: ParseError, @@ -241,7 +240,7 @@ where .map(|d: String| Constant::Integer(d.parse::().unwrap())) } -fn constant_bytestring() -> impl Parser +fn constant_bytestring() -> impl Parser, Output = Constant> where Input: Stream, Input::Error: ParseError, @@ -253,7 +252,7 @@ where .map(|b: String| Constant::ByteString(hex::decode(b).unwrap())) } -fn constant_string() -> impl Parser +fn constant_string() -> impl Parser, Output = Constant> where Input: Stream, Input::Error: ParseError, @@ -264,7 +263,7 @@ where .map(Constant::String) } -fn constant_unit() -> impl Parser +fn constant_unit() -> impl Parser, Output = Constant> where Input: Stream, Input::Error: ParseError, @@ -275,7 +274,7 @@ where .map(|_| Constant::Unit) } -fn constant_bool() -> impl Parser +fn constant_bool() -> impl Parser, Output = Constant> where Input: Stream, Input::Error: ParseError,