use sexp::Sexp; use crate::error::Error; use crate::instr::{Cond, Instr}; use crate::parse::parse_instr::parse_instructions; use crate::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::patches::TryRemove; pub fn parse_cond_branch(tok: Sexp) -> Result<(Cond, Vec), Error> { let mut list = expect_list(Some(tok), false)?; let kw = expect_string_atom(list.try_remove(0))?; if !kw.ends_with('?') { return Err(Error::Parse(format!("Condition must end with '?': {}", kw).into())); } Ok((parse_cond(&kw)?, parse_instructions(list)?)) } pub fn parse_cond(text: &str) -> Result { Ok(match text.trim_end_matches('?') { "eq" | "=" | "==" => Cond::Equal, "ne" | "<>" | "!=" | "≠" => Cond::NotEqual, "z" | "0" => Cond::Zero, "nz" | "<>0" | "!0" => Cond::NotZero, "lt" | "<" => Cond::Lower, "le" | "<=" | "≤" => Cond::LowerOrEqual, "gt" | ">" => Cond::Greater, "ge" | ">=" | "≥" => Cond::GreaterOrEqual, "pos" | "+" | ">0" => Cond::Positive, "neg" | "-" | "<0" => Cond::Negative, "npos" | "!+" | "0-" | "<=0" | "≥0" => Cond::NonPositive, "nneg" | "!-" | "0+" | ">=0" | "≤0" => Cond::NonNegative, "ov" | "^" => Cond::Overflow, "c" => Cond::Carry, "nc" | "!c" => Cond::NotCarry, "nov" | "!ov" | "!^" => Cond::NotOverflow, _ => { return Err(Error::Parse(format!("Unknown cond: {}", text).into())); } }) }