diff options
author | Zhongheng Liu <z.liu@outlook.com.gr> | 2025-01-15 23:56:23 +0200 |
---|---|---|
committer | Zhongheng Liu <z.liu@outlook.com.gr> | 2025-01-15 23:56:23 +0200 |
commit | b66833f6dc447906c31a1eca03bdcdfe26069a8f (patch) | |
tree | aac12e2d87ea88362c50009d197d6fb4eb951781 | |
download | rpn-parse-rs-b66833f6dc447906c31a1eca03bdcdfe26069a8f.tar.gz rpn-parse-rs-b66833f6dc447906c31a1eca03bdcdfe26069a8f.tar.bz2 rpn-parse-rs-b66833f6dc447906c31a1eca03bdcdfe26069a8f.zip |
feat(cs): implemented rpn
-rw-r--r-- | .envrc | 3 | ||||
-rw-r--r-- | .gitignore | 14 | ||||
-rw-r--r-- | Cargo.lock | 7 | ||||
-rw-r--r-- | Cargo.toml | 6 | ||||
-rw-r--r-- | devenv.lock | 100 | ||||
-rw-r--r-- | devenv.nix | 48 | ||||
-rw-r--r-- | devenv.yaml | 15 | ||||
-rw-r--r-- | src/main.rs | 107 | ||||
-rw-r--r-- | src/rpn.rs | 54 |
9 files changed, 354 insertions, 0 deletions
@@ -0,0 +1,3 @@ +source_url "https://raw.githubusercontent.com/cachix/devenv/82c0147677e510b247d8b9165c54f73d32dfd899/direnvrc" "sha256-7u4iDd1nZpxL4tCzmPG0dQgC5V+/44Ba+tHkPob1v2k=" + +use devenv diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b972a7f --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Devenv +.devenv* +devenv.local.nix + +# direnv +.direnv + +# pre-commit +.pre-commit-config.yaml + + +# Added by cargo + +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..3980da4 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "rust-test" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..7c99670 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rust-test" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/devenv.lock b/devenv.lock new file mode 100644 index 0000000..3a86f3f --- /dev/null +++ b/devenv.lock @@ -0,0 +1,100 @@ +{ + "nodes": { + "devenv": { + "locked": { + "dir": "src/modules", + "lastModified": 1736426010, + "owner": "cachix", + "repo": "devenv", + "rev": "1c384bc4be3ee571511fbbc6fdc94fe47d60f6cf", + "type": "github" + }, + "original": { + "dir": "src/modules", + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1733328505, + "owner": "edolstra", + "repo": "flake-compat", + "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1733477122, + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "7bd9e84d0452f6d2e63b6e6da29fe73fac951857", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1735882644, + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "a5a961387e75ae44cc20f0a57ae463da5e959656", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/devenv.nix b/devenv.nix new file mode 100644 index 0000000..9363b5f --- /dev/null +++ b/devenv.nix @@ -0,0 +1,48 @@ +{ pkgs, lib, config, inputs, ... }: + +{ + # https://devenv.sh/basics/ + env.GREET = "devenv"; + + # https://devenv.sh/packages/ + packages = [ pkgs.git ]; + + # https://devenv.sh/languages/ + # languages.rust.enable = true; + + # https://devenv.sh/processes/ + # processes.cargo-watch.exec = "cargo-watch"; + + # https://devenv.sh/services/ + # services.postgres.enable = true; + + # https://devenv.sh/scripts/ + scripts.hello.exec = '' + echo hello from $GREET + ''; + + enterShell = '' + hello + git --version + ''; + + # https://devenv.sh/tasks/ + # tasks = { + # "myproj:setup".exec = "mytool build"; + # "devenv:enterShell".after = [ "myproj:setup" ]; + # }; + + # https://devenv.sh/tests/ + enterTest = '' + echo "Running tests" + git --version | grep --color=auto "${pkgs.git.version}" + ''; + + languages.rust = { + enable = true; + }; + # https://devenv.sh/pre-commit-hooks/ + # pre-commit.hooks.shellcheck.enable = true; + + # See full reference at https://devenv.sh/reference/options/ +} diff --git a/devenv.yaml b/devenv.yaml new file mode 100644 index 0000000..116a2ad --- /dev/null +++ b/devenv.yaml @@ -0,0 +1,15 @@ +# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json +inputs: + nixpkgs: + url: github:cachix/devenv-nixpkgs/rolling + +# If you're using non-OSS software, you can set allowUnfree to true. +# allowUnfree: true + +# If you're willing to use a package that's vulnerable +# permittedInsecurePackages: +# - "openssl-1.1.1w" + +# If you have more than one devenv you can merge them +#imports: +# - ./backend 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...")) +} |