Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Refined Command stucture

  • Loading branch information...
sphinxc0re committed Mar 1, 2018
1 parent 8e7f43a commit c03b3b9eb73e37abf801b06e1610147031d11a84
Showing with 317 additions and 235 deletions.
  1. +15 −15 Cargo.lock
  2. +1 −1 README.md
  3. +17 −17 hudson/basm.rs
  4. +3 −7 hudson/beast.rs
  5. +58 −28 hudson/commands/compile.rs
  6. +2 −2 hudson/commands/mod.rs
  7. +138 −114 hudson/commands/pack.rs
  8. +83 −51 hudson/main.rs

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -46,7 +46,7 @@ After the installation, you should have the following binaries installed: `baker

`hudson` is the bakervm toolkit. It is currently only able to *compile* `*.basm` files.
```
hudson compile -l basm path/to/main.basm
hudson compile path/to/source.basm
```
`bakervm` is the VM itself. On startup it loads the stock image by default. But you can specify any bakerVM image:
```shell
@@ -8,7 +8,7 @@ use std::env;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::Path;
use std::path::{Path, PathBuf};

lazy_static! {
static ref LABELED_MNEMONIC_RE: Regex = Regex::new(r"^\.(.+?) +?(.+)$").unwrap();
@@ -30,7 +30,9 @@ impl BASMCompiler {
if self.label_addr_map.contains_key(&label) {
bail!("label {:?} already exists", label)
} else {
self.label_addr_map.entry(label).or_insert(self.mnemonics.len());
self.label_addr_map
.entry(label)
.or_insert(self.mnemonics.len());

Ok(())
}
@@ -77,9 +79,9 @@ impl BASMCompiler {
}

let first_half: String = if LABELED_MNEMONIC_RE.is_match(first_half) {
let captures = if let Some(captures) = LABELED_MNEMONIC_RE
.captures_iter(first_half)
.next() {
let captures = if let Some(captures) =
LABELED_MNEMONIC_RE.captures_iter(first_half).next()
{
captures
} else {
bail!("no label capture found")
@@ -91,12 +93,12 @@ impl BASMCompiler {

captures[2].trim().to_owned()
} else if LABEL_RE.is_match(first_half) {
let captures =
if let Some(captures) = LABEL_RE.captures_iter(first_half).next() {
captures
} else {
bail!("no label capture found")
};
let captures = if let Some(captures) = LABEL_RE.captures_iter(first_half).next()
{
captures
} else {
bail!("no label capture found")
};

let label = captures[1].trim();

@@ -140,7 +142,6 @@ impl BASMCompiler {
if let Some(opcode) = first_half_split.next() {
let opcode = opcode.trim().to_lowercase();


let args: Vec<String> = if let Some(args) = first_half_split.next() {
args.split(',').map(|arg| arg.trim().to_owned()).collect()
} else {
@@ -223,9 +224,8 @@ impl BASMCompiler {
}
}

pub fn compile(&mut self, file_name: String) -> Result<ImageData> {
let path =
Path::new(&file_name).canonicalize().chain_err(|| "unable to canonicalize path")?;
pub fn compile(&mut self, path: PathBuf) -> Result<ImageData> {
ensure!(path.is_absolute(), "file name must be absolute");

let parent = if let Some(ref parent) = path.parent() {
parent.to_path_buf().clone()
@@ -280,8 +280,8 @@ fn text_to_mnemonic(opcode: String, args: Vec<String>) -> Result<Mnemonic> {
}
}

pub fn compile(file_name: String) -> Result<ImageData> {
BASMCompiler::default().compile(file_name)
pub fn compile(path: PathBuf) -> Result<ImageData> {
BASMCompiler::default().compile(path)
}

#[cfg(test)]
@@ -3,20 +3,16 @@ use core::typedef::*;
use pest::Parser;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::path::PathBuf;

const _GRAMMAR: &str = include_str!("../src/beast.pest");

#[derive(Parser)]
#[grammar = "beast.pest"]
pub struct BeastParser;

pub fn compile(file_name: String) -> Result<ImageData> {
let orig_path = Path::new(&file_name)
.canonicalize()
.chain_err(|| "unable to canonicalize path")?;

let mut file = File::open(orig_path).chain_err(|| "unable to open file")?;
pub fn compile(path: PathBuf) -> Result<ImageData> {
let mut file = File::open(path).chain_err(|| "unable to open file")?;

let mut buf = String::new();

@@ -1,47 +1,77 @@
use basm;
use beast;
use clap::ArgMatches;
// use clap::ArgMatches;
use core::error::*;
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use std::str::FromStr;

pub fn compile(matches: &ArgMatches) -> Result<()> {
let input_file_name = if let Some(file_name) = matches.value_of("input") {
file_name
} else {
bail!("no file name given");
};
const BAKERVM_IMAGE_EXTENSION: &str = "img";
pub const DEFAULT_LANG: Lang = Lang::Beast;

let start_dir = env::current_dir().chain_err(|| "unable to get current directory")?;
#[derive(Debug)]
pub enum Lang {
Beast,
Basm,
}

if matches.value_of("lang") == Some("basm") {
let program = basm::compile(input_file_name.to_owned())
.chain_err(|| "unable to compile file")?;
impl FromStr for Lang {
type Err = &'static str;
fn from_str(s: &str) -> ::std::result::Result<Self, Self::Err> {
match s {
"basm" => Ok(Lang::Basm),
"beast" | "bst" => Ok(Lang::Beast),
_ => bail!("unknown language. Language must be one of [beast, bst, basm]"),
}
}
}

pub fn compile(lang: Option<Lang>, input: PathBuf, output: Option<PathBuf>) -> Result<()> {
let input = input
.canonicalize()
.chain_err(|| "unable to canonicalize input path")?;

let output_file_name = if let Some(file_name) = matches.value_of("output") {
file_name.to_owned()
// We don't want to fail at recognizing the language, so we just default to
// Beast
let lang = lang.unwrap_or_else(|| {
if let Some(extension) = input.extension() {
if let Some(extension) = extension.to_str() {
extension.parse().unwrap_or(DEFAULT_LANG)
} else {
DEFAULT_LANG
}
} else {
format!("{}.img", input_file_name)
};
DEFAULT_LANG
}
});

let mut fallback_output = input.clone();

env::set_current_dir(start_dir).chain_err(|| "unable to switch directories")?;
ensure!(
fallback_output.set_extension(BAKERVM_IMAGE_EXTENSION),
"unable to set file extension"
);

let mut file = File::create(output_file_name).chain_err(|| "unable to create file")?;
let output = output.unwrap_or(fallback_output);

file.write_all(&program[..]).chain_err(|| "unable to write program data")?;
let start_dir = env::current_dir().chain_err(|| "unable to get current directory")?;

file.sync_all().chain_err(|| "unable to sync output file to file system")?;
} else {
let program = beast::compile(input_file_name.to_owned())
.chain_err(|| "unable to compile file")?;
let program = match lang {
Lang::Basm => basm::compile(input).chain_err(|| "unable to compile basm file")?,
Lang::Beast => beast::compile(input).chain_err(|| "unable to compile Beast file")?,
};

let output_file_name = if let Some(file_name) = matches.value_of("output") {
file_name.to_owned()
} else {
format!("{}.img", input_file_name)
};
}
env::set_current_dir(start_dir).chain_err(|| "unable to switch directories")?;

let mut file = File::create(output).chain_err(|| "unable to create file")?;

file.write_all(&program[..])
.chain_err(|| "unable to write program data")?;

file.sync_all()
.chain_err(|| "unable to sync output file to file system")?;

Ok(())
}
@@ -1,5 +1,5 @@
mod pack;
mod compile;

pub use self::compile::compile;
pub use self::pack::pack;
pub use self::compile::*;
// pub use self::pack::pack;
Oops, something went wrong.

0 comments on commit c03b3b9

Please sign in to comment.
You can’t perform that action at this time.