Run rustfmt

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-03-09 16:47:30 -04:00
parent 63c81f07f7
commit d0f8d93edf
16 changed files with 218 additions and 194 deletions

View File

@@ -1,6 +1,6 @@
use cfgrammar::yacc::YaccKind;
use lrlex::LexerBuilder;
use lrpar::{CTParserBuilder};
use lrpar::CTParserBuilder;
use rerun_except::rerun_except;
fn main() -> Result<(), Box<dyn std::error::Error>> {
@@ -10,9 +10,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
LexerBuilder::new()
.rule_ids_map(lex_rule_ids_map)
.process_file_in_src("obj/syn/lexer.l")?;
rerun_except(&[
"examples/*.asm",
"tests/*.asm",
]).unwrap();
rerun_except(&["examples/*.asm", "tests/*.asm"]).unwrap();
Ok(())
}

View File

@@ -33,7 +33,7 @@ macro_rules! impl_add_assign {
self.0 = self.0 + (rhs as u64);
}
}
}
};
}
impl_add_assign!(usize);
@@ -53,7 +53,7 @@ macro_rules! impl_cmp {
self.0.partial_cmp(&other)
}
}
}
};
}
impl_cmp!(usize);
@@ -66,7 +66,7 @@ macro_rules! impl_from {
Addr(other as u64)
}
}
}
};
}
impl_from!(usize);

View File

@@ -1,4 +1,4 @@
use crate::{inst::InstOp, reg::Reg, addr::*,};
use crate::{addr::*, inst::InstOp, reg::Reg};
use snafu::Snafu;
#[derive(Snafu, Debug, Clone)]

View File

