Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
yegor256 committed Aug 15, 2022
1 parent aaa7dea commit 5df9ae3
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 57 deletions.
1 change: 0 additions & 1 deletion eo-tests/org/eolang/reo/fibonacci.eo
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,3 @@
x.minus 1
f
x.minus 2

45 changes: 32 additions & 13 deletions src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use anyhow::{Context, Result};

pub struct Data {
bytes: Vec<u8>
}
Expand Down Expand Up @@ -68,25 +70,35 @@ impl Data {
self.bytes.len() == 0
}

pub fn as_int(&self) -> u64 {
let a : &[u8; 8] = &self.bytes.clone().try_into().unwrap();
u64::from_be_bytes(*a)
pub fn as_int(&self) -> Result<u64> {
let a : &[u8; 8] = &self.bytes
.as_slice()
.try_into()
.context(format!("There is no data, can't make INT"))?;
Ok(u64::from_be_bytes(*a))
}

pub fn as_float(&self) -> f64 {
let a : &[u8; 8] = &self.bytes.clone().try_into().unwrap();
f64::from_be_bytes(*a)
pub fn as_float(&self) -> Result<f64> {
let a : &[u8; 8] = &self.bytes
.as_slice()
.try_into()
.context(format!("There is no data, can't make FLOAT"))?;
Ok(f64::from_be_bytes(*a))
}

pub fn as_string(&self) -> String {
String::from_utf8(self.bytes.clone()).unwrap()
pub fn as_string(&self) -> Result<String> {
Ok(String::from_utf8(self.bytes.clone())?)
}

pub fn as_hex(&self) -> String {
self.bytes.iter()
.map(|b| format!("{:02x}", b).to_string())
.collect::<Vec<String>>()
.join("-")
if self.bytes.is_empty() {
"--".to_string()
} else {
self.bytes.iter()
.map(|b| format!("{:02x}", b).to_string())
.collect::<Vec<String>>()
.join("-")
}
}

}
Expand All @@ -95,7 +107,7 @@ impl Data {
fn simple_int() {
let i = 42;
let d = Data::from_int(42);
assert_eq!(i, d.as_int());
assert_eq!(i, d.as_int().unwrap());
}

#[test]
Expand All @@ -104,3 +116,10 @@ fn prints_bytes() {
let d = Data::from_str(txt);
assert_eq!("d0-bf-d1-80-d0-b8-d0-b2-d0-b5-d1-82", d.as_hex());
}

#[test]
fn prints_empty_bytes() {
let txt = "";
let d = Data::from_str(txt);
assert_eq!("--", d.as_hex());
}
10 changes: 5 additions & 5 deletions src/gmi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl Gmi {
fn parse_data(s: &str) -> Result<Data> {
lazy_static! {
static ref DATA_STRIP: Regex = Regex::new(
"[^0-9A-Fa-f]"
"[ \t\n\r\\-]"
).unwrap();
static ref DATA: Regex = Regex::new(
"^[0-9A-Fa-f]{2}([0-9A-Fa-f]{2})*$"
Expand Down Expand Up @@ -173,15 +173,15 @@ fn deploys_simple_commands() {
DATA('ν2', 'd0 bf d1 80 d0 b8 d0 b2 d0 b5 d1 82');
".to_string()
).unwrap().deploy_to(uni).unwrap();
assert_eq!("привет", uni.dataize(0, "foo.Δ").unwrap().as_string());
assert_eq!("привет", uni.dataize(0, "foo.Δ").unwrap().as_string().unwrap());
}

#[test]
fn deploys_fibonacci() -> Result<()> {
let uni : &mut Universe = &mut Universe::empty();
uni.add(0);
Gmi::from_file("target/eo/gmi/org/eolang/reo/fibonacci.gmi")?
.deploy_to(uni)?;
assert_eq!(8, uni.dataize(0, "fibonacci.f").unwrap().as_int());
Gmi::from_file("target/eo/gmi/org/eolang/reo/fibonacci.gmi")?.deploy_to(uni)?;
println!("{uni:?}");
assert_eq!(8, uni.dataize(0, "fibonacci.f.Δ")?.as_int()?);
Ok(())
}
79 changes: 41 additions & 38 deletions src/universe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use crate::data::Data;
use std::collections::HashMap;
use std::fmt;
use anyhow::{anyhow, Context, Result};
use std::str::FromStr;
use log::trace;

Expand All @@ -41,18 +42,18 @@ impl Edge {

pub type Error = String;

pub type Lambda = fn(&mut Universe) -> Result<u32, Error>;
pub type Lambda = fn(&mut Universe) -> Result<u32>;

struct Vertex {
data: Data,
lambda: Lambda
data: Option<Data>,
lambda: Option<Lambda>
}

impl Vertex {
pub fn empty() -> Self {
Vertex {
data: Data::empty(),
lambda: |_| -> Result<u32, Error> { Ok(0) }
data: None,
lambda: None
}
}
}
Expand All @@ -66,22 +67,18 @@ impl fmt::Debug for Universe {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut lines = vec![];
for (i, v) in self.vertices.iter() {
let data = if v.data.is_empty() {
"".to_string()
} else {
format!("Δ ➞ {},", v.data.as_hex())
};
lines.push(format!(
"ν{} -> ⟦{}{}⟧",
i,
data.as_str(),
self.edges
.iter()
.filter(|(_, e)| e.from == *i)
.map(|(j, e)| format!("\n\t{} ε{}➞ ν{}", e.a, j, e.to))
.collect::<Vec<String>>()
.join("")
));
let mut attrs = self.edges
.iter()
.filter(|(_, e)| e.from == *i)
.map(|(j, e)| format!("\n\t{} ε{}➞ ν{}", e.a, j, e.to))
.collect::<Vec<String>>();
if let Some(d) = &v.data {
attrs.push(format!("{}", d.as_hex()));
}
if let Some(_) = &v.lambda {
attrs.push("λ".to_string());
}
lines.push(format!("ν{} -> ⟦{}⟧", i, attrs.join(", ")));
}
f.write_str(lines.join("\n").as_str())
}
Expand Down Expand Up @@ -153,13 +150,13 @@ impl Universe {

// Set atom lambda.
pub fn atom(&mut self, v: u32, m: Lambda) {
self.vertices.get_mut(&v).unwrap().lambda = m;
self.vertices.get_mut(&v).unwrap().lambda = Some(m);
trace!("#atom({}, ...): lambda set", v);
}

// Set vertex data.
pub fn data(&mut self, v: u32, d: Data) {
self.vertices.get_mut(&v).unwrap().data = d.clone();
self.vertices.get_mut(&v).unwrap().data = Some(d.clone());
trace!("#data({}, \"{}\"): data set", v, d.as_hex());
}
}
Expand All @@ -171,34 +168,40 @@ impl Universe {
}

// Find a vertex by locator.
fn find(&mut self, v: u32, loc: &str) -> Result<u32, String> {
fn find(&mut self, v: u32, loc: &str) -> Result<u32> {
let mut vtx = v;
loc.split(".").for_each( |k| {
for k in loc.split(".") {
if k.starts_with("ν") {
vtx = u32::from_str(&k[2..]).unwrap()
vtx = u32::from_str(&k[2..])?
} else if k == "𝜉" {
vtx = vtx;
} else if k == "Φ" {
vtx = 0;
} else {
vtx = self.edges.values().find(
|e| e.from == vtx && e.a == k
).ok_or(format!("Can't find .{} from ν{}", k, vtx)).unwrap().to
let to = self.edges.values()
.find(|e| e.from == vtx && e.a == k)
.context(format!("Can't find .{} from ν{}", k, vtx))?
.to;
if !self.vertices.contains_key(&to) {
return Err(anyhow!("Can't move to ν{}.{}, ν{} is absent", vtx, k, to));
}
vtx = to;
}
});
}
Ok(vtx)
}

// Dataize by locator.
pub fn dataize(&mut self, v: u32, loc: &str) -> Result<&Data, String> {
pub fn dataize(&mut self, v: u32, loc: &str) -> Result<Data> {
let id = self.find(v, loc)?;
let v = self.vertex(id).ok_or(format!("ν{} is absent", id))?;
Ok(&(*v).data)
let v = self.vertex(id).context(format!("ν{} is absent", id))?;
let data = v.data.clone().unwrap();
Ok(data)
}
}

#[cfg(test)]
fn rand(uni: &mut Universe) -> Result<u32, Error> {
fn rand(uni: &mut Universe) -> Result<u32> {
let e = uni.next_id();
uni.reff(e, 0, "𝜉.int", "i");
let i = uni.next_id();
Expand Down Expand Up @@ -236,11 +239,11 @@ fn generates_random_int() {
let e2 = uni.next_id();
uni.bind(e2, 0, v2, "rand");
let e3 = uni.next_id();
uni.reff(e3, 0, "ν2", "x");
uni.atom(v1, rand);
uni.reff(e3, 0, "Φ.rand", "x");
uni.atom(v2, rand);
println!("{uni:?}");
assert_ne!(
uni.dataize(0, "x.Δ").unwrap().as_int(),
uni.dataize(0, "x.Δ").unwrap().as_int()
uni.dataize(0, "x.Δ").unwrap().as_int().unwrap(),
uni.dataize(0, "x.Δ").unwrap().as_int().unwrap()
);
}

0 comments on commit 5df9ae3

Please sign in to comment.