]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/mix/repl.c
merge
[plan9front.git] / sys / src / games / mix / repl.c
1 #include <u.h>
2 #include <libc.h>
3 #include <ctype.h>
4 #include <bio.h>
5 #include <avl.h>
6 #include "mix.h"
7
8 int
9 getf(char *line)
10 {
11         long a, b;
12
13         if(*line == '\0')
14                 return 5;
15         if(*line++ != '(') 
16                 return -1;
17         a = strtol(line, &line, 10);
18         if(*line++ != ':')
19                 return -1;
20         b = strtol(line, &line, 10);
21         if(*line != ')')
22                 return -1;
23         return F(a, b);
24 }       
25
26 int
27 disp(char *line)
28 {
29         int f;
30         long m;
31
32         if(setjmp(errjmp) == 1)
33                 return -1;
34         m = strtol(line, &line, 10);
35         if((f = getf(line)) == -1)
36                 return -1;
37         print("%d\n", V(cells[m], f));
38         return 0;
39 }
40
41 int
42 dispreg(char *line)
43 {
44         vlong rax;
45         char c;
46         int i, f;
47         u32int reg;
48
49         if(setjmp(errjmp) == 1)
50                 return -1;
51
52         switch(c = *line++) {
53         case 'a':
54                 if(*line == 'x') {
55                         rax = ra & MASK5;
56                         rax <<= 5 * BITS;
57                         rax |= rx & MASK5;
58                         if(ra >> 31)
59                                 rax = -rax;
60                         print("%lld\n", rax);
61                         return 0;
62                 } else
63                         reg = ra;
64                 break;
65         case 'x':
66                 reg = rx;
67                 break;
68         case 'j':
69                 reg = ri[0];
70                 break;
71         default:
72                 if(!isdigit(c))
73                         return -1;
74                 i = c - '0';
75                 if(i < 1 || i > 6)
76                         return -1;
77                 reg = ri[i];
78         }
79
80         if((f = getf(line)) == -1)
81                 return -1;
82
83         print("%d\n", V(reg, f));
84         return 0;
85 }
86
87 int
88 breakp(char *line)
89 {
90         long l;
91
92         line = strskip(line);
93         if(!isdigit(*line))
94                 return -1;
95         l = strtol(line, nil, 10);
96         if(l < 0 || l > 4000)
97                 return -1;
98         bp[l] ^= 1;
99         return 0;
100 }
101
102 int
103 asm(char *l)
104 {
105         char *file;
106
107         if(yydone) {
108                 print("Assembly complete\n");
109                 return 0;
110         }
111         l = strskip(l);
112         if(*l++ == '<') {
113                 Bterm(&bin);
114                 l = strskip(l);
115                 file = estrdup(strim(l));
116                 if(asmfile(file) == -1) {
117                         free(file);
118                         return -1;
119                 }
120                 Binit(&bin, 0, OREAD);
121                 free(file);
122                 return 0;
123         }
124
125         line = 1;
126         filename = "<stdin>";
127         if(setjmp(errjmp) == 0)
128                 yyparse();
129         Bterm(&bin);
130         Binit(&bin, 0, OREAD);
131         return 0;
132 }
133
134 int
135 disasm(char *line)
136 {
137         long l;
138
139         line = strskip(line);
140         if(!isdigit(*line))
141                 return -1;
142
143         l = strtol(line, nil, 10);
144         if(l < 0 || l > 4000)
145                 return -1;
146         print("%I\n", cells[l]);
147         return 0;
148 }
149
150 void
151 mixprint(int m, int words)
152 {
153         int i;
154         u32int *wp, w;
155         Rune buf[6], *rp;
156
157         wp = cells+m;
158         while(words-- > 0) {
159                 rp = buf;
160                 w = *wp++;
161                 for(i = 4; i > -1; i--)
162                         *rp++ = mixtorune(w>>i*BITS & MASK1);
163                 *rp = '\0';
164                 print("%S", buf);
165         }
166         print("\n");
167 }
168
169 int
170 out(char *line)
171 {
172         long l, i;
173
174         line = strskip(line);
175         i = 1;
176         if(*line == '(') {
177                 l = strtol(strskip(line+1), &line, 10);
178                 line = strskip(line);
179                 if(*line != ',')
180                         return -1;
181                 i = strtol(strskip(line+1), &line, 10);
182                 line = strskip(line);
183                 if(*line != ')')
184                         return -1;
185         } else {
186                 if(!isdigit(*line))
187                         return -1;
188                 l = strtol(line, nil, 10);
189         }
190         mixprint(l, i);
191         return 0;
192 }
193
194 void
195 clearsyms(Sym *s)
196 {
197         if(s == nil)
198                 return;
199
200         clearsyms((Sym*)s->c[0]);
201         clearsyms((Sym*)s->c[1]);
202         free(s);
203 }
204
205 void
206 repl(int go)
207 {
208         char *line, c;
209         int len, once;
210                 
211
212         Binit(&bin, 0, OREAD);
213
214         if(go) {
215                 once = 0;
216                 goto Go;
217         }
218
219         for(;;) {
220                 print("MIX ");
221
222                 if((line = Brdline(&bin, '\n')) == nil)
223                         return;
224
225                 if((len = Blinelen(&bin)) == 1)
226                         continue;
227
228                 line[len-1] = '\0';
229
230                 once = 0;
231                 switch(c = line[0]) {
232                 Err:
233                         print("?\n");
234                         break;
235                 default:
236                         if(!isdigit(c)) 
237                                 goto Err;
238                         if(disp(line) == -1)
239                                 goto Err;
240                         break;
241                 case 'a':
242                         if(asm(line+1) == -1)
243                                 goto Err;
244                         break;
245                 case 'b':
246                         if(breakp(line+1) == -1)
247                                 goto Err;
248                         break;
249                 case 'c':
250                         ra = rx = ri[0] = ri[1] = ri[2] = ri[3] = ri[4] = ri[5] = ri[6] = 0;
251                         memset(cells, 0, sizeof(cells));
252                         vmstart = -1;
253                         yydone = 0;
254                         clearsyms((Sym*)syms->root);
255                         syms->root = nil;
256                         sinit();
257                         break;
258                 case 'd':
259                         if(disasm(line+1) == -1)
260                                 goto Err;
261                         break;
262                 case 'o':
263                         if(out(line+1) == -1)
264                                 goto Err;
265                         break;
266                 case 'r':
267                         if(dispreg(line+1) == -1)
268                                 goto Err;
269                         break;
270                 case 's':
271                         once = 1;
272                 case 'g':
273                 Go:
274                         if(vmstart == -1)
275                                 goto Err;
276                         if(setjmp(errjmp) == 0)
277                                 vmstart = mixvm(vmstart, once);
278                         else
279                                 break;
280                         if(vmstart == -1)
281                                 print("halted\n");
282                         else
283                                 print("at %d:\t%I\n", vmstart, cells[vmstart]);
284                         break;
285                 case 'x':
286                         return;
287                 }
288         }
289 }