You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
42 lines
1.5 KiB
42 lines
1.5 KiB
5 years ago
|
use crate::parse::sexp_expect::{expect_list, expect_string_atom};
|
||
|
use sexp::Sexp;
|
||
|
use crate::instr::{Cond, Instr};
|
||
|
use crate::error::Error;
|
||
|
use crate::parse::parse_instr::parse_instructions;
|
||
|
use crate::patches::TryRemove;
|
||
|
|
||
|
pub fn parse_cond_branch(tok: Sexp) -> Result<(Cond, Vec<Instr>), 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<Cond, Error> {
|
||
|
Ok(match text.trim_end_matches('?') {
|
||
|
"eq" | "=" | "==" => Cond::Equal,
|
||
|
"ne" | "<>" | "!=" | "≠" => Cond::NotEqual,
|
||
|
"z" | "0" => Cond::Zero,
|
||
|
"nz" | "<>0" | "!0" => Cond::NotZero,
|
||
|
"lt" | "<" => Cond::Less,
|
||
|
"le" | "<=" | "≤" => Cond::LessOrEqual,
|
||
|
"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()));
|
||
|
}
|
||
|
})
|
||
|
}
|