use sexp::Sexp; use crate::asm::data::{Rd, Wr}; use crate::asm::parse::parse_data::{parse_rd, parse_wr}; use crate::asm::parse::sexp_expect::expect_string_atom; /// Utility for argument parsing pub struct ArgParser { orig_len: usize, args: Vec, } impl IntoIterator for ArgParser { type Item = Sexp; type IntoIter = std::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.args.into_iter() } } impl ArgParser { /// Create a new argument parser pub fn new(mut args: Vec) -> Self { args.reverse(); Self { orig_len: args.len(), args, } } /// 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 { self.args.pop() } /// Get the next string entry pub fn next_string(&mut self) -> anyhow::Result { Ok(expect_string_atom(self.next())?) } /// Get the next entry as read location pub fn next_rd(&mut self) -> anyhow::Result { parse_rd(self.next()) } /// Get the next entry as write location pub fn next_wr(&mut self) -> anyhow::Result { parse_wr(self.next()) } }