|
|
|
@ -1,25 +1,26 @@ |
|
|
|
|
use crate::instr::{lower, Op}; |
|
|
|
|
|
|
|
|
|
pub mod data; |
|
|
|
|
pub mod error; |
|
|
|
|
pub mod instr; |
|
|
|
|
pub mod parse; |
|
|
|
|
pub mod patches; |
|
|
|
|
|
|
|
|
|
use crate::instr::{Op, lower}; |
|
|
|
|
|
|
|
|
|
/// Parse a program from string and assemble a low level instruction sequence from it.
|
|
|
|
|
pub fn assemble(source : &str) -> Result<Vec<Op>, error::Error> { |
|
|
|
|
pub fn assemble(source: &str) -> Result<Vec<Op>, error::Error> { |
|
|
|
|
let parsed = parse::parse(source)?; |
|
|
|
|
Ok(lower(parsed)?) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[cfg(test)] |
|
|
|
|
mod tests { |
|
|
|
|
use crate::parse::{parse, parse_instructions}; |
|
|
|
|
use crate::instr::{HLOp, Op, Flatten, Instr, lower}; |
|
|
|
|
use crate::data::{Wr, DstDisp, Register, SrcDisp, Rd}; |
|
|
|
|
use crate::data::literal::{Addr, Label}; |
|
|
|
|
use std::sync::atomic::AtomicU32; |
|
|
|
|
|
|
|
|
|
use crate::data::{DstDisp, Rd, Register, SrcDisp, Wr}; |
|
|
|
|
use crate::data::literal::{Addr, Label}; |
|
|
|
|
use crate::instr::{Flatten, HLOp, Instr, lower, Op}; |
|
|
|
|
use crate::instr::Cond; |
|
|
|
|
use crate::parse::{parse, parse_instructions}; |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn test_parse_empty() { |
|
|
|
@ -147,11 +148,11 @@ mod tests { |
|
|
|
|
], parsed); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn parse_single_instr(src : &str) -> anyhow::Result<Instr> { |
|
|
|
|
fn parse_single_instr(src: &str) -> anyhow::Result<Instr> { |
|
|
|
|
Ok(parse_instructions(vec![sexp::parse(src)?])?.remove(0)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn parse_single_op(src : &str) -> anyhow::Result<Vec<HLOp>> { |
|
|
|
|
fn parse_single_op(src: &str) -> anyhow::Result<Vec<HLOp>> { |
|
|
|
|
let num = AtomicU32::new(0); |
|
|
|
|
Ok(parse_single_instr(src)?.flatten(&num)?) |
|
|
|
|
} |
|
|
|
@ -187,14 +188,14 @@ mod tests { |
|
|
|
|
Wr::new(DstDisp::Register(Register::Gen(0))), |
|
|
|
|
Rd::new(SrcDisp::Register(Register::Gen(0))), |
|
|
|
|
)), |
|
|
|
|
branches: None |
|
|
|
|
branches: None, |
|
|
|
|
}, |
|
|
|
|
Instr { |
|
|
|
|
op: HLOp::L(Op::Mov( |
|
|
|
|
Wr::new(DstDisp::Register(Register::Gen(1))), |
|
|
|
|
Rd::new(SrcDisp::Register(Register::Gen(2))), |
|
|
|
|
)), |
|
|
|
|
branches: None |
|
|
|
|
branches: None, |
|
|
|
|
} |
|
|
|
|
] |
|
|
|
|
), |
|
|
|
@ -206,18 +207,18 @@ mod tests { |
|
|
|
|
Wr::new(DstDisp::Register(Register::Gen(0))), |
|
|
|
|
Rd::new(SrcDisp::Register(Register::Gen(0))), |
|
|
|
|
)), |
|
|
|
|
branches: None |
|
|
|
|
branches: None, |
|
|
|
|
}, |
|
|
|
|
Instr { |
|
|
|
|
op: HLOp::L(Op::Mov( |
|
|
|
|
Wr::new(DstDisp::Register(Register::Gen(1))), |
|
|
|
|
Rd::new(SrcDisp::Register(Register::Gen(1))), |
|
|
|
|
)), |
|
|
|
|
branches: None |
|
|
|
|
branches: None, |
|
|
|
|
} |
|
|
|
|
] |
|
|
|
|
) |
|
|
|
|
]) |
|
|
|
|
]), |
|
|
|
|
} |
|
|
|
|
, parsed); |
|
|
|
|
} |
|
|
|
|