From 819a0a20e6fd6a5a4b8cfe61719654f55bc1a5e0 Mon Sep 17 00:00:00 2001 From: microproofs Date: Sat, 2 Sep 2023 21:25:34 -0400 Subject: [PATCH] add tests for case and constr Fix a minor issue with decoding order --- crates/flat-rs/src/decode/decoder.rs | 15 ++++++++ crates/uplc/src/flat.rs | 36 +++++++++++++----- crates/uplc/src/machine.rs | 4 +- crates/uplc/src/machine/cost_model.rs | 18 ++++----- crates/uplc/src/parser.rs | 4 +- .../test_data/case_constr/case_constr.flat | Bin 0 -> 14 bytes .../test_data/case_constr/case_constr.uplc | 4 ++ crates/uplc/tests/integ_tests.rs | 8 ++++ 8 files changed, 67 insertions(+), 22 deletions(-) create mode 100644 crates/uplc/test_data/case_constr/case_constr.flat create mode 100644 crates/uplc/test_data/case_constr/case_constr.uplc diff --git a/crates/flat-rs/src/decode/decoder.rs b/crates/flat-rs/src/decode/decoder.rs index 0c1cfca9..1481fbeb 100644 --- a/crates/flat-rs/src/decode/decoder.rs +++ b/crates/flat-rs/src/decode/decoder.rs @@ -182,6 +182,21 @@ impl<'b> Decoder<'b> { Ok(vec_array) } + pub fn decode_list_with_debug( + &mut self, + decoder_func: F, + state_log: &mut Vec, + ) -> Result, Error> + where + F: Copy + FnOnce(&mut Decoder, &mut Vec) -> Result, + { + let mut vec_array: Vec = Vec::new(); + while self.bit()? { + vec_array.push(decoder_func(self, state_log)?) + } + Ok(vec_array) + } + /// Decode the next bit in the buffer. /// If the bit was 0 then return true. /// Otherwise return false. diff --git a/crates/uplc/src/flat.rs b/crates/uplc/src/flat.rs index 3809eee4..0505cf6e 100644 --- a/crates/uplc/src/flat.rs +++ b/crates/uplc/src/flat.rs @@ -207,22 +207,17 @@ where 6 => Ok(Term::Error), 7 => Ok(Term::Builtin(DefaultFunction::decode(d)?)), 8 => { + let tag = usize::decode(d)?; let fields = d.decode_list_with(|d| Term::::decode(d))?; - Ok(Term::Constr { - tag: usize::decode(d)?, - fields, - }) + Ok(Term::Constr { tag, fields }) } 9 => { - let constr = Term::::decode(d)?; + let constr = (Term::::decode(d)?).into(); let branches = d.decode_list_with(|d| Term::::decode(d))?; - Ok(Term::Case { - constr: Rc::new(constr), - branches, - }) + Ok(Term::Case { constr, branches }) } x => { let buffer_slice: Vec = d @@ -386,6 +381,29 @@ where } } } + 8 => { + state_log.push("(constr ".to_string()); + + let tag = usize::decode(d)?; + + let fields = d.decode_list_with_debug( + |d, state_log| Term::::decode_debug(d, state_log), + state_log, + )?; + + Ok(Term::Constr { tag, fields }) + } + 9 => { + state_log.push("(case ".to_string()); + let constr = Term::::decode_debug(d, state_log)?.into(); + + let branches = d.decode_list_with_debug( + |d, state_log| Term::::decode_debug(d, state_log), + state_log, + )?; + + Ok(Term::Case { constr, branches }) + } x => { state_log.push("parse error".to_string()); diff --git a/crates/uplc/src/machine.rs b/crates/uplc/src/machine.rs index 95600519..8384bcff 100644 --- a/crates/uplc/src/machine.rs +++ b/crates/uplc/src/machine.rs @@ -505,7 +505,7 @@ mod tests { ]; for (fun, tag, n, m, result) in test_data { - let eval_result = make_program(fun, tag, n, m).eval(ExBudget::default()); + let eval_result = make_program(fun, tag, n, m).eval(ExBudget::max()); assert_eq!( eval_result.result().unwrap(), @@ -535,7 +535,7 @@ mod tests { let test_data = vec![(0, 5), (1, 10), (2, 15)]; for (tag, result) in test_data { - let eval_result = make_program(tag).eval(ExBudget::default()); + let eval_result = make_program(tag).eval(ExBudget::max()); assert_eq!( eval_result.result().unwrap(), diff --git a/crates/uplc/src/machine/cost_model.rs b/crates/uplc/src/machine/cost_model.rs index 02f7bdde..3ca2b6ed 100644 --- a/crates/uplc/src/machine/cost_model.rs +++ b/crates/uplc/src/machine/cost_model.rs @@ -39,7 +39,7 @@ impl ExBudget { pub fn max() -> Self { ExBudget { - mem: 14000000000, + mem: 14000000000000, cpu: 10000000000000, } } @@ -147,12 +147,12 @@ impl MachineCosts { }, // Placeholder values constr: ExBudget { - mem: 100, - cpu: 23000, + mem: 30000000000, + cpu: 30000000000, }, case: ExBudget { - mem: 100, - cpu: 23000, + mem: 30000000000, + cpu: 30000000000, }, } } @@ -193,12 +193,12 @@ impl Default for MachineCosts { }, // Placeholder values constr: ExBudget { - mem: 100, - cpu: 23000, + mem: 30000000000, + cpu: 30000000000, }, case: ExBudget { - mem: 100, - cpu: 23000, + mem: 30000000000, + cpu: 30000000000, }, } } diff --git a/crates/uplc/src/parser.rs b/crates/uplc/src/parser.rs index 4a70c1e2..e62d4bbb 100644 --- a/crates/uplc/src/parser.rs +++ b/crates/uplc/src/parser.rs @@ -145,13 +145,13 @@ peg::parser! { = "(" _* "error" _* ")" { Term::Error } rule constr() -> Term - = "(" _* "constr" _+ tag:decimal() _+ fields:(t:term() _* { t })+ ")" { + = "(" _* "constr" _+ tag:decimal() _* fields:(t:term() _* { t })* _* ")" { Term::Constr { tag, fields } } #[cache_left_rec] rule case() -> Term - = "(" _* "case" _+ constr:term() _* branches:(t:term() _* { t })+ ")" { + = "(" _* "case" _+ constr:term() _* branches:(t:term() _* { t })+ _* ")" { Term::Case { constr: constr.into(), branches } } diff --git a/crates/uplc/test_data/case_constr/case_constr.flat b/crates/uplc/test_data/case_constr/case_constr.flat new file mode 100644 index 0000000000000000000000000000000000000000..0d34982c756cc8d8fb2541a540f5ed1a44f54e5d GIT binary patch literal 14 VcmZQ%V3@&>z%+rufZ2ng5daWb0*C+r literal 0 HcmV?d00001 diff --git a/crates/uplc/test_data/case_constr/case_constr.uplc b/crates/uplc/test_data/case_constr/case_constr.uplc new file mode 100644 index 00000000..6fc1ecde --- /dev/null +++ b/crates/uplc/test_data/case_constr/case_constr.uplc @@ -0,0 +1,4 @@ +(program + 1.0.0 + (case (constr 0)(constr 0(con integer 0))(constr 1(con integer 1))) +) \ No newline at end of file diff --git a/crates/uplc/tests/integ_tests.rs b/crates/uplc/tests/integ_tests.rs index 753e73c0..b57a834f 100644 --- a/crates/uplc/tests/integ_tests.rs +++ b/crates/uplc/tests/integ_tests.rs @@ -74,6 +74,14 @@ fn fibonacci() { round_trip_test(bytes, code); } +#[test] +fn case_constr() { + let bytes = include_bytes!("../test_data/case_constr/case_constr.flat"); + let code = include_str!("../test_data/case_constr/case_constr.uplc"); + + round_trip_test(bytes, code); +} + #[test] fn one_way_fibonacci() { let bytes = include_bytes!("../test_data/fibonacci/fibonacci.flat");