use crsn::asm::error::CrsnError; use crsn::asm::instr::op::OpKind; use crsn::asm::parse::arg_parser::TokenParser; use crsn::module::ParseRes; use crsn::sexp::{SourcePosition, Sexp, Atom}; use crate::defs::{BufOps, BufValue}; use crsn::asm::data::Rd; use crsn::sexp; use crsn::asm::parse::parse_data::parse_rd; pub(crate) fn parse<'a>(_pos: &SourcePosition, keyword: &str, mut args: TokenParser<'a>) -> Result, CrsnError> { Ok(ParseRes::ext(match keyword { "mkbf" => { let dst = args.next_wr()?; let len = if args.have_more() { args.next_rd()? } else { Rd::immediate(0) }; BufOps::New { dst, value: BufValue::Zeros(len) } } "mkbfv" => { let dst = args.next_wr()?; let next = args.next_or_err()?; match next { Sexp::Atom(Atom::QS(s), _) => { BufOps::New { dst, value: BufValue::Chars(s), } } Sexp::List(list, _) => { let mut vals = vec![]; for v in list { vals.push(parse_rd(v, args.pcx)?); } BufOps::New { dst, value: BufValue::Values(vals), } } other => { return Err(CrsnError::Parse("Expected quoted string or a tuple of values".into(), other.pos().clone())); } } } "bfrd" => { let dst = args.next_wr()?; let obj = args.next_rdobj()?; let idx = args.next_rd()?; BufOps::Read { dst, obj, idx } } "bfwr" => { let obj = args.next_rdobj()?; let idx = args.next_rd()?; let value = args.next_rd()?; BufOps::Write { obj, idx, value } } "bfsz" => { let dst = args.next_wr()?; let obj = args.next_rdobj()?; BufOps::GetLen { dst, obj } } "bfins" => { let obj = args.next_rdobj()?; let idx = args.next_rd()?; let value = args.next_rd()?; BufOps::Insert { obj, idx, value } } "bfrm" => { let dst = args.next_wr()?; let obj = args.next_rdobj()?; let idx = args.next_rd()?; BufOps::Remove { dst, obj, idx } } "bfpush" => { BufOps::Push { obj: args.next_rdobj()?, src: args.next_rd()?, } } "bfpop" => { BufOps::Pop { dst: args.next_wr()?, obj: args.next_rdobj()?, } } "bfrpush" => { BufOps::Insert { obj: args.next_rdobj()?, idx: Rd::immediate(0), value: args.next_rd()?, } } "bfrpop" => { BufOps::Remove { dst: args.next_wr()?, obj: args.next_rdobj()?, idx: Rd::immediate(0), } } "bfrsz" => { BufOps::Resize { obj: args.next_rdobj()?, len: args.next_rd()?, } } "bfrev" => { BufOps::Reverse { obj: args.next_rdobj()?, } } "bfapp" => { BufOps::AppendBuf { obj: args.next_rdobj()?, obj2: args.next_rdobj()?, } } "bfprep" => { BufOps::PrependBuf { obj: args.next_rdobj()?, obj2: args.next_rdobj()?, } } _other => { return Ok(ParseRes::Unknown(args)); } })) }