diff options
author | NerdyPepper <[email protected]> | 2019-03-20 15:03:05 +0000 |
---|---|---|
committer | NerdyPepper <[email protected]> | 2019-03-20 15:03:05 +0000 |
commit | 1ddd824f0e2bfaa38b3dad56808bbce951bb1b5c (patch) | |
tree | 220b66a9e14b30454a2c511497ccb146fe76468a /src | |
parent | 5385cffe564eb3ddec78eecf6ffff30bdfc49bf4 (diff) |
eva now lexes functions
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 68 |
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 @@ | |||
1 | use std::io::{ stdin, stdout }; | 1 | use std::io::{ stdin, stdout }; |
2 | use std::io::{self, Write}; | ||
2 | 3 | ||
3 | #[derive(Debug, Copy, Clone, PartialEq)] | 4 | #[derive(Debug, Copy, Clone, PartialEq)] |
4 | pub struct Operator { | 5 | pub 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)] |
13 | pub struct Function { | ||
14 | token: String, | ||
15 | relation: fn(f64) -> f64, | ||
16 | } | ||
17 | |||
18 | #[derive(Debug, Clone)] | ||
12 | pub enum Token { | 19 | pub 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 | ||
43 | impl 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 | |||
35 | fn main() { | 57 | fn 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 | ||
54 | fn lexer(input: &str) -> Result<Vec<Token>, String> { | 76 | fn 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 | ' ' => {} |