update code
This commit is contained in:
parent
e58a65369b
commit
1542e5bf48
8 changed files with 87 additions and 40 deletions
3
examples/.gitignore
vendored
Normal file
3
examples/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# these files are auto-derived from the skiplist example
|
||||||
|
skiplist-1-4.p3l
|
||||||
|
skiplist-3-8.p3l
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Reference in a new issue