You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
2.4 KiB
95 lines
2.4 KiB
use sexp::Sexp;
|
|
|
|
use crate::asm::data::{Mask, Rd, RdData, RdObj, Wr};
|
|
use crate::asm::parse::parse_data::{parse_rd, parse_wr};
|
|
use crate::asm::parse::ParserContext;
|
|
use crate::asm::parse::sexp_expect::expect_string_atom;
|
|
|
|
/// Utility for argument parsing
|
|
pub struct TokenParser<'a> {
|
|
orig_len: usize,
|
|
args: Vec<Sexp>,
|
|
pub pcx: &'a ParserContext<'a>,
|
|
}
|
|
|
|
impl<'a> IntoIterator for TokenParser<'a> {
|
|
type Item = Sexp;
|
|
type IntoIter = std::vec::IntoIter<Sexp>;
|
|
|
|
fn into_iter(mut self) -> Self::IntoIter {
|
|
// The vec is reversed so we can call "pop", but here we will iterate it as slice so it
|
|
// must be reversed to its original direction.
|
|
self.args.reverse();
|
|
self.args.into_iter()
|
|
}
|
|
}
|
|
|
|
impl<'a> TokenParser<'a> {
|
|
/// Create a new argument parser
|
|
pub fn new(mut args: Vec<Sexp>, pcx: &'a ParserContext) -> Self {
|
|
args.reverse();
|
|
Self {
|
|
orig_len: args.len(),
|
|
args,
|
|
pcx,
|
|
}
|
|
}
|
|
|
|
pub fn have_more(&self) -> bool {
|
|
self.len() > 0
|
|
}
|
|
|
|
/// Get remaining items count
|
|
pub fn len(&self) -> usize {
|
|
self.args.len()
|
|
}
|
|
|
|
/// Get len before parsing started
|
|
pub fn orig_len(&self) -> usize {
|
|
self.orig_len
|
|
}
|
|
|
|
/// Check if parsing started
|
|
pub fn parsing_started(&self) -> bool {
|
|
self.args.len() != self.orig_len
|
|
}
|
|
|
|
/// Get the next entry
|
|
pub fn next(&mut self) -> Option<Sexp> {
|
|
self.args.pop()
|
|
}
|
|
|
|
/// Look at the next entry
|
|
pub fn peek(&mut self) -> Option<&Sexp> {
|
|
self.args.last()
|
|
}
|
|
|
|
/// Get the next string entry
|
|
pub fn next_string(&mut self) -> anyhow::Result<String> {
|
|
let next = self.next();
|
|
let esa = expect_string_atom(next)?;
|
|
Ok(esa)
|
|
}
|
|
|
|
/// Get the next entry as read location
|
|
pub fn next_rd(&mut self) -> anyhow::Result<Rd> {
|
|
parse_rd(self.next(), self.pcx)
|
|
}
|
|
|
|
/// Get the next entry as read location
|
|
pub fn next_rdobj(&mut self) -> anyhow::Result<RdObj> {
|
|
match parse_rd(self.next(), self.pcx)? {
|
|
Rd(RdData::ObjectPtr(reg), Mask::FULL) => {
|
|
return Ok(RdObj::new(reg));
|
|
}
|
|
other => {
|
|
anyhow::bail!("Not a valid object handle syntax: {:?}", other);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Get the next entry as write location
|
|
pub fn next_wr(&mut self) -> anyhow::Result<Wr> {
|
|
parse_wr(self.next(), self.pcx)
|
|
}
|
|
}
|
|
|