update code

This commit is contained in:
Dominic 2022-11-28 13:45:10 +01:00
parent e58a65369b
commit 1542e5bf48
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
8 changed files with 87 additions and 40 deletions

3
examples/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# these files are auto-derived from the skiplist example
skiplist-1-4.p3l
skiplist-3-8.p3l

View file

@ -239,19 +239,20 @@ fn skiplist_insert<V>(
// NOT PUBLIC API // NOT PUBLIC API
// Find a value in the skiplist, starting the search at a specific node. // 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<V>( fn skiplist_get_impl<V>(
node: SkipListNode<V>, node: SkipListNode<V>,
key: int key: int
) -> (Option<V>, int) { ) -> (Option<V>, int) {
let steps: int = 1; let pathlen: int = 1;
if (*node).3 < key { if (*node).3 < key {
while true { while true {
if let Some(next) = (*node).2 { if let Some(next) = (*node).2 {
let next_key: int = (*next).3; let next_key: int = (*next).3;
steps = steps + 1;
if next_key <= key { if next_key <= key {
node = next; node = next;
pathlen = pathlen + 1;
if next_key == key { if next_key == key {
break; break;
} else { } else {
@ -270,26 +271,26 @@ fn skiplist_get_impl<V>(
} }
if (*node).3 != key { if (*node).3 != key {
return (None, steps); return (None, pathlen);
} }
// the value is only stored at the lowest level // the value is only stored at the lowest level
while let Some(below) = (*node).1 { while let Some(below) = (*node).1 {
node = below; node = below;
} }
return (Some(unwrap::<V>((*node).4)), steps); return (Some(unwrap::<V>((*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<V>(list: SkipList<V>, key: int) -> (Option<V>, int) { fn skiplist_get<V>(list: SkipList<V>, key: int) -> (Option<V>, int) {
let steps: int = 0; let pathlen: int = 0;
while true { while true {
if let Some(node) = list.2 { if let Some(node) = list.2 {
steps = steps + 1;
if (*node).3 <= key { if (*node).3 <= key {
let tmp: (Option<V>, int) = skiplist_get_impl::<V>(node, key); let tmp: (Option<V>, int) = skiplist_get_impl::<V>(node, key);
return (tmp.0, steps + tmp.1); return (tmp.0, pathlen + tmp.1);
} }
} }
@ -298,7 +299,7 @@ fn skiplist_get<V>(list: SkipList<V>, key: int) -> (Option<V>, int) {
continue; 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 lookup: (Option<()>, int) = skiplist_get::<()>(list, key);
let _unit: () = unwrap::<()>(lookup.0); let _unit: () = unwrap::<()>(lookup.0);
let steps: int = lookup.1; let pathlen: int = lookup.1;
let lvl: int = skiplist_level::<()>(list); let lvl: int = skiplist_level::<()>(list);
output!(len); output!(len);
output!(lvl, steps); output!(lvl, pathlen);

View file

@ -239,19 +239,20 @@ fn skiplist_insert<V>(
// NOT PUBLIC API // NOT PUBLIC API
// Find a value in the skiplist, starting the search at a specific node. // 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<V>( fn skiplist_get_impl<V>(
node: SkipListNode<V>, node: SkipListNode<V>,
key: int key: int
) -> (Option<V>, int) { ) -> (Option<V>, int) {
let steps: int = 1; let pathlen: int = 1;
if (*node).3 < key { if (*node).3 < key {
while true { while true {
if let Some(next) = (*node).2 { if let Some(next) = (*node).2 {
let next_key: int = (*next).3; let next_key: int = (*next).3;
steps = steps + 1;
if next_key <= key { if next_key <= key {
node = next; node = next;
pathlen = pathlen + 1;
if next_key == key { if next_key == key {
break; break;
} else { } else {
@ -270,26 +271,26 @@ fn skiplist_get_impl<V>(
} }
if (*node).3 != key { if (*node).3 != key {
return (None, steps); return (None, pathlen);
} }
// the value is only stored at the lowest level // the value is only stored at the lowest level
while let Some(below) = (*node).1 { while let Some(below) = (*node).1 {
node = below; node = below;
} }
return (Some(unwrap::<V>((*node).4)), steps); return (Some(unwrap::<V>((*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<V>(list: SkipList<V>, key: int) -> (Option<V>, int) { fn skiplist_get<V>(list: SkipList<V>, key: int) -> (Option<V>, int) {
let steps: int = 0; let pathlen: int = 0;
while true { while true {
if let Some(node) = list.2 { if let Some(node) = list.2 {
steps = steps + 1;
if (*node).3 <= key { if (*node).3 <= key {
let tmp: (Option<V>, int) = skiplist_get_impl::<V>(node, key); let tmp: (Option<V>, int) = skiplist_get_impl::<V>(node, key);
return (tmp.0, steps + tmp.1); return (tmp.0, pathlen + tmp.1);
} }
} }
@ -298,7 +299,7 @@ fn skiplist_get<V>(list: SkipList<V>, key: int) -> (Option<V>, int) {
continue; 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 lookup: (Option<()>, int) = skiplist_get::<()>(list, key);
let _unit: () = unwrap::<()>(lookup.0); let _unit: () = unwrap::<()>(lookup.0);
let steps: int = lookup.1; let pathlen: int = lookup.1;
let lvl: int = skiplist_level::<()>(list); let lvl: int = skiplist_level::<()>(list);
output!(len); output!(len);
output!(lvl, steps); output!(lvl, pathlen);

View file

@ -239,19 +239,20 @@ fn skiplist_insert<V>(
// NOT PUBLIC API // NOT PUBLIC API
// Find a value in the skiplist, starting the search at a specific node. // 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<V>( fn skiplist_get_impl<V>(
node: SkipListNode<V>, node: SkipListNode<V>,
key: int key: int
) -> (Option<V>, int) { ) -> (Option<V>, int) {
let steps: int = 1; let pathlen: int = 1;
if (*node).3 < key { if (*node).3 < key {
while true { while true {
if let Some(next) = (*node).2 { if let Some(next) = (*node).2 {
let next_key: int = (*next).3; let next_key: int = (*next).3;
steps = steps + 1;
if next_key <= key { if next_key <= key {
node = next; node = next;
pathlen = pathlen + 1;
if next_key == key { if next_key == key {
break; break;
} else { } else {
@ -270,26 +271,26 @@ fn skiplist_get_impl<V>(
} }
if (*node).3 != key { if (*node).3 != key {
return (None, steps); return (None, pathlen);
} }
// the value is only stored at the lowest level // the value is only stored at the lowest level
while let Some(below) = (*node).1 { while let Some(below) = (*node).1 {
node = below; node = below;
} }
return (Some(unwrap::<V>((*node).4)), steps); return (Some(unwrap::<V>((*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<V>(list: SkipList<V>, key: int) -> (Option<V>, int) { fn skiplist_get<V>(list: SkipList<V>, key: int) -> (Option<V>, int) {
let steps: int = 0; let pathlen: int = 0;
while true { while true {
if let Some(node) = list.2 { if let Some(node) = list.2 {
steps = steps + 1;
if (*node).3 <= key { if (*node).3 <= key {
let tmp: (Option<V>, int) = skiplist_get_impl::<V>(node, key); let tmp: (Option<V>, int) = skiplist_get_impl::<V>(node, key);
return (tmp.0, steps + tmp.1); return (tmp.0, pathlen + tmp.1);
} }
} }
@ -298,7 +299,7 @@ fn skiplist_get<V>(list: SkipList<V>, key: int) -> (Option<V>, int) {
continue; 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 lookup: (Option<()>, int) = skiplist_get::<()>(list, key);
let _unit: () = unwrap::<()>(lookup.0); let _unit: () = unwrap::<()>(lookup.0);
let steps: int = lookup.1; let pathlen: int = lookup.1;
let lvl: int = skiplist_level::<()>(list); let lvl: int = skiplist_level::<()>(list);
output!(len); output!(len);
output!(lvl, steps); output!(lvl, pathlen);

View file

@ -258,10 +258,12 @@ impl Parse for Type {
if input.peek(Paren) { if input.peek(Paren) {
let content; let content;
let paren_token = syn::parenthesized!(content in input); let paren_token = syn::parenthesized!(content in input);
return Ok(Self::Tuple(TypeTuple { let elems = Punctuated::parse_terminated(&content)?;
paren_token, return Ok(if elems.len() == 1 && !elems.trailing_punct() {
elems: Punctuated::parse_terminated(&content)? elems.into_iter().next().unwrap()
})); } else {
Self::Tuple(TypeTuple { paren_token, elems })
});
} }
let ident: Ident = input.parse()?; let ident: Ident = input.parse()?;
@ -348,8 +350,14 @@ mod tests {
} }
#[test] #[test]
fn parse_tuple_1() { fn parse_paren_int() {
let ty: Type = syn::parse_str("(int)").unwrap(); 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(_))); assert!(matches!(ty, Type::Tuple(_)));
match ty { match ty {
Type::Tuple(tuple) => { Type::Tuple(tuple) => {
@ -376,6 +384,21 @@ mod tests {
} }
} }
#[test]
fn parse_tuple_2_trailing() {
let ty: Type = syn::parse_str("(int, Option<int>,)").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] #[test]
fn parse_rc() { fn parse_rc() {
let ty: Type = syn::parse_str("Rc<int>").unwrap(); let ty: Type = syn::parse_str("Rc<int>").unwrap();

View file

@ -101,7 +101,9 @@ impl<T> Rc<T> {
pub fn new(inner: T) -> Self { pub fn new(inner: T) -> Self {
Self(std::rc::Rc::new(std::cell::RefCell::new(inner))) Self(std::rc::Rc::new(std::cell::RefCell::new(inner)))
} }
}
impl<T> Rc<T> {
pub fn into_inner(this: Rc<T>) -> T pub fn into_inner(this: Rc<T>) -> T
where where
T: Clone T: Clone
@ -111,7 +113,9 @@ impl<T> Rc<T> {
Err(rc) => rc.borrow().clone() Err(rc) => rc.borrow().clone()
} }
} }
}
impl<T> Rc<T> {
pub fn with_mut<F>(&mut self, callback: F) pub fn with_mut<F>(&mut self, callback: F)
where where
F: FnOnce(&mut T) F: FnOnce(&mut T)

View file

@ -135,6 +135,13 @@ impl OutputPrinter for BarChartPrinter {
E: IntoIterator<Item = (&'static str, int)>, E: IntoIterator<Item = (&'static str, int)>,
W: Write W: Write
{ {
writeln!(out, "<!--")?;
writeln!(out, "Output Variable Analysis:")?;
for (key, stats) in list.stats() {
writeln!(out, " {key}: {stats:?}")?;
}
writeln!(out, "-->")?;
let mut yaxis = YAxis::default(); let mut yaxis = YAxis::default();
let mut xaxis = XAxis::default(); let mut xaxis = XAxis::default();
let mut xaxis_name = None; let mut xaxis_name = None;

View file

@ -1,6 +1,7 @@
use super::{OutputList, OutputPrinter, Svg}; use super::{OutputList, OutputPrinter, Svg};
use crate::int; use crate::int;
use indexmap::IndexMap; use indexmap::IndexMap;
use num_integer::div_ceil;
use std::{fmt::Write as _, io}; use std::{fmt::Write as _, io};
use svgwriter::{ use svgwriter::{
tags::{ tags::{
@ -9,7 +10,6 @@ use svgwriter::{
}, },
Data, Transform Data, Transform
}; };
use num_integer::div_ceil;
/// Output printer for SVG Bar Charts. Works only with two /// Output printer for SVG Bar Charts. Works only with two
/// output variables. /// output variables.
@ -76,6 +76,13 @@ impl OutputPrinter for BubbleChartPrinter {
E: IntoIterator<Item = (&'static str, int)>, E: IntoIterator<Item = (&'static str, int)>,
W: io::Write W: io::Write
{ {
writeln!(out, "<!--")?;
writeln!(out, "Output Variable Analysis:")?;
for (key, stats) in list.stats() {
writeln!(out, " {key}: {stats:?}")?;
}
writeln!(out, "-->")?;
let mut percentages = Vec::new(); let mut percentages = Vec::new();
let mut min_percentage: f32 = 100.0; let mut min_percentage: f32 = 100.0;
let mut max_percentage: f32 = 0.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_min_r: f32 = 2.5;
let bubble_max_r: f32 = 15.0; let bubble_max_r: f32 = 15.0;
let axis_step_dist = 40; 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 (yaxis_step, yaxis_step_count) = yaxis.step(6);
let chart_width = axis_step_dist * xaxis_step_count as i32; let chart_width = axis_step_dist * xaxis_step_count as i32;
let chart_height = axis_step_dist * yaxis_step_count as i32; let chart_height = axis_step_dist * yaxis_step_count as i32;