aboutsummaryrefslogtreecommitdiff
path: root/lua.stx
diff options
context:
space:
mode:
Diffstat (limited to 'lua.stx')
-rw-r--r--lua.stx771
1 files changed, 771 insertions, 0 deletions
diff --git a/lua.stx b/lua.stx
new file mode 100644
index 00000000..dc44cc12
--- /dev/null
+++ b/lua.stx
@@ -0,0 +1,771 @@
1%{
2
3char *rcs_luastx = "$Id: $";
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8
9#include "opcode.h"
10#include "hash.h"
11#include "inout.h"
12#include "table.h"
13#include "lua.h"
14
15#ifndef ALIGNMENT
16#define ALIGNMENT (sizeof(void *))
17#endif
18
19#ifndef MAXCODE
20#define MAXCODE 1024
21#endif
22static long buffer[MAXCODE];
23static Byte *code = (Byte *)buffer;
24static long mainbuffer[MAXCODE];
25static Byte *maincode = (Byte *)mainbuffer;
26static Byte *basepc;
27static Byte *pc;
28
29#define MAXVAR 32
30static long varbuffer[MAXVAR];
31static Byte nvarbuffer=0; /* number of variables at a list */
32
33static Word localvar[STACKGAP];
34static Byte nlocalvar=0; /* number of local variables */
35static int ntemp; /* number of temporary var into stack */
36static int err; /* flag to indicate error */
37
38/* Internal functions */
39#define align(n) align_n(sizeof(n))
40
41static void code_byte (Byte c)
42{
43 if (pc-basepc>MAXCODE-1)
44 {
45 lua_error ("code buffer overflow");
46 err = 1;
47 }
48 *pc++ = c;
49}
50
51static void code_word (Word n)
52{
53 if (pc-basepc>MAXCODE-sizeof(Word))
54 {
55 lua_error ("code buffer overflow");
56 err = 1;
57 }
58 *((Word *)pc) = n;
59 pc += sizeof(Word);
60}
61
62static void code_float (float n)
63{
64 if (pc-basepc>MAXCODE-sizeof(float))
65 {
66 lua_error ("code buffer overflow");
67 err = 1;
68 }
69 *((float *)pc) = n;
70 pc += sizeof(float);
71}
72
73static void incr_ntemp (void)
74{
75 if (ntemp+nlocalvar+MAXVAR+1 < STACKGAP)
76 ntemp++;
77 else
78 {
79 lua_error ("stack overflow");
80 err = 1;
81 }
82}
83
84static void add_nlocalvar (int n)
85{
86 if (ntemp+nlocalvar+MAXVAR+n < STACKGAP)
87 nlocalvar += n;
88 else
89 {
90 lua_error ("too many local variables or expression too complicate");
91 err = 1;
92 }
93}
94
95static void incr_nvarbuffer (void)
96{
97 if (nvarbuffer < MAXVAR-1)
98 nvarbuffer++;
99 else
100 {
101 lua_error ("variable buffer overflow");
102 err = 1;
103 }
104}
105
106static void align_n (unsigned size)
107{
108 if (size > ALIGNMENT) size = ALIGNMENT;
109 while (((pc+1-code)%size) != 0) /* +1 to include BYTECODE */
110 code_byte (NOP);
111}
112
113static void code_number (float f)
114{ int i = f;
115 if (f == i) /* f has an integer value */
116 {
117 if (i <= 2) code_byte(PUSH0 + i);
118 else if (i <= 255)
119 {
120 code_byte(PUSHBYTE);
121 code_byte(i);
122 }
123 else
124 {
125 align(Word);
126 code_byte(PUSHWORD);
127 code_word(i);
128 }
129 }
130 else
131 {
132 align(float);
133 code_byte(PUSHFLOAT);
134 code_float(f);
135 }
136 incr_ntemp();
137}
138
139%}
140
141
142%union
143{
144 int vInt;
145 long vLong;
146 float vFloat;
147 Word vWord;
148 Byte *pByte;
149}
150
151%start functionlist
152
153%token NIL
154%token IF THEN ELSE ELSEIF WHILE DO REPEAT UNTIL END
155%token RETURN
156%token LOCAL
157%token <vFloat> NUMBER
158%token <vWord> FUNCTION NAME STRING
159%token <vInt> DEBUG
160
161%type <pByte> PrepJump
162%type <vInt> expr, exprlist, exprlist1, varlist1, typeconstructor
163%type <vInt> fieldlist, localdeclist
164%type <vInt> ffieldlist, ffieldlist1
165%type <vInt> lfieldlist, lfieldlist1
166%type <vLong> var, objectname
167
168
169%left AND OR
170%left '=' NE '>' '<' LE GE
171%left CONC
172%left '+' '-'
173%left '*' '/'
174%left UNARY NOT
175
176
177%% /* beginning of rules section */
178
179
180functionlist : /* empty */
181 | functionlist {pc=basepc=maincode; nlocalvar=0;} stat sc {maincode=pc;}
182 | functionlist function
183 | functionlist setdebug
184 ;
185
186function : FUNCTION NAME {pc=basepc=code; nlocalvar=0;} '(' parlist ')'
187 {
188 if (lua_debug)
189 {
190 align(Word);
191 code_byte(SETFUNCTION);
192 code_word($1);
193 code_word($2);
194 }
195 lua_codeadjust (0);
196 }
197 block
198 END
199 {
200 if (lua_debug) code_byte(RESET);
201 code_byte(RETCODE); code_byte(nlocalvar);
202 s_tag($2) = T_FUNCTION;
203 s_bvalue($2) = calloc (pc-code, sizeof(Byte));
204 memcpy (s_bvalue($2), code, (pc-code)*sizeof(Byte));
205 }
206 ;
207
208statlist : /* empty */
209 | statlist stat sc
210 ;
211
212stat : {
213 ntemp = 0;
214 if (lua_debug)
215 {
216 align(Word); code_byte(SETLINE); code_word(lua_linenumber);
217 }
218 }
219 stat1
220
221sc : /* empty */ | ';' ;
222
223
224stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END
225 {
226 {
227 Byte *elseinit = $6 + sizeof(Word)+1;
228 if (pc - elseinit == 0) /* no else */
229 {
230 pc -= sizeof(Word)+1;
231 /* if (*(pc-1) == NOP) --pc; */
232 elseinit = pc;
233 }
234 else
235 {
236 *($6) = JMP;
237 *((Word *)($6+1)) = pc - elseinit;
238 }
239 *($4) = IFFJMP;
240 *((Word *)($4+1)) = elseinit - ($4 + sizeof(Word)+1);
241 }
242 }
243
244 | WHILE {$<pByte>$ = pc;} expr1 DO PrepJump block PrepJump END
245
246 {
247 *($5) = IFFJMP;
248 *((Word *)($5+1)) = pc - ($5 + sizeof(Word)+1);
249
250 *($7) = UPJMP;
251 *((Word *)($7+1)) = pc - $<pByte>2;
252 }
253
254 | REPEAT {$<pByte>$ = pc;} block UNTIL expr1 PrepJump
255
256 {
257 *($6) = IFFUPJMP;
258 *((Word *)($6+1)) = pc - $<pByte>2;
259 }
260
261
262 | varlist1 '=' exprlist1
263 {
264 {
265 int i;
266 if ($3 == 0 || nvarbuffer != ntemp - $1 * 2)
267 lua_codeadjust ($1 * 2 + nvarbuffer);
268 for (i=nvarbuffer-1; i>=0; i--)
269 lua_codestore (i);
270 if ($1 > 1 || ($1 == 1 && varbuffer[0] != 0))
271 lua_codeadjust (0);
272 }
273 }
274 | functioncall { lua_codeadjust (0); }
275 | typeconstructor { lua_codeadjust (0); }
276 | LOCAL localdeclist decinit { add_nlocalvar($2); lua_codeadjust (0); }
277 ;
278
279elsepart : /* empty */
280 | ELSE block
281 | ELSEIF expr1 THEN PrepJump block PrepJump elsepart
282 {
283 {
284 Byte *elseinit = $6 + sizeof(Word)+1;
285 if (pc - elseinit == 0) /* no else */
286 {
287 pc -= sizeof(Word)+1;
288 /* if (*(pc-1) == NOP) --pc; */
289 elseinit = pc;
290 }
291 else
292 {
293 *($6) = JMP;
294 *((Word *)($6+1)) = pc - elseinit;
295 }
296 *($4) = IFFJMP;
297 *((Word *)($4+1)) = elseinit - ($4 + sizeof(Word)+1);
298 }
299 }
300 ;
301
302block : {$<vInt>$ = nlocalvar;} statlist {ntemp = 0;} ret
303 {
304 if (nlocalvar != $<vInt>1)
305 {
306 nlocalvar = $<vInt>1;
307 lua_codeadjust (0);
308 }
309 }
310 ;
311
312ret : /* empty */
313 | { if (lua_debug){align(Word);code_byte(SETLINE);code_word(lua_linenumber);}}
314 RETURN exprlist sc
315 {
316 if (lua_debug) code_byte(RESET);
317 code_byte(RETCODE); code_byte(nlocalvar);
318 }
319 ;
320
321PrepJump : /* empty */
322 {
323 align(Word);
324 $$ = pc;
325 code_byte(0); /* open space */
326 code_word (0);
327 }
328
329expr1 : expr { if ($1 == 0) {lua_codeadjust (ntemp+1); incr_ntemp();}}
330 ;
331
332expr : '(' expr ')' { $$ = $2; }
333 | expr1 '=' expr1 { code_byte(EQOP); $$ = 1; ntemp--;}
334 | expr1 '<' expr1 { code_byte(LTOP); $$ = 1; ntemp--;}
335 | expr1 '>' expr1 { code_byte(LEOP); code_byte(NOTOP); $$ = 1; ntemp--;}
336 | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; ntemp--;}
337 | expr1 LE expr1 { code_byte(LEOP); $$ = 1; ntemp--;}
338 | expr1 GE expr1 { code_byte(LTOP); code_byte(NOTOP); $$ = 1; ntemp--;}
339 | expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; ntemp--;}
340 | expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; ntemp--;}
341 | expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; ntemp--;}
342 | expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; ntemp--;}
343 | expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; ntemp--;}
344 | '+' expr1 %prec UNARY { $$ = 1; }
345 | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 1;}
346 | typeconstructor { $$ = $1; }
347 | '@' '(' dimension ')'
348 {
349 code_byte(CREATEARRAY);
350 $$ = 1;
351 }
352 | var { lua_pushvar ($1); $$ = 1;}
353 | NUMBER { code_number($1); $$ = 1; }
354 | STRING
355 {
356 align(Word);
357 code_byte(PUSHSTRING);
358 code_word($1);
359 $$ = 1;
360 incr_ntemp();
361 }
362 | NIL {code_byte(PUSHNIL); $$ = 1; incr_ntemp();}
363 | functioncall
364 {
365 $$ = 0;
366 if (lua_debug)
367 {
368 align(Word); code_byte(SETLINE); code_word(lua_linenumber);
369 }
370 }
371 | NOT expr1 { code_byte(NOTOP); $$ = 1;}
372 | expr1 AND PrepJump {code_byte(POP); ntemp--;} expr1
373 {
374 *($3) = ONFJMP;
375 *((Word *)($3+1)) = pc - ($3 + sizeof(Word)+1);
376 $$ = 1;
377 }
378 | expr1 OR PrepJump {code_byte(POP); ntemp--;} expr1
379 {
380 *($3) = ONTJMP;
381 *((Word *)($3+1)) = pc - ($3 + sizeof(Word)+1);
382 $$ = 1;
383 }
384 ;
385
386typeconstructor: '@'
387 {
388 code_byte(PUSHBYTE);
389 $<pByte>$ = pc; code_byte(0);
390 incr_ntemp();
391 code_byte(CREATEARRAY);
392 }
393 objectname fieldlist
394 {
395 *($<pByte>2) = $4;
396 if ($3 < 0) /* there is no function to be called */
397 {
398 $$ = 1;
399 }
400 else
401 {
402 lua_pushvar ($3+1);
403 code_byte(PUSHMARK);
404 incr_ntemp();
405 code_byte(PUSHOBJECT);
406 incr_ntemp();
407 code_byte(CALLFUNC);
408 ntemp -= 4;
409 $$ = 0;
410 if (lua_debug)
411 {
412 align(Word); code_byte(SETLINE); code_word(lua_linenumber);
413 }
414 }
415 }
416 ;
417
418dimension : /* empty */ { code_byte(PUSHNIL); incr_ntemp();}
419 | expr1
420 ;
421
422functioncall : functionvalue {code_byte(PUSHMARK); $<vInt>$ = ntemp; incr_ntemp();}
423 '(' exprlist ')' { code_byte(CALLFUNC); ntemp = $<vInt>2-1;}
424
425functionvalue : var {lua_pushvar ($1); }
426 ;
427
428exprlist : /* empty */ { $$ = 1; }
429 | exprlist1 { $$ = $1; }
430 ;
431
432exprlist1 : expr { $$ = $1; }
433 | exprlist1 ',' {if (!$1){lua_codeadjust (ntemp+1); incr_ntemp();}}
434 expr {$$ = $4;}
435 ;
436
437parlist : /* empty */
438 | parlist1
439 ;
440
441parlist1 : NAME {localvar[nlocalvar]=$1; add_nlocalvar(1);}
442 | parlist1 ',' NAME {localvar[nlocalvar]=$3; add_nlocalvar(1);}
443 ;
444
445objectname : /* empty */ {$$=-1;}
446 | NAME {$$=$1;}
447 ;
448
449fieldlist : '{' ffieldlist '}' { $$ = $2; }
450 | '[' lfieldlist ']' { $$ = $2; }
451 ;
452
453ffieldlist : /* empty */ { $$ = 0; }
454 | ffieldlist1 { $$ = $1; }
455 ;
456
457ffieldlist1 : ffield {$$=1;}
458 | ffieldlist1 ',' ffield {$$=$1+1;}
459 ;
460
461ffield : NAME
462 {
463 align(Word);
464 code_byte(PUSHSTRING);
465 code_word(lua_findconstant (s_name($1)));
466 incr_ntemp();
467 }
468 '=' expr1
469 {
470 code_byte(STOREFIELD);
471 ntemp-=2;
472 }
473 ;
474
475lfieldlist : /* empty */ { $$ = 0; }
476 | lfieldlist1 { $$ = $1; }
477 ;
478
479lfieldlist1 : { code_number(1); } lfield {$$=1;}
480 | lfieldlist1 ',' { code_number($1+1); } lfield
481 {$$=$1+1;}
482 ;
483
484lfield : expr1
485 {
486 code_byte(STOREFIELD);
487 ntemp-=2;
488 }
489 ;
490
491varlist1 : var
492 {
493 nvarbuffer = 0;
494 varbuffer[nvarbuffer] = $1; incr_nvarbuffer();
495 $$ = ($1 == 0) ? 1 : 0;
496 }
497 | varlist1 ',' var
498 {
499 varbuffer[nvarbuffer] = $3; incr_nvarbuffer();
500 $$ = ($3 == 0) ? $1 + 1 : $1;
501 }
502 ;
503
504var : NAME
505 {
506 int local = lua_localname ($1);
507 if (local == -1) /* global var */
508 $$ = $1 + 1; /* return positive value */
509 else
510 $$ = -(local+1); /* return negative value */
511 }
512
513 | var {lua_pushvar ($1);} '[' expr1 ']'
514 {
515 $$ = 0; /* indexed variable */
516 }
517 | var {lua_pushvar ($1);} '.' NAME
518 {
519 align(Word);
520 code_byte(PUSHSTRING);
521 code_word(lua_findconstant (s_name($4))); incr_ntemp();
522 $$ = 0; /* indexed variable */
523 }
524 ;
525
526localdeclist : NAME {localvar[nlocalvar]=$1; $$ = 1;}
527 | localdeclist ',' NAME {localvar[nlocalvar+$1]=$3; $$ = $1+1;}
528 ;
529
530decinit : /* empty */
531 | '=' exprlist1
532 ;
533
534setdebug : DEBUG {lua_debug = $1;}
535
536%%
537
538/*
539** Search a local name and if find return its index. If do not find return -1
540*/
541static int lua_localname (Word n)
542{
543 int i;
544 for (i=nlocalvar-1; i >= 0; i--)
545 if (n == localvar[i]) return i; /* local var */
546 return -1; /* global var */
547}
548
549/*
550** Push a variable given a number. If number is positive, push global variable
551** indexed by (number -1). If negative, push local indexed by ABS(number)-1.
552** Otherwise, if zero, push indexed variable (record).
553*/
554static void lua_pushvar (long number)
555{
556 if (number > 0) /* global var */
557 {
558 align(Word);
559 code_byte(PUSHGLOBAL);
560 code_word(number-1);
561 incr_ntemp();
562 }
563 else if (number < 0) /* local var */
564 {
565 number = (-number) - 1;
566 if (number < 10) code_byte(PUSHLOCAL0 + number);
567 else
568 {
569 code_byte(PUSHLOCAL);
570 code_byte(number);
571 }
572 incr_ntemp();
573 }
574 else
575 {
576 code_byte(PUSHINDEXED);
577 ntemp--;
578 }
579}
580
581static void lua_codeadjust (int n)
582{
583 code_byte(ADJUST);
584 code_byte(n + nlocalvar);
585}
586
587static void lua_codestore (int i)
588{
589 if (varbuffer[i] > 0) /* global var */
590 {
591 align(Word);
592 code_byte(STOREGLOBAL);
593 code_word(varbuffer[i]-1);
594 }
595 else if (varbuffer[i] < 0) /* local var */
596 {
597 int number = (-varbuffer[i]) - 1;
598 if (number < 10) code_byte(STORELOCAL0 + number);
599 else
600 {
601 code_byte(STORELOCAL);
602 code_byte(number);
603 }
604 }
605 else /* indexed var */
606 {
607 int j;
608 int upper=0; /* number of indexed variables upper */
609 int param; /* number of itens until indexed expression */
610 for (j=i+1; j <nvarbuffer; j++)
611 if (varbuffer[j] == 0) upper++;
612 param = upper*2 + i;
613 if (param == 0)
614 code_byte(STOREINDEXED0);
615 else
616 {
617 code_byte(STOREINDEXED);
618 code_byte(param);
619 }
620 }
621}
622
623void yyerror (char *s)
624{
625 static char msg[256];
626 sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"",
627 s, lua_lasttext (), lua_linenumber, lua_filename());
628 lua_error (msg);
629 err = 1;
630}
631
632int yywrap (void)
633{
634 return 1;
635}
636
637
638/*
639** Parse LUA code and execute global statement.
640** Return 0 on success or 1 on error.
641*/
642int lua_parse (void)
643{
644 Byte *initcode = maincode;
645 err = 0;
646 if (yyparse () || (err==1)) return 1;
647 *maincode++ = HALT;
648 if (lua_execute (initcode)) return 1;
649 maincode = initcode;
650 return 0;
651}
652
653
654#if 0
655
656static void PrintCode (void)
657{
658 Byte *p = code;
659 printf ("\n\nCODE\n");
660 while (p != pc)
661 {
662 switch ((OpCode)*p)
663 {
664 case NOP: printf ("%d NOP\n", (p++)-code); break;
665 case PUSHNIL: printf ("%d PUSHNIL\n", (p++)-code); break;
666 case PUSH0: case PUSH1: case PUSH2:
667 printf ("%d PUSH%c\n", p-code, *p-PUSH0+'0');
668 p++;
669 break;
670 case PUSHBYTE:
671 printf ("%d PUSHBYTE %d\n", p-code, *(++p));
672 p++;
673 break;
674 case PUSHWORD:
675 printf ("%d PUSHWORD %d\n", p-code, *((Word *)(p+1)));
676 p += 1 + sizeof(Word);
677 break;
678 case PUSHFLOAT:
679 printf ("%d PUSHFLOAT %f\n", p-code, *((float *)(p+1)));
680 p += 1 + sizeof(float);
681 break;
682 case PUSHSTRING:
683 printf ("%d PUSHSTRING %d\n", p-code, *((Word *)(p+1)));
684 p += 1 + sizeof(Word);
685 break;
686 case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3:
687 case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7:
688 case PUSHLOCAL8: case PUSHLOCAL9:
689 printf ("%d PUSHLOCAL%c\n", p-code, *p-PUSHLOCAL0+'0');
690 p++;
691 break;
692 case PUSHLOCAL: printf ("%d PUSHLOCAL %d\n", p-code, *(++p));
693 p++;
694 break;
695 case PUSHGLOBAL:
696 printf ("%d PUSHGLOBAL %d\n", p-code, *((Word *)(p+1)));
697 p += 1 + sizeof(Word);
698 break;
699 case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break;
700 case PUSHMARK: printf ("%d PUSHMARK\n", (p++)-code); break;
701 case PUSHOBJECT: printf ("%d PUSHOBJECT\n", (p++)-code); break;
702 case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3:
703 case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7:
704 case STORELOCAL8: case STORELOCAL9:
705 printf ("%d STORELOCAL%c\n", p-code, *p-STORELOCAL0+'0');
706 p++;
707 break;
708 case STORELOCAL:
709 printf ("%d STORELOCAK %d\n", p-code, *(++p));
710 p++;
711 break;
712 case STOREGLOBAL:
713 printf ("%d STOREGLOBAL %d\n", p-code, *((Word *)(p+1)));
714 p += 1 + sizeof(Word);
715 break;
716 case STOREINDEXED0: printf ("%d STOREINDEXED0\n", (p++)-code); break;
717 case STOREINDEXED: printf ("%d STOREINDEXED %d\n", p-code, *(++p));
718 p++;
719 break;
720 case STOREFIELD: printf ("%d STOREFIELD\n", (p++)-code); break;
721 case ADJUST:
722 printf ("%d ADJUST %d\n", p-code, *(++p));
723 p++;
724 break;
725 case CREATEARRAY: printf ("%d CREATEARRAY\n", (p++)-code); break;
726 case EQOP: printf ("%d EQOP\n", (p++)-code); break;
727 case LTOP: printf ("%d LTOP\n", (p++)-code); break;
728 case LEOP: printf ("%d LEOP\n", (p++)-code); break;
729 case ADDOP: printf ("%d ADDOP\n", (p++)-code); break;
730 case SUBOP: printf ("%d SUBOP\n", (p++)-code); break;
731 case MULTOP: printf ("%d MULTOP\n", (p++)-code); break;
732 case DIVOP: printf ("%d DIVOP\n", (p++)-code); break;
733 case CONCOP: printf ("%d CONCOP\n", (p++)-code); break;
734 case MINUSOP: printf ("%d MINUSOP\n", (p++)-code); break;
735 case NOTOP: printf ("%d NOTOP\n", (p++)-code); break;
736 case ONTJMP:
737 printf ("%d ONTJMP %d\n", p-code, *((Word *)(p+1)));
738 p += sizeof(Word) + 1;
739 break;
740 case ONFJMP:
741 printf ("%d ONFJMP %d\n", p-code, *((Word *)(p+1)));
742 p += sizeof(Word) + 1;
743 break;
744 case JMP:
745 printf ("%d JMP %d\n", p-code, *((Word *)(p+1)));
746 p += sizeof(Word) + 1;
747 break;
748 case UPJMP:
749 printf ("%d UPJMP %d\n", p-code, *((Word *)(p+1)));
750 p += sizeof(Word) + 1;
751 break;
752 case IFFJMP:
753 printf ("%d IFFJMP %d\n", p-code, *((Word *)(p+1)));
754 p += sizeof(Word) + 1;
755 break;
756 case IFFUPJMP:
757 printf ("%d IFFUPJMP %d\n", p-code, *((Word *)(p+1)));
758 p += sizeof(Word) + 1;
759 break;
760 case POP: printf ("%d POP\n", (p++)-code); break;
761 case CALLFUNC: printf ("%d CALLFUNC\n", (p++)-code); break;
762 case RETCODE:
763 printf ("%d RETCODE %d\n", p-code, *(++p));
764 p++;
765 break;
766 default: printf ("%d Cannot happen\n", (p++)-code); break;
767 }
768 }
769}
770#endif
771