vasm now supports files

This commit is contained in:
2022-06-01 16:11:34 -05:00
parent 3ca3a2eeac
commit 84230676cb
6 changed files with 85 additions and 55 deletions
+26 -7
View File
@@ -3,6 +3,7 @@ use crate::parse_error::AssembleError;
use crate::vasm_evaluator::eval;
use crate::vasm_preprocessor::{Line, LineSource};
use std::collections::BTreeMap;
use std::fs;
/// This will solve all the .equ directives and return a symbol table of them.
/// .equ directives must be able to be solved in order, that is, in terms of
@@ -162,14 +163,14 @@ fn code_bounds(
/// bytes long and index 0 will represent 0x400.
/// ```
/// assert_eq!(
/// vasm::assemble_snippet(vec![".org 0x400", "push 5", "add 7"]),
/// vasm::assemble_snippet(".org 0x400 \n push 5 \n add 7".lines().map(String::from)),
/// Ok(vec![0x01, 0x05, 0x05, 0x07])
/// )
/// ```
pub fn assemble_snippet<'a, T: IntoIterator<Item = &'a str>>(
pub fn assemble_snippet<T: IntoIterator<Item = String>>(
lines: T,
) -> Result<Vec<u8>, AssembleError> {
let mut line_results: Vec<Result<Line, AssembleError>> =
let line_results: Vec<Result<Line, AssembleError>> =
LineSource::new("_snippet", lines, |_file| {
Err(AssembleError::IncludeError(
0,
@@ -178,6 +179,19 @@ pub fn assemble_snippet<'a, T: IntoIterator<Item = &'a str>>(
})
.collect();
assemble_line_results(line_results)
}
pub fn assemble_file(filename: &str) -> Result<Vec<u8>, AssembleError> {
let lines = lines_from_file(filename)?;
let line_results: Vec<Result<Line, AssembleError>> = LineSource::new(filename, lines, |file| {
lines_from_file(file.as_str())
}).collect();
assemble_line_results(line_results)
}
fn assemble_line_results(mut line_results: Vec<Result<Line, AssembleError>>) -> Result<Vec<u8>, AssembleError> {
if let Some(Err(error)) = line_results.iter().find(|line| line.is_err()) {
Err(error.clone())
} else {
@@ -189,6 +203,11 @@ pub fn assemble_snippet<'a, T: IntoIterator<Item = &'a str>>(
}
}
fn lines_from_file(filename: &str) -> Result<Vec<String>, AssembleError> {
let file = fs::read_to_string(filename).map_err(|_e| AssembleError::FileError(filename.into()))?;
Ok(file.lines().map(String::from).collect())
}
/// At this point all lines have addresses and lengths, and all arguments are reduced to
/// numeric constants. It's time to generate code.
///
@@ -474,9 +493,9 @@ mod test {
#[test]
fn test_assemble_snippet() {
assert_eq!(assemble_snippet(["add"]), Ok(vec![4]));
assert_eq!(assemble_snippet(["add"].map(String::from)), Ok(vec![4]));
assert_eq!(
assemble_snippet(["apple"]),
assemble_snippet(["apple"].map(String::from)),
Err(ParseError(
1,
parse_error::ParseError::InvalidInstruction("apple".into())
@@ -491,7 +510,7 @@ mod test {
hlt
blah: mul 2
ret"
.lines()
.lines().map(String::from)
),
Ok(vec![
0x01, 0x03, // nop 3
@@ -509,7 +528,7 @@ mod test {
nop $+2
nop 0x111111
nop 0x222222".lines()),
nop 0x222222".lines().map(String::from)),
Ok(vec![
0x03, 0x08, 0x04, 0x00,
0x03, 0x11, 0x11, 0x11,