Finish up parser and assembler with more-or-less complete syntax
Major changes inlude: * Bit the bullet and now instructions have their length hard-coded * Move from_utf8 object parsing to be done by their objects (instead of a Parser god object) * A list of AST sections are assembled into an Object using the new vm::obj::assemble module. * Changed the object layout some in the spec, and adjusted code to match this. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
114
src/vm/obj/syn/ast.rs
Normal file
114
src/vm/obj/syn/ast.rs
Normal file
@@ -0,0 +1,114 @@
|
||||
use crate::vm::{reg::Reg, inst::*};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum SectionBlock {
|
||||
Data {
|
||||
org: Option<SectionOrg>,
|
||||
body: Vec<Line>,
|
||||
},
|
||||
Code {
|
||||
org: Option<SectionOrg>,
|
||||
body: Vec<Line>,
|
||||
},
|
||||
Meta {
|
||||
entries: Vec<(String, ImmValue)>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum SectionOrg {
|
||||
Start(u64),
|
||||
Range(u64, u64),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Line {
|
||||
Inst(Inst),
|
||||
LabelDef(String),
|
||||
ImmValue(ImmValue),
|
||||
Export(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ImmValue {
|
||||
Number(u64),
|
||||
Label(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Inst {
|
||||
Add(Reg, Reg),
|
||||
Mul(Reg, Reg),
|
||||
Div(Reg, Reg),
|
||||
Mod(Reg, Reg),
|
||||
INeg(Reg),
|
||||
And(Reg, Reg),
|
||||
Or(Reg, Reg),
|
||||
Inv(Reg),
|
||||
Not(Reg),
|
||||
Xor(Reg, Reg),
|
||||
Shl(Reg, Reg),
|
||||
Shr(Reg, Reg),
|
||||
|
||||
CmpEq(Reg, Reg),
|
||||
CmpLt(Reg, Reg),
|
||||
Jmp(Reg),
|
||||
Jz(Reg),
|
||||
Jnz(Reg),
|
||||
|
||||
Load(Reg, Reg),
|
||||
Store(Reg, Reg),
|
||||
StoreImm(Reg, ImmValue),
|
||||
MemCopy(Reg, Reg),
|
||||
RegCopy(Reg, Reg),
|
||||
|
||||
Nop,
|
||||
Halt,
|
||||
}
|
||||
|
||||
impl Inst {
|
||||
pub fn op(&self) -> InstOp {
|
||||
match self {
|
||||
Inst::Add(_, _) => { ADD }
|
||||
Inst::Mul(_, _) => { MUL }
|
||||
Inst::Div(_, _) => { DIV }
|
||||
Inst::Mod(_, _) => { MOD }
|
||||
Inst::INeg(_) => { INEG }
|
||||
Inst::And(_, _) => { AND }
|
||||
Inst::Or(_, _) => { OR }
|
||||
Inst::Inv(_) => { INV }
|
||||
Inst::Not(_) => { NOT }
|
||||
Inst::Xor(_, _) => { XOR }
|
||||
Inst::Shl(_, _) => { SHL }
|
||||
Inst::Shr(_, _) => { SHR }
|
||||
|
||||
Inst::CmpEq(_, _) => { CMPEQ }
|
||||
Inst::CmpLt(_, _) => { CMPLT }
|
||||
Inst::Jmp(_) => { JMP }
|
||||
Inst::Jz(_) => { JZ }
|
||||
Inst::Jnz(_) => { JNZ }
|
||||
|
||||
Inst::Load(_, _) => { LOAD }
|
||||
Inst::Store(_, _) => { STORE }
|
||||
Inst::StoreImm(_, imm) => {
|
||||
if let ImmValue::Number(imm) = imm {
|
||||
if *imm > (u32::max_value() as u64) {
|
||||
STOREIMM64
|
||||
} else {
|
||||
STOREIMM32
|
||||
}
|
||||
} else {
|
||||
STOREIMM64
|
||||
}
|
||||
}
|
||||
Inst::MemCopy(_, _) => { MEMCOPY }
|
||||
Inst::RegCopy(_, _) => { REGCOPY }
|
||||
|
||||
Inst::Nop => { NOP }
|
||||
Inst::Halt => { HALT }
|
||||
}
|
||||
}
|
||||
pub fn len(&self) -> usize {
|
||||
inst_len(self.op())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user