|
|
@ -1,12 +1,14 @@ |
|
|
|
use sexp::{Sexp, Atom}; |
|
|
|
|
|
|
|
use crate::data::{DataDisp, Rd, Wr, DstDisp, SrcDisp, reg}; |
|
|
|
|
|
|
|
use crate::error::Error; |
|
|
|
|
|
|
|
use crate::data::literal::{Addr, Label}; |
|
|
|
|
|
|
|
use std::convert::TryFrom; |
|
|
|
use std::convert::TryFrom; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use sexp::{Atom, Sexp}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use crate::data::{DataDisp, DstDisp, Rd, reg, SrcDisp, Wr}; |
|
|
|
|
|
|
|
use crate::data::literal::{Addr, Label}; |
|
|
|
|
|
|
|
use crate::error::Error; |
|
|
|
use crate::parse::sexp_expect::expect_string_atom; |
|
|
|
use crate::parse::sexp_expect::expect_string_atom; |
|
|
|
|
|
|
|
|
|
|
|
/// Parse a label
|
|
|
|
/// Parse a label
|
|
|
|
pub fn parse_label(name : Option<Sexp>) -> Result<Label, Error> { |
|
|
|
pub fn parse_label(name: Option<Sexp>) -> Result<Label, Error> { |
|
|
|
let name = expect_string_atom(name)?; |
|
|
|
let name = expect_string_atom(name)?; |
|
|
|
Ok(Label::Named(name.trim_start_matches(':').into())) |
|
|
|
Ok(Label::Named(name.trim_start_matches(':').into())) |
|
|
|
} |
|
|
|
} |
|
|
@ -24,32 +26,32 @@ pub fn parse_data_disp(tok: Option<Sexp>) -> Result<DataDisp, Error> { |
|
|
|
match &tok { |
|
|
|
match &tok { |
|
|
|
Sexp::Atom(Atom::I(val)) => { |
|
|
|
Sexp::Atom(Atom::I(val)) => { |
|
|
|
Ok(DataDisp::Immediate(unsafe { std::mem::transmute(*val) })) |
|
|
|
Ok(DataDisp::Immediate(unsafe { std::mem::transmute(*val) })) |
|
|
|
}, |
|
|
|
} |
|
|
|
Sexp::Atom(Atom::S(s)) => { |
|
|
|
Sexp::Atom(Atom::S(s)) => { |
|
|
|
if s == "_" { |
|
|
|
if s == "_" { |
|
|
|
return Ok(DataDisp::Discard); |
|
|
|
return Ok(DataDisp::Discard); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if let Some(reference) = s.strip_prefix('@') { |
|
|
|
if let Some(reference) = s.strip_prefix('@') { |
|
|
|
if reference.starts_with(|c : char| c.is_ascii_digit()) { |
|
|
|
if reference.starts_with(|c: char| c.is_ascii_digit()) { |
|
|
|
let val : u64 = parse_u64(reference)?; |
|
|
|
let val: u64 = parse_u64(reference)?; |
|
|
|
Ok(DataDisp::ImmediatePtr(Addr(val))) |
|
|
|
Ok(DataDisp::ImmediatePtr(Addr(val))) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
Ok(DataDisp::RegisterPtr(reg::parse_reg(reference)?)) |
|
|
|
Ok(DataDisp::RegisterPtr(reg::parse_reg(reference)?)) |
|
|
|
} |
|
|
|
} |
|
|
|
} else if s.starts_with(|c : char| c.is_ascii_digit()) { |
|
|
|
} else if s.starts_with(|c: char| c.is_ascii_digit()) { |
|
|
|
Ok(DataDisp::Immediate(unsafe { std::mem::transmute(parse_i64(s)?) })) |
|
|
|
Ok(DataDisp::Immediate(unsafe { std::mem::transmute(parse_i64(s)?) })) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
Ok(DataDisp::Register(reg::parse_reg(s)?)) |
|
|
|
Ok(DataDisp::Register(reg::parse_reg(s)?)) |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
_ => { |
|
|
|
_ => { |
|
|
|
Err(Error::Parse(format!("bad data disp: {:?}", tok).into())) |
|
|
|
Err(Error::Parse(format!("bad data disp: {:?}", tok).into())) |
|
|
|
}, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn parse_u64(literal : &str) -> anyhow::Result<u64> { |
|
|
|
pub fn parse_u64(literal: &str) -> anyhow::Result<u64> { |
|
|
|
if let Some(hex) = literal.strip_prefix("0x") { |
|
|
|
if let Some(hex) = literal.strip_prefix("0x") { |
|
|
|
Ok(u64::from_str_radix(hex, 16)?) |
|
|
|
Ok(u64::from_str_radix(hex, 16)?) |
|
|
|
} else if let Some(hex) = literal.strip_prefix("0b") { |
|
|
|
} else if let Some(hex) = literal.strip_prefix("0b") { |
|
|
@ -59,7 +61,7 @@ pub fn parse_u64(literal : &str) -> anyhow::Result<u64> { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn parse_i64(literal : &str) -> anyhow::Result<i64> { |
|
|
|
pub fn parse_i64(literal: &str) -> anyhow::Result<i64> { |
|
|
|
if let Some(_value) = literal.strip_prefix("-") { |
|
|
|
if let Some(_value) = literal.strip_prefix("-") { |
|
|
|
Ok(-1 * i64::try_from(parse_u64(literal)?)?) |
|
|
|
Ok(-1 * i64::try_from(parse_u64(literal)?)?) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|