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_buf/src/parse.rs

147 lines
3.9 KiB

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 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));
}
}))
}