implement a custom shunting yard algorithm for bit manipulation only
This commit is contained in:
parent
90b2087c82
commit
43457aae9f
21
src/input.rs
21
src/input.rs
@ -1,5 +1,4 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use libbitfyre::base;
|
|
||||||
|
|
||||||
use crate::{diff::{self, Compare}, eval::{eval, EvalError, EvalResult}, map::{input_error, MapDisplay}};
|
use crate::{diff::{self, Compare}, eval::{eval, EvalError, EvalResult}, map::{input_error, MapDisplay}};
|
||||||
|
|
||||||
@ -25,12 +24,16 @@ fn init_message() {
|
|||||||
|
|
||||||
pub struct Out;
|
pub struct Out;
|
||||||
impl Out {
|
impl Out {
|
||||||
|
fn binary(&self, val: i64) -> String {
|
||||||
|
format!("{:b}", val)
|
||||||
|
}
|
||||||
|
|
||||||
fn error(&self, eval_error: EvalError) {
|
fn error(&self, eval_error: EvalError) {
|
||||||
match eval_error {
|
match eval_error {
|
||||||
EvalError::I64Conversion(parse_int_error) => println!("{parse_int_error}"),
|
EvalError::I64Conversion(parse_int_error) => println!("{parse_int_error}"),
|
||||||
EvalError::InvalidOperator(invalid_op) => println!("The operator {:?} is invalid.", invalid_op),
|
EvalError::InvalidOperator(invalid_op) => println!("The operator {:?} is invalid.", invalid_op),
|
||||||
EvalError::LeftMissing => println!("Left side expression missing."),
|
|
||||||
EvalError::RightMissing => println!("Right side expression missing."),
|
EvalError::RightMissing => println!("Right side expression missing."),
|
||||||
|
EvalError::LeftMissing => println!("Left side expression missing."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,9 +41,7 @@ impl Out {
|
|||||||
let diffed_eval_chars = diffed_eval.chars().count();
|
let diffed_eval_chars = diffed_eval.chars().count();
|
||||||
let mut char_counts = [diffed_left.chars().count(), diffed_right.chars().count(), diffed_eval_chars];
|
let mut char_counts = [diffed_left.chars().count(), diffed_right.chars().count(), diffed_eval_chars];
|
||||||
char_counts.sort();
|
char_counts.sort();
|
||||||
let subtracted_count = char_counts.last().map_or(0, |biggest_len| {
|
let subtracted_count = char_counts.last().map_or(0, |biggest_len| *biggest_len-diffed_eval_chars);
|
||||||
*biggest_len-diffed_eval_chars
|
|
||||||
});
|
|
||||||
format!("{}{diffed_eval}", "0".repeat(subtracted_count))
|
format!("{}{diffed_eval}", "0".repeat(subtracted_count))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,11 +49,11 @@ impl Out {
|
|||||||
eval_out.map_or_else(|e| self.error(e), |result| {
|
eval_out.map_or_else(|e| self.error(e), |result| {
|
||||||
let mut differ = diff::Comparer::new();
|
let mut differ = diff::Comparer::new();
|
||||||
let diffed = differ.compare(Compare {
|
let diffed = differ.compare(Compare {
|
||||||
right: base::binary(result.input.right),
|
right: self.binary(result.input.right),
|
||||||
left: base::binary(result.input.left),
|
left: self.binary(result.input.left),
|
||||||
});
|
});
|
||||||
|
|
||||||
let padded_eval = self.padded(&diffed.left, &diffed.right, base::binary(result.eval));
|
let padded_eval = self.padded(&diffed.left, &diffed.right, self.binary(result.eval));
|
||||||
println!("{}", diffed.left);
|
println!("{}", diffed.left);
|
||||||
println!("{}", diffed.right);
|
println!("{}", diffed.right);
|
||||||
println!("{}", "-".repeat(padded_eval.chars().count()));
|
println!("{}", "-".repeat(padded_eval.chars().count()));
|
||||||
@ -79,7 +80,9 @@ impl Bitfyre {
|
|||||||
io::stdin().read_line(&mut input).map_or_display(|_size| match input.trim() {
|
io::stdin().read_line(&mut input).map_or_display(|_size| match input.trim() {
|
||||||
"exit" => self.terminate(None),
|
"exit" => self.terminate(None),
|
||||||
"help" => help_docs(),
|
"help" => help_docs(),
|
||||||
trim => Out.evaled(eval(trim.split_whitespace().collect()))
|
trim => {
|
||||||
|
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use input::Bitfyre;
|
use input::Bitfyre;
|
||||||
use cli::parser;
|
use cli::parser;
|
||||||
|
|
||||||
|
mod shunting_yard;
|
||||||
mod input;
|
mod input;
|
||||||
mod eval;
|
mod eval;
|
||||||
mod diff;
|
mod diff;
|
||||||
|
48
src/shunting_yard.rs
Normal file
48
src/shunting_yard.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
pub type Precision = i64;
|
||||||
|
|
||||||
|
struct ShuntingYard {
|
||||||
|
input: String,
|
||||||
|
output: Vec<String>,
|
||||||
|
stack: Vec<String>,
|
||||||
|
}
|
||||||
|
impl ShuntingYard {
|
||||||
|
pub const fn new(input: String) -> Self {
|
||||||
|
Self {
|
||||||
|
input,
|
||||||
|
output: Vec::new(),
|
||||||
|
stack: Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_operator(&mut self, value: char) -> bool {
|
||||||
|
match value {
|
||||||
|
'&' | '^' | '|' => {
|
||||||
|
self.stack.push(value.to_string());
|
||||||
|
true
|
||||||
|
},
|
||||||
|
'>' | '<' => {
|
||||||
|
if let Some(last) = self.stack.last_mut() {
|
||||||
|
match last.as_str() {
|
||||||
|
">" => *last = ">>".to_owned(),
|
||||||
|
"<" => *last = "<<".to_owned(),
|
||||||
|
_ => self.stack.push(value.to_string())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.stack.push(value.to_string())
|
||||||
|
};
|
||||||
|
true
|
||||||
|
}
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eval(&mut self) {
|
||||||
|
self.output = self.input.chars()
|
||||||
|
.collect::<Vec<char>>()
|
||||||
|
.into_iter()
|
||||||
|
.filter(|char| self.is_operator(*char))
|
||||||
|
.map(|char_num| char_num.to_string())
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user