@@ -64,6 +64,6 @@ impl Span {
|
|||||||
pub fn union(self, other: Span) -> Self {
|
pub fn union(self, other: Span) -> Self {
|
||||||
let start = self.start.min(other.start);
|
let start = self.start.min(other.start);
|
||||||
let end = self.end.max(other.end);
|
let end = self.end.max(other.end);
|
||||||
Span { start, end, }
|
Span { start, end }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ fn main() -> Result<()> {
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("{}", err);
|
eprintln!("{}", err);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
let obj = vm::obj::obj::Object::try_from(&ast)?;
|
let obj = vm::obj::obj::Object::try_from(&ast)?;
|
||||||
println!("{:#?}", obj);
|
println!("{:#?}", obj);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use snafu::Snafu;
|
|
||||||
use crate::vm::vm::*;
|
use crate::vm::vm::*;
|
||||||
|
use snafu::Snafu;
|
||||||
|
|
||||||
#[derive(Snafu, Debug, Clone)]
|
#[derive(Snafu, Debug, Clone)]
|
||||||
pub enum VmError {
|
pub enum VmError {
|
||||||
MemOutOfBounds { addr: Addr, }
|
MemOutOfBounds { addr: Addr },
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T, E = VmError> = std::result::Result<T, E>;
|
pub type Result<T, E = VmError> = std::result::Result<T, E>;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ macro_rules! instructions {
|
|||||||
}
|
}
|
||||||
pub type InstOp = u16;
|
pub type InstOp = u16;
|
||||||
|
|
||||||
|
|
||||||
instructions! {
|
instructions! {
|
||||||
ADD = 0x0000,
|
ADD = 0x0000,
|
||||||
MUL = 0x0001,
|
MUL = 0x0001,
|
||||||
@@ -42,30 +41,10 @@ instructions! {
|
|||||||
pub fn inst_len(op: InstOp) -> usize {
|
pub fn inst_len(op: InstOp) -> usize {
|
||||||
match op {
|
match op {
|
||||||
// 2 bytes
|
// 2 bytes
|
||||||
INEG
|
INEG | INV | NOT | HALT | NOP => 2,
|
||||||
| INV
|
|
||||||
| NOT
|
|
||||||
| HALT
|
|
||||||
| NOP => 2,
|
|
||||||
// 4 bytes
|
// 4 bytes
|
||||||
ADD
|
ADD | MUL | DIV | MOD | AND | OR | XOR | SHL | SHR | CMPEQ | CMPLT | JMP | JZ | JNZ
|
||||||
| MUL
|
| LOAD | REGCOPY | MEMCOPY | STORE => 4,
|
||||||
| DIV
|
|
||||||
| MOD
|
|
||||||
| AND
|
|
||||||
| OR
|
|
||||||
| XOR
|
|
||||||
| SHL
|
|
||||||
| SHR
|
|
||||||
| CMPEQ
|
|
||||||
| CMPLT
|
|
||||||
| JMP
|
|
||||||
| JZ
|
|
||||||
| JNZ
|
|
||||||
| LOAD
|
|
||||||
| REGCOPY
|
|
||||||
| MEMCOPY
|
|
||||||
| STORE => 4,
|
|
||||||
// Immediates - 4+ bytes
|
// Immediates - 4+ bytes
|
||||||
STOREIMM64 => 16,
|
STOREIMM64 => 16,
|
||||||
STOREIMM32 => 8,
|
STOREIMM32 => 8,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use crate::vm::{error::*, reg::*};
|
use crate::vm::{error::*, reg::*};
|
||||||
use byteorder::{LE, ReadBytesExt};
|
use byteorder::{ReadBytesExt, LE};
|
||||||
use std::{
|
use std::{
|
||||||
ops::{Deref, DerefMut},
|
|
||||||
io::Cursor,
|
io::Cursor,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
const R1_MASK: u16 = 0b1111_1100_0000_0000;
|
const R1_MASK: u16 = 0b1111_1100_0000_0000;
|
||||||
@@ -15,7 +15,7 @@ pub struct MemCursor<'mem> {
|
|||||||
impl<'mem> MemCursor<'mem> {
|
impl<'mem> MemCursor<'mem> {
|
||||||
pub fn new(mem: &'mem [u8]) -> Self {
|
pub fn new(mem: &'mem [u8]) -> Self {
|
||||||
MemCursor {
|
MemCursor {
|
||||||
cursor: Cursor::new(mem)
|
cursor: Cursor::new(mem),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
use snafu::Snafu;
|
use snafu::Snafu;
|
||||||
use std::{
|
use std::{fmt::Debug, io};
|
||||||
fmt::Debug,
|
|
||||||
io,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Snafu)]
|
#[derive(Debug, Snafu)]
|
||||||
pub enum AssembleError {
|
pub enum AssembleError {
|
||||||
#[snafu(display("IO error: {}", source))]
|
#[snafu(display("IO error: {}", source))]
|
||||||
Io { source: io::Error },
|
Io { source: io::Error },
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[snafu(display("duplicate symbol name: {}", name))]
|
#[snafu(display("duplicate symbol name: {}", name))]
|
||||||
DuplicateSymbol { name: String },
|
DuplicateSymbol { name: String },
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
pub mod assemble;
|
pub mod assemble;
|
||||||
pub mod syn;
|
|
||||||
pub mod obj;
|
pub mod obj;
|
||||||
|
pub mod syn;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
use crate::vm::obj::syn::error::{ParseError, Result};
|
||||||
use byteorder::{ReadBytesExt, LE};
|
use byteorder::{ReadBytesExt, LE};
|
||||||
use crate::vm::obj::syn::error::{Result, ParseError};
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
convert::{TryFrom, TryInto},
|
convert::{TryFrom, TryInto},
|
||||||
@@ -27,7 +27,7 @@ impl Object {
|
|||||||
let section_count = cursor.read_u32::<LE>()?;
|
let section_count = cursor.read_u32::<LE>()?;
|
||||||
|
|
||||||
let mut sections = Vec::new();
|
let mut sections = Vec::new();
|
||||||
for _ in 0 .. section_count {
|
for _ in 0..section_count {
|
||||||
let section = Section::from_bytes(&mut cursor)?;
|
let section = Section::from_bytes(&mut cursor)?;
|
||||||
sections.push(section);
|
sections.push(section);
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ impl Section {
|
|||||||
let start = cursor.position() as usize;
|
let start = cursor.position() as usize;
|
||||||
let end = start + len as usize;
|
let end = start + len as usize;
|
||||||
|
|
||||||
let bytes = &cursor.get_ref()[start .. end];
|
let bytes = &cursor.get_ref()[start..end];
|
||||||
let kind: SectionKind = cursor.read_u8()?.try_into()?;
|
let kind: SectionKind = cursor.read_u8()?.try_into()?;
|
||||||
match kind {
|
match kind {
|
||||||
SectionKind::Data => Section::data_section_from_bytes(bytes),
|
SectionKind::Data => Section::data_section_from_bytes(bytes),
|
||||||
@@ -131,7 +131,7 @@ impl Section {
|
|||||||
let mut cursor = Cursor::new(bytes);
|
let mut cursor = Cursor::new(bytes);
|
||||||
let entry_count = cursor.read_u64::<LE>()?;
|
let entry_count = cursor.read_u64::<LE>()?;
|
||||||
let mut entries = HashMap::new();
|
let mut entries = HashMap::new();
|
||||||
for _ in 0 .. entry_count {
|
for _ in 0..entry_count {
|
||||||
// key
|
// key
|
||||||
let key_len = cursor.read_u64::<LE>()?;
|
let key_len = cursor.read_u64::<LE>()?;
|
||||||
let mut key_bytes = vec![0u8; key_len as usize];
|
let mut key_bytes = vec![0u8; key_len as usize];
|
||||||
@@ -142,8 +142,6 @@ impl Section {
|
|||||||
let value = cursor.read_u64::<LE>()?;
|
let value = cursor.read_u64::<LE>()?;
|
||||||
entries.insert(key, value);
|
entries.insert(key, value);
|
||||||
}
|
}
|
||||||
Ok(Section::Meta {
|
Ok(Section::Meta { entries })
|
||||||
entries
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::vm::{reg::Reg, inst::*};
|
use crate::vm::{inst::*, reg::Reg};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum SectionBlock {
|
pub enum SectionBlock {
|
||||||
@@ -69,27 +69,27 @@ pub enum Inst {
|
|||||||
impl Inst {
|
impl Inst {
|
||||||
pub fn op(&self) -> InstOp {
|
pub fn op(&self) -> InstOp {
|
||||||
match self {
|
match self {
|
||||||
Inst::Add(_, _) => { ADD }
|
Inst::Add(_, _) => ADD,
|
||||||
Inst::Mul(_, _) => { MUL }
|
Inst::Mul(_, _) => MUL,
|
||||||
Inst::Div(_, _) => { DIV }
|
Inst::Div(_, _) => DIV,
|
||||||
Inst::Mod(_, _) => { MOD }
|
Inst::Mod(_, _) => MOD,
|
||||||
Inst::INeg(_) => { INEG }
|
Inst::INeg(_) => INEG,
|
||||||
Inst::And(_, _) => { AND }
|
Inst::And(_, _) => AND,
|
||||||
Inst::Or(_, _) => { OR }
|
Inst::Or(_, _) => OR,
|
||||||
Inst::Inv(_) => { INV }
|
Inst::Inv(_) => INV,
|
||||||
Inst::Not(_) => { NOT }
|
Inst::Not(_) => NOT,
|
||||||
Inst::Xor(_, _) => { XOR }
|
Inst::Xor(_, _) => XOR,
|
||||||
Inst::Shl(_, _) => { SHL }
|
Inst::Shl(_, _) => SHL,
|
||||||
Inst::Shr(_, _) => { SHR }
|
Inst::Shr(_, _) => SHR,
|
||||||
|
|
||||||
Inst::CmpEq(_, _) => { CMPEQ }
|
Inst::CmpEq(_, _) => CMPEQ,
|
||||||
Inst::CmpLt(_, _) => { CMPLT }
|
Inst::CmpLt(_, _) => CMPLT,
|
||||||
Inst::Jmp(_) => { JMP }
|
Inst::Jmp(_) => JMP,
|
||||||
Inst::Jz(_) => { JZ }
|
Inst::Jz(_) => JZ,
|
||||||
Inst::Jnz(_) => { JNZ }
|
Inst::Jnz(_) => JNZ,
|
||||||
|
|
||||||
Inst::Load(_, _) => { LOAD }
|
Inst::Load(_, _) => LOAD,
|
||||||
Inst::Store(_, _) => { STORE }
|
Inst::Store(_, _) => STORE,
|
||||||
Inst::StoreImm(_, imm) => {
|
Inst::StoreImm(_, imm) => {
|
||||||
if let ImmValue::Number(imm) = imm {
|
if let ImmValue::Number(imm) = imm {
|
||||||
if *imm > (u32::max_value() as u64) {
|
if *imm > (u32::max_value() as u64) {
|
||||||
@@ -101,11 +101,11 @@ impl Inst {
|
|||||||
STOREIMM64
|
STOREIMM64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Inst::MemCopy(_, _) => { MEMCOPY }
|
Inst::MemCopy(_, _) => MEMCOPY,
|
||||||
Inst::RegCopy(_, _) => { REGCOPY }
|
Inst::RegCopy(_, _) => REGCOPY,
|
||||||
|
|
||||||
Inst::Nop => { NOP }
|
Inst::Nop => NOP,
|
||||||
Inst::Halt => { HALT }
|
Inst::Halt => HALT,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
use snafu::Snafu;
|
use snafu::Snafu;
|
||||||
use std::{
|
use std::{fmt::Debug, io};
|
||||||
fmt::Debug,
|
|
||||||
io,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Snafu)]
|
#[derive(Debug, Snafu)]
|
||||||
pub enum ParseError {
|
pub enum ParseError {
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ impl Vm {
|
|||||||
next_ip = cursor.position();
|
next_ip = cursor.position();
|
||||||
let value = ($mapping)(self.get_reg(r1), self.get_reg(r2));
|
let value = ($mapping)(self.get_reg(r1), self.get_reg(r2));
|
||||||
self.set_reg(r1, value);
|
self.set_reg(r1, value);
|
||||||
}}
|
}};
|
||||||
}
|
}
|
||||||
match op {
|
match op {
|
||||||
ADD => math_inst!(|w1: u64, w2: u64| w1.wrapping_add(w2)),
|
ADD => math_inst!(|w1: u64, w2: u64| w1.wrapping_add(w2)),
|
||||||
MUL => math_inst!(|w1: u64, w2: u64| w1.wrapping_mul(w2)),
|
MUL => math_inst!(|w1: u64, w2: u64| w1.wrapping_mul(w2)),
|
||||||
DIV => math_inst!(|w1: u64, w2: u64| w1.wrapping_div(w2)),
|
DIV => math_inst!(|w1: u64, w2: u64| w1.wrapping_div(w2)),
|
||||||
MOD => math_inst!(|w1: u64, w2: u64| w1 % w2),
|
MOD => math_inst!(|w1: u64, w2: u64| w1 % w2),
|
||||||
INEG => { todo!() }
|
INEG => todo!(),
|
||||||
AND => math_inst!(|w1: u64, w2: u64| w1 & w2),
|
AND => math_inst!(|w1: u64, w2: u64| w1 & w2),
|
||||||
OR => math_inst!(|w1: u64, w2: u64| w1 | w2),
|
OR => math_inst!(|w1: u64, w2: u64| w1 | w2),
|
||||||
INV => {
|
INV => {
|
||||||
|
|||||||
Reference in New Issue
Block a user