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
|
#include <stdlib.h>
#include "basic.h"
void level2(int*), level3(int*), level4(int*), level5(int*), level6(int*), primitive(int*);
void unary(char, int*), arith(char, int*, int*);
/* Entry point into parser. */
void get_exp(int *result)
{
get_token();
if(!*token) {
serror(2);
return;
}
level2(result);
putback(); /* return last token read to input stream */
}
/* Add or subtract two terms. */
void level2(int *result)
{
register char op;
int hold;
level3(result);
while((op = *token) == '+' || op == '-') {
get_token();
level3(&hold);
arith(op, result, &hold);
}
}
/* Multiply or divide two factors. */
void level3(int *result)
{
register char op;
int hold;
level4(result);
while((op = *token) == '*' || op == '/' || op == '%') {
get_token();
level4(&hold);
arith(op, result, &hold);
}
}
/* Process integer exponent. */
void level4(int *result)
{
int hold;
level5(result);
if(*token== '^') {
get_token();
level4(&hold);
arith('^', result, &hold);
}
}
/* Is a unary + or -. */
void level5(int *result)
{
register char op;
op = 0;
if((token_type==DELIMITER) && (*token=='+' || *token=='-')) {
op = *token;
get_token();
}
level6(result);
if(op)
unary(op, result);
}
/* Process parenthesized expression. */
void level6(int *result)
{
if((*token == '(') && (token_type == DELIMITER)) {
get_token();
level2(result);
if(*token != ')')
serror(1);
get_token();
}
else
primitive(result);
}
/* Find value of number or variable. */
void primitive(int *result)
{
switch(token_type) {
case VARIABLE:
*result = *find_var(token);
get_token();
return;
case NUMBER:
*result = atoi(token);
get_token();
return;
case COMMAND:
switch(tok) {
case RND:
*result = rand();
get_token();
return;
}
default:
serror(0);
}
}
/* Perform the specified arithmetic. */
void arith(char o, int *r, int *h)
{
register int t, ex;
switch(o) {
case '-':
*r = *r-*h;
break;
case '+':
*r = *r+*h;
break;
case '*':
*r = *r * *h;
break;
case '/':
*r = (*r)/(*h);
break;
case '%':
t = (*r)/(*h);
*r = *r-(t*(*h));
break;
case '^':
ex = *r;
if(*h==0) {
*r = 1;
break;
}
for(t=*h-1; t>0; --t) *r = (*r) * ex;
break;
}
}
/* Reverse the sign. */
void unary(char o, int *r)
{
if(o=='-') *r = -(*r);
}
|