1 /* Loglan82 Compiler&Interpreter
\r
2 Copyright (C) 1993 Institute of Informatics, University of Warsaw
\r
3 Copyright (C) 1993, 1994 LITA, Pau
\r
5 This program is free software; you can redistribute it and/or modify
\r
6 it under the terms of the GNU General Public License as published by
\r
7 the Free Software Foundation; either version 2 of the License, or
\r
8 (at your option) any later version.
\r
10 This program is distributed in the hope that it will be useful,
\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 GNU General Public License for more details.
\r
15 You should have received a copy of the GNU General Public License
\r
16 along with this program; if not, write to the Free Software
\r
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
\r
19 contacts: Andrzej.Salwicki@univ-pau.fr
\r
22 LITA Departement d'Informatique
\r
24 Avenue de l'Universite
\r
26 tel. ++33 59923154 fax. ++33 59841696
\r
28 =======================================================================
\r
34 #include "process.h"
\r
35 #include "intproto.h"
\r
40 /* Execute one L-code instruction */
\r
48 virtaddr virt1, virt2, virt3;
\r
51 fprintf(stderr,"pix %d,ic %d,opcode %d\n",thispix,ic,opcode);fflush(stderr);
\r
56 case 1 : /* LOPENRC */
\r
57 openrc(a3, &virt2, &t2);
\r
58 storevirt(virt2, a1);
\r
62 case 2 : /* LBACKADDR */
\r
63 storevirt(thisp->backobj, a1);
\r
64 M[ a2 ] = M[ temporary ];
\r
67 case 3 : /* LRAISE */
\r
68 ic++; /* skip the address */
\r
69 raise_signal(a3, M[ ic-1 ], &t1, &t2);
\r
74 case 4 : /* LOPEN */
\r
75 openobj(M[ a3 ], &t1, &t2);
\r
80 case 5 : /* LSLOPEN */
\r
81 loadvirt(virt3, a3);
\r
82 slopen(M[ a3+APREF ], &virt3, &t1, &t2);
\r
87 case 15 : /* LTHIS */
\r
88 virt1.addr = M[ display2+a2 ];
\r
89 virt1.mark = M[ virt1.addr+1 ];
\r
90 storevirt(virt1, a1);
\r
93 case 20 : /* LVIRTDISPL */
\r
94 t2 = M[ display+a2 ];
\r
95 t1 = M[ t2+PROTNUM ];
\r
96 M[ a1 ] = M[ prototype[ t1 ]->virtlist+a3 ];
\r
99 case 21 : /* LSTATTYPE */
\r
104 case 23 : /* LIPAROUT */
\r
105 M[ a1 ] = param[ a3 ].xword;
\r
108 case 24 : /* LRPAROUT */
\r
109 MR(a1) = param[ a3 ].xreal;
\r
112 case 25 : /* LVPAROUT */
\r
113 storevirt(param[ a3 ].xvirt, a1);
\r
116 case 31 : /* LSIGN */
\r
117 if (M[ a2 ] == 0) M[ a1 ] = 0;
\r
119 if (M[ a2 ] < 0) M[ a1 ] = -1;
\r
123 case 33 : /* LLOWER */
\r
125 loadvirt(virt2, a2);
\r
126 if (member(&virt2, &t1))
\r
128 switch ((int) M[ t1+PROTNUM ])
\r
130 case AINT : t2 = APINT; break;
\r
131 case AREAL : t2 = APREAL; break;
\r
132 case AVIRT : t2 = APREF; break;
\r
134 M[ a1 ] = (M[ t1+2 ]+3)/t2;
\r
136 else errsignal(RTEREFTN);
\r
139 case 35 : /* LUPPER */
\r
141 loadvirt(virt2, a2);
\r
142 if (member(&virt2, &t1))
\r
144 switch ((int) M[ t1+PROTNUM ])
\r
146 case AINT : t2 = APINT; break;
\r
147 case AREAL : t2 = APREAL; break;
\r
148 case AVIRT : t2 = APREF; break;
\r
150 M[ a1 ] = (M[ t1+2 ]+M[ t1 ])/t2-1;
\r
152 else errsignal(RTEREFTN);
\r
155 case 40 : /* LGETTYPE */
\r
156 typep(M[ a2 ], a3, &virt1.addr, &virt1.mark);
\r
157 storevirt(virt1, a1);
\r
160 case 41 : /* LCOPY */
\r
161 loadvirt(virt2, a2);
\r
162 copy(&virt2, &virt1);
\r
163 storevirt(virt1, a1);
\r
166 case 42 : /* LNOT */
\r
167 M[ a1 ] = ~ M[ a2 ];
\r
170 case 43 : /* LRCVAVIRT */ /* recover virtual address from ah */
\r
171 virt1.addr = M[ a2 ];
\r
172 virt1.mark = M[ virt1.addr+1 ];
\r
173 storevirt(virt1, a1);
\r
176 case 44 : /* LVIRTDOT */
\r
178 M[ a1 ] = M[ prototype[ M[ temporary ] ]->virtlist+a2 ];
\r
181 case 46 : /* LADDRPH */
\r
182 case 47 : /* LADDRPH2 */
\r
183 loadvirt(virt2, a2);
\r
184 if (!member(&virt2, &M[ a1 ])) errsignal(RTEREFTN);
\r
187 case 48 : /* LIABS */
\r
189 M[ a1 ] = absolute(t2);
\r
192 case 49 : /* LINEG */
\r
193 M[ a1 ] = -M[ a2 ];
\r
196 case 50 : /* LRABS */
\r
198 if( r < (real)0.0 )
\r
203 case 51 : /* LRNEG */
\r
207 case 52 : /* LPARAMADDR */
\r
209 M[ a1 ] = t2+M[ prototype[ M[ t2+PROTNUM ] ]->parlist+a3 ];
\r
212 case 54 : /* LLOADT */
\r
213 t1 = M[ ic++ ]; /* offset */
\r
214 t2 = t1+loadt(M[ M[ a2 ] ], a3); /* object address */
\r
215 loadvirt(virt1, t2);
\r
216 storevirt(virt1, a1);
\r
219 case 55 : /* LIS */
\r
220 loadvirt(virt2, a2);
\r
221 M[ a1 ] = lbool(is(&virt2, a3));
\r
224 case 56 : /* LIN */
\r
225 loadvirt(virt2, a2);
\r
226 M[ a1 ] = lbool(inl(&virt2, a3));
\r
229 case 57 : /* LQUA */
\r
230 loadvirt(virt2, a2);
\r
231 if (member(&virt2, &M[ a1 ]))
\r
233 else errsignal(RTEREFTN);
\r
236 case 58 : /* LIFIX */
\r
237 M[ a1 ] = (word)( MR(a2) );
\r
240 case 59 : /* LFLOAT */
\r
241 MR(a1) = (real)( M[ a2 ] );
\r
244 case 60 : /* LIMOVE */
\r
248 case 61 : /* LVMOVE */
\r
249 loadvirt(virt1, a2);
\r
250 storevirt(virt1, a1);
\r
253 case 62 : /* LRMOVE */ /* WARNING: these areas may overlap! */
\r
258 case 63 : /* LFPMOVE */ /* WARNING: these areas may overlap! */
\r
259 loadvirt(virt1, a2); /* MACHINE DEPENDENT */
\r
261 storevirt(virt1, a1);
\r
265 case 82 : /* LEQNONE */
\r
266 M[ a1 ] = lbool(M[ a2+1 ] != M[ M[ a2 ]+1 ]);
\r
269 case 83 : /* LNENONE */
\r
270 M[ a1 ] = lbool(M[ a2+1 ] == M[ M[ a2 ]+1 ]);
\r
273 case 87 : /* LMDFTYPE */ /* modify the formal type */
\r
274 loadvirt(virt1, a2);
\r
275 virt1.addr += a3; /* number of "arrayof" */
\r
276 storevirt(virt1, a1);
\r
279 case 100 : /* LOR */
\r
280 M[ a1 ] = M[ a2 ] | M[ a3 ];
\r
283 case 101 : /* LAND */
\r
284 M[ a1 ] = M[ a2 ] & M[ a3 ];
\r
287 case 102 : /* LARRAY */
\r
290 loadvirt(virt2, a2);
\r
291 if (member(&virt2, &t2))
\r
293 t1 = M[ a3 ]-M[ t2+2 ]; /* index-lower+3 */
\r
294 if (t1 < 3 || t1 >= M[ t2 ]) errsignal(RTEINVIN);
\r
295 else M[ a1 ] = t2+t1;
\r
297 else errsignal(RTEREFTN);
\r
300 case 105 : /* LFARRAY */ /* without any tests */
\r
301 t1 = M[ M[ a2 ] ]; /* physical address */
\r
302 M[ a1 ] = t1+M[ a3 ]-M[ t1+2 ];
\r
305 case 106 : /* LIEQUAL */
\r
306 M[ a1 ] = lbool(M[ a2 ] == M[ a3 ]);
\r
309 case 107 : /* LINEQUAL */
\r
310 M[ a1 ] = lbool(M[ a2 ] != M[ a3 ]);
\r
313 case 108 : /* LILT */
\r
314 M[ a1 ] = lbool(M[ a2 ] < M[ a3 ]);
\r
317 case 109 : /* LILE */
\r
318 M[ a1 ] = lbool(M[ a2 ] <= M[ a3 ]);
\r
321 case 110 : /* LIGT */
\r
322 M[ a1 ] = lbool(M[ a2 ] > M[ a3 ]);
\r
325 case 111 : /* LIGE */
\r
326 M[ a1 ] = lbool(M[ a2 ] >= M[ a3 ]);
\r
329 case 112 : /* LCOMBINE */
\r
330 loadvirt(virt2, a2);
\r
332 storevirt(virt2, a1);
\r
333 M[ a1+APREF ] = t1;
\r
336 case 113 : /* LIADD */
\r
337 M[ a1 ] = M[ a2 ]+M[ a3 ];
\r
340 case 114 : /* LISUB */
\r
341 M[ a1 ] = M[ a2 ]-M[ a3 ];
\r
344 case 115 : /* LIMULT */
\r
345 M[ a1 ] = M[ a2 ] * M[ a3 ];
\r
348 case 116 : /* LSHIFT */
\r
349 M[ a1 ] = shift(M[ a2 ], M[ a3 ]);
\r
352 case 117 : /* LIDIVE */
\r
353 if (M[ a3 ] == 0) errsignal(RTEDIVBZ);
\r
354 else M[ a1 ] = M[ a2 ] / M[ a3 ];
\r
357 case 118 : /* LIMODE */
\r
358 if (M[ a3 ] == 0) errsignal(RTEDIVBZ);
\r
359 else M[ a1 ] = M[ a2 ] % M[ a3 ];
\r
362 case 119 : /* LRADD */
\r
363 MR(a1) = MR(a2)+MR(a3);
\r
366 case 120 : /* LRSUB */
\r
367 MR(a1) = MR(a2)-MR(a3);
\r
370 case 121 : /* LRMULT */
\r
371 MR(a1) = MR(a2) * MR(a3);
\r
374 case 122 : /* LRDIVE */
\r
375 if (MR(a3) == (real)0.0) errsignal(RTEDIVBZ);
\r
376 else MR(a1) = MR(a2) / MR(a3);
\r
379 case 123 : /* LEQREF */
\r
380 loadvirt(virt2, a2);
\r
381 loadvirt(virt3, a3);
\r
382 if (member(&virt2, &t1))
\r
383 M[ a1 ] = lbool(member(&virt3, &t2) && t1 == t2);
\r
384 else M[ a1 ] = lbool(!member(&virt3, &t2));
\r
387 case 124 : /* LNEREF */
\r
388 loadvirt(virt2, a2);
\r
389 loadvirt(virt3, a3);
\r
390 if (member(&virt2, &t1))
\r
391 M[ a1 ] = lbool(!member(&virt3, &t2) || t1 != t2);
\r
392 else M[ a1 ] = lbool(member(&virt3, &t2));
\r
395 case 125 : /* LREQ */
\r
396 M[ a1 ] = lbool(MR(a2) == MR(a3));
\r
399 case 126 : /* LRNE */
\r
400 M[ a1 ] = lbool(MR(a2) != MR(a3));
\r
403 case 127 : /* LRLT */
\r
404 M[ a1 ] = lbool(MR(a2) < MR(a3));
\r
407 case 128 : /* LRLE */
\r
408 M[ a1 ] = lbool(MR(a2) <= MR(a3));
\r
411 case 129 : /* LRGT */
\r
412 M[ a1 ] = lbool(MR(a2) > MR(a3));
\r
415 case 130 : /* LRGE */
\r
416 M[ a1 ] = lbool(MR(a2) >= MR(a3));
\r
419 case 131 : /* LXOR */
\r
420 M[ a1 ] = M[ a2 ] ^ M[ a3 ];
\r
423 case 132 : /* LCALLPROCSTAND */
\r
425 alarm(0); /* reschedule forced so alarm may be switched off */
\r
431 case 143 : /* LKILL */
\r
432 loadvirt(virt1, a1);
\r
436 case 144 : /* LHEADS */
\r
437 loadvirt(virt1, a1);
\r
441 case 145 : /* LIPARINP */
\r
442 param[ a3 ].xword = M[ a1 ];
\r
445 case 146 : /* LGKILL */
\r
446 loadvirt(virt1, a1);
\r
450 case 147 : /* LVPARINP */
\r
451 loadvirt(param[ a3 ].xvirt, a1);
\r
454 case 148 : /* LRPARINP */
\r
455 param[ a3 ].xreal = MR(a1);
\r
458 case 149 : /* LQUATEST */
\r
459 loadvirt(virt1, a1);
\r
463 case 150 : /* LSTYPE */
\r
464 loadvirt(virt1, a1);
\r
465 typref(&virt1, a2);
\r
468 case 151 : /* LIFFALSE */
\r
469 if (M[ a1 ] == LFALSE) ic = a2;
\r
472 case 152 : /* LIFTRUE */
\r
473 if (M[ a1 ] == LTRUE) ic = a2;
\r
476 case 159 : /* LGO */
\r
477 go(M[ a2 ], M[ a1 ]);
\r
480 case 160 : /* LGOLOCAL */
\r
481 goloc(M[ a2 ], M[ a1 ]);
\r
484 case 170 : /* LDTYPE */
\r
485 loadvirt(virt1, a1); /* left side type */
\r
486 loadvirt(virt2, a2);
\r
487 loadvirt(virt3, a3); /* right side type */
\r
488 typed(virt1.addr, virt1.mark, virt3.addr, virt3.mark, &virt2);
\r
491 case 172 : /* LTERMINATE */
\r
495 case 173 : /* LWIND */
\r
499 case 174 : /* LBLOCK2 */
\r
500 goloc(thisp->blck1, thisp->blck2);
\r
503 case 176 : /* LBLOCK3 */
\r
504 disp(&thisp->backobj);
\r
507 case 177 : /* LTRACE */
\r
511 case 178 : /* LINNER */
\r
515 case 180 : /* LBACKHD */
\r
516 backhd(&thisp->backobj, &M[ temporary ]);
\r
519 case 182 : /* LJUMP */
\r
523 case 186 : /* LBLOCK1 */
\r
524 openobj(a1, &thisp->blck1, &thisp->blck2);
\r
527 case 187 : /* LDETACH */
\r
531 case 188 : /* LATTACH */
\r
532 loadvirt(virt1, a1);
\r
536 case 191 : /* LBACKBL */
\r
537 backbl(&thisp->backobj, &M[ temporary ]);
\r
540 case 192 : /* LBACKPR */
\r
541 /* backpr(&thisp->backobj, &M[ temporary ]); */
\r
542 back(&thisp->backobj, &M[ temporary ], (word) 0);
\r
545 case 193 : /* LBACK */
\r
546 back(&thisp->backobj, &M[ temporary ], (word) 0);
\r
549 case 194 : /* LFIN */
\r
550 fin(ic-APOPCODE, &thisp->backobj, &M[ temporary ]);
\r
553 case 195 : /* LCASE */
\r
554 /* a2 = address of case description : */
\r
555 /* minimal value, number of branches, */
\r
556 /* remaining branches followed by "otherwise" code */
\r
557 t1 = M[ a1 ]-M[ a2 ]; /* in 0..number of branches-1 */
\r
558 if (t1 < 0 || t1 >= M[ a2+1 ])
\r
559 ic = a2+2+M[ a2+1 ]; /* otherwise */
\r
561 ic = M[ a2+2+t1 ]; /* indirect jump */
\r
564 case 220 : /* LRESUME */
\r
565 loadvirt(virt1, a1);
\r
569 case 221 : /* LSTOP */
\r
570 passivate(STOPPED);
\r
573 case 222 : /* LKILLTEMP */
\r
574 disp(&thisp->template);
\r
577 case 223 : /* LENABLE */
\r
578 for (i = 0; i < a1; i++)
\r
579 enable(thispix, virtprot(M[ ic++ ]));
\r
580 evaluaterpc(thispix);
\r
583 case 224 : /* LDISABLE */
\r
584 for (i = 0; i < a1; i++)
\r
585 disable(thispix, virtprot(M[ ic++ ]));
\r
588 case 225 : /* LACCEPT1 */
\r
592 case 226 : /* LACCEPT2 */
\r
597 case 227 : /* LBACKRPC */
\r
598 back(&thisp->backobj, &M[ temporary ], a1);
\r
601 case 228 : /* LASKPROT */
\r
602 loadvirt(virt1, a1);
\r
606 case 240 : /* LSTEP */
\r
607 if (M[ a1 ] < 0) errsignal(RTENEGST);
\r
611 fprintf( stderr, "Invalid opcode\n" );
\r
612 errsignal(RTESYSER);
\r