feat: add parsing for push
This commit is contained in:
parent
45ed7b2ba4
commit
9c2170299c
|
@ -6,11 +6,24 @@ use std::collections::{HashMap, BTreeMap, VecDeque};
|
||||||
|
|
||||||
use ponderosa::state::{Land, Rule};
|
use ponderosa::state::{Land, Rule};
|
||||||
|
|
||||||
|
macro_rules! assert_argument_count {
|
||||||
|
($tokens:expr, $count:expr) => {
|
||||||
|
if $tokens.len() < $count {
|
||||||
|
return Err("Too few arguments".to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
if $tokens.len() > $count {
|
||||||
|
return Err("Too many arguments".to_owned());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_number(string: &str) -> u16 {
|
fn parse_number(string: &str) -> u16 {
|
||||||
string.parse::<u16>().unwrap()
|
string.parse::<u16>().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stack_bit(c: char) -> Result<u16, String> {
|
fn stack_bit(token: &String) -> Result<u16, String> {
|
||||||
|
let c = token.as_bytes()[0] as char;
|
||||||
match c {
|
match c {
|
||||||
'r' => Ok(0),
|
'r' => Ok(0),
|
||||||
't' => Ok(1),
|
't' => Ok(1),
|
||||||
|
@ -18,27 +31,42 @@ fn stack_bit(c: char) -> Result<u16, String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_binary_math_format<'a>(tokens: &Vec<String>, opcode: u16, signed: bool) -> Result<u16, String> {
|
fn parse_unary_math_format<'a>(tokens: &Vec<String>, opcode: u16, signed: bool) -> Result<u16, String> {
|
||||||
if tokens.len() < 4 { Err("Too few arguments".to_owned()) }
|
assert_argument_count!(tokens, 4);
|
||||||
else if tokens.len() > 4 { Err("Too many arguments".to_owned()) }
|
|
||||||
else {
|
|
||||||
let left_parse = stack_bit(tokens[1].as_bytes()[0] as char);
|
|
||||||
let right_parse = stack_bit(tokens[2].as_bytes()[0] as char);
|
|
||||||
let dest_parse = stack_bit(tokens[3].as_bytes()[0] as char);
|
|
||||||
|
|
||||||
match (left_parse, right_parse, dest_parse) {
|
let src = stack_bit(&tokens[1])?;
|
||||||
(Ok(left), Ok(right), Ok(dest)) => Ok(
|
let dest = stack_bit(&tokens[2])?;
|
||||||
opcode << 11 &
|
|
||||||
left << 10 &
|
Ok(opcode<<11 & src<<9 & dest<<8 & (signed as u16)<<7)
|
||||||
right << 9 &
|
}
|
||||||
dest << 8 &
|
|
||||||
(signed as u16) << 7
|
fn parse_binary_math_format<'a>(tokens: &Vec<String>, opcode: u16, signed: bool) -> Result<u16, String> {
|
||||||
),
|
assert_argument_count!(tokens, 4);
|
||||||
(Err(e), _, _) => Err(e),
|
|
||||||
(_, Err(e), _) => Err(e),
|
let left = stack_bit(&tokens[1])?;
|
||||||
(_, _, Err(e)) => Err(e),
|
let right = stack_bit(&tokens[2])?;
|
||||||
}
|
let dest = stack_bit(&tokens[3])?;
|
||||||
|
|
||||||
|
Ok(opcode<<11 & left<<10 & right<<9 & dest<<8 & (signed as u16)<<7)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_push(tokens: &Vec<String>, opcode: u16, signed: bool) -> Result<u16, String> {
|
||||||
|
assert_argument_count!(tokens, 3);
|
||||||
|
|
||||||
|
let dest = stack_bit(&tokens[1])?;
|
||||||
|
let signed_immediate = tokens[2].parse::<i16>()
|
||||||
|
.map_err(|_| format!("Cannot parse number: {t}", t=tokens[2]))?;
|
||||||
|
|
||||||
|
let unsigned_immediate = tokens[2].parse::<u16>()
|
||||||
|
.map_err(|_| format!("Cannot parse number: {t}", t=tokens[2]))?;
|
||||||
|
|
||||||
|
let immediate = if signed { signed_immediate as u16 } else { unsigned_immediate };
|
||||||
|
|
||||||
|
if immediate > 511 {
|
||||||
|
return Err("Cannot push number larger than 511 due to bit width limitations".to_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(opcode<<11 & dest<<10 & (signed as u16) << 9 & immediate)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
fn main() -> io::Result<()> {
|
||||||
|
|
Loading…
Reference in New Issue