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::builtin::BuiltinOps; 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 builtins = [BuiltinOps::new()]; let mut cond = None; if let Some(pos) = keyword.find('.') { cond = Some(parse_cond(&keyword[(pos + 1)..], spos)?); keyword = &keyword[..pos]; } for p in builtins.iter().chain(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())); }