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::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 value = match args.next() { None => { BufValue::Zeros(Rd::immediate(0)) } Some(tok @ Sexp::Atom(Atom::S(_), _)) | Some(tok @ Sexp::Atom(Atom::I(_), _)) | Some(tok @ Sexp::Atom(Atom::U(_), _)) => { BufValue::Zeros(parse_rd(tok, args.pcx)?) } Some(Sexp::Atom(Atom::QS(s), _)) => { BufValue::Chars(s) } Some(Sexp::List(list, _)) => { let mut vals = vec![]; for v in list { vals.push(parse_rd(v, args.pcx)?); } BufValue::Values(vals) } Some(other) => { return Err(CrsnError::Parse("Expected quoted string or a tuple of values".into(), other.pos().clone())); } }; BufOps::New { dst, value } } "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)); } })) }