~ubuntu-branches/ubuntu/oneiric/9base/oneiric

« back to all changes in this revision

Viewing changes to hoc/code.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-11-07 12:25:14 UTC
  • mfrom: (6.2.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091107122514-tcw4u4ha2w2xbbnn
Tags: 1:4-1
* Adding maintainer homepage field to control.
* Marking maintainer homepage field to be also included in binary
  packages and changelog.
* Adding README.source.
* Merging upstream version 4.
* Adding sh4 to explicit architecture list (Closes: #545772).
* Moving maintainer homepage field from control to copyright.
* Updating README.source.
* Updating homepage field in control.
* Removing manpage patch, went upstream.
* Removing kfreebsd.patch, went upstream.
* Generalizing manpage moving in rules.
* Moving base directory from /usr/lib/9base to /usr/lib/plan9 for
  consistency reasons.
* Prefixing manpages with plan9 instead of 9base for consistency
  reasons.
* Bumping versioned build-depends on debhelper.
* Making internal mkMAP and sendcover scripts executable.
* Adding patch to adjust shebang in newly included troff commands.
* Updating lintian-overrides.
* Making buildd-depends on quilt versioned.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <u.h>
 
2
#include <libc.h>
 
3
#include <bio.h>
 
4
#include "hoc.h"
 
5
#include "y.tab.h"
 
6
 
 
7
#define NSTACK  256
 
8
 
 
9
static Datum stack[NSTACK];     /* the stack */
 
10
static Datum *stackp;           /* next free spot on stack */
 
11
 
 
12
#define NPROG   2000
 
13
Inst    prog[NPROG];    /* the machine */
 
14
Inst    *progp;         /* next free spot for code generation */
 
15
Inst    *pc;            /* program counter during execution */
 
16
Inst    *progbase = prog; /* start of current subprogram */
 
17
int     returning;      /* 1 if return stmt seen */
 
18
int     indef;  /* 1 if parsing a func or proc */
 
19
 
 
20
typedef struct Frame {  /* proc/func call stack frame */
 
21
        Symbol  *sp;    /* symbol table entry */
 
22
        Inst    *retpc; /* where to resume after return */
 
23
        Datum   *argn;  /* n-th argument on stack */
 
24
        int     nargs;  /* number of arguments */
 
25
} Frame;
 
26
#define NFRAME  100
 
27
Frame   frame[NFRAME];
 
28
Frame   *fp;            /* frame pointer */
 
29
 
 
30
void
 
31
initcode(void)
 
32
{
 
33
        progp = progbase;
 
34
        stackp = stack;
 
35
        fp = frame;
 
36
        returning = 0;
 
37
        indef = 0;
 
38
}
 
39
 
 
40
void
 
41
nop(void)
 
42
{
 
43
}
 
44
 
 
45
void
 
46
push(Datum d)
 
47
{
 
48
        if (stackp >= &stack[NSTACK])
 
49
                execerror("stack too deep", 0);
 
50
        *stackp++ = d;
 
51
}
 
52
 
 
53
Datum
 
54
pop(void)
 
55
{
 
56
        if (stackp == stack)
 
57
                execerror("stack underflow", 0);
 
58
        return *--stackp;
 
59
}
 
60
 
 
61
void
 
62
xpop(void)      /* for when no value is wanted */
 
63
{
 
64
        if (stackp == stack)
 
65
                execerror("stack underflow", (char *)0);
 
66
        --stackp;
 
67
}
 
68
 
 
69
void
 
70
constpush(void)
 
71
{
 
72
        Datum d;
 
73
        d.val = ((Symbol *)*pc++)->u.val;
 
74
        push(d);
 
75
}
 
76
 
 
77
void
 
78
varpush(void)
 
79
{
 
80
        Datum d;
 
81
        d.sym = (Symbol *)(*pc++);
 
82
        push(d);
 
83
}
 
84
 
 
85
void
 
86
whilecode(void)
 
87
{
 
88
        Datum d;
 
89
        Inst *savepc = pc;
 
90
 
 
91
        execute(savepc+2);      /* condition */
 
92
        d = pop();
 
93
        while (d.val) {
 
94
                execute(*((Inst **)(savepc)));  /* body */
 
95
                if (returning)
 
96
                        break;
 
97
                execute(savepc+2);      /* condition */
 
98
                d = pop();
 
99
        }
 
100
        if (!returning)
 
101
                pc = *((Inst **)(savepc+1)); /* next stmt */
 
102
}
 
103
 
 
104
void
 
105
forcode(void)
 
106
{
 
107
        Datum d;
 
108
        Inst *savepc = pc;
 
109
 
 
110
        execute(savepc+4);              /* precharge */
 
111
        pop();
 
112
        execute(*((Inst **)(savepc)));  /* condition */
 
113
        d = pop();
 
114
        while (d.val) {
 
115
                execute(*((Inst **)(savepc+2)));        /* body */
 
116
                if (returning)
 
117
                        break;
 
118
                execute(*((Inst **)(savepc+1)));        /* post loop */
 
119
                pop();
 
120
                execute(*((Inst **)(savepc)));  /* condition */
 
121
                d = pop();
 
122
        }
 
123
        if (!returning)
 
124
                pc = *((Inst **)(savepc+3)); /* next stmt */
 
125
}
 
126
 
 
127
void
 
128
ifcode(void) 
 
129
{
 
130
        Datum d;
 
131
        Inst *savepc = pc;      /* then part */
 
132
 
 
133
        execute(savepc+3);      /* condition */
 
134
        d = pop();
 
135
        if (d.val)
 
136
                execute(*((Inst **)(savepc)));  
 
137
        else if (*((Inst **)(savepc+1))) /* else part? */
 
138
                execute(*((Inst **)(savepc+1)));
 
139
        if (!returning)
 
140
                pc = *((Inst **)(savepc+2)); /* next stmt */
 
141
}
 
142
 
 
143
void
 
144
define(Symbol* sp, Formal *f)   /* put func/proc in symbol table */
 
145
{
 
146
        Fndefn *fd;
 
147
        int n;
 
148
 
 
149
        fd = emalloc(sizeof(Fndefn));
 
150
        fd->code = progbase;    /* start of code */
 
151
        progbase = progp;       /* next code starts here */
 
152
        fd->formals = f;
 
153
        for(n=0; f; f=f->next)
 
154
                n++;
 
155
        fd->nargs = n;
 
156
        sp->u.defn = fd;
 
157
}
 
158
 
 
159
void
 
160
call(void)              /* call a function */
 
161
{
 
162
        Formal *f;
 
163
        Datum *arg;
 
164
        Saveval *s;
 
165
        int i;
 
166
 
 
167
        Symbol *sp = (Symbol *)pc[0]; /* symbol table entry */
 
168
                                      /* for function */
 
169
        if (fp >= &frame[NFRAME])
 
170
                execerror(sp->name, "call nested too deeply");
 
171
        fp++;
 
172
        fp->sp = sp;
 
173
        fp->nargs = (int)(uintptr)pc[1];
 
174
        fp->retpc = pc + 2;
 
175
        fp->argn = stackp - 1;  /* last argument */
 
176
        if(fp->nargs != sp->u.defn->nargs)
 
177
                execerror(sp->name, "called with wrong number of arguments");
 
178
        /* bind formals */
 
179
        f = sp->u.defn->formals;
 
180
        arg = stackp - fp->nargs;
 
181
        while(f){
 
182
                s = emalloc(sizeof(Saveval));
 
183
                s->val = f->sym->u;
 
184
                s->type = f->sym->type;
 
185
                s->next = f->save;
 
186
                f->save = s;
 
187
                f->sym->u.val = arg->val;
 
188
                f->sym->type = VAR;
 
189
                f = f->next;
 
190
                arg++;
 
191
        }
 
192
        for (i = 0; i < fp->nargs; i++)
 
193
                pop();  /* pop arguments; no longer needed */
 
194
        execute(sp->u.defn->code);
 
195
        returning = 0;
 
196
}
 
197
 
 
198
void
 
199
restore(Symbol *sp)     /* restore formals associated with symbol */
 
200
{
 
201
        Formal *f;
 
202
        Saveval *s;
 
203
 
 
204
        f = sp->u.defn->formals;
 
205
        while(f){
 
206
                s = f->save;
 
207
                if(s == 0)      /* more actuals than formals */
 
208
                        break;
 
209
                f->sym->u = s->val;
 
210
                f->sym->type = s->type;
 
211
                f->save = s->next;
 
212
                free(s);
 
213
                f = f->next;
 
214
        }
 
215
}
 
216
 
 
217
void
 
218
restoreall(void)        /* restore all variables in case of error */
 
219
{
 
220
        while(fp>=frame && fp->sp){
 
221
                restore(fp->sp);
 
222
                --fp;
 
223
        }
 
224
        fp = frame;
 
225
}
 
226
 
 
227
static void
 
228
ret(void)               /* common return from func or proc */
 
229
{
 
230
        /* restore formals */
 
231
        restore(fp->sp);
 
232
        pc = (Inst *)fp->retpc;
 
233
        --fp;
 
234
        returning = 1;
 
235
}
 
236
 
 
237
void
 
238
funcret(void)   /* return from a function */
 
239
{
 
240
        Datum d;
 
241
        if (fp->sp->type == PROCEDURE)
 
242
                execerror(fp->sp->name, "(proc) returns value");
 
243
        d = pop();      /* preserve function return value */
 
244
        ret();
 
245
        push(d);
 
246
}
 
247
 
 
248
void
 
249
procret(void)   /* return from a procedure */
 
250
{
 
251
        if (fp->sp->type == FUNCTION)
 
252
                execerror(fp->sp->name,
 
253
                        "(func) returns no value");
 
254
        ret();
 
255
}
 
256
 
 
257
void
 
258
bltin(void) 
 
259
{
 
260
 
 
261
        Datum d;
 
262
        d = pop();
 
263
        d.val = (*(double (*)(double))*pc++)(d.val);
 
264
        push(d);
 
265
}
 
266
 
 
267
void
 
268
add(void)
 
269
{
 
270
        Datum d1, d2;
 
271
        d2 = pop();
 
272
        d1 = pop();
 
273
        d1.val += d2.val;
 
274
        push(d1);
 
275
}
 
276
 
 
277
void
 
278
sub(void)
 
279
{
 
280
        Datum d1, d2;
 
281
        d2 = pop();
 
282
        d1 = pop();
 
283
        d1.val -= d2.val;
 
284
        push(d1);
 
285
}
 
286
 
 
287
void
 
288
mul(void)
 
289
{
 
290
        Datum d1, d2;
 
291
        d2 = pop();
 
292
        d1 = pop();
 
293
        d1.val *= d2.val;
 
294
        push(d1);
 
295
}
 
296
 
 
297
void
 
298
div(void)
 
299
{
 
300
        Datum d1, d2;
 
301
        d2 = pop();
 
302
        if (d2.val == 0.0)
 
303
                execerror("division by zero", (char *)0);
 
304
        d1 = pop();
 
305
        d1.val /= d2.val;
 
306
        push(d1);
 
307
}
 
308
 
 
309
void
 
310
mod(void)
 
311
{
 
312
        Datum d1, d2;
 
313
        d2 = pop();
 
314
        if (d2.val == 0.0)
 
315
                execerror("division by zero", (char *)0);
 
316
        d1 = pop();
 
317
        /* d1.val %= d2.val; */
 
318
        d1.val = fmod(d1.val, d2.val);
 
319
        push(d1);
 
320
}
 
321
 
 
322
void
 
323
negate(void)
 
324
{
 
325
        Datum d;
 
326
        d = pop();
 
327
        d.val = -d.val;
 
328
        push(d);
 
329
}
 
330
 
 
331
void
 
332
verify(Symbol* s)
 
333
{
 
334
        if (s->type != VAR && s->type != UNDEF)
 
335
                execerror("attempt to evaluate non-variable", s->name);
 
336
        if (s->type == UNDEF)
 
337
                execerror("undefined variable", s->name);
 
338
}
 
339
 
 
340
void
 
341
eval(void)              /* evaluate variable on stack */
 
342
{
 
343
        Datum d;
 
344
        d = pop();
 
345
        verify(d.sym);
 
346
        d.val = d.sym->u.val;
 
347
        push(d);
 
348
}
 
349
 
 
350
void
 
351
preinc(void)
 
352
{
 
353
        Datum d;
 
354
        d.sym = (Symbol *)(*pc++);
 
355
        verify(d.sym);
 
356
        d.val = d.sym->u.val += 1.0;
 
357
        push(d);
 
358
}
 
359
 
 
360
void
 
361
predec(void)
 
362
{
 
363
        Datum d;
 
364
        d.sym = (Symbol *)(*pc++);
 
365
        verify(d.sym);
 
366
        d.val = d.sym->u.val -= 1.0;
 
367
        push(d);
 
368
}
 
369
 
 
370
void
 
371
postinc(void)
 
372
{
 
373
        Datum d;
 
374
        double v;
 
375
        d.sym = (Symbol *)(*pc++);
 
376
        verify(d.sym);
 
377
        v = d.sym->u.val;
 
378
        d.sym->u.val += 1.0;
 
379
        d.val = v;
 
380
        push(d);
 
381
}
 
382
 
 
383
void
 
384
postdec(void)
 
385
{
 
386
        Datum d;
 
387
        double v;
 
388
        d.sym = (Symbol *)(*pc++);
 
389
        verify(d.sym);
 
390
        v = d.sym->u.val;
 
391
        d.sym->u.val -= 1.0;
 
392
        d.val = v;
 
393
        push(d);
 
394
}
 
395
 
 
396
void
 
397
gt(void)
 
398
{
 
399
        Datum d1, d2;
 
400
        d2 = pop();
 
401
        d1 = pop();
 
402
        d1.val = (double)(d1.val > d2.val);
 
403
        push(d1);
 
404
}
 
405
 
 
406
void
 
407
lt(void)
 
408
{
 
409
        Datum d1, d2;
 
410
        d2 = pop();
 
411
        d1 = pop();
 
412
        d1.val = (double)(d1.val < d2.val);
 
413
        push(d1);
 
414
}
 
415
 
 
416
void
 
417
ge(void)
 
418
{
 
419
        Datum d1, d2;
 
420
        d2 = pop();
 
421
        d1 = pop();
 
422
        d1.val = (double)(d1.val >= d2.val);
 
423
        push(d1);
 
424
}
 
425
 
 
426
void
 
427
le(void)
 
428
{
 
429
        Datum d1, d2;
 
430
        d2 = pop();
 
431
        d1 = pop();
 
432
        d1.val = (double)(d1.val <= d2.val);
 
433
        push(d1);
 
434
}
 
435
 
 
436
void
 
437
eq(void)
 
438
{
 
439
        Datum d1, d2;
 
440
        d2 = pop();
 
441
        d1 = pop();
 
442
        d1.val = (double)(d1.val == d2.val);
 
443
        push(d1);
 
444
}
 
445
 
 
446
void
 
447
ne(void)
 
448
{
 
449
        Datum d1, d2;
 
450
        d2 = pop();
 
451
        d1 = pop();
 
452
        d1.val = (double)(d1.val != d2.val);
 
453
        push(d1);
 
454
}
 
455
 
 
456
void
 
457
and(void)
 
458
{
 
459
        Datum d1, d2;
 
460
        d2 = pop();
 
461
        d1 = pop();
 
462
        d1.val = (double)(d1.val != 0.0 && d2.val != 0.0);
 
463
        push(d1);
 
464
}
 
465
 
 
466
void
 
467
or(void)
 
468
{
 
469
        Datum d1, d2;
 
470
        d2 = pop();
 
471
        d1 = pop();
 
472
        d1.val = (double)(d1.val != 0.0 || d2.val != 0.0);
 
473
        push(d1);
 
474
}
 
475
 
 
476
void
 
477
not(void)
 
478
{
 
479
        Datum d;
 
480
        d = pop();
 
481
        d.val = (double)(d.val == 0.0);
 
482
        push(d);
 
483
}
 
484
 
 
485
void
 
486
power(void)
 
487
{
 
488
        Datum d1, d2;
 
489
        d2 = pop();
 
490
        d1 = pop();
 
491
        d1.val = Pow(d1.val, d2.val);
 
492
        push(d1);
 
493
}
 
494
 
 
495
void
 
496
assign(void)
 
497
{
 
498
        Datum d1, d2;
 
499
        d1 = pop();
 
500
        d2 = pop();
 
501
        if (d1.sym->type != VAR && d1.sym->type != UNDEF)
 
502
                execerror("assignment to non-variable",
 
503
                        d1.sym->name);
 
504
        d1.sym->u.val = d2.val;
 
505
        d1.sym->type = VAR;
 
506
        push(d2);
 
507
}
 
508
 
 
509
void
 
510
addeq(void)
 
511
{
 
512
        Datum d1, d2;
 
513
        d1 = pop();
 
514
        d2 = pop();
 
515
        if (d1.sym->type != VAR && d1.sym->type != UNDEF)
 
516
                execerror("assignment to non-variable",
 
517
                        d1.sym->name);
 
518
        d2.val = d1.sym->u.val += d2.val;
 
519
        d1.sym->type = VAR;
 
520
        push(d2);
 
521
}
 
522
 
 
523
void
 
524
subeq(void)
 
525
{
 
526
        Datum d1, d2;
 
527
        d1 = pop();
 
528
        d2 = pop();
 
529
        if (d1.sym->type != VAR && d1.sym->type != UNDEF)
 
530
                execerror("assignment to non-variable",
 
531
                        d1.sym->name);
 
532
        d2.val = d1.sym->u.val -= d2.val;
 
533
        d1.sym->type = VAR;
 
534
        push(d2);
 
535
}
 
536
 
 
537
void
 
538
muleq(void)
 
539
{
 
540
        Datum d1, d2;
 
541
        d1 = pop();
 
542
        d2 = pop();
 
543
        if (d1.sym->type != VAR && d1.sym->type != UNDEF)
 
544
                execerror("assignment to non-variable",
 
545
                        d1.sym->name);
 
546
        d2.val = d1.sym->u.val *= d2.val;
 
547
        d1.sym->type = VAR;
 
548
        push(d2);
 
549
}
 
550
 
 
551
void
 
552
diveq(void)
 
553
{
 
554
        Datum d1, d2;
 
555
        d1 = pop();
 
556
        d2 = pop();
 
557
        if (d1.sym->type != VAR && d1.sym->type != UNDEF)
 
558
                execerror("assignment to non-variable",
 
559
                        d1.sym->name);
 
560
        d2.val = d1.sym->u.val /= d2.val;
 
561
        d1.sym->type = VAR;
 
562
        push(d2);
 
563
}
 
564
 
 
565
void
 
566
ppush(Datum *d)
 
567
{
 
568
        push(*d);
 
569
}
 
570
 
 
571
void
 
572
modeq(void)
 
573
{
 
574
        Datum d1, d2;
 
575
        long x;
 
576
 
 
577
        d1 = pop();
 
578
        d2 = pop();
 
579
        if (d1.sym->type != VAR && d1.sym->type != UNDEF)
 
580
                execerror("assignment to non-variable",
 
581
                        d1.sym->name);
 
582
        /* d2.val = d1.sym->u.val %= d2.val; */
 
583
        x = d1.sym->u.val;
 
584
        x %= (long) d2.val;
 
585
        d2.val = x;
 
586
        d1.sym->u.val = x;
 
587
        d1.sym->type = VAR;
 
588
 
 
589
        /* push(d2) generates a compiler error on Linux w. gcc 2.95.4 */
 
590
        ppush(&d2);
 
591
}
 
592
 
 
593
void
 
594
printtop(void)  /* pop top value from stack, print it */
 
595
{
 
596
        Datum d;
 
597
        static Symbol *s;       /* last value computed */
 
598
        if (s == 0)
 
599
                s = install("_", VAR, 0.0);
 
600
        d = pop();
 
601
        print("%.17g\n", d.val);
 
602
        s->u.val = d.val;
 
603
}
 
604
 
 
605
void
 
606
prexpr(void)    /* print numeric value */
 
607
{
 
608
        Datum d;
 
609
        d = pop();
 
610
        print("%.17g ", d.val);
 
611
}
 
612
 
 
613
void
 
614
prstr(void)             /* print string value */ 
 
615
{
 
616
        print("%s", (char *) *pc++);
 
617
}
 
618
 
 
619
void
 
620
varread(void)   /* read into variable */
 
621
{
 
622
        Datum d;
 
623
        extern Biobuf *bin;
 
624
        Symbol *var = (Symbol *) *pc++;
 
625
        int c;
 
626
 
 
627
  Again:
 
628
        do
 
629
                c = Bgetc(bin);
 
630
        while(c==' ' || c=='\t');
 
631
        if(c == Beof){
 
632
  Iseof:
 
633
                if(moreinput())
 
634
                        goto Again;
 
635
                d.val = var->u.val = 0.0;
 
636
                goto Return;
 
637
        }
 
638
 
 
639
        if(strchr("+-.0123456789", c) == 0)
 
640
                execerror("non-number read into", var->name);
 
641
        Bungetc(bin);
 
642
        if(Bgetd(bin, &var->u.val) == Beof)
 
643
                goto Iseof;
 
644
        else
 
645
                d.val = 1.0;
 
646
  Return:
 
647
        var->type = VAR;
 
648
        push(d);
 
649
}
 
650
 
 
651
Inst*
 
652
code(Inst f)    /* install one instruction or operand */
 
653
{
 
654
        Inst *oprogp = progp;
 
655
        if (progp >= &prog[NPROG])
 
656
                execerror("program too big", (char *)0);
 
657
        *progp++ = f;
 
658
        return oprogp;
 
659
}
 
660
 
 
661
void
 
662
execute(Inst* p)
 
663
{
 
664
        for (pc = p; *pc != STOP && !returning; )
 
665
                (*((++pc)[-1]))();
 
666
}