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

167 lines
4.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, BufIoMode};
use crsn::asm::data::Rd;
use crsn::asm::parse::parse_data::parse_rd;
use crsn::asm::data::literal::Value;
pub const BUF_IOMODE_STACK : Value = 1;
pub const BUF_IOMODE_REVERSE_STACK : Value = 2;
pub const BUF_IOMODE_QUEUE : Value = 3;
pub const BUF_IOMODE_REVERSE_QUEUE : Value = 4;
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::new_imm(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 }
}
"bfio" => {
let obj = args.next_rdobj()?;
let (mode, modepos) = args.next_value()?;
BufOps::SetIoMode {
obj,
mode: match mode {
BUF_IOMODE_STACK => BufIoMode::Stack,
BUF_IOMODE_REVERSE_STACK => BufIoMode::ReverseStack,
BUF_IOMODE_QUEUE => BufIoMode::Queue,
BUF_IOMODE_REVERSE_QUEUE => BufIoMode::ReverseQueue,
_ => return Err(CrsnError::Parse("Bad buffer iomode".into(), modepos))
}
}
}
"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 }
}
"bfcas" => {
let obj = args.next_rdobj()?;
let idx = args.next_rd()?;
let expected = args.next_rd()?;
let src = args.next_rd()?;
BufOps::CompareSwap { obj, idx, expected, src }
}
"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::new_imm(0),
value: args.next_rd()?,
}
}
"bfrpop" => {
BufOps::Remove {
dst: args.next_wr()?,
obj: args.next_rdobj()?,
idx: Rd::new_imm(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));
}
}))
}