-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathass1-skel.c
288 lines (245 loc) · 6.44 KB
/
ass1-skel.c
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
/*
Extended precision integer calculation program
Skeleton program written by Alistair Moffat, August 2013
(Add your name and login name)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#define INTSIZE 100 /* max number of digits per integer value */
#define LINELEN 102 /* maximum length of any input line */
#define NVARS 26 /* number of different variables */
#define CH_BLANK ' ' /* character blank */
#define CH_ZERO '0' /* character zero */
#define CH_A 'a' /* character 'a', first variable name */
#define ERROR (-1) /* error return value from some functions */
#define PRINT '?' /* the print operator */
#define ASSIGN '=' /* the assignment operator */
#define PLUS '+' /* the addition operator */
#define ALLOPS "?=+" /* list of all valid operators */
#define SGNCHRS "+-" /* the two sign characters */
#define NUMCHRS "0123456789"
/* list of characters legal within numbers */
typedef int longint_t;
/* one extended-precision "variable" */
/****************************************************************/
/* function prototypes */
void print_prompt(void);
int read_line(char *line, int maxlen);
void process_line(longint_t vars[], char *line);
int to_varnum(char ident);
int get_second_value(longint_t vars[], char *rhsarg,
longint_t *second_value);
int to_int(char digit);
char to_digit(int number);
void do_print(longint_t *var);
void do_assign(longint_t *var1, longint_t *var2);
void do_plus(longint_t *var1, longint_t *var2);
void zero_vars(longint_t vars[]);
/****************************************************************/
/* main program controls all the action
*/
int
main(int argc, char **argv) {
char line[LINELEN+1];
longint_t vars[NVARS]; // vars: a list of variables in the form of pointers
zero_vars(vars);
print_prompt();
while (read_line(line, LINELEN)) {
if (strlen(line)>0) {
/* non empty line, so process it */
process_line(vars, line);
}
print_prompt();
}
/* all done, so pack up and go home */
printf("\n");
return 0;
}
/****************************************************************/
/* prints the prompt indicating ready for input
*/
void
print_prompt(void) {
printf("> ");
}
/****************************************************************/
/* read a line of input into the array passed as argument
* returns false if there is no input available
* all whitespace characters are removed
*/
int
read_line(char *line, int maxlen) {
int i=0, c;
while (((c=getchar())!=EOF) && (c!='\n')) {
if (i<maxlen && !isspace(c)) {
line[i++] = c;
}
}
line[i] = '\0';
return ((i>0) || (c!=EOF));
}
/****************************************************************/
/* process a command by parsing the input line into parts
*/
void
process_line(longint_t vars[], char *line) {
int varnum, optype, status;
longint_t second_value;
/* determine the LHS variable, it
* must be first character in line
*/
varnum = to_varnum(line[0]);
if (varnum==ERROR) {
printf("Invalid LHS variable\n");
return;
}
/* more testing for validity
*/
if (strlen(line)<2) {
printf("No operator supplied\n");
return;
}
/* determine the operation to be performed, it
* must be second character in line
*/
optype = line[1];
if (strchr(ALLOPS, optype) == NULL) {
printf("Unknown operator\n");
return;
}
/* determine the RHS argument (if one is required),
* it must start in third character of line
*/
if (optype != PRINT) {
if (strlen(line)<3) {
printf("No RHS supplied\n");
return;
}
status = get_second_value(vars, line+2, &second_value);
if (status==ERROR) {
printf("RHS argument is invalid\n");
return;
}
}
/* finally, do the actual operation
*/
if (optype == PRINT) {
do_print(vars+varnum);
} else if (optype == ASSIGN) {
do_assign(vars+varnum, &second_value);
} else if (optype == PLUS) {
do_plus(vars+varnum, &second_value);
}
return;
}
/****************************************************************/
/* convert a character variable identifier to a variable number
*/
int
to_varnum(char ident) {
int varnum;
varnum = ident - CH_A;
if (0<=varnum && varnum<NVARS) {
return varnum;
} else {
return ERROR;
}
}
/****************************************************************/
/* process the input line to extract the RHS argument, which
* should start at the pointer that is passed
*/
int
get_second_value(longint_t vars[], char *rhsarg,
longint_t *second_value) {
char *p;
int varnum2;
if (strchr(NUMCHRS, *rhsarg) != NULL ||
strchr(SGNCHRS, *rhsarg) != NULL) {
/* first character is a digit or a sign, so RHS
* should be a number
*/
p = rhsarg+1;
while (*p) {
if (strchr(NUMCHRS, *p) == NULL) {
/* nope, found an illegal character */
return ERROR;
}
p++;
}
*second_value = atoi(rhsarg);
return !ERROR;
} else {
/* argument is not a number, so might be a variable */
varnum2 = to_varnum(*rhsarg);
if (varnum2==ERROR || strlen(rhsarg)!=1) {
/* nope, not a variable either */
return ERROR;
}
/* is a variable, so can use its value to assign to
* second_value
*/
*second_value = vars[varnum2];
return !ERROR;
}
return ERROR;
}
/****************************************************************/
/* convert a character digit to the int equivalent, but null bytes
* stay as zero integers
*/
int
to_int(char digit) {
if (digit != '\0') {
return digit - CH_ZERO;
} else {
return 0;
}
}
/****************************************************************/
/* and back again to a digit */
char
to_digit(int number) {
return number + CH_ZERO;
}
/****************************************************************/
/* print out a longint value
*/
void
do_print(longint_t *var) {
printf("%d\n", *var);
return;
}
/****************************************************************/
/* update the indicated variable var1 by doing an assignment
* using var2
*/
void
do_assign(longint_t *var1, longint_t *var2) {
/* hey, this is trivial in this representation
*/
*var1 = *var2;
}
/****************************************************************/
/* update the indicated variable var1 by doing an addition
* using var2 to compute var1 = var1 + var2
*/
void
do_plus(longint_t *var1, longint_t *var2) {
*var1 += *var2;
}
/****************************************************************/
/* set the vars array to all zero values
*/
void
zero_vars(longint_t vars[]) {
int i;
longint_t zero = 0;
for (i=0; i<NVARS; i++) {
do_assign(vars+i, &zero);
}
return;
}