@@ -138,21 +138,15 @@ impl Inst {
| Inst::INeg(dest, source)
| Inst::Inv(dest, source)
| Inst::Not(dest, source)
| Inst::Mov(dest, source) => { 3 + dest.len() + source.len() }
Inst::CmpEq(s1, s2)
| Inst::CmpLt(s1, s2)
| Inst::Int(s1, s2) => { 3 + s1.len() + s2.len() }
Inst::Jmp(v)
| Inst::Jz(v)
| Inst::Jnz(v)
| Inst::Call(v)
| Inst::Push(v) => { 3 + v.len() }
Inst::Pop(v) => { 3 + v.len() }
Inst::Ret
| Inst::Halt
| Inst::Nop
| Inst::Dump
| Inst::IRet => { 2 }
| Inst::Mov(dest, source) => 3 + dest.len() + source.len(),
Inst::CmpEq(s1, s2) | Inst::CmpLt(s1, s2) | Inst::Int(s1, s2) => {
3 + s1.len() + s2.len()
}
Inst::Jmp(v) | Inst::Jz(v) | Inst::Jnz(v) | Inst::Call(v) | Inst::Push(v) => {
3 + v.len()
}
Inst::Pop(v) => 3 + v.len(),
Inst::Ret | Inst::Halt | Inst::Nop | Inst::Dump | Inst::IRet => 2,
}
}
}
@@ -176,7 +170,10 @@ impl Source {
pub fn len(&self) -> usize {
match self {
Source::Addr64(_) | Source::Addr32(_) | Source::Addr16(_) | Source::Addr8(_) => 8,
Source::RegAddr64(_) | Source::RegAddr32(_) | Source::RegAddr16(_) | Source::RegAddr8(_) => 1,
Source::RegAddr64(_)
| Source::RegAddr32(_)
| Source::RegAddr16(_)
| Source::RegAddr8(_) => 1,
Source::Reg(_) => 1,
Source::Imm(_) => 8,
}

View File

@@ -8,11 +8,14 @@ pub struct MemCursor<T> {
}
impl<T> MemCursor<T>
where Cursor<T>: ReadBytesExt,
T: AsRef<[u8]>
where
Cursor<T>: ReadBytesExt,
T: AsRef<[u8]>,
{
pub fn new(mem: T) -> Self {
MemCursor { cursor: Cursor::new(mem) }
MemCursor {
cursor: Cursor::new(mem),
}
}
pub fn position(&self) -> u64 {
@@ -32,7 +35,7 @@ impl<T> MemCursor<T>
let end = start + count;
self.check_addr(end as u64 - 1)?;
self.cursor.set_position(end as u64);
Ok(&self.cursor.get_ref().as_ref()[start .. end])
Ok(&self.cursor.get_ref().as_ref()[start..end])
}
pub fn next_u8_unchecked(&mut self) -> u8 {
@@ -220,7 +223,8 @@ impl<T> MemCursor<T>
}
impl<T> MemCursor<T>
where T: AsRef<[u8]>
where
T: AsRef<[u8]>,
{
fn check_addr(&self, addr: u64) -> Result<()> {
if addr >= (self.cursor.get_ref().as_ref().len() as u64) {
@@ -232,8 +236,9 @@ impl<T> MemCursor<T>
}
impl<T> MemCursor<T>
where Cursor<T>: WriteBytesExt,
T: AsRef<[u8]>
where
Cursor<T>: WriteBytesExt,
T: AsRef<[u8]>,
{
pub fn write_u8_unchecked(&mut self, value: u8) {
self.cursor.write_u8(value).unwrap();

View File

@@ -1,7 +1,7 @@
pub mod error;
pub mod session;
mod includes;
mod names;
pub mod session;
use self::{error::*, session::AsmSession};
use crate::{
@@ -11,7 +11,7 @@ use crate::{
obj::{
obj::{self, Object},
syn::ast::*,
}
},
};
use byteorder::{WriteBytesExt, LE};
use std::{collections::HashMap, path::Path};
@@ -48,7 +48,7 @@ impl Asm for Directive {
match self {
Directive::Data(section) => Ok(Some(obj::Section::Data(section.assemble(asm)?))),
Directive::Meta(section) => section.assemble(asm).map(Some),
Directive::Include(_) => { Ok(None) }
Directive::Include(_) => Ok(None),
}
}
}
@@ -81,7 +81,10 @@ impl Asm for DataSection {
let mut contents = Vec::with_capacity(content_len as usize);
for (pos, line) in self.lines(start) {
let expected_len = pos - (start as usize);
assert!(expected_len >= contents.len(), "next line size would cause section to shrink");
assert!(
expected_len >= contents.len(),
"next line size would cause section to shrink"
);
// resize contents if necessary, this pads out aligned values
contents.resize(expected_len, 0);
contents.extend(line.assemble(session)?);
@@ -93,11 +96,7 @@ impl Asm for DataSection {
"in section {}",
self.name
);
assert_eq!(
session.pos - start, content_len,
"in section {}",
self.name
);
assert_eq!(session.pos - start, content_len, "in section {}", self.name);
session.name_stack.pop();
Ok(obj::DataSection {
@@ -122,8 +121,15 @@ impl Asm for MetaSection {
}
let value = match &line.value {
Value::Int(i) => *i,
Value::Name(s) => session.lookup_name(s.as_str())
.ok_or_else(|| AsmError::UnknownName { name: s.to_string() })?.addr.0,
Value::Name(s) => {
session
.lookup_name(s.as_str())
.ok_or_else(|| AsmError::UnknownName {
name: s.to_string(),
})?
.addr
.0
}
Value::Reg(_) | Value::Here | Value::Addr(_, _) => {
return Err(AsmError::IllegalMetaValue {
name: line.name.to_string(),
@@ -218,10 +224,7 @@ impl Asm for Inst {
let dest_encoding = dest.source_encoding() << 4;
bytes.write_u8(dest_encoding).unwrap();
bytes.extend(dest.assemble(session)?);
assert_eq!(
len,
bytes.len(),
);
assert_eq!(len, bytes.len(),);
Ok(bytes)
}
Inst::Int(v1, v2) => self.map_source_source(session, inst::INT, v1, v2),
@@ -235,12 +238,18 @@ impl Asm for Inst {
}
impl Inst {
fn map_dest_source(&self, session: &mut AsmSession, op: inst::InstOp, dest: &Value, source: &Value) -> Result<Vec<u8>> {
fn map_dest_source(
&self,
session: &mut AsmSession,
op: inst::InstOp,
dest: &Value,
source: &Value,
) -> Result<Vec<u8>> {
let len = self.len();
let mut bytes = Vec::with_capacity(len);
bytes.write_u16::<LE>(op).unwrap();
let dest_encoding =
dest.dest_encoding()
let dest_encoding = dest
.dest_encoding()
.ok_or_else(|| AsmError::IllegalDestValue {
value: dest.clone(),
})?;
@@ -250,32 +259,35 @@ impl Inst {
.unwrap();
bytes.extend(dest.assemble(session)?);
bytes.extend(source.assemble(session)?);
assert_eq!(
len,
bytes.len(),
);
assert_eq!(len, bytes.len(),);
Ok(bytes)
}
fn map_source_source(&self, session: &mut AsmSession, op: inst::InstOp, s1: &Value, s2: &Value) -> Result<Vec<u8>> {
fn map_source_source(
&self,
session: &mut AsmSession,
op: inst::InstOp,
s1: &Value,
s2: &Value,
) -> Result<Vec<u8>> {
let len = self.len();
let mut bytes = Vec::with_capacity(len);
bytes.write_u16::<LE>(op).unwrap();
let s1_encoding = s1.source_encoding();
let s2_encoding = s2.source_encoding();
bytes
.write_u8((s1_encoding << 4) | s2_encoding)
.unwrap();
bytes.write_u8((s1_encoding << 4) | s2_encoding).unwrap();
bytes.extend(s1.assemble(session)?);
bytes.extend(s2.assemble(session)?);
assert_eq!(
len,
bytes.len(),
);
assert_eq!(len, bytes.len(),);
Ok(bytes)
}
fn map_source(&self, session: &mut AsmSession, op: inst::InstOp, source: &Value) -> Result<Vec<u8>> {
fn map_source(
&self,
session: &mut AsmSession,
op: inst::InstOp,
source: &Value,
) -> Result<Vec<u8>> {
let len = self.len();
let mut bytes = Vec::with_capacity(len);
bytes.write_u16::<LE>(op).unwrap();
@@ -290,10 +302,7 @@ impl Inst {
let len = self.len();
let mut bytes = Vec::with_capacity(len);
bytes.write_u16::<LE>(op).unwrap();
assert_eq!(
len,
bytes.len(),
);
assert_eq!(len, bytes.len(),);
Ok(bytes)
}
}
@@ -306,8 +315,12 @@ impl Asm for Value {
Value::Int(i) => Ok(i.to_le_bytes().to_vec()),
Value::Reg(r) => Ok(vec![*r]),
Value::Name(name) => {
let value = session.lookup_name(name.as_str())
.ok_or_else(|| AsmError::UnknownName { name: name.to_string() })?;
let value =
session
.lookup_name(name.as_str())
.ok_or_else(|| AsmError::UnknownName {
name: name.to_string(),
})?;
Ok(value.addr.0.to_le_bytes().to_vec())
}
Value::Here => Ok(session.pos.to_le_bytes().to_vec()),

View File

@@ -112,4 +112,3 @@ impl From<LexParseError> for SyntaxError {
}
pub type Result<T, E = AsmError> = std::result::Result<T, E>;

View File

@@ -1,14 +1,14 @@
use crate::{
addr::Addr,
obj::{
assemble::{
session::AsmSession,
error::*,
},
syn::ast::{DataSection, DataLine, Directive},
assemble::{error::*, session::AsmSession},
syn::ast::{DataLine, DataSection, Directive},
},
};
use std::{collections::{HashMap, HashSet}, rc::Rc};
use std::{
collections::{HashMap, HashSet},
rc::Rc,
};
// TODO(asm) make custom Names type that has "merge" that will catch errors with duplicate names
pub type Names = HashMap<String, Name>;
@@ -54,11 +54,14 @@ pub fn get_section_names(section: &DataSection) -> Result<Names> {
}
let export = exports.remove(name);
names.insert(name.clone(), Name {
names.insert(
name.clone(),
Name {
name: name.clone(),
addr: Addr(pos as u64),
export,
});
},
);
}
}
@@ -66,7 +69,9 @@ pub fn get_section_names(section: &DataSection) -> Result<Names> {
if exports.is_empty() {
Ok(names)
} else {
Err(AsmError::UnknownExport { name: exports.iter().next().unwrap().to_string() })
Err(AsmError::UnknownExport {
name: exports.iter().next().unwrap().to_string(),
})
}
}
@@ -93,12 +98,16 @@ pub fn get_exports(session: &mut AsmSession) -> Result<Names> {
for name_map in all_exports.iter() {
let names_set: HashSet<_> = name_map.keys().collect();
if let Some(dupe) = exports.intersection(&names_set).next() {
return Err(AsmError::DuplicateExport { name: dupe.to_string() });
return Err(AsmError::DuplicateExport {
name: dupe.to_string(),
});
}
exports.extend(names_set);
}
// NOTE: this can probably be done with a fancy combinator chain
Ok(all_exports.into_iter()
.fold(Names::new(), |mut acc, val| { acc.extend(val); acc }))
Ok(all_exports.into_iter().fold(Names::new(), |mut acc, val| {
acc.extend(val);
acc
}))
}

View File

@@ -1,14 +1,12 @@
use crate::{
obj::{
use crate::obj::{
assemble::{
Asm,
error::*,
includes::GetIncludes,
names::{self, Name, Names},
error::*,
Asm,
},
obj::Object,
syn::ast::Ast,
},
};
use std::{
collections::BTreeMap,
@@ -19,19 +17,17 @@ use std::{
/// A shared session for the assembler.
#[derive(Debug, Default)]
pub struct AsmSession {
pub (in super) includes: Rc<BTreeMap<PathBuf, Ast>>,
pub (in super) include_search_paths: Vec<PathBuf>,
pub (in super) include_stack: Vec<PathBuf>,
pub (in super) name_stack: Vec<Names>,
pub (in super) pos: u64,
pub(super) includes: Rc<BTreeMap<PathBuf, Ast>>,
pub(super) include_search_paths: Vec<PathBuf>,
pub(super) include_stack: Vec<PathBuf>,
pub(super) name_stack: Vec<Names>,
pub(super) pos: u64,
}
impl AsmSession {
pub fn assemble(&mut self) -> Result<Object> {
let includes = Rc::clone(&self.includes);
let sections: Vec<_> = includes.iter()
.flat_map(|(_, ast)| ast)
.collect();
let sections: Vec<_> = includes.iter().flat_map(|(_, ast)| ast).collect();
sections.assemble(self)
}
@@ -46,19 +42,21 @@ impl AsmSession {
Ok(())
}
pub (in super) fn current_include_path(&self) -> Option<&Path> {
pub(super) fn current_include_path(&self) -> Option<&Path> {
self.include_stack.last().map(PathBuf::as_path)
}
pub (in super) fn resolve_include_path(&self, path: impl AsRef<Path>) -> Option<PathBuf> {
pub(super) fn resolve_include_path(&self, path: impl AsRef<Path>) -> Option<PathBuf> {
let path = path.as_ref();
self.current_include_path()
.and_then(|last_path| last_path.parent())
.map(|last_dir| last_dir.join(path))
.or_else(|| self.include_search_paths
.or_else(|| {
self.include_search_paths
.iter()
.filter_map(|include| include.join(path).canonicalize().ok())
.next())
.next()
})
}
pub fn lookup_name(&self, name: &str) -> Option<&Name> {

View File

@@ -1,8 +1,9 @@
use crate::{mem::MemCursor, obj::obj::*};
use prettytable::{Table, row, cell};
use std::io::{self, Write as Write};
use prettytable::{cell, row, Table};
use std::io::{self, Write};
const SEP: &str = "================================================================================";
const SEP: &str =
"================================================================================";
pub trait Disasm {
fn disasm(&self, writer: &mut dyn Write) -> io::Result<()>;
@@ -61,8 +62,8 @@ impl Disasm for DataSection {
if let Ok(inst) = cursor.next_inst() {
let start = cursor_pos as usize;
let end = start + inst.len();
let data = &self.contents.as_slice()[start .. end];
table.add_row(row! [
let data = &self.contents.as_slice()[start..end];
table.add_row(row![
format!("{:016x} <{}+{:x}>", pos, self.name, cursor_pos),
bytes_hex(data),
format!("{:?}", inst),

View File

@@ -42,4 +42,3 @@ into_parse_error! {
}
pub type Result<T, E = ParseError> = std::result::Result<T, E>;

View File

@@ -114,8 +114,8 @@ pub enum Section {
impl Section {
pub fn len(&self) -> usize {
match self {
Section::Data(s) => { 1 + 8 + s.len() },
Section::Meta(s) => { 1 + 8 + s.len() },
Section::Data(s) => 1 + 8 + s.len(),
Section::Meta(s) => 1 + 8 + s.len(),
}
}
@@ -129,7 +129,7 @@ impl Section {
Section::Meta(s) => {
cursor.write_u8(SectionKind::Meta.into()).unwrap();
s.to_bytes()
},
}
};
cursor.write_u64::<LE>(bytes.len() as u64).unwrap();
cursor.write(&bytes).unwrap();
@@ -181,7 +181,7 @@ impl DataSection {
let name_len = cursor.read_u16::<LE>()? as usize;
let name_start = cursor.position() as usize;
let name_end = name_start + name_len;
let name_bytes = &bytes[name_start .. name_end];
let name_bytes = &bytes[name_start..name_end];
let name_string = String::from_utf8(name_bytes.to_vec())?;
cursor.set_position(name_end as u64);
@@ -205,7 +205,9 @@ pub struct MetaSection {
impl MetaSection {
pub fn len(&self) -> usize {
8 + self.entries.iter()
8 + self
.entries
.iter()
.map(|(k, _)| 8 + k.as_bytes().len() + 8)
.sum::<usize>()
}
@@ -254,11 +256,11 @@ mod test {
name: "data".to_string(),
start: 0,
len: 16,
contents: vec!(0u8; 16),
contents: vec![0u8; 16],
}),
Section::Meta(MetaSection {
entries: Default::default(),
})
}),
],
};

View File

@@ -1,8 +1,4 @@
use crate::{
interrupt::Interrupt,
inst,
reg::Reg,
};
use crate::{inst, interrupt::Interrupt, reg::Reg};
pub type Ast = Vec<Directive>;
@@ -307,18 +303,14 @@ impl Inst {
| Inst::CmpEq(v1, v2)
| Inst::CmpLt(v1, v2)
| Inst::Int(v1, v2)
| Inst::Mov(v1, v2) => { 3 + v1.len() + v2.len() }
| Inst::Mov(v1, v2) => 3 + v1.len() + v2.len(),
Inst::Jmp(v)
| Inst::Jz(v)
| Inst::Jnz(v)
| Inst::Call(v)
| Inst::Push(v)
| Inst::Pop(v) => { 3 + v.len() }
Inst::Ret
| Inst::IRet
| Inst::Halt
| Inst::Nop
| Inst::Dump => { 2 }
| Inst::Pop(v) => 3 + v.len(),
Inst::Ret | Inst::IRet | Inst::Halt | Inst::Nop | Inst::Dump => 2,
}
}
}

View File

@@ -146,21 +146,25 @@ impl State {
pub fn ivt(&self) -> Result<&[Interrupt]> {
let ivt_addr = self.get_reg_unchecked(IVT);
if ivt_addr % 64 != 0 {
panic!("illegal IVT address {:#x}; must be divisible by 64", ivt_addr);
panic!(
"illegal IVT address {:#x}; must be divisible by 64",
ivt_addr
);
}
let start = ivt_addr as usize;
let end = start + (IVT_LENGTH * mem::size_of::<Interrupt>());
if end > self.mem.len() {
return Err(VmError::MemOutOfBounds { addr: Addr(ivt_addr) });
return Err(VmError::MemOutOfBounds {
addr: Addr(ivt_addr),
});
}
// This is safe because we check the bounds above
let slice_ptr = (&self.mem[start..]).as_ptr();
let slice = unsafe {
std::slice::from_raw_parts(slice_ptr as *const Interrupt, IVT_LENGTH)
};
let slice =
unsafe { std::slice::from_raw_parts(slice_ptr as *const Interrupt, IVT_LENGTH) };
Ok(slice)
}
@@ -386,7 +390,9 @@ impl State {
// create a destination based on the size of the source
let dest = match source {
Source::Addr64(_) | Source::RegAddr64(_) | Source::Reg(_) | Source::Imm(_) => Dest::Addr64(Addr(stack_addr)),
Source::Addr64(_) | Source::RegAddr64(_) | Source::Reg(_) | Source::Imm(_) => {
Dest::Addr64(Addr(stack_addr))
}
Source::Addr32(_) | Source::RegAddr32(_) => Dest::Addr32(Addr(stack_addr)),
Source::Addr16(_) | Source::RegAddr16(_) => Dest::Addr16(Addr(stack_addr)),
Source::Addr8(_) | Source::RegAddr8(_) => Dest::Addr8(Addr(stack_addr)),

View File

@@ -2,21 +2,26 @@ mod common;
extern crate libvm as vm;
use structopt::StructOpt;
use snafu::Snafu;
use std::{fs, io::{stdout, Write}, path::{Path, PathBuf}, process};
use std::{
fs,
io::{stdout, Write},
path::{Path, PathBuf},
process,
};
use structopt::StructOpt;
const DEFAULT_MAX_MEM: usize = 64 * 1024 * 1024;
#[derive(Snafu, Debug, Clone, PartialEq)]
enum ArgParseError<'a> {
#[snafu(display("invalid specified size: {} (sizes may end in G, M, or K)", text))]
InvalidSize { text: &'a str }
InvalidSize { text: &'a str },
}
fn from_bytes_size<'a>(mut text: &'a str) -> std::result::Result<usize, ArgParseError<'a>> {
if text.is_empty() {
return Err(ArgParseError::InvalidSize { text })
return Err(ArgParseError::InvalidSize { text });
}
let multiplier = match text.chars().last().unwrap() {
'k' | 'K' => 1024,
@@ -26,9 +31,11 @@ fn from_bytes_size<'a>(mut text: &'a str) -> std::result::Result<usize, ArgParse
};
// trim the last character
if multiplier != 1 {
text = &text[0 .. text.len() - 1];
text = &text[0..text.len() - 1];
}
let value = text.parse::<usize>().map_err(|_| ArgParseError::InvalidSize { text })?;
let value = text
.parse::<usize>()
.map_err(|_| ArgParseError::InvalidSize { text })?;
Ok(value * multiplier)
}
@@ -56,7 +63,6 @@ fn test_bytes_size() {
struct Options {
// maybe some other options:
// * debug
/// The input file to work with.
///
/// By default, the file will be executed. If -c is passed, it will not run and only compile.
@@ -82,7 +88,6 @@ struct Options {
/// Only compile the input file to an object.
#[structopt(short = "c", long)]
compile_only: bool,
}
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
@@ -107,8 +112,8 @@ fn get_writer(path: impl AsRef<Path>) -> Result<Box<dyn Write>> {
fn main() -> Result<()> {
use vm::{
state::State,
obj::{assemble, disassemble::Disasm},
state::State,
};
let opt = Options::from_args();
@@ -125,7 +130,9 @@ fn main() -> Result<()> {
writer.write(&bytes)?;
Ok(())
} else if opt.disassemble {
let outfile = opt.out.as_ref()
let outfile = opt
.out
.as_ref()
.map(|p| p.as_path())
.unwrap_or_else(|| Path::new("-"));
let mut writer = get_writer(&outfile)?;
@@ -138,4 +145,3 @@ fn main() -> Result<()> {
process::exit((status & 0xffff_ffff) as i32);
}
}