Skip to content

Commit

Permalink
Merge branch 'master' into find_closure_self
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/ops.rs
  • Loading branch information
UARTman committed Jan 10, 2023
2 parents 58a9a16 + 8bbc202 commit d3a7462
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 59 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ categories = ["data-structures", "memory-management"]
[dependencies]
anyhow = "1.0.68"
log = "0.4.17"
regex = "1.7.0"
regex = "1.7.1"
lazy_static = "1.4.0"
simple_logger = "4.0.0"
sxd-xpath = "0.4.2"
Expand Down
16 changes: 8 additions & 8 deletions src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ impl Sodg {
/// If target vertex is not found or `v1` is absent,
/// an `Err` will be returned.
pub fn find(&self, v1: u32, loc: &str) -> Result<u32> {
self.find_with_closure(v1, loc, |v, head, tail, _| {
self.find_with_closure(v1, loc, |v, head, tail| {
Err(anyhow!("Can't find attribute {head}/{tail} in ν{v}"))
})
}
Expand All @@ -295,7 +295,7 @@ impl Sodg {
/// g.add(1).unwrap();
/// g.bind(0, 1, "foo").unwrap();
/// assert!(g.find(0, "bar").is_err());
/// let v = g.find_with_closure(0, "bar", |v, a, b, _| {
/// let v = g.find_with_closure(0, "bar", |v, a, b| {
/// assert_eq!(a, "bar");
/// assert_eq!(b, "");
/// Ok("foo".to_string())
Expand All @@ -309,7 +309,7 @@ impl Sodg {
&self,
v1: u32,
loc: &str,
cl: fn(u32, &str, &str, &Self) -> Result<String>,
cl: fn(u32, &str, &str) -> Result<String>,
) -> Result<u32> {
let mut v = v1;
let mut locator: VecDeque<String> = VecDeque::new();
Expand Down Expand Up @@ -338,9 +338,9 @@ impl Sodg {
continue;
};
let (head, tail) = Self::split_a(&k);
let other_name = cl(v, &head, &tail, self)?;
if let Some(to) = self.kid(v, other_name.as_str()) {
trace!("#find: ν{v}.{k} -> ν{to}");
let redirect = cl(v, &head, &tail)?;
if let Some(to) = self.kid(v, redirect.as_str()) {
trace!("#find: ν{v}.{k} -> ν{to} (redirect to {redirect})");
v = to;
continue;
};
Expand All @@ -354,7 +354,7 @@ impl Sodg {
.map(|e| e.a.clone())
.collect();
return Err(anyhow!(
"Can't find .{} in ν{} among other {} attribute{}: {}",
"Can't find .{} in ν{} among other {} attribute{}: {} (redirect to .{redirect} didn't help)",
k,
v,
others.len(),
Expand Down Expand Up @@ -438,7 +438,7 @@ fn finds_with_closure() -> Result<()> {
g.bind(2, 3, "something_else")?;
assert_eq!(
3,
g.find_with_closure(1, "first.second/abc", |v, head, tail, _| {
g.find_with_closure(1, "first.second/abc", |v, head, tail| {
if v == 1 && !tail.is_empty() {
panic!();
}
Expand Down
61 changes: 13 additions & 48 deletions src/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,22 @@ use std::str::FromStr;
pub struct Script {
txt: String,
vars: HashMap<String, u32>,
root: u32,
}

impl Script {
/// Make a new one, parsing a string with instructions. Instructions
/// must be separated by semicolon. There are just three of them
/// possible: `ADD`, `BIND`, and `PUT`. The arguments must be
/// separated by a comma. An argument may either be 1) a positive integer,
/// separated by a comma. An argument may either be 1) a positive integer
/// (possibly prepended by `ν`),
/// 2) a variable started with `$`, 3) an attribute name, or
/// 4) data in `XX-XX-...` hexadecimal format.
///
/// ```
/// use sodg::Script;
/// use sodg::Sodg;
/// let mut s = Script::from_str(
/// "ADD(0); ADD($ν1); BIND(0, $ν1, foo);"
/// "ADD(0); ADD($ν1); BIND(ν0, $ν1, foo);"
/// );
/// let mut g = Sodg::empty();
/// let total = s.deploy_to(&mut g).unwrap();
Expand All @@ -69,7 +69,6 @@ impl Script {
Script {
txt: s.to_string(),
vars: HashMap::new(),
root: 0,
}
}

Expand All @@ -78,25 +77,6 @@ impl Script {
Script::from_str(s.as_str())
}

/// Set a different root. By default, the root is set to zero.
/// If the root is changed, each time zero-vertex is mentioned
/// in instructions, if will be replaced by this number.
///
/// ```
/// use sodg::Script;
/// use sodg::Sodg;
/// let mut s = Script::from_str(
/// "ADD(1); BIND(0, 1, foo);"
/// );
/// s.set_root(42);
/// let mut g = Sodg::empty();
/// g.add(42).unwrap();
/// s.deploy_to(&mut g).unwrap();
/// ```
pub fn set_root(&mut self, v: u32) {
self.root = v;
}

/// Deploy the entire script to the SODG.
pub fn deploy_to(&mut self, g: &mut Sodg) -> Result<usize> {
let mut pos = 0;
Expand Down Expand Up @@ -159,7 +139,7 @@ impl Script {
}
}

/// Parse data
/// Parse data.
fn parse_data(s: &str) -> Result<Hex> {
lazy_static! {
static ref DATA_STRIP: Regex = Regex::new("[ \t\n\r\\-]").unwrap();
Expand All @@ -177,17 +157,18 @@ impl Script {
}
}

/// Parses `$ν5` into `5`.
/// Parses `$ν5` into `5`, and `ν23` into `23`, and `42` into `42`.
fn parse(&mut self, s: &str, g: &mut Sodg) -> Result<u32> {
let head = s.chars().next().context("Empty identifier".to_string())?;
if head == '$' {
if head == '$' || head == 'ν' {
let tail: String = s.chars().skip(1).collect::<Vec<_>>().into_iter().collect();
Ok(*self.vars.entry(tail).or_insert_with(|| g.next_id()))
} else {
let mut v = u32::from_str(s).context(format!("Parsing of '{s}' failed"))?;
if v == 0 {
v = self.root;
if head == '$' {
Ok(*self.vars.entry(tail).or_insert_with(|| g.next_id()))
} else {
Ok(u32::from_str(tail.as_str()).context(format!("Parsing of '{s}' failed"))?)
}
} else {
let v = u32::from_str(s).context(format!("Parsing of '{s}' failed"))?;
Ok(v)
}
}
Expand All @@ -202,7 +183,7 @@ fn simple_command() -> Result<()> {
let mut s = Script::from_str(
"
ADD(0); ADD($ν1); # adding two vertices
BIND(0, $ν1, foo );
BIND(ν0, $ν1, foo );
PUT($ν1 , d0-bf-D1-80-d0-B8-d0-b2-d0-b5-d1-82);
",
);
Expand All @@ -212,19 +193,3 @@ fn simple_command() -> Result<()> {
assert_eq!(1, g.kid(0, "foo").unwrap());
Ok(())
}

#[test]
fn deploy_to_another_root() -> Result<()> {
let mut g = Sodg::empty();
g.add(42)?;
let mut s = Script::from_str(
"
ADD($ν1);
BIND(0, $ν1, foo);
",
);
s.set_root(42);
s.deploy_to(&mut g)?;
assert_eq!(43, g.kid(42, "foo").unwrap());
Ok(())
}

0 comments on commit d3a7462

Please sign in to comment.