2
This software may only be used by you under license from AT&T Corp.
3
("AT&T"). A copy of AT&T's Source Code Agreement is available at
4
AT&T's Internet website having the URL:
5
<http://www.research.att.com/sw/tools/graphviz/license/source.html>
6
If you received this software without first entering into a license
7
with AT&T, you have an infringing copy of this software and cannot use
8
it without violating AT&T's intellectual property rights.
12
/* Lefteris Koutsofios - AT&T Bell Laboratories */
23
static int lvarn, llvari, flvari;
25
#define LVARSIZE sizeof (lvar_t)
30
int Eerrlevel, Estackdepth, Eshowbody, Eshowcalls, Eoktorun;
32
#define PUSHJMP(op, np, b) op = (volatile jmp_buf *) np, np = (jmp_buf *) &b
33
#define POPJMP(op, np) np = (jmp_buf *) op
35
/* longjmps for normal program execution */
37
PLJ_BREAK, PLJ_CONTINUE, PLJ_RETURN, PLJ_SIZE
39
static jmp_buf *pljbufp1, *pljbufp2;
40
static PLJtype_t pljtype;
42
/* longjmp for error handling */
43
static jmp_buf *eljbufp;
45
/* error levels and types */
47
ERR0, ERR1, ERR2, ERR3, ERR4, ERR5
50
ERRNOLHS, ERRNORHS, ERRNOSUCHFUNC, ERRBADARG, ERRARGMIS, ERRNOTATABLE,
51
ERRIFUNCERR, ERRRECRUN, ERRTABLECHANGED
53
static char *errnam[] = {
58
"argument number mismatch",
60
"internal function call error",
61
"recursive run attempt",
62
"table changed during a forin loop",
67
/* stack information */
68
typedef struct sinfo_t {
73
#define SINFOSIZE sizeof (sinfo_t)
75
static sinfo_t *sinfop;
76
static int sinfoi, sinfon;
81
typedef struct tnk_t {
96
typedef struct Num_t {
108
static Tobj eeval (Tobj, int);
109
static Tobj efcall (Tobj, int);
110
static void ewhilest (Tobj, int);
111
static void eforst (Tobj, int);
112
static void eforinst (Tobj, int);
114
static Tobj getval (Tobj, int);
115
static int getvar (Tobj, int, tnk_t *);
116
static void setvar (tnk_t, Tobj);
117
static int boolop (Tobj);
118
static int orderop (Tobj, Ctype_t, Tobj);
119
static Tobj arithop (Num_t *, Ctype_t, Num_t *);
120
static void err (int, int, Tobj, int);
121
static void printbody (char *, int);
125
rootm = Mpushmark (root);
126
Tinss (root, "null", (null = Ttable (2)));
128
pljbufp1 = pljbufp2 = NULL, pljtype = 0;
130
lvarp = Marrayalloc ((long) LVARINCR * LVARSIZE);
134
sinfop = Marrayalloc ((long) SINFOINCR * SINFOSIZE);
143
Marrayfree (sinfop), sinfop = NULL, sinfon = 0, sinfoi = 0;
144
Marrayfree (lvarp), lvarp = NULL, lvarn = 0, llvari = 0, flvari = 0;
150
Tobj Eunit (Tobj co) {
151
volatile jmp_buf *oeljbufp;
152
volatile int ownsinfoi;
159
if (running && !Eoktorun) {
160
err (ERRRECRUN, ERR2, NULL, 0);
169
if (Tgettype (co) != T_CODE)
170
panic (POS, "Eunit", "argument type is not T_CODE");
173
PUSHJMP (oeljbufp, eljbufp, eljbuf);
174
ownsinfoi = sinfoi++;
175
if (sinfoi == sinfon) {
176
sinfop = Marraygrow (sinfop, (long) (sinfon + SINFOINCR) * SINFOSIZE);
179
sinfop[ownsinfoi].co = co;
180
sinfop[ownsinfoi].ci = TCgetfp (co, 0);
181
sinfop[ownsinfoi].fco = NULL;
182
sinfop[ownsinfoi].flvari = flvari;
183
sinfop[ownsinfoi].llvari = llvari;
185
if (setjmp (*eljbufp))
188
lrtno = eeval (co, TCgetfp (co, 0));
191
flvari = sinfop[ownsinfoi].flvari;
192
llvari = sinfop[ownsinfoi].llvari;
194
POPJMP (oeljbufp, eljbufp);
200
/* shortcut: this function executes a piece of code that corresponds to
201
<internal func name> = function () internal "<internal func name>";
203
Tobj Efunction (Tobj co, char *ifnam) {
207
fi = TCgetnext (co, TCgetfp (co, TCgetfp (co, 0)));
208
v1o = Tcode (TCgetaddr (co, fi), fi,
209
(int) TCgetinteger (co, TCgetfp (co, fi)));
210
Tinss (root, ifnam, v1o);
214
static Tobj eeval (Tobj co, int ci) {
226
ctype = TCgettype (co, ci);
229
i1 = TCgetfp (co, ci);
230
if ((v1o = eeval (co, TCgetnext (co, i1))) == NULL) {
231
err (ERRNORHS, ERR4, co, TCgetnext (co, i1));
234
m1 = Mpushmark (v1o);
235
res = getvar (co, i1, &tnk);
238
err (ERRNOLHS, ERR3, co, i1);
246
i1 = TCgetfp (co, ci);
247
if ((v1o = eeval (co, i1)) == NULL)
248
err (ERRNORHS, ERR4, co, i1);
251
if (boolop (v1o) == TRUE)
253
if ((v1o = eeval (co, TCgetnext (co, i1))) == NULL)
254
err (ERRNORHS, ERR4, co, TCgetnext (co, i1));
255
return (boolop (v1o) == TRUE) ? Ttrue: Tfalse;
257
if (boolop (v1o) == FALSE)
259
if ((v1o = eeval (co, TCgetnext (co, i1))) == NULL)
260
err (ERRNORHS, ERR4, co, TCgetnext (co, i1));
261
return (boolop (v1o) == FALSE) ? Tfalse: Ttrue;
263
return (boolop (v1o) == TRUE) ? Tfalse: Ttrue;
273
i1 = TCgetfp (co, ci);
274
if ((v1o = eeval (co, i1)) == NULL)
275
err (ERRNORHS, ERR4, co, i1);
277
m1 = Mpushmark (v1o);
278
if ((v2o = eeval (co, TCgetnext (co, i1))) == NULL)
279
err (ERRNORHS, ERR4, co, TCgetnext (co, i1));
282
return (orderop (v1o, ctype, v2o) == TRUE) ? Ttrue: Tfalse;
289
i1 = TCgetfp (co, ci);
290
if ((lnum.type = TCgettype (co, i1)) == C_INTEGER)
291
lnum.u.i = TCgetinteger (co, i1);
292
else if (lnum.type == C_REAL)
293
lnum.u.d = TCgetreal (co, i1);
294
else if ((lnum.u.no = eeval (co, i1)) == NULL) {
295
err (ERRNORHS, ERR4, co, i1);
298
if (ctype == C_UMINUS) {
299
if (!(v1o = arithop (&lnum, ctype, NULL)))
300
err (ERRNORHS, ERR4, co, ci);
303
if (lnum.type != C_INTEGER && lnum.type != C_REAL)
304
m1 = Mpushmark (lnum.u.no);
305
i1 = TCgetnext (co, i1);
306
if ((rnum.type = TCgettype (co, i1)) == C_INTEGER)
307
rnum.u.i = TCgetinteger (co, i1);
308
else if (rnum.type == C_REAL)
309
rnum.u.d = TCgetreal (co, i1);
310
else if ((rnum.u.no = eeval (co, i1)) == NULL)
311
err (ERRNORHS, ERR4, co, i1);
312
if (lnum.type != C_INTEGER && lnum.type != C_REAL)
314
if (!(v1o = arithop (&lnum, ctype, &rnum)))
315
err (ERRNORHS, ERR4, co, ci);
318
ci = TCgetfp (co, ci);
321
return efcall (co, ci);
323
return Tinteger (TCgetinteger (co, ci));
325
return Treal (TCgetreal (co, ci));
327
return Tstring (TCgetstring (co, ci));
331
return getval (co, ci);
333
return Tcode (TCgetaddr (co, ci), ci,
334
(int) TCgetinteger (co, TCgetfp (co, ci)));
337
m1 = Mpushmark (v1o);
338
for (i1 = TCgetfp (co, ci); i1 != C_NULL;
339
i1 = TCgetnext (co, TCgetnext (co, i1))) {
340
if (!(v3o = eeval (co, TCgetnext (co, i1)))) {
341
err (ERRNORHS, ERR4, co, TCgetnext (co, i1));
344
m2 = Mpushmark (v3o);
345
if (!(v2o = eeval (co, i1))) {
346
err (ERRNOLHS, ERR3, co, i1);
350
ttype = Tgettype (v2o);
351
if (ttype == T_INTEGER || ttype == T_REAL || ttype == T_STRING)
352
Tinso (v1o, v2o, v3o);
354
err (ERRNOLHS, ERR1, co, i1);
359
for (i1 = TCgetfp (co, ci); i1 != C_NULL; )
360
if ((i2 = TCgetnext (co, i1)) != C_NULL) {
370
i1 = TCgetfp (co, ci);
371
if (!(v1o = eeval (co, i1)))
372
err (ERRNORHS, ERR5, co, i1);
373
if (boolop (v1o) == TRUE) {
374
ci = TCgetnext (co, i1);
376
} else if ((ci = TCgetnext (co, TCgetnext (co, i1))) != C_NULL)
390
longjmp (*pljbufp1, 1);
394
pljtype = PLJ_CONTINUE;
395
longjmp (*pljbufp1, 1);
399
if ((i1 = TCgetfp (co, ci)) != C_NULL)
400
rtno = eeval (co, i1);
401
pljtype = PLJ_RETURN;
402
longjmp (*pljbufp2, 1);
406
panic (POS, "eeval", "unknown program token type %d", ctype);
411
static Tobj efcall (Tobj co, int ci) {
412
volatile jmp_buf *opljbufp1, *opljbufp2;
414
volatile int bi, ownsinfoi, li, ln;
418
int i, fci, ai, di, di1, fid;
420
ownsinfoi = sinfoi++;
421
if (sinfoi == sinfon) {
422
sinfop = Marraygrow (sinfop, (long) (sinfon + SINFOINCR) * SINFOSIZE);
425
sinfop[ownsinfoi].co = co;
426
sinfop[ownsinfoi].ci = ci;
427
sinfop[ownsinfoi].fco = NULL;
428
sinfop[ownsinfoi].flvari = flvari;
429
sinfop[ownsinfoi].llvari = llvari;
430
fci = TCgetfp (co, ci);
431
if (!(fdo = getval (co, fci)) || Tgettype (fdo) != T_CODE) {
432
err (ERRNOSUCHFUNC, ERR2, co, fci);
437
m = Mpushmark ((Tobj) fdo);
438
ai = TCgetfp (co, TCgetnext (co, fci));
439
ln = (int) TCgetinteger (fdo, (li = TCgetnext (fdo, TCgetfp (fdo, 0))));
440
di = TCgetnext (fdo, li);
441
bi = TCgetnext (fdo, di);
442
if (bi != C_NULL && TCgettype (fdo, bi) == C_INTERNAL) {
443
for (i = 0; ai != C_NULL; ai = TCgetnext (co, ai), i++) {
444
if (!(vo = eeval (co, ai))) {
445
err (ERRBADARG, ERR2, co, ai);
447
llvari = sinfop[ownsinfoi].llvari;
451
if (llvari + 1 > lvarn) {
452
lvarp = Marraygrow (lvarp, (long) (llvari + 1) * LVARSIZE);
455
lvarp[llvari].m = Mpushmark ((lvarp[llvari].o = vo));
458
fid = (int) TCgetinteger (fdo, TCgetfp (fdo, bi));
459
if (Ifuncs[fid].min > i || Ifuncs[fid].max < i) {
460
err (ERRARGMIS, ERR2, co, ci);
462
llvari = sinfop[ownsinfoi].llvari;
466
flvari = sinfop[ownsinfoi].llvari;
467
sinfop[ownsinfoi].fco = fdo;
468
sinfop[ownsinfoi].fci = bi;
469
if (fid < 0 || fid >= Ifuncn)
470
panic (POS, "efcall", "no such internal function: %d", fid);
472
if ((*Ifuncs[fid].func) (i, &lvarp[flvari]) == L_FAILURE) {
474
err (ERRIFUNCERR, ERR2, co, ci);
477
if (llvari + ln > lvarn) {
478
lvarp = Marraygrow (lvarp, (long) (llvari + ln) * LVARSIZE);
481
di1 = TCgetfp (fdo, di);
482
for (i = 0; i < ln && di1 != C_NULL && ai != C_NULL;
483
i++, ai = TCgetnext (co, ai)) {
484
if (!(vo = eeval (co, ai))) {
485
err (ERRBADARG, ERR2, co, ai);
487
llvari = sinfop[ownsinfoi].llvari;
491
lvarp[llvari].m = Mpushmark ((lvarp[llvari].o = vo));
493
di1 = TCgetnext (fdo, di1);
495
if (di1 != C_NULL || ai != C_NULL) {
496
err (ERRARGMIS, ERR2, co, ci);
498
llvari = sinfop[ownsinfoi].llvari;
502
for (; i < ln; i++, llvari++)
503
lvarp[llvari].m = Mpushmark ((lvarp[llvari].o = NULL));
504
flvari = sinfop[ownsinfoi].llvari;
505
PUSHJMP (opljbufp2, pljbufp2, pljbuf);
506
opljbufp1 = (volatile jmp_buf *) pljbufp1;
507
if (setjmp (*pljbufp2)) {
510
sinfop[ownsinfoi].fco = fdo;
511
for (; bi != C_NULL; bi = TCgetnext (fdo, bi)) {
512
sinfop[ownsinfoi].fci = bi;
513
if (TCgettype (fdo, bi) != C_DECL)
514
eeval ((Tobj) fdo, bi);
517
POPJMP (opljbufp2, pljbufp2);
518
pljbufp1 = (jmp_buf *) opljbufp1;
520
flvari = sinfop[ownsinfoi].flvari;
521
llvari = sinfop[ownsinfoi].llvari;
524
lrtno = rtno, rtno = NULL;
529
static void ewhilest (Tobj co, int ci) {
530
volatile jmp_buf *opljbufp;
531
volatile jmp_buf pljbuf;
537
c1o = (volatile Tobj) co; /* protect argument from longjmp */
538
ei = TCgetfp (c1o, ci);
539
si = TCgetnext (c1o, ei);
540
PUSHJMP (opljbufp, pljbufp1, pljbuf);
542
if (!(v1o = eeval ((Tobj) c1o, ei)))
543
err (ERRNORHS, ERR5, c1o, ei);
544
if (boolop (v1o) == FALSE)
546
if (setjmp (*pljbufp1)) {
547
if (pljtype == PLJ_CONTINUE)
549
else if (pljtype == PLJ_BREAK)
552
eeval ((Tobj) c1o, si);
554
POPJMP (opljbufp, pljbufp1);
557
static void eforst (Tobj co, int ci) {
558
volatile jmp_buf *opljbufp;
559
volatile jmp_buf pljbuf;
561
volatile int ei1, ei2, ei3, si, eisnop1, eisnop2, eisnop3;
565
c1o = (volatile Tobj) co; /* protect argument from longjmp */
566
ei1 = TCgetfp (c1o, ci);
567
ei2 = TCgetnext (c1o, ei1);
568
ei3 = TCgetnext (c1o, ei2);
569
si = TCgetnext (c1o, ei3);
570
eisnop1 = (TCgettype (c1o, ei1) == C_NOP);
571
eisnop2 = (TCgettype (c1o, ei2) == C_NOP);
572
eisnop3 = (TCgettype (c1o, ei3) == C_NOP);
573
PUSHJMP (opljbufp, pljbufp1, pljbuf);
575
eeval ((Tobj) c1o, ei1);
578
if (!(v1o = eeval ((Tobj) c1o, ei2)))
579
err (ERRNORHS, ERR5, c1o, ei2);
580
if (boolop (v1o) == FALSE)
583
if (setjmp (*pljbufp1) != 0) {
584
if (pljtype == PLJ_CONTINUE)
586
else if (pljtype == PLJ_BREAK)
589
eeval ((Tobj) c1o, si);
592
eeval ((Tobj) c1o, ei3);
594
POPJMP (opljbufp, pljbufp1);
597
static void eforinst (Tobj co, int ci) {
598
volatile jmp_buf *opljbufp;
599
volatile jmp_buf pljbuf;
600
volatile Tobj tblo, c1o;
601
volatile Tkvindex_t tkvi;
604
volatile int ei1, ei2, si;
606
c1o = (volatile Tobj) co; /* protect argument from longjmp */
607
ei1 = TCgetfp (c1o, ci);
608
ei2 = TCgetnext (c1o, ei1);
609
si = TCgetnext (c1o, ei2);
610
if (getvar ((Tobj) c1o, ei1, (tnk_t *) &tnk) == -1) {
611
err (ERRNOLHS, ERR3, c1o, ei1);
614
if (tnk.type == TNK_O)
615
km = Mpushmark (tnk.u.tnko.ko);
616
if (!(tblo = (volatile Tobj) eeval ((Tobj) c1o, ei2))) {
617
if (tnk.type == TNK_O)
619
err (ERRNORHS, ERR4, c1o, ei2);
622
if (Tgettype (tblo) != T_TABLE) {
623
err (ERRNOTATABLE, ERR1, c1o, ei2);
626
PUSHJMP (opljbufp, pljbufp1, pljbuf);
628
for (Tgetfirst ((Tobj) tblo, (Tkvindex_t *) &tkvi); tkvi.kvp;
629
Tgetnext ((Tkvindex_t *) &tkvi)) {
630
setvar (tnk, tkvi.kvp->ko);
631
if (setjmp (*pljbufp1) != 0) {
632
if (pljtype == PLJ_CONTINUE)
634
else if (pljtype == PLJ_BREAK)
637
eeval ((Tobj) c1o, si);
638
if (t != Tgettime (tblo)) {
639
err (ERRTABLECHANGED, ERR1, c1o, ei2);
643
POPJMP (opljbufp, pljbufp1);
644
if (tnk.type == TNK_O)
648
static Tobj getval (Tobj co, int ci) {
653
if ((ct = TCgettype (co, ci)) == C_LVAR) {
654
nn = (int) TCgetinteger (co, (ni = TCgetnext (co, TCgetfp (co, ci))));
655
cto = cvo = lvarp[flvari + nn].o;
658
vi = TCgetnext (co, ni);
659
} else if (ct == C_GVAR) {
661
vi = TCgetfp (co, ci);
662
} else if (ct == C_PVAR)
663
return TCgetobject (co, ci);
667
while (vi != C_NULL) {
668
if (Tgettype (cto) != T_TABLE)
670
if ((vt = TCgettype (co, vi)) == C_STRING) {
671
if (!(cvo = Tfinds (cto, TCgetstring (co, vi))))
673
} else if (vt == C_INTEGER) {
674
if (!(cvo = Tfindi (cto, TCgetinteger (co, vi))))
676
} else if (vt == C_REAL) {
677
if (!(cvo = Tfindr (cto, TCgetreal (co, vi))))
680
if (!(cko = eeval (co, vi)) || !(cvo = Tfindo (cto, cko)))
684
vi = TCgetnext (co, vi);
689
static int getvar (Tobj co, int ci, tnk_t *tnkp) {
695
if ((ct = TCgettype (co, ci)) == C_LVAR) {
696
nn = (int) TCgetinteger (co, (ni = TCgetnext (co, TCgetfp (co, ci))));
697
cvo = cto = lvarp[flvari + nn].o;
698
vi = TCgetnext (co, ni);
699
if (vi != C_NULL && (!cvo || Tgettype (cvo) != T_TABLE))
700
Mresetmark (lvarp[flvari + nn].m,
701
(lvarp[flvari + nn].o = cvo = cto = Ttable (0)));
702
} else if (ct == C_GVAR) { /* else it's a global variable */
704
vi = TCgetfp (co, ci);
710
while (vi != C_NULL) {
712
if ((vt = TCgettype (co, vi)) == C_STRING) {
713
cvo = Tfinds (cto, TCgetstring (co, vi));
714
} else if (vt == C_INTEGER) {
715
cvo = Tfindi (cto, TCgetinteger (co, vi));
716
} else if (vt == C_REAL) {
717
cvo = Tfindr (cto, TCgetreal (co, vi));
719
if (!(cko = eeval (co, vi)) || !(T_ISSTRING (cko) ||
722
cvo = Tfindo (cto, cko);
724
ovi = vi, vi = TCgetnext (co, vi);
725
if (vi != C_NULL && (!cvo || Tgettype (cvo) != T_TABLE)) {
727
Tinss (cto, TCgetstring (co, ovi), (cvo = Ttable (0)));
728
else if (vt == C_INTEGER)
729
Tinsi (cto, TCgetinteger (co, ovi), (cvo = Ttable (0)));
730
else if (vt == C_REAL)
731
Tinsr (cto, TCgetreal (co, ovi), (cvo = Ttable (0)));
733
m = Mpushmark (cko), Tinso (cto, cko, (cvo = Ttable (0))),
737
if (ct == C_LVAR && ovi == -1) {
746
tnkp->u.tnks.kt = vt;
747
tnkp->u.tnks.to = cto;
748
tnkp->u.tnks.co = co;
749
tnkp->u.tnks.vi = ovi;
753
tnkp->u.tnko.to = cto;
754
tnkp->u.tnko.ko = cko;
761
static void setvar (tnk_t tnk, Tobj vo) {
764
Mresetmark (lvarp[flvari + tnk.u.li].m,
765
(lvarp[flvari + tnk.u.li].o = vo));
768
Tinso (tnk.u.tnko.to, tnk.u.tnko.ko, vo);
771
switch (tnk.u.tnks.kt) {
773
Tinss (tnk.u.tnks.to,
774
TCgetstring (tnk.u.tnks.co, tnk.u.tnks.vi), vo);
777
Tinsi (tnk.u.tnks.to,
778
TCgetinteger (tnk.u.tnks.co, tnk.u.tnks.vi), vo);
781
Tinsr (tnk.u.tnks.to, TCgetreal (tnk.u.tnks.co, tnk.u.tnks.vi), vo);
788
static int boolop (Tobj vo) {
795
switch (Tgettype (vo)) {
797
i = Tgetinteger (vo);
798
return (i == 0) ? FALSE : TRUE;
801
return (d == 0.0) ? FALSE : TRUE;
811
static int orderop (Tobj v1o, Ctype_t op, Tobj v2o) {
818
if ((v1o || v2o) && op == C_NE)
822
t1 = Tgettype (v1o), t2 = Tgettype (v2o);
823
if (t1 == T_STRING && t2 == T_STRING) {
824
r = Strcmp (Tgetstring (v1o), Tgetstring (v2o));
825
} else if (t1 == T_INTEGER && t2 == T_INTEGER) {
826
i1 = Tgetinteger (v1o), i2 = Tgetinteger (v2o);
827
r = (i1 == i2) ? 0 : ((i1 < i2) ? -1 : 1);
828
} else if (t1 == T_INTEGER && t2 == T_REAL) {
829
i1 = Tgetinteger (v1o), d2 = Tgetreal (v2o);
830
r = (i1 == d2) ? 0 : ((i1 < d2) ? -1 : 1);
831
} else if (t1 == T_REAL && t2 == T_INTEGER) {
832
d1 = Tgetreal (v1o), i2 = Tgetinteger (v2o);
833
r = (d1 == i2) ? 0 : ((d1 < i2) ? -1 : 1);
834
} else if (t1 == T_REAL && t2 == T_REAL) {
835
d1 = Tgetreal (v1o), d2 = Tgetreal (v2o);
836
r = (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
837
} else if (t1 == t2) {
838
if (op != C_EQ && op != C_NE)
840
r = (v1o == v2o) ? 0 : 1;
845
case C_EQ: return (r == 0) ? TRUE : FALSE;
846
case C_NE: return (r != 0) ? TRUE : FALSE;
847
case C_LT: return (r < 0) ? TRUE : FALSE;
848
case C_LE: return (r <= 0) ? TRUE : FALSE;
849
case C_GT: return (r > 0) ? TRUE : FALSE;
850
case C_GE: return (r >= 0) ? TRUE : FALSE;
852
panic (POS, "orderop", "bad op code");
853
return FALSE; /* NOT REACHED */
856
static Tobj arithop (Num_t *lnum, Ctype_t op, Num_t *rnum) {
859
if (!rnum && op != C_UMINUS)
861
if (lnum->type == C_INTEGER)
863
else if (lnum->type == C_REAL)
865
else if (!lnum->u.no)
867
else if (Tgettype (lnum->u.no) == T_INTEGER)
868
d1 = Tgetinteger (lnum->u.no);
869
else if (Tgettype (lnum->u.no) == T_REAL)
870
d1 = Tgetreal (lnum->u.no);
873
if (op == C_UMINUS) {
877
if (rnum->type == C_INTEGER)
879
else if (rnum->type == C_REAL)
881
else if (!rnum->u.no)
883
else if (Tgettype (rnum->u.no) == T_INTEGER)
884
d2 = Tgetinteger (rnum->u.no);
885
else if (Tgettype (rnum->u.no) == T_REAL)
886
d2 = Tgetreal (rnum->u.no);
890
case C_PLUS: d3 = d1 + d2; break;
891
case C_MINUS: d3 = d1 - d2; break;
892
case C_MUL: d3 = d1 * d2; break;
893
case C_DIV: d3 = d1 / d2; break;
894
case C_MOD: d3 = (long) d1 % (long) d2; break;
897
if (d3 == (double) (long) d3)
898
return Tinteger ((long) d3);
902
static void err (int errnum, int level, Tobj co, int ci) {
906
if (level > Eerrlevel || !errdo)
909
fprintf (stderr, "runtime error: %s\n", errnam[errnum]);
914
if (!sinfop[(si = sinfoi - 1)].fco && si > 0)
917
if (co == sinfop[si].fco)
918
s = Scfull (co, 0, ci);
919
else if (co == sinfop[si].co)
920
s = Scfull (co, TCgetfp (co, 0), ci);
921
printbody (s, Eshowbody), free (s);
922
if (Estackdepth == 1) {
923
fprintf (stderr, "\n");
926
for (i = si; i >= 0; i--) {
928
s = Scfull (sinfop[i].fco, 0, sinfop[i].fci);
929
printbody (s, Eshowbody), free (s);
932
s = Scfull (sinfop[0].co, TCgetfp (sinfop[0].co, 0), sinfop[0].ci);
933
printbody (s, Eshowbody), free (s);
935
fprintf (stderr, "\n");
939
static void printbody (char *s, int mode) {
944
fprintf (stderr, "%s\n", s);
948
for (s1 = s; *s1; s1++)
949
if (*s1 == '>' && *(s1 + 1) && *(s1 + 1) == '>')
953
for (; s1 != s; s1--)
954
if (*(s1 - 1) == '\n')
956
for (s2 = s1; *s2; s2++)
960
c = *s2, *s2 = '\000';
961
fprintf (stderr, "%s\n", s1);