use sexp::Sexp; use crate::asm::error::Error; use crate::asm::instr::Instr; use crate::asm::instr::op::AsmModule; use crate::asm::parse::arg_parser::ArgParser; use crate::asm::parse::parse_cond::parse_cond_branch; use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::asm::patches::SexpIsA; use super::parse_op::parse_op; pub fn parse_instructions(instrs: Vec, parsers: &[Box]) -> Result, Error> { let mut parsed = vec![]; for expr in instrs { let tokens = expect_list(Some(expr), false)?; let mut toki = tokens.into_iter(); let mut name = expect_string_atom(toki.next())?; let far = if name == "far" { name = expect_string_atom(toki.next())?; true } else { false }; let arg_tokens = ArgParser::new(toki.clone().take_while(|e| e.is_atom()).collect()); let branch_tokens = toki .skip_while(|e| e.is_atom()) .take_while(|e| e.is_list()); let branches = { let mut branches = vec![]; for t in branch_tokens { branches.push(parse_cond_branch(t, parsers)?); } if branches.is_empty() { None } else { Some(branches) } }; parsed.push(Instr { op: parse_op(name.as_str(), far, arg_tokens, parsers)?, branches, }); } Ok(parsed) }