Croissant Runtime
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.
 
 
crsn/crsn/src/asm/parse/parse_instr.rs

53 lines
1.5 KiB

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<Sexp>, parsers: &[Box<dyn AsmModule>]) -> Result<Vec<Instr>, 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)
}