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

138 lines
3.8 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 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));
}
}))
}