Skip to content

Commit

Permalink
mods
Browse files Browse the repository at this point in the history
  • Loading branch information
yegor256 committed Sep 3, 2022
1 parent f9081d2 commit e6e6658
Show file tree
Hide file tree
Showing 16 changed files with 640 additions and 225 deletions.
1 change: 1 addition & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use std::process::Command;
fn main() {
println!("cargo:rerun-if-changed=eo-tests");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=target/eo");
Command::new("mvn")
.arg("--file")
.arg("test-pom.xml")
Expand Down
62 changes: 36 additions & 26 deletions src/gmi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ use regex::Regex;
use crate::data::Data;
use itertools::Itertools;
use glob::glob;
use log::trace;
use crate::da;
use crate::scripts::setup;
use crate::setup::setup;

/// Collection of GMIs, which can be deployed to a `Universe`.
pub struct Gmi {
Expand Down Expand Up @@ -67,6 +68,7 @@ impl Gmi {
let txt = &self.text.clone();
let lines = txt.split("\n").map(|t| t.trim()).filter(|t| !t.is_empty());
for (pos, t) in lines.enumerate() {
trace!("#deploy_to: deploying line no.{} '{}'...", pos + 1, t);
self.deploy_one(t, uni).context(
format!("Failure at the line no.{}: '{}'", pos, t)
)?;
Expand Down Expand Up @@ -94,42 +96,42 @@ impl Gmi {
match &cap[1] {
"ADD" => {
let v = self.parse(&args[0], uni)?;
uni.add(v);
uni.add(v).context(
format!("Failed to ADD({})", &args[0])
)
},
"BIND" => {
let e = self.parse(&args[0], uni)?;
let v1 = self.parse(&args[1], uni)?;
let v2 = self.parse(&args[2], uni)?;
let a = &args[3];
uni.bind(e, v1, v2, a);
},
"REF" => {
let e1 = self.parse(&args[0], uni)?;
let v1 = self.parse(&args[1], uni)?;
let k = LOC.replace_all(&args[2], "$1");
let a = &args[3];
uni.reff(e1, v1, &k, a);
uni.bind(e, v1, v2, a).context(
format!("Failed to BIND({}, {}, {})", &args[0], &args[1], &args[2])
)
},
"COPY" => {
let e1 = self.parse(&args[0], uni)?;
let v3 = self.parse(&args[1], uni)?;
let e2 = self.parse(&args[2], uni)?;
uni.copy(e1, v3, e2);
uni.copy(e1, v3, e2).context(
format!("Failed to COPY({}, {}, {})", &args[0], &args[1], &args[2])
)
},
"DATA" => {
let v = self.parse(&args[0], uni)?;
uni.data(v, Self::parse_data(&args[1])?);
uni.data(v, Self::parse_data(&args[1])?).context(
format!("Failed to DATA({})", &args[0])
)
},
"ATOM" => {
let v = self.parse(&args[0], uni)?;
let m = &args[1];
uni.atom(v, m);
uni.atom(v, m).context(
format!("Failed to ATOM({})", &args[0])
)
},
_cmd => {
return Err(anyhow!("Unknown GMI: {}", _cmd))
}
_cmd => Err(anyhow!("Unknown GMI: {}", _cmd))
}
Ok(())
}

/// Parse data
Expand All @@ -155,10 +157,11 @@ impl Gmi {
.context(format!("Strange data format: '{}'", d))?;
match t {
"bytes" => Data::from_hex(tail.to_string()),
"string" => Data::from_string(tail.to_string()),
"string" => Data::from_string(Self::unescape(tail)),
"int" => Data::from_int(i64::from_str(tail)?),
"float" => Data::from_float(f64::from_str(tail)?),
"bool" => Data::from_bool(tail == "true"),
"array" => Data::from_bool(true),
_ => {
return Err(anyhow!("Unknown type of data '{}'", t))
}
Expand All @@ -177,21 +180,26 @@ impl Gmi {
Ok(u32::from_str(tail.as_str()).context(format!("Parsing of '{}' failed", s))?)
}
}

/// Goes through the string and replaces `\u0027` (for example)
/// with corresponding chars.
fn unescape(s: &str) -> String {
// todo!
s.to_string()
}
}

#[test]
fn deploys_simple_commands() -> Result<()> {
let uni : &mut Universe = &mut Universe::empty();
uni.add(0);
uni.add(0)?;
Gmi::from_string(
"
ADD('ν1'); # just first vertex
BIND('ε1', 'ν0', 'ν1', 'foo'); # just first vertex
ADD('ν2'); # its data vertex
BIND ( 'ε2', 'ν1', 'ν2', 'Δ' );
DATA('ν2', 'd0 bf d1 80 d0 b8 d0 b2 d0 b5 d1 82');
ADD('ν1');
BIND('ε1', 'ν0', 'ν1', 'foo');
DATA('ν1', 'd0 bf d1 80 d0 b8 d0 b2 d0 b5 d1 82');
".to_string()
).unwrap().deploy_to(uni).unwrap();
)?.deploy_to(uni)?;
assert_eq!("привет", da!(uni, "Φ.foo").as_string()?);
Ok(())
}
Expand Down Expand Up @@ -223,7 +231,9 @@ fn all_apps() -> Result<Vec<String>> {

#[test]
fn deploys_and_runs_all_apps() -> Result<()> {
let mut uni = setup(Path::new("target/eo/gmi"))?;
let mut uni = Universe::empty();
uni.add(0)?;
setup(&mut uni, Path::new("target/eo/gmi"))?;
for app in all_apps()? {
let expected = da!(uni, format!("Φ.{}.expected", app)).as_int()?;
let actual = da!(uni, format!("Φ.{}", app)).as_int()?;
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub mod data;
pub mod gmi;
pub mod universe;
pub mod org;
pub mod setup;
pub mod macros;
pub mod scripts;

Expand Down
3 changes: 2 additions & 1 deletion src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#[macro_export]
macro_rules! da {
($uni:expr, $loc:expr) => {
$uni.dataize(format!("{}.Δ", $loc).as_str()).unwrap()
$uni.dataize(format!("{}", $loc).as_str())
.expect(format!("Can't dataize {}", $loc).as_str())
};
}
43 changes: 43 additions & 0 deletions src/org/eolang/array.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) 2022 Yegor Bugayenko
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use crate::universe::Universe;
use anyhow::{anyhow, Result};

/// Register all known atoms in the Universe.
pub fn register(uni: &mut Universe) {
uni.register("org.eolang.array.length", array_length);
uni.register("org.eolang.array.at", array_at);
}

/// EO atom `array.length`.
pub fn array_length(_uni: &mut Universe, _v: u32) -> Result<u32> {
Err(anyhow!("Not implemented yet"))
}

/// EO atom `array.at`.
pub fn array_at(_uni: &mut Universe, _v: u32) -> Result<u32> {
Err(anyhow!("Not implemented yet"))
}

#[test]
fn simple() {
// assert_eq!(1, total);
}
7 changes: 6 additions & 1 deletion src/org/eolang/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,16 @@ use anyhow::Result;
use crate::da;
use crate::scripts::copy_of_int;

/// Register all known atoms in the Universe.
pub fn register(uni: &mut Universe) {
uni.register("org.eolang.int.plus", int_plus);
}

/// EO atom `int.plus`.
pub fn int_plus(uni: &mut Universe, v: u32) -> Result<u32> {
let rho = da!(uni, format!("ν{}.ρ", v)).as_int()?;
let x = da!(uni, format!("ν{}.α0", v)).as_int()?;
Ok(copy_of_int(uni, rho + x))
copy_of_int(uni, rho + x)
}

#[test]
Expand Down
9 changes: 9 additions & 0 deletions src/org/eolang/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,12 @@
// SOFTWARE.

mod int;
mod array;

use crate::universe::Universe;

/// Register all known atoms in the Universe.
pub fn register(uni: &mut Universe) {
int::register(uni);
array::register(uni);
}
65 changes: 9 additions & 56 deletions src/scripts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,65 +18,18 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use std::collections::HashMap;
use std::path::Path;
use crate::data::Data;
use glob::glob;
use crate::universe::Universe;
use anyhow::{Context, Result};
use crate::gmi::Gmi;
use anyhow::Result;

/// Deploy a directory of `*.gmi` files to a new `Universe`.
pub fn setup(dir: &Path) -> Result<Universe> {
let mut uni = Universe::empty();
uni.add(0);
let mut pkgs : HashMap<String, u32> = HashMap::new();
for f in glob(format!("{}/**/*.gmi", dir.display()).as_str())? {
let p = f?;
let path = p.as_path();
let pkg = path.parent()
.context(format!("Can't get parent from '{}'", path.display()))?
.to_str()
.context(format!("Can't turn path '{}' to str", path.display()))?
.replace("/", ".");
let mut gmi = Gmi::from_file(path)?;
let mut root : u32 = 0;
let mut pk = "".to_owned();
for p in pkg.split(".") {
pk.push_str(format!(".{}", p).as_str());
match pkgs.get(&pk) {
Some(v) => {
root = *v;
},
None => {
let v = uni.next_id();
uni.add(v);
let e = uni.next_id();
uni.bind(e, root, v, p);
root = v;
pkgs.insert(pk.clone(), root);
}
}
}
gmi.set_root(root);
gmi.deploy_to(&mut uni)?;
}
Ok(uni)
}

/// Makes a copy of `int` in the Universe. It is assumed
/// Makes a copy of `org.eolang.int` in the Universe. It is assumed
/// that it already exists there.
pub fn copy_of_int(uni: &mut Universe, data: i64) -> u32 {
pub fn copy_of_int(uni: &mut Universe, data: i64) -> Result<u32> {
let v = uni.next_id();
uni.add(v)?;
let int = uni.find(0, "org.eolang.int")?;
let e = uni.next_id();
uni.reff(e, 0, "𝜉.int", "i");
let i = uni.next_id();
uni.add(i);
let e2 = uni.next_id();
uni.copy(e, i, e2);
let d = uni.next_id();
uni.add(d);
let e3 = uni.next_id();
uni.bind(e3, i, d, "Δ");
uni.data(d, Data::from_int(data));
i
uni.bind(e, v, int, "π")?;
uni.data(v, Data::from_int(data))?;
Ok(v)
}
67 changes: 67 additions & 0 deletions src/setup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) 2022 Yegor Bugayenko
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use crate::universe::Universe;
use std::collections::HashMap;
use std::path::Path;
use anyhow::{Context, Result};
use glob::glob;
use log::trace;
use crate::gmi::Gmi;
use crate::org::eolang::register;

/// Deploy a directory of `*.gmi` files to a new `Universe`.
pub fn setup(uni: &mut Universe, dir: &Path) -> Result<()> {
register(uni);
let mut pkgs : HashMap<String, u32> = HashMap::new();
for f in glob(format!("{}/**/*.gmi", dir.display()).as_str())? {
let p = f?;
let path = p.as_path();
trace!("#setup: deploying {}...", path.display());
let pkg = path.parent()
.context(format!("Can't get parent from '{}'", path.display()))?
.to_str()
.context(format!("Can't turn path '{}' to str", path.display()))?
.replace("/", ".");
let mut gmi = Gmi::from_file(path).context(format!("Can't read {}", path.display()))?;
let mut root : u32 = 0;
let mut pk = "".to_owned();
for p in pkg.split(".") {
pk.push_str(format!(".{}", p).as_str());
match pkgs.get(&pk) {
Some(v) => {
root = *v;
},
None => {
let v = uni.next_id();
uni.add(v)?;
let e = uni.next_id();
uni.bind(e, root, v, p)?;
root = v;
pkgs.insert(pk.clone(), root);
}
}
}
gmi.set_root(root);
gmi.deploy_to(uni).context(format!("Failed to deploy '{}'", path.display()))?;
}
Ok(())
}

0 comments on commit e6e6658

Please sign in to comment.