summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZhongheng Liu <z.liu@outlook.com.gr>2025-01-15 23:56:23 +0200
committerZhongheng Liu <z.liu@outlook.com.gr>2025-01-15 23:56:23 +0200
commitb66833f6dc447906c31a1eca03bdcdfe26069a8f (patch)
treeaac12e2d87ea88362c50009d197d6fb4eb951781 /src
downloadrpn-parse-rs-b66833f6dc447906c31a1eca03bdcdfe26069a8f.tar.gz
rpn-parse-rs-b66833f6dc447906c31a1eca03bdcdfe26069a8f.tar.bz2
rpn-parse-rs-b66833f6dc447906c31a1eca03bdcdfe26069a8f.zip
feat(cs): implemented rpn
Diffstat (limited to 'src')
-rw-r--r--src/main.rs107
-rw-r--r--src/rpn.rs54
2 files changed, 161 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..f7fe16c
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,107 @@
+mod rpn;
+use std::{collections::HashMap, io::stdin};
+/*struct TextSettings {}
+struct Component {
+ text: String,
+ setting: TextSettings,
+}
+struct Article {
+ title: String,
+ components: Vec<Component>,
+}
+impl Display for Component {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", self.text)
+ }
+}
+impl Component {
+ fn new(text: String, setting: Option<TextSettings>) -> Component {
+ match setting {
+ Some(s) => {
+ return Component {
+ text,
+ setting: s,
+ }
+ },
+ None => {
+ return Component {
+ text,
+ setting: TextSettings {}
+ }
+ }
+ }
+ }
+}
+impl Article {
+ fn new(lines: Vec<String>) -> Article {
+ let mut components = vec![];
+ for (i, l) in lines.iter().enumerate() {
+ components.insert(i, Component::new(l.to_string(), None));
+ }
+ Article {
+ title: "article title".to_string(),
+ components,
+ }
+ }
+}
+impl Display for Article {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ let mut builder = String::from("");
+ for c in &self.components {
+ builder += &format!("{}\n", c);
+ }
+ write!(f, "{}", builder)
+ }
+}*/
+fn main() {
+ let mut vars: HashMap<char, f32> = HashMap::new();
+ println!("Input your variable mappings below, in K:char,V:f32 format, * to break;");
+ let term = stdin();
+ loop {
+ let mut s = String::new();
+ let _ = term.read_line(&mut s);
+ if s.trim() == "*" {
+ break;
+ }
+ let vals = s.trim().split_once(',');
+ if vals.is_none() {
+ println!("Format invalid!");
+ return;
+ }
+ let (k_s, v_s) = vals.unwrap();
+ println!("'{}': '{}'", k_s, v_s);
+ if k_s.chars().count() != 1 {
+ println!("Identifier must only be one character!");
+ return;
+ }
+ let k = k_s.chars().next();
+ if k.is_none() {
+ return;
+ }
+ vars.insert(k.unwrap(), v_s.parse::<f32>().unwrap());
+ }
+ println!("Great! Now put your RPN expression below");
+ let mut rpn_str = String::new();
+ let _ = term.read_line(&mut rpn_str);
+ let result = rpn::eval(rpn_str.trim().to_string(), vars);
+ match result {
+ Ok(number) => println!("Result: {}", number),
+ Err(_) => println!("Error occurred"),
+ }
+}
+/*fn _main() -> Result<(), Box<dyn Error>> {
+ println!("running main function");
+ let mut cont = true;
+ let mut lines: Vec<String> = vec![];
+ while true {
+ let mut s = String::new();
+ let input = stdin();
+ let _size = input.read_line(&mut s);
+ println!("{}", s);
+ if s.eq("stop") { break; }
+ lines.push(s);
+ }
+ let a = Article::new(lines);
+ println!("{}", a);
+ Ok(())
+}*/
diff --git a/src/rpn.rs b/src/rpn.rs
new file mode 100644
index 0000000..92272ba
--- /dev/null
+++ b/src/rpn.rs
@@ -0,0 +1,54 @@
+use std::collections::HashMap;
+
+pub enum RpnOperation {
+ Add,
+ Subtract,
+ Multiply,
+ Divide,
+}
+fn apply_op(op: RpnOperation, v1: f32, v2: f32) -> f32 {
+ match op {
+ RpnOperation::Add => v1 + v2,
+ RpnOperation::Subtract => v1 - v2,
+ RpnOperation::Multiply => v1 * v2,
+ RpnOperation::Divide => v1 / v2,
+ }
+}
+fn rpn_match_op(c: char) -> Option<RpnOperation> {
+ match c {
+ '+' => Some(RpnOperation::Add),
+ '-' => Some(RpnOperation::Subtract),
+ '/' => Some(RpnOperation::Divide),
+ '*' => Some(RpnOperation::Multiply),
+ _ => None,
+ }
+}
+pub fn eval(rpn_str: String, var_map: HashMap<char, f32>) -> Result<f32, ()> {
+ let mut stack: Vec<f32> = vec![];
+ for (_i, ch) in rpn_str.chars().enumerate() {
+ println!("Parsing: {}", ch);
+ let res = rpn_match_op(ch);
+ if res.is_none() {
+ let num = var_map.get(&ch);
+ if num.is_none() {
+ return Err(());
+ }
+ stack.push(*num.unwrap());
+ continue;
+ }
+ let v1 = stack.pop();
+ let v2 = stack.pop();
+ if v1.is_none() || v2.is_none() {
+ return Err(());
+ }
+ let num = apply_op(res.unwrap(), v1.unwrap(), v2.unwrap());
+ println!("Result tmp: {}", num);
+ stack.push(num)
+ }
+ if stack.len() != 1 {
+ return Err(());
+ }
+ Ok(stack
+ .pop()
+ .expect("Expected there to be at least 1 element left..."))
+}