-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalculator.js
357 lines (347 loc) · 8.51 KB
/
calculator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
/**
* Created by 61640 on 2017/7/25.
*/
var pos=0;
var parse="";
var buffer;
var if_buffer=false;
var put_back=Array(0,0);
var if_put=false;
function putBack(a)
{
if (if_put)
throw "Already put";
put_back=a;
if_put=true;
}
function getNumber()
{
var ans="";
while (true)
{
var now=parse[pos];
var flag=false;
switch (now)
{
case"0":case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":case".":
ans+=now;
break;
default:
flag=true;
}
if (flag)
break;
pos++;
}
return Number(ans);
}
function getChar()
{
pos++;
return parse[pos-1];
}
function getString(a)
{
var ans="";
for (;a!=0;a--)
ans+=getChar();
return ans;
}
function get() { //获取输入的实现
if (if_put)
{
if_put=false;
return put_back;
}
var ch = getChar();
switch (ch)
{
case ';':
case'(':
case')':
case'+':
case'-':
case'*':
case'/':
case'!':
case'%':
case'M':
var arr = new Array(ch, 0);
return arr;
break;
case'p'://处理常量
var temp = getChar();
if (temp == 'i') {
var pi = new Array(8,3.1415926);
return pi;
}
else throw "Bad Token";
break;
case'e':
return Array(8,2.71828);
break;
//处理记忆
case'R':
if (if_buffer)
return Array(8,buffer);
else
throw "Bad Token";
break;
case'.'://若接下来的符号为数字的一部分时,将读取内容返回缓存区,并读取出一个浮点数
case'0':
case'1':
case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
case'8':
case'9':
pos--;
return Array(8,getNumber());
case's':
var temp = getString(2);
if (temp == "in")
return Array(ch, 0);
else if (temp == "qr")
if (getChar() == "t")
return Array("g", 0);
else throw "Bad Token";
case'c': {
var temp = getString(2);
if (temp == "os")
return Array(ch, 0);
else
throw "Bad Token";
}
case't': {
var temp = getString(2);
if (temp == "an")
return Array(ch, 0);
else
throw "Bad Token";
}
case'a': {
var temp = getString(3);
if (temp == "sin")
return Array("a", 0);
if (temp == "cos")
return Array("x", 0);
if (temp == "tan")
return Array("r", 0);
else
throw "Bad Token";
}
case'l': {
var temp = getChar();
if (temp == 'n')
return Array("l", 0);
else
throw "Bad Token";
}
case'^':
return Array(ch, 0);
default://若输入包含不属于以上字符时,报错
throw "BadToken";
}
}
function rangeCheck(d, l, r)
{
if (l<d&&d<r)
return true;
return false;
}
function intRank( a)
{//通过递归计算阶乘
if (a==1)
return 1;
if (a<0)
throw "PositiveExpected";
if (a%1!=0)
throw "intExpected";
return intRank(a - 1)*a;
}
function primary() {//primary的实现细节
var t = get();
switch (t[0]) {
case 8://数字与阶乘
var l = get();
if (l[0] == '!')
return intRank(t[1]);
if (l[0] == '^')
{
var temp_left = primary();
return Math.pow(t[1], temp_left);
}
else {
putBack(l);
return t[1];
}
case's'://处理数学函数
return Math.sin(primary());
case'c':
return Math.cos(primary());
case't':
return Math.tan(primary());
case'a':
{
var left = primary();
try {
return Math.asin(left);
}
catch(str) {
throw "Out Of Range";
}
}
case'x':
{
var left = primary();
try {
return Math.acos(left);
}
catch(str) {
throw "Out Of Range";
}
}
case'r':
return Math.atan(primary());
case'l':
{
var left = primary();
if (left>0)
return Math.log(left);
else
throw "Out Of Range";
}
case'g':
{
var left = primary();
if (left>0)
return Math.sqrt(left);
else if (left == 0)
return 0;
else
throw "Out Of Range";
}
case '-'://处理一元运算
return -primary();
case '+':
return primary();
case'(': {//处理括号
var d = expression();
t = get();
if (t[0]!= ')')throw "BracketExpected";//error("')' expected!");
var l = get();
if (l[0] == '!')
d = intRank(d);
else
putBack(t);
return d; }
default:
throw "PrimaryExpected";
//error("primary expected");
}
}
function term() {
var left = primary();
var t = get();
while (true) {
switch (t[0]) {
case'*'://处理乘号
left *= primary();
t = get();
break;
case'/': {//处理除号
var temp = primary();
if (temp == 0)throw"ZeroDivision"//error("division by zero");
left /= temp;
t = get();
break; }
case'%': {//处理模
var temp = primary();;
if (temp%1!=0||left%1!=0)throw "DivisionInt";//error("% right expected a int");
//if (t != left)throw "DivisionInt";//error("% left expected a int");
if (temp == 0)throw "ZeroDivision";//error("0 division erro");
left = left%temp;
t = get();
break;
}
default:
putBack(t);
return left;
}
}
}
function expression() {
var left = term();
var t = get();
while (true) {
switch (t[0]) {
case'+'://处理加号
left += term();
t = get();
break;
case'-'://处理减号
left -= term();
t = get();
break;
default:
putBack(t);
return left;
}
}
}
function calculate()
{
//判断输入是否有效,无效则中断
try {
var left = expression();
if (isNaN(left)||!isFinite(left))
return "Out Of Range";
var t = get();
switch (t[0])
{
case'M'://记忆算式结果,并直接输出
buffer = left;
if_buffer = true;
var l = get();
case ';'://当最后一个字符为输出提示符时,输出
pos=0;
return left;
default:
pos=0;
return "Wrong expression!";
//break;
}
}
catch (str)
{
pos=0;
return str;
}
}
function calcu(str)
{
//document.getElementById("result_display").value =str;
if (str==="=") {
parse=document.getElementById("txt_display").value;
parse+=";";
document.getElementById("result_display").value = calculate();
parse=parse.substring(0,parse.length-1);
}
else if (str=="AC")
{
document.getElementById("txt_display").value="";
document.getElementById("result_display").value="";
parse="";
}
else if(str=="DEL") {
parse=parse.substring(0,parse.length-1);
document.getElementById("txt_display").value=parse;
}
else {
parse += str;
document.getElementById("txt_display").value = parse;
}
}