Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / sources / int / execute.c
1 /*     Loglan82 Compiler&Interpreter\r
2      Copyright (C) 1993 Institute of Informatics, University of Warsaw\r
3      Copyright (C)  1993, 1994 LITA, Pau\r
4      \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
9      \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
14      \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
18 \r
19  contacts:  Andrzej.Salwicki@univ-pau.fr\r
20 \r
21 or             Andrzej Salwicki\r
22                 LITA   Departement d'Informatique\r
23                 Universite de Pau\r
24                 Avenue de l'Universite\r
25                 64000 Pau   FRANCE\r
26                  tel.  ++33 59923154    fax. ++33 59841696\r
27 \r
28 =======================================================================\r
29 */\r
30 \r
31 #include "depend.h"\r
32 #include "genint.h"\r
33 #include "int.h"\r
34 #include "process.h"\r
35 #include "intproto.h"\r
36 \r
37 #include <assert.h>\r
38 \r
39 \r
40 /* Execute one L-code instruction */\r
41 \r
42 \r
43 void execute()\r
44 {\r
45     word t1, t2;\r
46     int i;\r
47     real r;\r
48     virtaddr virt1, virt2, virt3;\r
49 \r
50 #ifdef TRACE\r
51     fprintf(stderr,"pix %d,ic %d,opcode %d\n",thispix,ic,opcode);fflush(stderr);\r
52 #endif\r
53 \r
54     switch (opcode)\r
55     {\r
56         case 1   : /* LOPENRC */\r
57                 openrc(a3, &virt2, &t2);\r
58                 storevirt(virt2, a1);\r
59                 M[ a2 ] = t2;\r
60                 break;\r
61         \r
62         case 2   : /* LBACKADDR */\r
63                 storevirt(thisp->backobj, a1);\r
64                 M[ a2 ] = M[ temporary ];\r
65                 break;\r
66         \r
67         case 3   : /* LRAISE */\r
68                 ic++;                   /* skip the address */\r
69                 raise_signal(a3, M[ ic-1 ], &t1, &t2);\r
70                 M[ a1 ] = t1;\r
71                 M[ a2 ] = t2;\r
72                 break;\r
73         \r
74         case 4   : /* LOPEN */\r
75                 openobj(M[ a3 ], &t1, &t2);\r
76                 M[ a1 ] = t1;\r
77                 M[ a2 ] = t2;\r
78                 break;\r
79         \r
80         case 5   : /* LSLOPEN */\r
81                 loadvirt(virt3, a3);\r
82                 slopen(M[ a3+APREF ], &virt3, &t1, &t2);\r
83                 M[ a1 ] = t1;\r
84                 M[ a2 ] = t2;\r
85                 break;\r
86 \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
91                 break;\r
92 \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
97                 break;\r
98 \r
99         case 21  : /* LSTATTYPE */\r
100                 M[ a1 ] = a2;\r
101                 M[ a1+1 ] = a3;\r
102                 break;\r
103 \r
104         case 23  : /* LIPAROUT */\r
105                 M[ a1 ] = param[ a3 ].xword;\r
106                 break;\r
107 \r
108         case 24  : /* LRPAROUT */\r
109                 MR(a1) = param[ a3 ].xreal;\r
110                 break;\r
111 \r
112         case 25  : /* LVPAROUT */\r
113                 storevirt(param[ a3 ].xvirt, a1);\r
114                 break;\r
115 \r
116         case 31  : /* LSIGN */\r
117                 if (M[ a2 ] == 0) M[ a1 ] = 0;\r
118                 else\r
119                     if (M[ a2 ] < 0) M[ a1 ] = -1;\r
120                     else M[ a1 ] = 1;\r
121                 break;\r
122                         \r
123         case 33  : /* LLOWER */\r
124         case 34  :\r
125                 loadvirt(virt2, a2);\r
126                 if (member(&virt2, &t1))\r
127                 {\r
128                     switch ((int) M[ t1+PROTNUM ])\r
129                     {\r
130                         case AINT  :  t2 = APINT;   break;\r
131                         case AREAL :  t2 = APREAL;  break;\r
132                         case AVIRT :  t2 = APREF;   break;\r
133                     }\r
134                     M[ a1 ] = (M[ t1+2 ]+3)/t2;\r
135                 }\r
136                 else errsignal(RTEREFTN);\r
137                 break;\r
138         \r
139         case 35  : /* LUPPER */\r
140         case 36  :\r
141                 loadvirt(virt2, a2);\r
142                 if (member(&virt2, &t1))\r
143                 {\r
144                     switch ((int) M[ t1+PROTNUM ])\r
145                     {\r
146                         case AINT  :  t2 = APINT;   break;\r
147                         case AREAL :  t2 = APREAL;  break;\r
148                         case AVIRT :  t2 = APREF;   break;\r
149                     }\r
150                     M[ a1 ] = (M[ t1+2 ]+M[ t1 ])/t2-1;\r
151                 }\r
152                 else errsignal(RTEREFTN);\r
153                 break;\r
154         \r
155         case 40  : /* LGETTYPE */\r
156                 typep(M[ a2 ], a3, &virt1.addr, &virt1.mark);\r
157                 storevirt(virt1, a1);\r
158                 break;\r
159         \r
160         case 41  : /* LCOPY */\r
161                 loadvirt(virt2, a2);\r
162                 copy(&virt2, &virt1);\r
163                 storevirt(virt1, a1);\r
164                 break;\r
165         \r
166         case 42  : /* LNOT */\r
167                 M[ a1 ] = ~ M[ a2 ];\r
168                 break;\r
169 \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
174                 break;\r
175 \r
176         case 44  : /* LVIRTDOT */\r
177         case 45  :\r
178                 M[ a1 ] = M[ prototype[ M[ temporary ] ]->virtlist+a2 ];\r
179                 break;\r
180 \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
185                 break;\r
186         \r
187         case 48  : /* LIABS */\r
188                 t2 = M[ a2 ];\r
189                 M[ a1 ] = absolute(t2);\r
190                 break;\r
191         \r
192         case 49  : /* LINEG */\r
193                 M[ a1 ] = -M[ a2 ];\r
194                 break;\r
195         \r
196         case 50  : /* LRABS */\r
197                 r = MR(a2);\r
198                 if( r < (real)0.0 )\r
199                    r=(real)0.0-r;\r
200                 MR(a1) = r;\r
201                 break;\r
202                 \r
203         case 51  : /* LRNEG */\r
204                 MR(a1) = -MR(a2);\r
205                 break;\r
206 \r
207         case 52  : /* LPARAMADDR */\r
208                 t2 = M[ a2 ];\r
209                 M[ a1 ] = t2+M[ prototype[ M[ t2+PROTNUM ] ]->parlist+a3 ];\r
210                 break;\r
211 \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
217                 break;\r
218         \r
219         case 55  : /* LIS */\r
220                 loadvirt(virt2, a2);\r
221                 M[ a1 ] = lbool(is(&virt2, a3));\r
222                 break;\r
223         \r
224         case 56  : /* LIN */\r
225                 loadvirt(virt2, a2);\r
226                 M[ a1 ] = lbool(inl(&virt2, a3));\r
227                 break;\r
228         \r
229         case 57  : /* LQUA */\r
230                 loadvirt(virt2, a2);\r
231                 if (member(&virt2, &M[ a1 ]))\r
232                     qua(&virt2, a3);\r
233                 else errsignal(RTEREFTN);\r
234                 break;\r
235 \r
236         case 58  : /* LIFIX */\r
237                 M[ a1 ] = (word)( MR(a2) );\r
238                 break;\r
239         \r
240         case 59  : /* LFLOAT */\r
241                 MR(a1) = (real)( M[ a2 ] );\r
242                 break;\r
243         \r
244         case 60  : /* LIMOVE */\r
245                 M[ a1 ] = M[ a2 ];\r
246                 break;\r
247         \r
248         case 61  : /* LVMOVE */\r
249                 loadvirt(virt1, a2);\r
250                 storevirt(virt1, a1);\r
251                 break;\r
252         \r
253         case 62  : /* LRMOVE */         /* WARNING: these areas may overlap! */\r
254                 r = MR(a2);\r
255                 MR(a1) = r;\r
256                 break;\r
257 \r
258         case 63  : /* LFPMOVE */        /* WARNING: these areas may overlap! */\r
259                 loadvirt(virt1, a2);    /* MACHINE DEPENDENT */\r
260                 t1 = M[ a2+2 ];\r
261                 storevirt(virt1, a1);\r
262                 M[ a1+2 ] = t1;\r
263                 break;\r
264 \r
265         case 82  : /* LEQNONE */\r
266                 M[ a1 ] = lbool(M[ a2+1 ] != M[ M[ a2 ]+1 ]);\r
267                 break;\r
268                 \r
269         case 83  : /* LNENONE */\r
270                 M[ a1 ] = lbool(M[ a2+1 ] == M[ M[ a2 ]+1 ]);\r
271                 break;\r
272                 \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
277                 break;\r
278 \r
279         case 100 : /* LOR */\r
280                 M[ a1 ] = M[ a2 ] | M[ a3 ];\r
281                 break;\r
282                 \r
283         case 101 : /* LAND */\r
284                 M[ a1 ] = M[ a2 ] & M[ a3 ];\r
285                 break;\r
286 \r
287         case 102 : /* LARRAY */\r
288         case 103 :\r
289         case 104 :\r
290                 loadvirt(virt2, a2);\r
291                 if (member(&virt2, &t2))\r
292                 {\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
296                 }\r
297                 else errsignal(RTEREFTN);\r
298                 break;\r
299                 \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
303                 break;\r
304                 \r
305         case 106 : /* LIEQUAL */\r
306                 M[ a1 ] = lbool(M[ a2 ] == M[ a3 ]);\r
307                 break;\r
308                                 \r
309         case 107 : /* LINEQUAL */\r
310                 M[ a1 ] = lbool(M[ a2 ] != M[ a3 ]);\r
311                 break;\r
312                                 \r
313         case 108 : /* LILT */\r
314                 M[ a1 ] = lbool(M[ a2 ] < M[ a3 ]);\r
315                 break;\r
316                                 \r
317         case 109 : /* LILE */\r
318                 M[ a1 ] = lbool(M[ a2 ] <= M[ a3 ]);\r
319                 break;\r
320                                 \r
321         case 110 : /* LIGT */\r
322                 M[ a1 ] = lbool(M[ a2 ] > M[ a3 ]);\r
323                 break;\r
324                                 \r
325         case 111 : /* LIGE */\r
326                 M[ a1 ] = lbool(M[ a2 ] >= M[ a3 ]);\r
327                 break;\r
328                                 \r
329         case 112 : /* LCOMBINE */\r
330                 loadvirt(virt2, a2);\r
331                 t1 = M[ a3 ];\r
332                 storevirt(virt2, a1);\r
333                 M[ a1+APREF ] = t1;\r
334                 break;\r
335                 \r
336         case 113 : /* LIADD */\r
337                 M[ a1 ] = M[ a2 ]+M[ a3 ];\r
338                 break;\r
339         \r
340         case 114 : /* LISUB */\r
341                 M[ a1 ] = M[ a2 ]-M[ a3 ];\r
342                 break;\r
343         \r
344         case 115 : /* LIMULT */\r
345                 M[ a1 ] = M[ a2 ] * M[ a3 ];\r
346                 break;\r
347         \r
348         case 116 : /* LSHIFT */\r
349                 M[ a1 ] = shift(M[ a2 ], M[ a3 ]);\r
350                 break;\r
351                 \r
352         case 117 : /* LIDIVE */\r
353                 if (M[ a3 ] == 0) errsignal(RTEDIVBZ);\r
354                 else M[ a1 ] = M[ a2 ] / M[ a3 ];\r
355                 break;\r
356         \r
357         case 118 : /* LIMODE */\r
358                 if (M[ a3 ] == 0) errsignal(RTEDIVBZ);\r
359                 else M[ a1 ] = M[ a2 ] % M[ a3 ];\r
360                 break;\r
361 \r
362         case 119 : /* LRADD */\r
363                 MR(a1) = MR(a2)+MR(a3);\r
364                 break;\r
365 \r
366         case 120 : /* LRSUB */\r
367                 MR(a1) = MR(a2)-MR(a3);\r
368                 break;\r
369 \r
370         case 121 : /* LRMULT */\r
371                 MR(a1) = MR(a2) * MR(a3);\r
372                 break;\r
373 \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
377                 break;\r
378 \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
385                 break;\r
386         \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
393                 break;\r
394                                 \r
395         case 125 : /* LREQ */\r
396                 M[ a1 ] = lbool(MR(a2) == MR(a3));\r
397                 break;\r
398                                 \r
399         case 126 : /* LRNE */\r
400                 M[ a1 ] = lbool(MR(a2) != MR(a3));\r
401                 break;\r
402                                 \r
403         case 127 : /* LRLT */\r
404                 M[ a1 ] = lbool(MR(a2) < MR(a3));\r
405                 break;\r
406                                 \r
407         case 128 : /* LRLE */\r
408                 M[ a1 ] = lbool(MR(a2) <= MR(a3));\r
409                 break;\r
410                                 \r
411         case 129 : /* LRGT */\r
412                 M[ a1 ] = lbool(MR(a2) > MR(a3));\r
413                 break;\r
414                                 \r
415         case 130 : /* LRGE */\r
416                 M[ a1 ] = lbool(MR(a2) >= MR(a3));\r
417                 break;\r
418                                 \r
419         case 131 : /* LXOR */\r
420                 M[ a1 ] = M[ a2 ] ^ M[ a3 ];\r
421                 break;\r
422 \r
423         case 132 : /* LCALLPROCSTAND */\r
424 #if USE_ALARM\r
425                 alarm(0);     /* reschedule forced so alarm may be switched off */\r
426 #endif\r
427       reschedule=TRUE;\r
428                 standard(a1);\r
429                 break;\r
430 \r
431         case 143 : /* LKILL */\r
432                 loadvirt(virt1, a1);\r
433                 disp(&virt1);\r
434                 break;\r
435 \r
436         case 144 : /* LHEADS */\r
437                 loadvirt(virt1, a1);\r
438                 heads(&virt1, a2);\r
439                 break;\r
440 \r
441         case 145 : /* LIPARINP */\r
442                 param[ a3 ].xword = M[ a1 ];\r
443                 break;\r
444         \r
445         case 146 : /* LGKILL */\r
446                 loadvirt(virt1, a1);\r
447                 gkill(&virt1);\r
448                 break;\r
449 \r
450         case 147 : /* LVPARINP */\r
451                 loadvirt(param[ a3 ].xvirt, a1);\r
452                 break;\r
453         \r
454         case 148 : /* LRPARINP */\r
455                 param[ a3 ].xreal = MR(a1);\r
456                 break;\r
457 \r
458         case 149 : /* LQUATEST */\r
459                 loadvirt(virt1, a1);\r
460                 qua(&virt1, a2);\r
461                 break;\r
462         \r
463         case 150 : /* LSTYPE */\r
464                 loadvirt(virt1, a1);\r
465                 typref(&virt1, a2);\r
466                 break;\r
467         \r
468         case 151 : /* LIFFALSE */\r
469                 if (M[ a1 ] == LFALSE) ic = a2;\r
470                 break;\r
471         \r
472         case 152 : /* LIFTRUE */\r
473                 if (M[ a1 ] == LTRUE) ic = a2;\r
474                 break;\r
475         \r
476         case 159 : /* LGO */\r
477                 go(M[ a2 ], M[ a1 ]);\r
478                 break;\r
479         \r
480         case 160 : /* LGOLOCAL */\r
481                 goloc(M[ a2 ], M[ a1 ]);\r
482                 break;\r
483 \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
489                 break;\r
490                 \r
491         case 172 : /* LTERMINATE */\r
492                 term();\r
493                 break;\r
494         \r
495         case 173 : /* LWIND */\r
496                 wind();\r
497                 break;\r
498 \r
499         case 174 : /* LBLOCK2 */\r
500                 goloc(thisp->blck1, thisp->blck2);\r
501                 break;\r
502         \r
503         case 176 : /* LBLOCK3 */\r
504                 disp(&thisp->backobj);\r
505                 break;\r
506                         \r
507         case 177 : /* LTRACE */\r
508                 trace(a1);\r
509                 break;\r
510 \r
511         case 178 : /* LINNER */\r
512                 inner(a1);\r
513                 break;\r
514 \r
515         case 180 : /* LBACKHD */\r
516                 backhd(&thisp->backobj, &M[ temporary ]);\r
517                 break;\r
518         \r
519         case 182 : /* LJUMP */\r
520                 ic = a1;\r
521                 break;\r
522 \r
523         case 186 : /* LBLOCK1 */\r
524                 openobj(a1, &thisp->blck1, &thisp->blck2);\r
525                 break;\r
526                 \r
527         case 187 : /* LDETACH */\r
528                 detach();\r
529                 break;\r
530         \r
531         case 188 : /* LATTACH */\r
532                 loadvirt(virt1, a1);\r
533                 attach(&virt1);\r
534                 break;\r
535                 \r
536         case 191 : /* LBACKBL */\r
537                 backbl(&thisp->backobj, &M[ temporary ]);\r
538                 break;\r
539                         \r
540         case 192 : /* LBACKPR */\r
541              /* backpr(&thisp->backobj, &M[ temporary ]); */\r
542                 back(&thisp->backobj, &M[ temporary ], (word) 0);\r
543                 break;\r
544                         \r
545         case 193 : /* LBACK */\r
546                 back(&thisp->backobj, &M[ temporary ], (word) 0);\r
547                 break;\r
548 \r
549         case 194 : /* LFIN */\r
550                 fin(ic-APOPCODE, &thisp->backobj, &M[ temporary ]);\r
551                 break;\r
552         \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
560                 else\r
561                     ic = M[ a2+2+t1 ];  /* indirect jump */\r
562                 break;\r
563 \r
564         case 220 : /* LRESUME */\r
565                 loadvirt(virt1, a1);\r
566                 resume(&virt1);\r
567                 break;\r
568 \r
569         case 221 : /* LSTOP */\r
570                 passivate(STOPPED);\r
571                 break;\r
572 \r
573         case 222 : /* LKILLTEMP */\r
574                 disp(&thisp->template);\r
575                 break;\r
576 \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
581                 break;\r
582 \r
583         case 224 : /* LDISABLE */\r
584                 for (i = 0;  i < a1;  i++)\r
585                     disable(thispix, virtprot(M[ ic++ ]));\r
586                 break;\r
587 \r
588         case 225 : /* LACCEPT1 */\r
589                 rpc_accept(a1);\r
590                 break;\r
591 \r
592         case 226 : /* LACCEPT2 */\r
593                 popmask(thispix);\r
594                 rpc3();\r
595                 break;\r
596 \r
597         case 227 : /* LBACKRPC */\r
598                 back(&thisp->backobj, &M[ temporary ], a1);\r
599                 break;\r
600 \r
601         case 228 : /* LASKPROT */\r
602                 loadvirt(virt1, a1);\r
603                 askprot(&virt1);\r
604                 break;\r
605 \r
606         case 240 : /* LSTEP */\r
607                 if (M[ a1 ] < 0) errsignal(RTENEGST);\r
608                 break;\r
609 \r
610         default  :\r
611                 fprintf( stderr, "Invalid opcode\n" );\r
612                 errsignal(RTESYSER);\r
613                 break;\r
614     }\r
615 \r
616 }\r
617 \r
618 \r