AMAZING NEW FEATURES ldn, bfio

This commit is contained in:
2020-10-11 01:35:19 +02:00
parent 74e3716ce4
commit 4062ff4d09
17 changed files with 400 additions and 109 deletions
+8 -1
View File
@@ -2,9 +2,10 @@ use sexp::{Sexp, SourcePosition};
use crate::asm::data::{Rd, RdData, RdObj, Wr, RdWr};
use crate::asm::error::CrsnError;
use crate::asm::parse::parse_data::{parse_rd, parse_wr};
use crate::asm::parse::parse_data::{parse_rd, parse_wr, parse_value};
use crate::asm::parse::ParserContext;
use crate::asm::parse::sexp_expect::expect_string_atom;
use crate::asm::data::literal::Value;
/// Utility for argument parsing
#[derive(Debug)]
@@ -85,6 +86,12 @@ impl<'a> TokenParser<'a> {
Ok(esa)
}
/// Get the next value entry
pub fn next_value(&mut self) -> Result<(Value, SourcePosition), CrsnError> {
let next = self.next_or_err()?;
parse_value(next, self.pcx)
}
/// Get the next entry as read location
pub fn next_rd(&mut self) -> Result<Rd, CrsnError> {
let next = self.next_or_err()?;
+18 -11
View File
@@ -12,7 +12,7 @@ use crate::asm::patches::ErrWithPos;
fn is_valid_identifier(name: &str) -> bool {
// ascii symbols "!\"#$_&'()*+,-./:;<=>?@[\\]^_`{|}~"
const BLACKLIST : &str = "!\"#$&'()*+,-./:;<=>?@[\\]^`{|}~";
const BLACKLIST : &str = "!\"#$&'()*+,./;<=>?@[\\]^`{|}~";
name != "_"
&& !name.starts_with(|c: char| c.is_ascii_digit() || BLACKLIST.contains(c))
&& !name.contains(|c : char| c.is_whitespace() || BLACKLIST.contains(c))
@@ -161,27 +161,34 @@ pub fn parse_data_disp(tok: Sexp, pcx: &ParserContext) -> Result<DataDisp, CrsnE
}
/// Parse immediate value
pub fn parse_value(tok: Sexp, pcx: &ParserContext) -> Result<Value, CrsnError> {
pub fn parse_value(tok: Sexp, pcx: &ParserContext) -> Result<(Value, SourcePosition), CrsnError> {
match tok {
Sexp::Atom(Atom::I(val), _pos) => {
Ok(unsafe { std::mem::transmute(val) })
Sexp::Atom(Atom::I(val), pos) => {
Ok((unsafe { std::mem::transmute(val) }, pos))
}
Sexp::Atom(Atom::U(val), _pos) => {
Ok(val)
Sexp::Atom(Atom::U(val), pos) => {
Ok((val, pos))
}
Sexp::Atom(Atom::C(val), _pos) => {
Ok(val as u64)
Sexp::Atom(Atom::C(val), pos) => {
Ok((val as u64, pos))
}
Sexp::Atom(Atom::QS(_), pos) => {
Err(CrsnError::Parse("quoted string not expected here".into(), pos))
}
Sexp::Atom(Atom::F(val), _) => {
Ok(unsafe { std::mem::transmute(val) })
Sexp::Atom(Atom::F(val), pos) => {
Ok((unsafe { std::mem::transmute(val) }, pos))
}
Sexp::Atom(Atom::S(s), pos) => {
let pstate = pcx.state.borrow();
if let Some(val) = pstate.constants.get(&s) {
return Ok(*val);
return Ok((*val, pos));
}
/* extension constants */
for p in pcx.parsers {
if let Some(val) = p.get_constant_value(&s) {
return Ok((val, pos));
}
}
Err(CrsnError::Parse(format!("unknown constant: {}", s).into(), pos))
+3 -1
View File
@@ -70,8 +70,10 @@ pub enum BuiltinOp {
/// Deallocate an extension object.
/// The object is released and the handle becomes invalid.
Delete(RdObj),
/// Copy value
/// Move a value
MoveValue { dst: Wr, src: Rd },
/// Move N values
MoveMultipleValues { dst: Wr, src: Rd, count: Rd },
/// Swap two registers
SwapValues { a: RdWr, b: RdWr },
/// Store runtime status to a register
+11
View File
@@ -109,6 +109,17 @@ impl OpTrait for BuiltinOp {
state.update_status(val);
state.write(dst, val)?;
}
BuiltinOp::MoveMultipleValues { dst, src, count } => {
state.clear_status();
let mut count = state.read(count)?;
let mut last = 0;
while count > 0 {
last = state.read(src)?;
state.write(dst, last)?;
count -= 1;
}
state.update_status(last);
}
BuiltinOp::SwapValues { a, b } => {
let aa = state.read(a)?;
let bb = state.read(b)?;
+12 -2
View File
@@ -88,7 +88,7 @@ pub(crate) fn parse_op<'a>(op_pos: &SourcePosition, keyword: &str, mut args: Tok
"def" => {
let (name, namepos) = parse_constant_name(args.next_or_err()?)?;
let value = parse_value(args.next_or_err()?, pcx)?;
let (value, _valuepos) = parse_value(args.next_or_err()?, pcx)?;
let mut pstate = pcx.state.borrow_mut();
if pstate.constants.contains_key(&name) {
@@ -189,6 +189,14 @@ pub(crate) fn parse_op<'a>(op_pos: &SourcePosition, keyword: &str, mut args: Tok
}
}
"ldn" => {
BuiltinOp::MoveMultipleValues {
dst: args.next_wr()?,
src: args.next_rd()?,
count: args.next_rd()?,
}
}
"swap" => {
BuiltinOp::SwapValues {
a: args.next_rdwr()?,
@@ -309,7 +317,8 @@ pub(crate) fn to_sexp(op: &BuiltinOp) -> Sexp {
}
BuiltinOp::Delete(obj) => sexp::list(&[A("del"), A(obj)]),
BuiltinOp::MoveValue { dst, src } => sexp::list(&[A("ld"), A(dst), A(src)]),
BuiltinOp::SwapValues { a, b } => sexp::list(&[A("swp"), A(a), A(b)]),
BuiltinOp::MoveMultipleValues { dst, src, count } => sexp::list(&[A("ldn"), A(dst), A(src), A(count)]),
BuiltinOp::SwapValues { a, b } => sexp::list(&[A("swap"), A(a), A(b)]),
BuiltinOp::StoreFlags { dst } => sexp::list(&[A("stf"), A(dst)]),
BuiltinOp::LoadFlags { src } => sexp::list(&[A("ldf"), A(src)])
}
@@ -382,6 +391,7 @@ mod test {
("(ld r0 r0)", "(ld r0 r0)"),
("(ld r0 156)", "(ld r0 156)"),
("(ld _ -32767)", "(ld _ -32767)"),
("(ldn _ @r0 7)", "(ldn _ @r0 7)"),
("(stf r0)", "(stf r0)"),
("(ldf r0)", "(ldf r0)"),
("(far :label)", "(far :label)"),