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,