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.
148 lines
3.9 KiB
148 lines
3.9 KiB
4 years ago
|
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<ParseRes<'a, OpKind>, 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));
|
||
|
}
|
||
|
}))
|
||
|
}
|