summaryrefslogtreecommitdiff
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
downloadrpn-parse-rs-b66833f6dc447906c31a1eca03bdcdfe26069a8f.tar.gz
rpn-parse-rs-b66833f6dc447906c31a1eca03bdcdfe26069a8f.tar.bz2
rpn-parse-rs-b66833f6dc447906c31a1eca03bdcdfe26069a8f.zip
feat(cs): implemented rpn
-rw-r--r--.envrc3
-rw-r--r--.gitignore14
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml6
-rw-r--r--devenv.lock100
-rw-r--r--devenv.nix48
-rw-r--r--devenv.yaml15
-rw-r--r--src/main.rs107
-rw-r--r--src/rpn.rs54
9 files changed, 354 insertions, 0 deletions
diff --git a/.envrc b/.envrc
new file mode 100644
index 0000000..894571b
--- /dev/null
+++ b/.envrc
@@ -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..."))
+}