Skip to content

Commit

Permalink
Merge pull request #36 from rozukke/fix/run-command
Browse files Browse the repository at this point in the history
Fix running and compiling
  • Loading branch information
rozukke authored Sep 20, 2024
2 parents 067d278 + ff00548 commit 50a665f
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 18 deletions.
30 changes: 28 additions & 2 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 @@ -19,6 +19,7 @@ console = "0.15.8"
[dev-dependencies]
assert_cmd = "2.0.14"
predicates = "3.1.2"
tempfile = "3.12.0"

[[bin]]
name = "lace"
Expand Down
40 changes: 34 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::fs::{self, File};
use std::io::Write;
use std::io::{Read, Write};
use std::path::PathBuf;
use std::time::Duration;

Expand All @@ -10,7 +10,7 @@ use hotwatch::{
blocking::{Flow, Hotwatch},
EventKind,
};
use miette::{IntoDiagnostic, Result};
use miette::{bail, IntoDiagnostic, Result};

use lace::reset_state;
use lace::{Air, RunState, StaticSource};
Expand Down Expand Up @@ -78,7 +78,7 @@ fn main() -> miette::Result<()> {
let air = assemble(&contents)?;

let out_file_name =
dest.unwrap_or(name.with_extension("lc3").file_stem().unwrap().into());
dest.unwrap_or(name.with_extension("lc3").file_name().unwrap().into());
let mut file = File::create(&out_file_name).unwrap();

// Deal with .orig
Expand Down Expand Up @@ -194,11 +194,39 @@ where

fn run(name: &PathBuf) -> Result<()> {
file_message(MsgColor::Green, "Assembling", &name);
let contents = StaticSource::new(fs::read_to_string(&name).into_diagnostic()?);
let air = assemble(&contents)?;
let mut program = if let Some(ext) = name.extension() {
match ext.to_str().unwrap() {
"lc3" | "obj" => {
// Read to byte buffer
let mut file = File::open(&name).into_diagnostic()?;
let f_size = file.metadata().unwrap().len();
let mut buffer = Vec::with_capacity(f_size as usize);
file.read_to_end(&mut buffer).into_diagnostic()?;

if buffer.len() % 2 != 0 {
bail!("File is not aligned to 16 bits")
}

let u16_buf: Vec<u16> = buffer
.chunks_exact(2)
.map(|word| u16::from_be_bytes([word[0], word[1]]))
.collect();
RunState::from_raw(&u16_buf)?
}
"asm" => {
let contents = StaticSource::new(fs::read_to_string(&name).into_diagnostic()?);
let air = assemble(&contents)?;
RunState::try_from(air)?
}
_ => {
bail!("File has unknown extension. Exiting...")
}
}
} else {
bail!("File has no extension. Exiting...");
};

message(MsgColor::Green, "Running", "emitted binary");
let mut program = RunState::try_from(air)?;
program.run();

file_message(MsgColor::Green, "Completed", &name);
Expand Down
22 changes: 14 additions & 8 deletions src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const MEMORY_MAX: usize = 0x10000;
pub struct RunState {
/// System memory - 128KB in size.
/// Need to figure out if this would cause problems with the stack.
mem: [u16; MEMORY_MAX],
mem: Box<[u16; MEMORY_MAX]>,
/// Program counter
pc: u16,
/// 8x 16-bit registers
Expand All @@ -35,23 +35,29 @@ enum RunFlag {
impl RunState {
// Not generic because of miette error
pub fn try_from(air: Air) -> Result<RunState> {
let orig: usize = air.orig().unwrap_or(0x3000).into();
let mut mem = [0; MEMORY_MAX];
let mut air_array = Vec::with_capacity(air.len());
let orig = air.orig().unwrap_or(0x3000);
let mut air_array: Vec<u16> = Vec::with_capacity(air.len() + 1);

air_array.push(orig);
for stmt in air {
air_array.push(stmt.emit()?);
}
RunState::from_raw(air_array.as_slice())
}

// Sanity check
if orig + air_array.len() > MEMORY_MAX {
pub fn from_raw(raw: &[u16]) -> Result<RunState> {
let orig = raw[0] as usize;
if orig as usize + raw.len() > MEMORY_MAX {
panic!("Assembly file is too long and cannot fit in memory.");
}

mem[orig..orig + air_array.len()].clone_from_slice(&air_array);
let mut mem = [0; MEMORY_MAX];
let raw = &raw[1..];

mem[orig..orig + raw.len()].clone_from_slice(&raw);

Ok(RunState {
mem,
mem: Box::new(mem),
pc: orig as u16,
reg: [0; 8],
flag: RunFlag::Uninit,
Expand Down
23 changes: 21 additions & 2 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use assert_cmd::prelude::*;
use assert_cmd::Command;
use predicates::str::contains;
use std::process::Command;
use tempfile::tempdir;

#[test]
fn runs_without_arguments() {
Expand All @@ -18,3 +18,22 @@ fn runs_hello_world() {
.stdout(contains("Hello, world!"))
.stdout(contains("Halted"));
}

#[test]
fn compile_and_run() {
let dir = tempdir().expect("Could not make tempdir");

let outfile_path = dir.path().join("hw.lc3");

let mut cmd = Command::cargo_bin("lace").unwrap();
cmd.arg("compile")
.arg("tests/files/hw.asm")
.arg(&outfile_path);

cmd.assert().success().stdout(contains("Saved target"));

let mut cmd = Command::cargo_bin("lace").unwrap();
cmd.arg(&outfile_path);

cmd.assert().success().stdout(contains("Hello, world!"));
}

0 comments on commit 50a665f

Please sign in to comment.