aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs68
1 files changed, 55 insertions, 13 deletions
diff --git a/src/main.rs b/src/main.rs
index aaf285d..8f0d4e6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,5 @@
1use std::io::{ stdin, stdout }; 1use std::io::{ stdin, stdout };
2use std::io::{self, Write};
2 3
3#[derive(Debug, Copy, Clone, PartialEq)] 4#[derive(Debug, Copy, Clone, PartialEq)]
4pub struct Operator { 5pub struct Operator {
@@ -8,10 +9,17 @@ pub struct Operator {
8 is_left_associative: bool, 9 is_left_associative: bool,
9} 10}
10 11
11#[derive(Debug, Copy, Clone)] 12#[derive(Debug, Clone, PartialEq)]
13pub struct Function {
14 token: String,
15 relation: fn(f64) -> f64,
16}
17
18#[derive(Debug, Clone)]
12pub enum Token { 19pub enum Token {
13 Operator(Operator), 20 Operator(Operator),
14 Num(f64), 21 Num(f64),
22 Function(Function),
15 LParen, 23 LParen,
16 RParen 24 RParen
17} 25}
@@ -32,6 +40,20 @@ impl Operator {
32 } 40 }
33} 41}
34 42
43impl Function {
44 fn token_from_fn(token: String, relation: fn(f64) -> f64) -> Token {
45 Token::Function(
46 Function {
47 token,
48 relation
49 }
50 )
51 }
52 fn apply(self, arg: f64) -> f64 {
53 (self.relation)(arg)
54 }
55}
56
35fn main() { 57fn main() {
36 loop { 58 loop {
37 let mut input = String::new(); 59 let mut input = String::new();
@@ -47,26 +69,34 @@ fn main() {
47 let lexed = lexer(&input[..]); 69 let lexed = lexer(&input[..]);
48 let postfixed = to_postfix(lexed.unwrap()); 70 let postfixed = to_postfix(lexed.unwrap());
49 let evaled = eval_postfix(postfixed.unwrap()); 71 let evaled = eval_postfix(postfixed.unwrap());
50 println!("{}", evaled.unwrap()); 72 println!("ans: {}", evaled.unwrap());
51 } 73 }
52} 74}
53 75
54fn lexer(input: &str) -> Result<Vec<Token>, String> { 76fn lexer(input: &str) -> Result<Vec<Token>, String> {
55 let mut num_vec: String = String::new(); 77 let mut num_vec: String = String::new();
78 let mut char_vec: String = String::new();
56 let mut result: Vec<Token> = vec![]; 79 let mut result: Vec<Token> = vec![];
57 for letter in input.chars() { 80 for letter in input.chars() {
58 match letter { 81 match letter {
59 '0'...'9' | '.' => { 82 '0'...'9' | '.' => {
60 num_vec.push(letter); 83 num_vec.push(letter);
61 }, 84 },
85 'a'...'z' | 'A'...'Z' => {
86 let parse_num = num_vec.parse::<f64>().ok();
87 if let Some(x) = parse_num {
88 result.push(Token::Num(x));
89 result.push(Operator::token_from_op('*', |x, y| x * y, 3, true));
90 num_vec.clear();
91 }
92 char_vec.push(letter);
93 },
62 '+' | '-' | '/' | '*' | '^' => { 94 '+' | '-' | '/' | '*' | '^' => {
63 // parse num buf
64 let parse_num = num_vec.parse::<f64>().ok(); 95 let parse_num = num_vec.parse::<f64>().ok();
65 if let Some(x) = parse_num { 96 if let Some(x) = parse_num {
66 result.push(Token::Num(x)); 97 result.push(Token::Num(x));
67 num_vec.clear(); 98 num_vec.clear();
68 } 99 }
69 // finish
70 let operator_token: Token = match letter { 100 let operator_token: Token = match letter {
71 '+' => Operator::token_from_op('+', |x, y| x + y, 2, true), 101 '+' => Operator::token_from_op('+', |x, y| x + y, 2, true),
72 '-' => Operator::token_from_op('-', |x, y| x - y, 2, true), 102 '-' => Operator::token_from_op('-', |x, y| x - y, 2, true),
@@ -78,13 +108,28 @@ fn lexer(input: &str) -> Result<Vec<Token>, String> {
78 result.push(operator_token); 108 result.push(operator_token);
79 }, 109 },
80 '(' => { 110 '(' => {
81 // parse num buf 111 if char_vec.len() > 0 {
82 let parse_num = num_vec.parse::<f64>().ok(); 112 let funct = char_vec.clone();
83 if let Some(x) = parse_num { 113 match &funct[..] {
84 result.push(Token::Num(x)); 114 "sin" | "sine" => result.push(Function::token_from_fn("sin".into(), |x| x.sin())),
85 result.push(Operator::token_from_op('*', |x, y| x * y, 3, true)); 115 "cos" | "cosine" => result.push(Function::token_from_fn("cos".into(), |x| x.cos())),
86 num_vec.clear(); 116 "tan" | "tangent" => result.push(Function::token_from_fn("tan".into(), |x| x.tan())),
117 "csc" | "cosec" => result.push(Function::token_from_fn("csc".into(), |x| 1f64 / x.sin())),
118 "sec" | "secant" => result.push(Function::token_from_fn("sec".into(), |x| 1f64 / x.cos())),
119 "cot" | "cotangent" => result.push(Function::token_from_fn("cot".into(), |x| 1f64 / x.tan())),
120 "ln" => result.push(Function::token_from_fn("ln".into(), |x| x.ln())),
121 _ => {}
122 }
123 char_vec.clear();
124 } else {
125 let parse_num = num_vec.parse::<f64>().ok();
126 if let Some(x) = parse_num {
127 result.push(Token::Num(x));
128 result.push(Operator::token_from_op('*', |x, y| x * y, 3, true));
129 num_vec.clear();
130 }
87 } 131 }
132
88 if let Some(x) = result.last() { 133 if let Some(x) = result.last() {
89 match x { 134 match x {
90 Token::RParen => { 135 Token::RParen => {
@@ -93,17 +138,14 @@ fn lexer(input: &str) -> Result<Vec<Token>, String> {
93 _ => {} 138 _ => {}
94 }; 139 };
95 } 140 }
96 // finish
97 result.push(Token::LParen); 141 result.push(Token::LParen);
98 }, 142 },
99 ')' => { 143 ')' => {
100 // parse num buf
101 let parse_num = num_vec.parse::<f64>().ok(); 144 let parse_num = num_vec.parse::<f64>().ok();
102 if let Some(x) = parse_num { 145 if let Some(x) = parse_num {
103 result.push(Token::Num(x)); 146 result.push(Token::Num(x));
104 num_vec.clear(); 147 num_vec.clear();
105 } 148 }
106 // finish
107 result.push(Token::RParen); 149 result.push(Token::RParen);
108 } 150 }
109 ' ' => {} 151 ' ' => {}