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};
|
||||
|
||||
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 {
|
||||
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 {
|
||||
'r' => Ok(0),
|
||||
'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> {
|
||||
if tokens.len() < 4 { Err("Too few arguments".to_owned()) }
|
||||
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);
|
||||
fn parse_unary_math_format<'a>(tokens: &Vec<String>, opcode: u16, signed: bool) -> Result<u16, String> {
|
||||
assert_argument_count!(tokens, 4);
|
||||
|
||||
match (left_parse, right_parse, dest_parse) {
|
||||
(Ok(left), Ok(right), Ok(dest)) => Ok(
|
||||
opcode << 11 &
|
||||
left << 10 &
|
||||
right << 9 &
|
||||
dest << 8 &
|
||||
(signed as u16) << 7
|
||||
),
|
||||
(Err(e), _, _) => Err(e),
|
||||
(_, Err(e), _) => Err(e),
|
||||
(_, _, Err(e)) => Err(e),
|
||||
}
|
||||
let src = stack_bit(&tokens[1])?;
|
||||
let dest = stack_bit(&tokens[2])?;
|
||||
|
||||
Ok(opcode<<11 & src<<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);
|
||||
|
||||
let left = stack_bit(&tokens[1])?;
|
||||
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<()> {
|
||||
|
|
Loading…
Reference in New Issue