init
This commit is contained in:
parent
ea374f5607
commit
9853da6332
|
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
/history.txt
|
||||
|
|
@ -0,0 +1,320 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
version = "4.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4ea1881992efc993e4dc50a324cdbd03216e41bdc8385720ff47efc9bd2ca8"
|
||||
dependencies = [
|
||||
"error-code",
|
||||
"str-buf",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-next"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"dirs-sys-next",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys-next"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "endian-type"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
|
||||
|
||||
[[package]]
|
||||
name = "error-code"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5115567ac25674e0043e472be13d14e537f37ea8aa4bdc4aef0c89add1db1ff"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"str-buf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fd-lock"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0010f02effd88c702318c5dde0463206be67495d0b4d906ba7c0a8f166cc7f06"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "nibble_vec"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "radix_trie"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd"
|
||||
dependencies = [
|
||||
"endian-type",
|
||||
"nibble_vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustyline"
|
||||
version = "8.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbd4eaf7a7738f76c98e4f0395253ae853be3eb018f7b0bb57fe1b6c17e31874"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"clipboard-win",
|
||||
"dirs-next",
|
||||
"fd-lock",
|
||||
"libc",
|
||||
"log",
|
||||
"memchr",
|
||||
"nix",
|
||||
"radix_trie",
|
||||
"scopeguard",
|
||||
"smallvec",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
"utf8parse",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sangnak"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"rustyline",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
|
||||
|
||||
[[package]]
|
||||
name = "str-buf"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "sangnak"
|
||||
version = "0.1.0"
|
||||
authors = ["Piyush Mishra <piyush.raj.kit@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rustyline = "8.2.0"
|
||||
clap = "2.33.3"
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# Sangnak
|
||||
|
||||
It is a a simple command line calculator.
|
||||
|
||||
### Features
|
||||
|
||||
* Parsing and claculating expressions
|
||||
* Support for brackets
|
||||
* It have a shell
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
|
||||
mod solve;
|
||||
|
||||
use clap::{Arg, App};
|
||||
|
||||
use rustyline::error::ReadlineError;
|
||||
use rustyline::Editor;
|
||||
|
||||
fn start_shell() {
|
||||
let mut rl = Editor::<()>::new();
|
||||
rl.load_history("history.txt").unwrap_or(());
|
||||
loop {
|
||||
let readline = rl.readline("\x1b[1;32m>>\x1b[1;97m ");
|
||||
match readline {
|
||||
Ok(line) => {
|
||||
rl.add_history_entry(line.as_str());
|
||||
if line == "quit" || line == "exit" {
|
||||
break;
|
||||
}
|
||||
|
||||
if let Ok(out) = solve::solve(&line) {
|
||||
println!("{}", out);
|
||||
}
|
||||
},
|
||||
Err(ReadlineError::Interrupted) => {
|
||||
println!("CTRL-C");
|
||||
break
|
||||
},
|
||||
Err(ReadlineError::Eof) => {
|
||||
println!("CTRL-D");
|
||||
break
|
||||
},
|
||||
Err(err) => {
|
||||
println!("Error: {:?}", err);
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
rl.save_history("history.txt").unwrap();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let matches = App::new("Calculator")
|
||||
.version("0.1.0")
|
||||
.author("Piyush Mishra <piyush.raj.kit@gmail.com>")
|
||||
.about("Calculate with expression")
|
||||
.arg(Arg::with_name("expression")
|
||||
.short("e")
|
||||
.long("expr")
|
||||
.value_name("EXPRESSION")
|
||||
.help("Expression to calculate")
|
||||
.takes_value(true))
|
||||
.get_matches();
|
||||
|
||||
match matches.value_of("expression") {
|
||||
Some(exp) => {
|
||||
if let Ok(out) = solve::solve(exp) {
|
||||
println!("{}", out);
|
||||
}
|
||||
}, None => start_shell()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
use std::fmt;
|
||||
use std::error::Error;
|
||||
|
||||
use Khand::*;
|
||||
use Opr::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Khand {
|
||||
NUM(f64),
|
||||
OPR(Opr),
|
||||
NIL
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Opr {
|
||||
DIV,
|
||||
MUL,
|
||||
ADD,
|
||||
SUB
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WorngStatementError;
|
||||
|
||||
impl fmt::Display for WorngStatementError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "SuperError is here!")
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for WorngStatementError {}
|
||||
|
||||
pub fn solve(exp: &str) -> Result<f64, WorngStatementError> {
|
||||
let chars = exp.replace(" ", "").chars().collect::<Vec<char>>();
|
||||
|
||||
match solve_expression(&chars, None) {
|
||||
Ok((out, _)) => Ok(out),
|
||||
Err(err) => Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
fn solve_expression(exp: &Vec<char>, start: Option<usize>) -> Result<(f64, usize), WorngStatementError> {
|
||||
// println!("start: {:?}", start);
|
||||
let mut khand: Vec<Khand> = Vec::new();
|
||||
|
||||
let mut div: Vec<usize> = Vec::new();
|
||||
let mut mul: Vec<usize> = Vec::new();
|
||||
let mut add: Vec<usize> = Vec::new();
|
||||
let mut sub: Vec<usize> = Vec::new();
|
||||
|
||||
let mut buf = String::new();
|
||||
let mut index: usize = start.unwrap_or(0);
|
||||
while index < exp.len() {
|
||||
let chr = exp[index];
|
||||
// println!("LOOP: ({}) {:?}", chr, khand);
|
||||
|
||||
let is_part_of_number = ('0' <= chr && chr <= '9') || (buf.len() > 0 && chr == '.');
|
||||
if is_part_of_number {
|
||||
buf.push(chr);
|
||||
// println!(" BUF: {}", buf);
|
||||
}
|
||||
|
||||
if (!is_part_of_number || (index+1 >= exp.len())) && buf.len() > 0 {
|
||||
match buf.parse::<f64>() {
|
||||
Ok(num) => khand.push(NUM(num)),
|
||||
Err(_) => return Err(WorngStatementError)
|
||||
}
|
||||
buf = String::new();
|
||||
}
|
||||
|
||||
if chr == '(' {
|
||||
let (out,i) = solve_expression(exp, Some(index +1))?;
|
||||
khand.push(NUM(out));
|
||||
index = i;
|
||||
} else if chr == ')' && start.is_some() {
|
||||
break;
|
||||
}
|
||||
|
||||
match chr {
|
||||
'/' => {
|
||||
div.push(khand.len());
|
||||
khand.push(OPR(DIV));
|
||||
},
|
||||
'*' => {
|
||||
mul.push(khand.len());
|
||||
khand.push(OPR(MUL));
|
||||
},
|
||||
'+' => {
|
||||
add.push(khand.len());
|
||||
khand.push(OPR(ADD));
|
||||
},
|
||||
'-' => {
|
||||
sub.push(khand.len());
|
||||
khand.push(OPR(SUB));
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
index += 1;
|
||||
}
|
||||
|
||||
// println!("AFTER LOOP: {:?}", khand);
|
||||
|
||||
for i in div {
|
||||
let (left, left_index) = get_left(&khand, i)?;
|
||||
let (right, right_index) = get_right(&khand, i)?;
|
||||
khand[i] = NUM(left/right);
|
||||
khand[left_index] = NIL;
|
||||
khand[right_index] = NIL;
|
||||
// println!("DIV: {:?}", khand);
|
||||
}
|
||||
|
||||
for i in mul {
|
||||
let (left, left_index) = get_left(&khand, i)?;
|
||||
let (right, right_index) = get_right(&khand, i)?;
|
||||
khand[i] = NUM(left*right);
|
||||
khand[left_index] = NIL;
|
||||
khand[right_index] = NIL;
|
||||
// println!("MUL: {:?}", khand);
|
||||
}
|
||||
|
||||
for i in add {
|
||||
let (left, left_index) = get_left(&khand, i)?;
|
||||
let (right, right_index) = get_right(&khand, i)?;
|
||||
khand[i] = NUM(left+right);
|
||||
khand[left_index] = NIL;
|
||||
khand[right_index] = NIL;
|
||||
// println!("ADD: {:?}", khand);
|
||||
}
|
||||
|
||||
for i in sub {
|
||||
let (left, left_index) = get_left(&khand, i)?;
|
||||
let (right, right_index) = get_right(&khand, i)?;
|
||||
khand[i] = NUM(left-right);
|
||||
khand[left_index] = NIL;
|
||||
khand[right_index] = NIL;
|
||||
// println!("SUB: {:?}", khand);
|
||||
}
|
||||
|
||||
// println!("CLOSING: {}", get_right(&khand, 0)?.0);
|
||||
Ok((get_right(&khand, 0)?.0, index))
|
||||
}
|
||||
|
||||
fn get_left(khand: &Vec<Khand>, i: usize) -> Result<(f64, usize), WorngStatementError> {
|
||||
if khand.len() == 1 {
|
||||
match khand[0] {
|
||||
NUM(num) => return Ok((num, i)),
|
||||
_ => return Err(WorngStatementError)
|
||||
}
|
||||
}
|
||||
|
||||
let mut i = i;
|
||||
loop {
|
||||
i -= 1;
|
||||
if let NUM(num) = match khand.get(i) {
|
||||
Some(num) => num,
|
||||
None => return Err(WorngStatementError)
|
||||
} {
|
||||
return Ok((*num, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn get_right(khand: &Vec<Khand>, i: usize) -> Result<(f64, usize), WorngStatementError> {
|
||||
if khand.len() == 1 {
|
||||
match khand[0] {
|
||||
NUM(num) => return Ok((num, i)),
|
||||
_ => return Err(WorngStatementError)
|
||||
}
|
||||
}
|
||||
|
||||
let mut i = i;
|
||||
loop {
|
||||
i += 1;
|
||||
if let NUM(num) = match khand.get(i) {
|
||||
Some(num) => num,
|
||||
None => return Err(WorngStatementError)
|
||||
} {
|
||||
return Ok((*num, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue