feat: spec complaint program encoding
Co-authored-by: rvcas <x@rvcas.dev>
This commit is contained in:
@@ -8,7 +8,7 @@ const CONST_TAG_WIDTH: u32 = 4;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Program {
|
||||
pub version: String,
|
||||
pub version: (usize, usize, usize),
|
||||
pub term: Term,
|
||||
}
|
||||
|
||||
@@ -97,7 +97,12 @@ pub fn encode_constant_tag(tag: u8, e: &mut Encoder) -> Result<(), String> {
|
||||
|
||||
impl Encode for Program {
|
||||
fn encode(&self, e: &mut Encoder) -> Result<(), String> {
|
||||
self.version.encode(e)?;
|
||||
let (major, minor, patch) = self.version;
|
||||
|
||||
major.encode(e)?;
|
||||
minor.encode(e)?;
|
||||
patch.encode(e)?;
|
||||
|
||||
self.term.encode(e)?;
|
||||
|
||||
Ok(())
|
||||
@@ -123,7 +128,6 @@ impl Encode for Term {
|
||||
encode_term_tag(2, e)?;
|
||||
// need to create encoding for Binder
|
||||
todo!();
|
||||
body.encode(e)?;
|
||||
}
|
||||
Term::Apply { function, argument } => {
|
||||
encode_term_tag(3, e)?;
|
||||
@@ -169,12 +173,17 @@ impl Encode for &Constant {
|
||||
}
|
||||
Constant::String(s) => {
|
||||
encode_constant(2, e)?;
|
||||
s.encode(e)?;
|
||||
s.as_bytes().encode(e)?;
|
||||
}
|
||||
// there is no char constant tag
|
||||
Constant::Char(c) => {
|
||||
c.encode(e)?;
|
||||
todo!()
|
||||
|
||||
let mut b = [0; 4];
|
||||
|
||||
let s = c.encode_utf8(&mut b);
|
||||
|
||||
s.as_bytes().encode(e)?;
|
||||
}
|
||||
Constant::Unit => encode_constant(3, e)?,
|
||||
Constant::Bool(b) => {
|
||||
@@ -186,3 +195,23 @@ impl Encode for &Constant {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{Constant, Program, Term};
|
||||
|
||||
#[test]
|
||||
fn flat_encode_integer() {
|
||||
let program = Program {
|
||||
version: (11, 22, 33),
|
||||
term: Term::Constant(Constant::Integer(11)),
|
||||
};
|
||||
|
||||
let bytes = program.flat().unwrap();
|
||||
|
||||
assert_eq!(
|
||||
bytes,
|
||||
vec![0b00001011, 0b00010110, 0b00100001, 0b01001000, 0b00000101, 0b10000001]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::{
|
||||
pub fn program(src: &str) -> anyhow::Result<Program> {
|
||||
let mut parser = program_();
|
||||
|
||||
let result = parser.easy_parse(position::Stream::new(src));
|
||||
let result = parser.easy_parse(position::Stream::new(src.trim()));
|
||||
|
||||
match result {
|
||||
Ok((program, _)) => Ok(program),
|
||||
@@ -37,7 +37,7 @@ where
|
||||
between(token('('), token(')'), prog).skip(spaces())
|
||||
}
|
||||
|
||||
fn version<Input>() -> impl Parser<Input, Output = String>
|
||||
fn version<Input>() -> impl Parser<Input, Output = (usize, usize, usize)>
|
||||
where
|
||||
Input: Stream<Token = char>,
|
||||
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
|
||||
@@ -51,7 +51,11 @@ where
|
||||
)
|
||||
.map(
|
||||
|(major, _, minor, _, patch): (String, char, String, char, String)| {
|
||||
format!("{}.{}.{}", major, minor, patch)
|
||||
(
|
||||
major.parse::<usize>().unwrap(),
|
||||
minor.parse::<usize>().unwrap(),
|
||||
patch.parse::<usize>().unwrap(),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -203,7 +207,7 @@ where
|
||||
string("integer")
|
||||
.with(skip_many1(space()))
|
||||
.with(many1(digit()))
|
||||
.map(|d: String| Constant::Integer(d.parse::<i64>().unwrap()))
|
||||
.map(|d: String| Constant::Integer(d.parse::<isize>().unwrap()))
|
||||
}
|
||||
|
||||
fn constant_bytestring<Input>() -> impl Parser<Input, Output = Constant>
|
||||
@@ -253,18 +257,19 @@ where
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use combine::Parser;
|
||||
|
||||
const CODE: &str = include_str!("../example/plutus-core");
|
||||
|
||||
#[test]
|
||||
fn parse_program() {
|
||||
let result = super::program_().parse(CODE);
|
||||
let code = r#"
|
||||
(program 11.22.33
|
||||
(con integer 11)
|
||||
)
|
||||
"#;
|
||||
let result = super::program(code);
|
||||
|
||||
assert!(result.is_ok());
|
||||
|
||||
let program = result.unwrap().0;
|
||||
let program = result.unwrap();
|
||||
|
||||
assert_eq!(program.version, "1.0.0");
|
||||
assert_eq!(program.version, (11, 22, 33));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user