|
|
|
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<ParseRes<'a, OpKind>, 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));
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
}
|