From 1542e5bf483634ecb6583bef87863f55a6212cf7 Mon Sep 17 00:00:00 2001 From: Dominic Date: Mon, 28 Nov 2022 13:45:10 +0100 Subject: [PATCH] update code --- examples/.gitignore | 3 +++ examples/skiplist-1-4.p3l | 23 ++++++++++++----------- examples/skiplist-3-8.p3l | 23 ++++++++++++----------- examples/skiplist.p3l | 23 ++++++++++++----------- src/ast/ty.rs | 33 ++++++++++++++++++++++++++++----- stdlib/src/lib.rs | 4 ++++ stdlib/src/output/bar.rs | 7 +++++++ stdlib/src/output/bubble.rs | 11 +++++++++-- 8 files changed, 87 insertions(+), 40 deletions(-) create mode 100644 examples/.gitignore diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000..1e62411 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,3 @@ +# these files are auto-derived from the skiplist example +skiplist-1-4.p3l +skiplist-3-8.p3l diff --git a/examples/skiplist-1-4.p3l b/examples/skiplist-1-4.p3l index bf346e8..c60107c 100644 --- a/examples/skiplist-1-4.p3l +++ b/examples/skiplist-1-4.p3l @@ -239,19 +239,20 @@ fn skiplist_insert( // NOT PUBLIC API // Find a value in the skiplist, starting the search at a specific node. +// Return the value along with the path length of the search. fn skiplist_get_impl( node: SkipListNode, key: int ) -> (Option, int) { - let steps: int = 1; + let pathlen: int = 1; if (*node).3 < key { while true { if let Some(next) = (*node).2 { let next_key: int = (*next).3; - steps = steps + 1; if next_key <= key { node = next; + pathlen = pathlen + 1; if next_key == key { break; } else { @@ -270,26 +271,26 @@ fn skiplist_get_impl( } if (*node).3 != key { - return (None, steps); + return (None, pathlen); } // the value is only stored at the lowest level while let Some(below) = (*node).1 { node = below; } - return (Some(unwrap::((*node).4)), steps); + return (Some(unwrap::((*node).4)), pathlen); } -// Find a value in the skiplist. +// Find a value in the skiplist. Return the value along with the path +// length of the search. fn skiplist_get(list: SkipList, key: int) -> (Option, int) { - let steps: int = 0; + let pathlen: int = 0; while true { if let Some(node) = list.2 { - steps = steps + 1; if (*node).3 <= key { let tmp: (Option, int) = skiplist_get_impl::(node, key); - return (tmp.0, steps + tmp.1); + return (tmp.0, pathlen + tmp.1); } } @@ -298,7 +299,7 @@ fn skiplist_get(list: SkipList, key: int) -> (Option, int) { continue; } - return (None, steps); + return (None, pathlen); } } @@ -375,8 +376,8 @@ let _unit: () = assert_in_range(key, 0, len); let lookup: (Option<()>, int) = skiplist_get::<()>(list, key); let _unit: () = unwrap::<()>(lookup.0); -let steps: int = lookup.1; +let pathlen: int = lookup.1; let lvl: int = skiplist_level::<()>(list); output!(len); -output!(lvl, steps); +output!(lvl, pathlen); diff --git a/examples/skiplist-3-8.p3l b/examples/skiplist-3-8.p3l index 111aaf4..356d95d 100644 --- a/examples/skiplist-3-8.p3l +++ b/examples/skiplist-3-8.p3l @@ -239,19 +239,20 @@ fn skiplist_insert( // NOT PUBLIC API // Find a value in the skiplist, starting the search at a specific node. +// Return the value along with the path length of the search. fn skiplist_get_impl( node: SkipListNode, key: int ) -> (Option, int) { - let steps: int = 1; + let pathlen: int = 1; if (*node).3 < key { while true { if let Some(next) = (*node).2 { let next_key: int = (*next).3; - steps = steps + 1; if next_key <= key { node = next; + pathlen = pathlen + 1; if next_key == key { break; } else { @@ -270,26 +271,26 @@ fn skiplist_get_impl( } if (*node).3 != key { - return (None, steps); + return (None, pathlen); } // the value is only stored at the lowest level while let Some(below) = (*node).1 { node = below; } - return (Some(unwrap::((*node).4)), steps); + return (Some(unwrap::((*node).4)), pathlen); } -// Find a value in the skiplist. +// Find a value in the skiplist. Return the value along with the path +// length of the search. fn skiplist_get(list: SkipList, key: int) -> (Option, int) { - let steps: int = 0; + let pathlen: int = 0; while true { if let Some(node) = list.2 { - steps = steps + 1; if (*node).3 <= key { let tmp: (Option, int) = skiplist_get_impl::(node, key); - return (tmp.0, steps + tmp.1); + return (tmp.0, pathlen + tmp.1); } } @@ -298,7 +299,7 @@ fn skiplist_get(list: SkipList, key: int) -> (Option, int) { continue; } - return (None, steps); + return (None, pathlen); } } @@ -375,8 +376,8 @@ let _unit: () = assert_in_range(key, 0, len); let lookup: (Option<()>, int) = skiplist_get::<()>(list, key); let _unit: () = unwrap::<()>(lookup.0); -let steps: int = lookup.1; +let pathlen: int = lookup.1; let lvl: int = skiplist_level::<()>(list); output!(len); -output!(lvl, steps); +output!(lvl, pathlen); diff --git a/examples/skiplist.p3l b/examples/skiplist.p3l index 586bb14..55e3c14 100644 --- a/examples/skiplist.p3l +++ b/examples/skiplist.p3l @@ -239,19 +239,20 @@ fn skiplist_insert( // NOT PUBLIC API // Find a value in the skiplist, starting the search at a specific node. +// Return the value along with the path length of the search. fn skiplist_get_impl( node: SkipListNode, key: int ) -> (Option, int) { - let steps: int = 1; + let pathlen: int = 1; if (*node).3 < key { while true { if let Some(next) = (*node).2 { let next_key: int = (*next).3; - steps = steps + 1; if next_key <= key { node = next; + pathlen = pathlen + 1; if next_key == key { break; } else { @@ -270,26 +271,26 @@ fn skiplist_get_impl( } if (*node).3 != key { - return (None, steps); + return (None, pathlen); } // the value is only stored at the lowest level while let Some(below) = (*node).1 { node = below; } - return (Some(unwrap::((*node).4)), steps); + return (Some(unwrap::((*node).4)), pathlen); } -// Find a value in the skiplist. +// Find a value in the skiplist. Return the value along with the path +// length of the search. fn skiplist_get(list: SkipList, key: int) -> (Option, int) { - let steps: int = 0; + let pathlen: int = 0; while true { if let Some(node) = list.2 { - steps = steps + 1; if (*node).3 <= key { let tmp: (Option, int) = skiplist_get_impl::(node, key); - return (tmp.0, steps + tmp.1); + return (tmp.0, pathlen + tmp.1); } } @@ -298,7 +299,7 @@ fn skiplist_get(list: SkipList, key: int) -> (Option, int) { continue; } - return (None, steps); + return (None, pathlen); } } @@ -375,8 +376,8 @@ let _unit: () = assert_in_range(key, 0, len); let lookup: (Option<()>, int) = skiplist_get::<()>(list, key); let _unit: () = unwrap::<()>(lookup.0); -let steps: int = lookup.1; +let pathlen: int = lookup.1; let lvl: int = skiplist_level::<()>(list); output!(len); -output!(lvl, steps); +output!(lvl, pathlen); diff --git a/src/ast/ty.rs b/src/ast/ty.rs index fa866bf..9f5d0bc 100644 --- a/src/ast/ty.rs +++ b/src/ast/ty.rs @@ -258,10 +258,12 @@ impl Parse for Type { if input.peek(Paren) { let content; let paren_token = syn::parenthesized!(content in input); - return Ok(Self::Tuple(TypeTuple { - paren_token, - elems: Punctuated::parse_terminated(&content)? - })); + let elems = Punctuated::parse_terminated(&content)?; + return Ok(if elems.len() == 1 && !elems.trailing_punct() { + elems.into_iter().next().unwrap() + } else { + Self::Tuple(TypeTuple { paren_token, elems }) + }); } let ident: Ident = input.parse()?; @@ -348,8 +350,14 @@ mod tests { } #[test] - fn parse_tuple_1() { + fn parse_paren_int() { let ty: Type = syn::parse_str("(int)").unwrap(); + assert!(matches!(ty, Type::Int(_))); + } + + #[test] + fn parse_tuple_1() { + let ty: Type = syn::parse_str("(int,)").unwrap(); assert!(matches!(ty, Type::Tuple(_))); match ty { Type::Tuple(tuple) => { @@ -376,6 +384,21 @@ mod tests { } } + #[test] + fn parse_tuple_2_trailing() { + let ty: Type = syn::parse_str("(int, Option,)").unwrap(); + assert!(matches!(ty, Type::Tuple(_))); + match ty { + Type::Tuple(tuple) => { + let mut iter = tuple.elems.into_iter(); + assert!(matches!(iter.next(), Some(Type::Int(_)))); + assert!(matches!(iter.next(), Some(Type::Option(_)))); + assert!(iter.next().is_none()); + }, + _ => unreachable!() + } + } + #[test] fn parse_rc() { let ty: Type = syn::parse_str("Rc").unwrap(); diff --git a/stdlib/src/lib.rs b/stdlib/src/lib.rs index e61158b..4a2f45c 100644 --- a/stdlib/src/lib.rs +++ b/stdlib/src/lib.rs @@ -101,7 +101,9 @@ impl Rc { pub fn new(inner: T) -> Self { Self(std::rc::Rc::new(std::cell::RefCell::new(inner))) } +} +impl Rc { pub fn into_inner(this: Rc) -> T where T: Clone @@ -111,7 +113,9 @@ impl Rc { Err(rc) => rc.borrow().clone() } } +} +impl Rc { pub fn with_mut(&mut self, callback: F) where F: FnOnce(&mut T) diff --git a/stdlib/src/output/bar.rs b/stdlib/src/output/bar.rs index 7ca7696..1991c79 100644 --- a/stdlib/src/output/bar.rs +++ b/stdlib/src/output/bar.rs @@ -135,6 +135,13 @@ impl OutputPrinter for BarChartPrinter { E: IntoIterator, W: Write { + writeln!(out, "")?; + let mut yaxis = YAxis::default(); let mut xaxis = XAxis::default(); let mut xaxis_name = None; diff --git a/stdlib/src/output/bubble.rs b/stdlib/src/output/bubble.rs index 32dad36..eb49df6 100644 --- a/stdlib/src/output/bubble.rs +++ b/stdlib/src/output/bubble.rs @@ -1,6 +1,7 @@ use super::{OutputList, OutputPrinter, Svg}; use crate::int; use indexmap::IndexMap; +use num_integer::div_ceil; use std::{fmt::Write as _, io}; use svgwriter::{ tags::{ @@ -9,7 +10,6 @@ use svgwriter::{ }, Data, Transform }; -use num_integer::div_ceil; /// Output printer for SVG Bar Charts. Works only with two /// output variables. @@ -76,6 +76,13 @@ impl OutputPrinter for BubbleChartPrinter { E: IntoIterator, W: io::Write { + writeln!(out, "")?; + let mut percentages = Vec::new(); let mut min_percentage: f32 = 100.0; let mut max_percentage: f32 = 0.0; @@ -103,7 +110,7 @@ impl OutputPrinter for BubbleChartPrinter { let bubble_min_r: f32 = 2.5; let bubble_max_r: f32 = 15.0; let axis_step_dist = 40; - let (xaxis_step, xaxis_step_count) = xaxis.step(8); + let (xaxis_step, xaxis_step_count) = xaxis.step(7); let (yaxis_step, yaxis_step_count) = yaxis.step(6); let chart_width = axis_step_dist * xaxis_step_count as i32; let chart_height = axis_step_dist * yaxis_step_count as i32;