Add assembler and execution logic

Most everything works, but there's one small bug with the execution
involving jumps - still have to figure that one out.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-02-18 17:44:41 -05:00
parent 0598bd1526
commit b0ef49bc2a
11 changed files with 788 additions and 78 deletions

View File

@@ -1,4 +1,7 @@
use crate::vm::reg::Reg;
use crate::vm::{
inst,
reg::Reg,
};
#[derive(Debug, Clone)]
pub enum SectionDef {
@@ -8,7 +11,7 @@ pub enum SectionDef {
#[derive(Debug, Clone)]
pub struct MetaSection {
pub values: Vec<MetaLine>,
pub lines: Vec<MetaLine>,
}
#[derive(Debug, Clone)]
@@ -20,10 +23,27 @@ pub struct MetaLine {
#[derive(Debug, Clone)]
pub struct DataSection {
pub name: String,
pub org: Option<SectionOrg>,
pub org: SectionOrg,
pub lines: Vec<DataLine>,
}
impl DataSection {
pub fn exports(&self) -> impl Iterator<Item=&str> {
self.lines.iter()
.filter_map(|line| if let DataLine::Export(s) = line {
Some(s.as_str())
} else {
None
})
}
pub fn len(&self) -> usize {
self.lines.iter()
.map(DataLine::len)
.sum()
}
}
#[derive(Debug, Clone)]
pub enum SectionOrg {
Start(u64),
@@ -38,6 +58,16 @@ pub enum DataLine {
Label(String),
}
impl DataLine {
pub fn len(&self) -> usize {
match self {
DataLine::ValueDef(v) => v.len(),
DataLine::Inst(i) => i.len(),
DataLine::Export(_) | DataLine::Label(_) => 0,
}
}
}
#[derive(Debug, Clone)]
pub enum ValueDef {
Int(u64),
@@ -45,6 +75,16 @@ pub enum ValueDef {
ZString(String),
}
impl ValueDef {
pub fn len(&self) -> usize {
match self {
ValueDef::Int(_) => 8,
ValueDef::String(s) => 8 + s.as_bytes().len(),
ValueDef::ZString(s) => s.as_bytes().len() + 1,
}
}
}
#[derive(Debug, Clone)]
pub enum Value {
Int(u64),
@@ -52,7 +92,34 @@ pub enum Value {
Name(String),
Here,
//Array(Vec<Value>),
//Deref(Value, Size
//Deref(Value, IntSize),
}
impl Value {
pub fn len(&self) -> usize {
match self {
// TODO : immediate int sizes
Value::Int(_) => 8,
Value::Reg(_) => 1,
Value::Name(_) => 8,
Value::Here => 8,
}
}
pub fn dest_encoding(&self) -> Option<u8> {
match self {
Value::Int(_) | Value::Name(_) | Value::Here => None,
Value::Reg(_) => Some(inst::DEST_REG),
}
}
pub fn source_encoding(&self) -> u8 {
match self {
Value::Int(_) => inst::SOURCE_IMM64,
Value::Reg(_) => inst::SOURCE_REG,
Value::Name(_) | Value::Here => inst::SOURCE_IMM64,
}
}
}
#[derive(Debug, Clone)]
@@ -80,3 +147,32 @@ pub enum Inst {
Nop,
Dump,
}
impl Inst {
pub fn len(&self) -> usize {
match self {
Inst::Add(v1, v2)
| Inst::Sub(v1, v2)
| Inst::Mul(v1, v2)
| Inst::Div(v1, v2)
| Inst::Mod(v1, v2)
| Inst::And(v1, v2)
| Inst::Or(v1, v2)
| Inst::Xor(v1, v2)
| Inst::Shl(v1, v2)
| Inst::Shr(v1, v2)
| Inst::INeg(v1, v2)
| Inst::Inv(v1, v2)
| Inst::Not(v1, v2)
| Inst::CmpEq(v1, v2)
| Inst::CmpLt(v1, v2)
| Inst::Mov(v1, v2) => { 3 + v1.len() + v2.len() }
Inst::Jmp(v)
| Inst::Jz(v)
| Inst::Jnz(v) => { 3 + v.len() }
Inst::Halt
| Inst::Nop
| Inst::Dump => { 2 }
}
}
}

View File

@@ -7,8 +7,8 @@ SectionDefs -> Vec<SectionDef>:
;
SectionDef -> SectionDef:
'DIR_META' MetaBlock { SectionDef::Meta(MetaSection { values: $2 }) }
| 'DIR_SECTION' Name MaybeSectionOrg DataBlock {
'DIR_META' MetaBlock { SectionDef::Meta(MetaSection { lines: $2 }) }
| 'DIR_SECTION' Name SectionOrg DataBlock {
SectionDef::Data(DataSection {
name: $2,
org: $3,
@@ -27,11 +27,6 @@ MetaLines -> Vec<MetaLine>:
MetaLine -> MetaLine: Name 'COLON' Value { MetaLine { name: $1, value: $3 } };
MaybeSectionOrg -> Option<SectionOrg>:
SectionOrg { Some($1) }
| { None }
;
SectionOrg -> SectionOrg:
Int { SectionOrg::Start($1) }
| Int 'DOTDOT' Int { SectionOrg::StartEnd($1, $3) }