use sexp::SourcePosition; use crate::asm::error::CrsnError; use crate::asm::instr::cond::parse_cond; use crate::asm::instr::Op; use crate::asm::parse::arg_parser::TokenParser; use crate::module::ParseRes; pub fn parse_op<'a>(mut keyword: &str, mut arg_tokens: TokenParser<'a>, spos: &SourcePosition) -> Result, CrsnError> { // Include built-in instructions let mut cond = None; if let Some(pos) = keyword.find('.') { cond = Some(parse_cond(&keyword[(pos + 1)..], spos)?); keyword = &keyword[..pos]; } if cond.is_some() && arg_tokens.pcx.state.borrow().parsing_expr { return Err(CrsnError::Parse("Conditional suffixes are not allowed in const expression".into(), spos.clone())); } for p in arg_tokens.pcx.parsers { arg_tokens = match p.parse_op(spos, keyword, arg_tokens) { Ok(ParseRes::Parsed(kind)) => return Ok(Some(Op { cond, pos: spos.clone(), kind, })), Ok(ParseRes::ParsedNone) => return Ok(None), Ok(ParseRes::Unknown(to_reuse)) => { if to_reuse.parsing_started() { return Err(CrsnError::Parse(format!("Module \"{}\" started parsing {}, but returned Unknown!", p.name(), keyword).into(), spos.clone())); } to_reuse } Err(err) => { return Err(err); } } } return Err(CrsnError::Parse(format!("Unknown instruction: {}", keyword).into(), spos.clone())); }