Skip to content

Commit

Permalink
#13: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
yegor256 committed Sep 5, 2022
1 parent 066e4b7 commit be8632f
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 16 deletions.
66 changes: 66 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ lazy_static = "1.4.0"
tempfile = "3.3.0"
env_logger = "0.9.0"
log = "0.4.1"
clap = { version = "3.2.20", features = ["cargo"] }
simple_logger = "2.1.0"
assert_cmd = "2.0.4"
ctor = "0.1.21"
Expand Down
4 changes: 4 additions & 0 deletions gmi-tests/primitive.gmi
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ADD('ν0');
ADD('ν1');
BIND('ε2', 'ν0', 'ν1', 'foo');
DATA('ν1', 'd0 bf d1 80 d0 b8 d0 b2 d0 b5 d1 82');
141 changes: 135 additions & 6 deletions src/bin/reo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,145 @@

extern crate reo;

use std::fs;
use std::fs::File;
use std::path::Path;
use clap::{AppSettings, Arg, ArgAction, Command, crate_version};
use log::{debug, LevelFilter};
use predicates::prelude::predicate;
use simple_logger::SimpleLogger;

pub fn main() {
env_logger::init();
println!("reo here, to transpile XMIR to Rust");
let matches = Command::new("reo")
.setting(AppSettings::ColorNever)
.about("GMI to Rust compiler and runner")
.version(crate_version!())
.arg(
Arg::new("verbose")
.long("verbose")
.required(false)
.takes_value(false)
.help("Print all possible debug messages")
)
.arg(
Arg::new("file")
.long("file")
.short('f')
.required(false)
.help("Name of a single .gmi file to work with")
.takes_value(true)
.action(ArgAction::Set)
)
.arg(
Arg::new("home")
.long("home")
.required(false)
.help("Directory with .gmi files")
.takes_value(true)
.action(ArgAction::Set)
)
.subcommand_required(true)
.allow_external_subcommands(true)
.subcommand(
Command::new("dataize")
.setting(AppSettings::ColorNever)
.about("Dataizes an object")
.arg(
Arg::new("object")
.required(true)
.help("Fully qualified object name")
.takes_value(false)
.action(ArgAction::Set)
)
.arg_required_else_help(true)
)
.get_matches();
let mut logger = SimpleLogger::new().without_timestamps();
if matches.contains_id("verbose") {
logger = logger.with_level(LevelFilter::Trace);
}
logger.init().unwrap();
match matches.subcommand() {
Some(("dataize", subs)) => {
let object = subs.get_one::<String>("object").unwrap();
let home = matches.value_of("home").unwrap_or(".");
let full_home = fs::canonicalize(home).unwrap();
let cwd = full_home.as_path();
let mut uni = Universe::empty();
debug!("Home is set to {}", cwd.display());
let mut total = 0;
if matches.contains_id("file") {
let file = Path::new(matches.value_of("file").unwrap());
debug!("Deploying instructions from a single file {}", file.display());
total += Gmi::from_file(file).unwrap().deploy_to(&mut uni).unwrap();
} else {
debug!("Deploying instructions from a directory {}", cwd.display());
uni.add(0).unwrap();
total += setup(&mut uni, cwd).unwrap();
}
debug!("Deployed {} GMI instructions", total);
debug!("Dataizing '{}' object...", object);
let ret = da!(uni, format!("Φ.{}", object)).as_hex();
debug!("Dataization result is: {}", ret);
println!("{}", ret);
}
_ => unreachable!(),
}
}

#[test]
fn prints_help() {
assert_cmd::Command::cargo_bin("reo").unwrap()
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("GMI to Rust"))
.stdout(predicate::str::contains("--home"));
}

#[cfg(test)]
use simple_logger::SimpleLogger;
use tempfile::TempDir;
use reo::da;
use reo::setup::setup;
use reo::universe::Universe;
use anyhow::Result;
use std::io::Write;
use reo::gmi::Gmi;
use glob::glob;

#[test]
fn prints_help() {
SimpleLogger::new().init().unwrap();
// assert_eq!(21, fibo(7))
fn dataizes_simple_gmi() -> Result<()> {
let tmp = TempDir::new()?;
File::create(tmp.path().join("foo.gmi"))?.write_all(
"
ADD('$ν1');
BIND('$ε2', 'ν0', '$ν1', 'foo');
DATA('$ν1', 'ff ff');
".as_bytes()
)?;
assert_cmd::Command::cargo_bin("reo").unwrap()
.arg(format!("--home={}", tmp.path().display()))
.arg("dataize")
.arg("foo")
.assert()
.success()
.stdout("ff-ff\n");
Ok(())
}

#[test]
fn dataizes_all_gmi_tests() -> Result<()> {
for f in glob("gmi-tests/*.gmi")? {
let p = f?;
let path = p.as_path();
assert_cmd::Command::cargo_bin("reo").unwrap()
.arg(format!("--file={}", path.display()))
.arg("--verbose")
.arg("dataize")
.arg("foo")
.assert()
.success()
.stdout(predicate::str::contains("Dataization result is: "));
}
Ok(())
}
9 changes: 6 additions & 3 deletions src/gmi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,19 @@ impl Gmi {
self.vars.insert("v0".to_string(), v0);
}

/// Deploy this collection of GMIs to the Universe.
pub fn deploy_to(&mut self, uni: &mut Universe) -> Result<()> {
/// Deploy this collection of GMIs to the Universe. Returns total
/// number of GMI instructions deployed.
pub fn deploy_to(&mut self, uni: &mut Universe) -> Result<u32> {
let txt = &self.text.clone();
let lines = txt.split("\n").map(|t| t.trim()).filter(|t| !t.is_empty());
let mut total = 0;
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))?;
total += 1;
}
Ok(())
Ok(total)
}

/// Deploy a sing command to the universe.
Expand Down
20 changes: 13 additions & 7 deletions src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,25 @@ use log::trace;
use std::collections::HashMap;
use std::path::Path;

/// Deploy a directory of `*.gmi` files to a new `Universe`.
pub fn setup(uni: &mut Universe, dir: &Path) -> Result<()> {
/// Deploy a directory of `*.gmi` files to a new `Universe`. Returns
/// total number of GMI instructions deployed to the Universe.
pub fn setup(uni: &mut Universe, dir: &Path) -> Result<u32> {
register(uni);
let mut pkgs: HashMap<String, u32> = HashMap::new();
let mut total = 0;
for f in glob(format!("{}/**/*.gmi", dir.display()).as_str())? {
let p = f?;
if p.is_dir() {
continue;
}
let path = p.as_path();
let rel = path.strip_prefix(dir)?;
trace!("#setup: deploying {}...", path.display());
let pkg = path
let pkg = rel
.parent()
.context(format!("Can't get parent from '{}'", path.display()))?
.context(format!("Can't get parent from '{}'", rel.display()))?
.to_str()
.context(format!("Can't turn path '{}' to str", path.display()))?
.context(format!("Can't turn path '{}' to str", rel.display()))?
.replace("/", ".");
let mut gmi = Gmi::from_file(path).context(format!("Can't read {}", path.display()))?;
let mut root: u32 = 0;
Expand All @@ -61,8 +67,8 @@ pub fn setup(uni: &mut Universe, dir: &Path) -> Result<()> {
}
}
gmi.set_root(root);
gmi.deploy_to(uni)
total += gmi.deploy_to(uni)
.context(format!("Failed to deploy '{}'", path.display()))?;
}
Ok(())
Ok(total)
}

0 comments on commit be8632f

Please sign in to comment.