1 using System;
2
3 namespace Calculator
4 {
5 public Result<bool> Parse(const ustring& input)
6 {
7 Scanner scanner(input);
8 auto nextTokenResult = scanner.NextToken();
9 if (nextTokenResult.Error())
10 {
11 return nextTokenResult;
12 }
13 if (scanner.CurrentToken() is PrintToken*)
14 {
15 SymbolTable.Instance().Print();
16 return Result<bool>(true);
17 }
18 else if (scanner.CurrentToken() is VariableNameToken*)
19 {
20 VariableNameToken* token = cast<VariableNameToken*>(scanner.CurrentToken());
21 ustring variableName = token->VariableName();
22 auto nextTokenResult = scanner.NextToken();
23 if (nextTokenResult.Error())
24 {
25 return nextTokenResult;
26 }
27 if (scanner.CurrentToken() is OperatorToken*)
28 {
29 OperatorToken* token = cast<OperatorToken*>(scanner.CurrentToken());
30 if (token->Char() == '=')
31 {
32 auto nextTokenResult = scanner.NextToken();
33 if (nextTokenResult.Error())
34 {
35 return nextTokenResult;
36 }
37 auto expr = Expr(scanner);
38 if (expr.Error())
39 {
40 return Result<bool>(ErrorId(expr.GetErrorId()));
41 }
42 double value = expr.Value();
43 Token* token = scanner.CurrentToken();
44 if (token is EndToken*)
45 {
46 SymbolTable.Instance().SetVariable(variableName, value);
47 Console.Out() << variableName << " = " << value << endl();
48 return Result<bool>(true);
49 }
50 else
51 {
52 int errorId = AllocateError("invalid input");
53 return Result<bool>(ErrorId(errorId));
54 }
55 }
56 }
57 }
58 scanner.Rewind();
59 nextTokenResult = scanner.NextToken();
60 if (nextTokenResult.Error())
61 {
62 return nextTokenResult;
63 }
64 auto expr = Expr(scanner);
65 if (expr.Error())
66 {
67 return Result<bool>(ErrorId(expr.GetErrorId()));
68 }
69 Token* token = scanner.CurrentToken();
70 if (token is EndToken*)
71 {
72 Console.Out() << "= " << expr.Value() << endl();
73 }
74 else
75 {
76 int errorId = AllocateError("invalid input");
77 return Result<bool>(ErrorId(errorId));
78 }
79 return Result<bool>(true);
80 }
81
82 internal Result<double> Expr(Scanner& scanner)
83 {
84 auto term = Term(scanner);
85 if (term.Error())
86 {
87 return Result<double>(ErrorId(term.GetErrorId()));
88 }
89 double value = term.Value();
90 Token* token = scanner.CurrentToken();
91 OperatorToken* op = token as OperatorToken*;
92 while (op != null && op->IsAdditiveOperator())
93 {
94 uchar opChar = op->Char();
95 auto nextTokenResult = scanner.NextToken();
96 if (nextTokenResult.Error())
97 {
98 return Result<double>(ErrorId(nextTokenResult.GetErrorId()));
99 }
100 auto rightTerm = Term(scanner);
101 if (rightTerm.Error())
102 {
103 return Result<double>(ErrorId(rightTerm.GetErrorId()));
104 }
105 double right = rightTerm.Value();
106 if (opChar == '+')
107 {
108 value = value + right;
109 }
110 else if (opChar == '-')
111 {
112 value = value - right;
113 }
114 else
115 {
116 int errorId = AllocateError("logic error");
117 return Result<double>(ErrorId(errorId));
118 }
119 token = scanner.CurrentToken();
120 op = token as OperatorToken*;
121 }
122 return value;
123 }
124
125 internal Result<double> Term(Scanner& scanner)
126 {
127 auto factor = Factor(scanner);
128 if (factor.Error())
129 {
130 return factor;
131 }
132 double value = factor.Value();
133 Token* token = scanner.CurrentToken();
134 OperatorToken* op = token as OperatorToken*;
135 while (op != null && op->IsMultiplicativeOperator())
136 {
137 uchar opChar = op->Char();
138 auto nextTokenResult = scanner.NextToken();
139 if (nextTokenResult.Error())
140 {
141 return Result<double>(ErrorId(nextTokenResult.GetErrorId()));;
142 }
143 auto rightFactor = Factor(scanner);
144 if (rightFactor.Error())
145 {
146 return rightFactor;
147 }
148 double right = rightFactor.Value();
149 if (opChar == '*')
150 {
151 value = value * right;
152 }
153 else if (opChar == '/')
154 {
155 if (right == 0)
156 {
157 int errorId = AllocateError("division by zero");
158 return Result<double>(ErrorId(errorId));
159 }
160 value = value / right;
161 }
162 else
163 {
164 int errorId = AllocateError("logic error");
165 return Result<double>(ErrorId(errorId));
166 }
167 token = scanner.CurrentToken();
168 op = token as OperatorToken*;
169 }
170 return value;
171 }
172
173 internal Result<double> Factor(Scanner& scanner)
174 {
175 Token* token = scanner.CurrentToken();
176 OperatorToken* op = token as OperatorToken*;
177 bool neg = false;
178 if (op != null && op->IsAdditiveOperator())
179 {
180 if (op->Char() == '-')
181 {
182 neg = true;
183 }
184 auto nextTokenResult = scanner.NextToken();
185 if (nextTokenResult.Error())
186 {
187 return Result<double>(ErrorId(nextTokenResult.GetErrorId()));
188 }
189 }
190 auto primary = Primary(scanner);
191 if (primary.Error())
192 {
193 return primary;
194 }
195 double value = primary.Value();
196 if (neg)
197 {
198 return -value;
199 }
200 return Result<double>(value);
201 }
202
203 internal Result<double> Primary(Scanner& scanner)
204 {
205 Token* token = scanner.CurrentToken();
206 if (token is NumberToken*)
207 {
208 NumberToken* number = cast<NumberToken*>(token);
209 double value = number->Value();
210 auto nextTokenResult = scanner.NextToken();
211 if (nextTokenResult.Error())
212 {
213 return Result<double>(ErrorId(nextTokenResult.GetErrorId()));
214 }
215 return Result<double>(value);
216 }
217 else if (token is VariableNameToken*)
218 {
219 VariableNameToken* variableNameToken = cast<VariableNameToken*>(token);
220 auto variableResult = SymbolTable.Instance().GetVariableValue(variableNameToken->VariableName());
221 if (variableResult.Error())
222 {
223 return variableResult;
224 }
225 double value = variableResult.Value();
226 auto nextTokenResult = scanner.NextToken();
227 if (nextTokenResult.Error())
228 {
229 return Result<double>(ErrorId(nextTokenResult.GetErrorId()));
230 }
231 return Result<double>(value);
232 }
233 else if (token is OperatorToken*)
234 {
235 OperatorToken* op = cast<OperatorToken*>(token);
236 if (op->Char() == '(')
237 {
238 auto nextTokenResult = scanner.NextToken();
239 if (nextTokenResult.Error())
240 {
241 return Result<double>(ErrorId(nextTokenResult.GetErrorId()));
242 }
243 auto expr = Expr(scanner);
244 if (expr.Error())
245 {
246 return expr;
247 }
248 double value = expr.Value();
249 token = scanner.CurrentToken();
250 if (token is OperatorToken*)
251 {
252 op = cast<OperatorToken*>(token);
253 if (op->Char() == ')')
254 {
255 auto nextTokenResult = scanner.NextToken();
256 if (nextTokenResult.Error())
257 {
258 return Result<double>(ErrorId(nextTokenResult.GetErrorId()));
259 }
260 return Result<double>(value);
261 }
262 else
263 {
264 int errorId = AllocateError("\')\' expected");
265 return Result<double>(ErrorId(errorId));
266 }
267 }
268 }
269 }
270 int errorId = AllocateError("number, variable name or subexpression expected");
271 return Result<double>(ErrorId(errorId));
272 }