BSD 2 development
[unix-history] / .ref-BSD-1 / pcs / block.i
CommitLineData
fc2b415a
BJ
1procedure block(fsys: symset; isfun: boolean; level: integer);
2
3 type conrec =
4 record case tp: types of
5 ints,chars,bools: (i: integer);
6 reals: (r: real)
7 end ;
8
9 var dx: integer; (*data allocation index*)
10 prt: integer; (*t-index of this procedure*)
11 prb: integer; (*b-index of this procedure*)
12 x: integer;
13 procedure skip(fsys: symset; n: integer);
14 begin error(n);
15 while not (sy in fsys) do insymbol
16 end (*skip*) ;
17
18 procedure test(s1,s2: symset; n: integer);
19 begin if not (sy in s1) then
20 skip(s1+s2,n)
21 end (*test*) ;
22
23 procedure testsemicolon;
24 begin
25 if sy = semicolon then insymbol else
26 begin error(14);
27 if sy in [comma,colon] then insymbol
28 end ;
29 test([ident]+blockbegsys, fsys, 6)
30 end (*testsemicolon*) ;
31
32 procedure enter(id: alfa; k: object);
33 var j,l: integer;
34 begin if t = tmax then fatal(1) else
35 begin tab[0].name := id;
36 j := btab[display[level]].last; l := j;
37 while tab[j].name <> id do j := tab[j].link;
38 if j <> 0 then error(1) else
39 begin t := t+1;
40 with tab[t] do
41 begin name := id; link := l;
42 obj := k; typ := notyp; ref := 0; lev := level; adr := 0
43 end ;
44 btab[display[level]].last := t
45 end
46 end
47 end (*enter*) ;
48
49 function loc(id: alfa): integer;
50 var i,j: integer; (*locate id in table*)
51 begin i := level; tab[0].name := id; (*sentinel*)
52 repeat j := btab[display[i]].last;
53 while tab[j].name <> id do j := tab[j].link;
54 i := i-1;
55 until (i<0) or (j<>0);
56 if j = 0 then error(0); loc := j
57 end (*loc*) ;
58
59 procedure entervariable;
60 begin if sy = ident then
61 begin enter(id,variable); insymbol
62 end
63 else error(2)
64 end (*entervariable*) ;
65
66 procedure constant(fsys: symset; var c: conrec);
67 var x, sign: integer;
68 begin c.tp := notyp; c.i := 0;
69 test(constbegsys, fsys, 50);
70 if sy in constbegsys then
71 begin
72 if sy = charcon then
73 begin c.tp := chars; c.i := inum; insymbol
74 end
75 else
76 begin sign := 1;
77 if sy in [plus,minus] then
78 begin if sy = minus then sign := -1;
79 insymbol
80 end ;
81 if sy = ident then
82 begin x := loc(id);
83 if x <> 0 then
84 if tab[x].obj <> konstant then error(25) else
85 begin c.tp := tab[x].typ;
86 if c.tp = reals then c.r := sign*rconst[tab[x].adr]
87 else c.i := sign*tab[x].adr
88 end ;
89 insymbol
90 end
91 else
92 if sy = intcon then
93 begin c.tp := ints; c.i := sign*inum; insymbol
94 end else
95 if sy = realcon then
96 begin c.tp := reals; c.r := sign*rnum; insymbol
97 end else skip(fsys,50)
98 end;
99 test(fsys, [], 6)
100 end
101 end (*constant*) ;
102 procedure typ(fsys: symset; var tp: types; var rf, sz: integer);
103 var x: integer;
104 eltp: types; elrf: integer;
105 elsz, offset, t0,t1: integer;
106
107 procedure arraytyp(var aref,arsz: integer);
108 var eltp: types;
109 low, high: conrec;
110 elrf, elsz: integer;
111 begin constant([colon,rbrack,rparent,ofsy]+fsys, low);
112 if low.tp = reals then
113 begin error(27); low.tp := ints; low.i := 0
114 end ;
115 if sy = colon then insymbol else error(13);
116 constant([rbrack,comma,rparent,ofsy]+fsys, high);
117 if high.tp <> low.tp then
118 begin error(27); high.i := low.i
119 end ;
120 enterarray(low.tp, low.i, high.i); aref := a;
121 if sy = comma then
122 begin insymbol; eltp := arrays; arraytyp(elrf,elsz)
123 end else
124 begin
125 if sy = rbrack then insymbol else
126 begin error(12);
127 if sy = rparent then insymbol
128 end ;
129 if sy = ofsy then insymbol else error(8);
130 typ(fsys,eltp,elrf,elsz)
131 end ;
132 with atab[aref] do
133 begin arsz := (high-low+1)*elsz; size := arsz;
134 eltyp := eltp; elref := elrf; elsize := elsz
135 end ;
136 end (*arraytyp*) ;
137
138 begin (*typ*) tp := notyp; rf := 0; sz := 0;
139 test(typebegsys, fsys, 10);
140 if sy in typebegsys then
141 begin
142 if sy = ident then
143 begin x := loc(id);
144 if x <> 0 then
145 with tab[x] do
146 if obj <> type1 then error(29) else
147 begin tp := typ; rf := ref; sz := adr;
148 if tp = notyp then error(30)
149 end ;
150 insymbol
151 end else
152 if sy = arraysy then
153 begin insymbol;
154 if sy = lbrack then insymbol else
155 begin error(11);
156 if sy = lparent then insymbol
157 end ;
158 tp := arrays; arraytyp(rf,sz)
159 end else
160 begin (*records*) insymbol;
161 enterblock; tp := records; rf := b;
162 if level = lmax then fatal(5);
163 level := level+1; display[level] := b; offset := 0;
164 while sy <> endsy do
165 begin (*field section*)
166 if sy = ident then
167 begin t0 := t; entervariable;
168 while sy = comma do
169 begin insymbol; entervariable
170 end ;
171 if sy = colon then insymbol else error(5);
172 t1 := t;
173 typ(fsys+[semicolon,endsy,comma,ident],eltp,elrf,elsz);
174 while t0 < t1 do
175 begin t0 := t0+1;
176 with tab[t0] do
177 begin typ := eltp; ref := elrf; normal := true;
178 adr := offset; offset := offset + elsz
179 end
180 end
181 end ;
182 if sy <> endsy then
183 begin if sy = semicolon then insymbol else
184 begin error(14);
185 if sy = comma then insymbol
186 end ;
187 test([ident,endsy,semicolon], fsys, 6)
188 end
189 end ;
190 btab[rf].vsize := offset; sz := offset; btab[rf].psize := 0;
191 insymbol; level := level-1
192 end ;
193 test(fsys, [], 6)
194 end
195 end (*typ*) ;
196
197 procedure parameterlist; (*formal parameter list*)
198 var tp: types;
199 rf, sz, x, t0: integer;
200 valpar: boolean;
201 begin insymbol; tp := notyp; rf := 0; sz := 0;
202 test([ident, varsy], fsys+[rparent], 7);
203 while sy in [ident,varsy] do
204 begin if sy <> varsy then valpar := true else
205 begin insymbol; valpar := false
206 end ;
207 t0 := t; entervariable;
208 while sy = comma do
209 begin insymbol; entervariable;
210 end ;
211 if sy = colon then
212 begin insymbol;
213 if sy <> ident then error(2) else
214 begin x := loc(id); insymbol;
215 if x <> 0 then
216 with tab[x] do
217 if obj <> type1 then error(29) else
218 begin tp := typ; rf := ref;
219 if valpar then sz := adr else sz := 1
220 end ;
221 end ;
222 test([semicolon,rparent], [comma,ident]+fsys, 14)
223 end
224 else error(5);
225 while t0 < t do
226 begin t0 := t0+1;
227 with tab[t0] do
228 begin typ := tp; ref := rf;
229 normal := valpar; adr := dx; lev := level;
230 dx := dx + sz
231 end
232 end ;
233 if sy <> rparent then
234 begin if sy = semicolon then insymbol else
235 begin error(14);
236 if sy = comma then insymbol
237 end ;
238 test([ident,varsy], [rparent]+fsys, 6)
239 end
240 end (*while*) ;
241 if sy = rparent then
242 begin insymbol;
243 test([semicolon,colon], fsys, 6)
244 end
245 else error(4)
246 end (*parameterlist*) ;
247
248 procedure constantdeclaration;
249 var c: conrec;
250 begin insymbol;
251 test([ident], blockbegsys, 2);
252 while sy = ident do
253 begin enter(id,konstant); insymbol;
254 if sy = eql then insymbol else
255 begin error(16);
256 if sy = becomes then insymbol
257 end ;
258 constant([semicolon,comma,ident]+fsys,c);
259 tab[t].typ := c.tp; tab[t].ref := 0;
260 if c.tp = reals then
261 begin enterreal(c.r); tab[t].adr := c1 end
262 else tab[t].adr := c.i;
263 testsemicolon
264 end
265 end (*constantdeclaration*) ;
266
267 procedure typedeclaration;
268 var tp: types; rf, sz, t1: integer;
269 begin insymbol;
270 test([ident], blockbegsys, 2);
271 while sy = ident do
272 begin enter(id,type1); t1 := t; insymbol;
273 if sy = eql then insymbol else
274 begin error(16);
275 if sy = becomes then insymbol
276 end ;
277 typ([semicolon,comma,ident]+fsys, tp, rf, sz);
278 with tab[t1] do
279 begin typ := tp; ref := rf; adr := sz
280 end ;
281 testsemicolon
282 end
283 end (*typedeclaration*) ;
284
285 procedure variabledeclaration;
286 var t0, t1, rf, sz: integer;
287 tp: types;
288 begin insymbol;
289 while sy = ident do
290 begin t0 := t; entervariable;
291 while sy = comma do
292 begin insymbol; entervariable;
293 end ;
294 if sy = colon then insymbol else error(5);
295 t1 := t;
296 typ([semicolon,comma,ident]+fsys, tp, rf, sz);
297 while t0 < t1 do
298 begin t0 := t0+1;
299 with tab[t0] do
300 begin typ := tp; ref := rf;
301 lev := level; adr := dx; normal := true;
302 dx := dx + sz
303 end
304 end ;
305 testsemicolon
306 end
307 end (*variabledeclaration*) ;
308
309 procedure procdeclaration;
310 var isfun: boolean;
311 begin isfun := sy = functionsy; insymbol;
312 if sy <> ident then
313 begin error(2); id := ' '
314 end ;
315 if isfun then enter(id,funktion) else enter(id,prozedure);
316 tab[t].normal := true;
317 insymbol; block([semicolon]+fsys, isfun, level+1);
318 if sy = semicolon then insymbol else error(14);
319 emit(32+ord(isfun)) (*exit*)
320 end (*proceduredeclaration*) ;
321
322(*---------------------------------------------------------statement--*)
323
324 procedure statement(fsys: symset);
325 var i: integer;
326 procedure expression(fsys: symset; var x: item); forward;
327
328 procedure selector(fsys: symset; var v:item);
329 var x: item; a,j: integer;
330 begin (*sy in [lparent, lbrack, period]*)
331 repeat
332 if sy = period then
333 begin insymbol; (*field selector*)
334 if sy <> ident then error(2) else
335 begin
336 if v.typ <> records then error(31) else
337 begin (*search field identifier*)
338 j := btab[v.ref] .last; tab[0].name := id;
339 while tab[j].name <> id do j := tab[j].link;
340 if j = 0 then error(0);
341 v.typ := tab[j].typ; v.ref := tab[j].ref;
342 a := tab[j].adr; if a <> 0 then emit1(9,a)
343 end ;
344 insymbol
345 end
346 end else
347 begin (*array selector*)
348 if sy <> lbrack then error(11);
349 repeat insymbol;
350 expression(fsys+[comma,rbrack], x);
351 if v.typ <> arrays then error(28) else
352 begin a := v.ref;
353 if atab[a].inxtyp <> x.typ then error(26) else
354 if atab[a].elsize = 1 then emit1(20,a) else emit1(21,a);
355 v.typ := atab[a].eltyp; v.ref := atab[a].elref
356 end
357 until sy <> comma;
358 if sy = rbrack then insymbol else
359 begin error(12); if sy = rparent then insymbol
360 end
361 end
362 until not (sy in [lbrack,lparent,period]);
363 test(fsys, [], 6)
364 end (*selector*) ;
365
366 procedure call(fsys: symset; i: integer);
367 var x: item;
368 lastp, cp, k: integer;
369 begin emit1(18,i); (*mark stack*)
370 lastp := btab[tab[i].ref].lastpar; cp := i;
371 if sy = lparent then
372 begin (*actual parameter list*)
373 repeat insymbol;
374 if cp >= lastp then error(39) else
375 begin cp := cp+1;
376 if tab[cp].normal then
377 begin (*value parameter*)
378 expression(fsys+[comma,colon,rparent], x);
379 if x.typ=tab[cp].typ then
380 begin
381 if x.ref <> tab[cp].ref then error(36) else
382 if x.typ = arrays then emit1(22,atab[x.ref].size) else
383 if x.typ = records then emit1(22,btab[x.ref].vsize)
384 end else
385 if (x.typ=ints) and (tab[cp].typ=reals) then
386 emit1(26,0) else
387 if x.typ<>notyp then error(36);
388 end else
389 begin (*variable parameter*)
390 if sy <> ident then error(2) else
391 begin k := loc(id); insymbol;
392 if k <> 0 then
393 begin if tab[k].obj <> variable then error(37);
394 x.typ := tab[k].typ; x.ref := tab[k].ref;
395 if tab[k].normal then emit2(0,tab[k].lev,tab[k].adr)
396 else emit2(1,tab[k].lev,tab[k].adr);
397 if sy in [lbrack,lparent,period] then
398 selector(fsys+[comma,colon,rparent], x);
399 if (x.typ<>tab[cp].typ) or (x.ref<>tab[cp].ref) then
400 error(36)
401 end
402 end
403 end
404 end ;
405 test([comma,rparent], fsys, 6)
406 until sy <> comma;
407 if sy = rparent then insymbol else error(4)
408 end ;
409 if cp < lastp then error(39); (*too few actual parameters*)
410 emit1(19, btab[tab[i].ref].psize-1);
411 if tab[i].lev < level then emit2(3, tab[i].lev, level)
412 end (*call*) ;
413
414 function resulttype(a,b: types): types;
415 begin
416 if (a>reals) or (b>reals) then
417 begin error(33); resulttype := notyp
418 end else
419 if (a=notyp) or (b=notyp) then resulttype := notyp else
420 if a=ints then
421 if b=ints then resulttype := ints else
422 begin resulttype := reals; emit1(26,1)
423 end
424 else
425 begin resulttype := reals;
426 if b=ints then emit1(26,0)
427 end
428 end (*resulttype*) ;
429
430 procedure expression;
431 var y:item; op:symbol;
432
433 procedure simpleexpression(fsys:symset; var x:item);
434 var y:item; op:symbol;
435
436 procedure term(fsys:symset; var x:item);
437 var y:item; op:symbol;
438
439 procedure factor(fsys:symset; var x:item);
440 var i,f: integer;
441
442 procedure standfct(n: integer);
443 var ts: typset;
444 begin (*standard function no. n*)
445 if sy = lparent then insymbol else error(9);
446 if n < 17 then
447 begin expression(fsys+[rparent],x);
448 case n of
449(*abs,sqr*) 0,2: begin ts := [ints,reals]; tab[i].typ := x.typ;
450 if x.typ = reals then n := n+1
451 end ;
452(*odd,chr*) 4,5: ts := [ints];
453(*ord*) 6: begin
454 if x.typ = ints then n := 19;
455 ts := [ints,bools,chars];
456 end;
457(*succ,pred*) 7,8: ts := [chars];
458(*round,trunc*) 9,10,11,12,13,14,15,16:
459(*sin,cos,...*) begin ts := [ints,reals];
460 if x.typ = ints then emit1(26,0)
461 end ;
462 end ;
463 if x.typ in ts then emit1(8,n) else
464 if x.typ <> notyp then error(48);
465 end else
466(*eof,eoln*) begin (*n in [17,18]*)
467 if sy <> ident then error(2) else
468 if id <> 'input ' then error(0) else insymbol;
469 emit1(8,n);
470 end ;
471 x.typ := tab[i].typ;
472 if sy = rparent then insymbol else error(4)
473 end (*standfct*) ;
474
475 begin (*factor*) x.typ := notyp; x.ref := 0;
476 test(facbegsys, fsys, 58);
477 while sy in facbegsys do
478 begin
479 if sy = ident then
480 begin i := loc(id); insymbol;
481 with tab[i] do
482 case obj of
483 konstant: begin x.typ := typ; x.ref := 0;
484 case x.typ of
485 ints: emit1(24,adr);
486 reals: emit1(25,adr);
487 bools: emit1(64,adr);
488 chars: emit1(65,adr);
489 end;
490 end ;
491 variable: begin x.typ := typ; x.ref := ref;
492 if sy in [lbrack,lparent,period] then
493 begin if normal then f := 0 else f := 1;
494 emit2(f, lev, adr);
495 selector(fsys,x);
496 if x.typ in stantyps then emit(34)
497 end else
498 begin
499 if x.typ in stantyps then
500 if normal then f := 1 else f := 2
501 else
502 if normal then f := 0 else f := 1;
503 emit2(f, lev, adr)
504 end
505 end ;
506 type1, prozedure: error(44);
507 funktion :begin x.typ := typ;
508 if lev <> 0 then call(fsys, i)
509 else standfct(adr)
510 end
511 end (*case,with*)
512 end else
513 if sy in [charcon,intcon,realcon] then
514 begin
515 if sy = realcon then
516 begin x.typ := reals; enterreal(rnum);
517 emit1(25, c1)
518 end else
519 begin
520 if sy = charcon then begin
521 x.typ := chars;
522 emit1(65, inum);
523 end else begin
524 x.typ := ints;
525 emit1(24, inum);
526 end;
527 end ;
528 x.ref := 0; insymbol
529 end else
530 if sy = lparent then
531 begin insymbol; expression(fsys+[rparent], x);
532 if sy = rparent then insymbol else error(4)
533 end else
534 if sy = notsy then
535 begin insymbol; factor(fsys,x);
536 if x.typ=bools then emit(35) else
537 if x.typ<>notyp then error(32)
538 end ;
539 test(fsys, facbegsys, 6)
540 end (*while*)
541 end (*factor*) ;
542
543 begin (*term*)
544 factor(fsys+[times,rdiv,idiv,imod,andsy], x);
545 while sy in [times,rdiv,idiv,imod,andsy] do
546 begin op := sy; insymbol;
547 factor(fsys+[times,rdiv,idiv,imod,andsy], y);
548 if op = times then
549 begin x.typ := resulttype(x.typ, y.typ);
550 case x.typ of
551 notyp: ;
552 ints : emit(57);
553 reals: emit(60);
554 end
555 end else
556 if op = rdiv then
557 begin
558 if x.typ = ints then
559 begin emit1(26,1); x.typ := reals
560 end ;
561 if y.typ = ints then
562 begin emit1(26,0); y.typ := reals
563 end ;
564 if (x.typ=reals) and (y.typ=reals) then emit(61) else
565 begin if (x.typ<>notyp) and (y.typ<>notyp) then
566 error(33);
567 x.typ := notyp
568 end
569 end else
570 if op = andsy then
571 begin if (x.typ=bools) and (y.typ=bools) then
572 emit(56) else
573 begin if (x.typ<>notyp) and (y.typ<>notyp) then
574 error(32);
575 x.typ := notyp
576 end
577 end else
578 begin (*op in [idiv,imod]*)
579 if (x.typ=ints) and (y.typ=ints) then
580 if op=idiv then emit(58)
581 else emit(59) else
582 begin if (x.typ<>notyp) and (y.typ<>notyp) then
583 error(34);
584 x.typ := notyp
585 end
586 end
587 end
588 end (*term*) ;
589
590 begin (*simpleexpression*)
591 if sy in [plus,minus] then
592 begin op := sy; insymbol;
593 term(fsys+[plus,minus], x);
594 if x.typ > reals then error(33) else
595 if op = minus then
596 if x.typ = reals then
597 emit(66)
598 else
599 emit(36)
600 end else
601 term(fsys+[plus,minus,orsy], x);
602 while sy in [plus,minus,orsy] do
603 begin op := sy; insymbol;
604 term(fsys+[plus,minus,orsy], y);
605 if op = orsy then
606 begin
607 if (x.typ=bools) and (y.typ=bools) then emit(51) else
608 begin if (x.typ<>notyp) and (y.typ<>notyp) then
609 error(32);
610 x.typ := notyp
611 end
612 end else
613 begin x.typ := resulttype(x.typ, y.typ);
614 case x.typ of
615 notyp: ;
616 ints : if op = plus then emit(52)
617 else emit(53);
618 reals: if op = plus then emit(54)
619 else emit(55)
620 end
621 end
622 end
623 end (*simpleexpression*) ;
624
625 begin (*expression*)
626 simpleexpression(fsys+[eql,neq,lss,leq,gtr,geq], x);
627 if sy in [eql,neq,lss,leq,gtr,geq] then
628 begin op := sy; insymbol;
629 simpleexpression(fsys, y);
630 if (x.typ in [ notyp,ints,bools,chars]) and (x.typ = y.typ) then
631 case op of
632 eql: emit(45);
633 neq: emit(46);
634 lss: emit(47);
635 leq: emit(48);
636 gtr: emit(49);
637 geq: emit(50);
638 end else
639 begin if x.typ = ints then
640 begin x.typ := reals; emit1(26,1)
641 end else
642 if y.typ = ints then
643 begin y.typ := reals; emit1(26,0)
644 end ;
645 if (x.typ=reals) and (y.typ=reals) then
646 case op of
647 eql: emit(39);
648 neq: emit(40);
649 lss: emit(41);
650 leq: emit(42);
651 gtr: emit(43);
652 geq: emit(44);
653 end
654 else error(35)
655 end ;
656 x.typ := bools
657 end
658 end (*expression*) ;
659
660 procedure assignment(lv,ad: integer);
661 var x,y: item; f: integer;
662 (*tab[i].obj in [variable,prozedure]*)
663 begin x.typ := tab[i].typ; x.ref := tab[i].ref;
664 if tab[i].normal then f := 0 else f := 1;
665 emit2(f, lv, ad);
666 if sy in [lbrack,lparent,period] then
667 selector([becomes,eql]+fsys, x);
668 if sy = becomes then insymbol else
669 begin error(51); if sy = eql then insymbol
670 end ;
671 expression(fsys, y);
672 if x.typ = y.typ then
673 if x.typ in stantyps then emit(38) else
674 if x.ref <> y.ref then error(46) else
675 if x.typ = arrays then emit1(23, atab[x.ref].size)
676 else emit1(23, btab[x.ref].vsize)
677 else
678 if (x.typ=reals) and (y.typ=ints) then
679 begin emit1(26,0); emit(38)
680 end else
681 if (x.typ<>notyp) and (y.typ<>notyp) then error(46)
682 end (*assignment*) ;
683
684 procedure compoundstatement;
685 begin insymbol;
686 statement([semicolon,endsy]+fsys);
687 while sy in [semicolon]+statbegsys do
688 begin if sy = semicolon then insymbol else error(14);
689 statement([semicolon,endsy]+fsys)
690 end ;
691 if sy = endsy then insymbol else error(57)
692 end (*compoundstatemenet*) ;
693
694 procedure ifstatement;
695 var x: item; lc1,lc2: integer;
696 begin insymbol;
697 expression(fsys+[thensy,dosy], x);
698 if not (x.typ in [bools,notyp]) then error(17);
699 lc1 := lc; emit(11); (*jmpc*)
700 if sy = thensy then insymbol else
701 begin error(52); if sy = dosy then insymbol
702 end ;
703 statement(fsys+[elsesy]);
704 if sy = elsesy then
705 begin insymbol; lc2 := lc; emit(10);
706 code[lc1].y := lc; statement(fsys); code[lc2].y := lc
707 end
708 else code[lc1].y := lc
709 end (*ifstatement*) ;
710
711 procedure casestatement;
712 var x: item;
713 i,j,k,lc1: integer;
714 casetab: array [1..csmax] of
715 packed record val, lc: index end ;
716 exittab: array [1..csmax] of integer;
717
718 procedure caselabel;
719 var lab: conrec; k: integer;
720 begin constant(fsys+[comma,colon], lab);
721 if lab.tp <> x.typ then error(47) else
722 if i = csmax then fatal(6) else
723 begin i := i+1; k := 0;
724 casetab[i].val := lab.i; casetab[i].lc := lc;
725 repeat k := k+1 until casetab[k].val = lab.i;
726 if k < i then error(1); (*multiple definition*)
727 end
728 end (*caselabel*) ;
729
730 procedure onecase;
731 begin if sy in constbegsys then
732 begin caselabel;
733 while sy = comma do
734 begin insymbol; caselabel
735 end ;
736 if sy = colon then insymbol else error(5);
737 statement([semicolon,endsy]+fsys);
738 j := j+1; exittab[j] := lc; emit(10)
739 end
740 end (*onecase*) ;
741
742 begin insymbol; i := 0; j := 0;
743 expression(fsys+[ofsy,comma,colon], x);
744 if not (x.typ in [ints,bools,chars,notyp]) then error(23);
745 lc1 := lc; emit(12); (*jmpx*)
746 if sy = ofsy then insymbol else error(8);
747 onecase;
748 while sy = semicolon do
749 begin insymbol; onecase
750 end ;
751 code[lc1].y := lc;
752 for k := 1 to i do
753 begin emit1(13,casetab[k].val); emit1(13,casetab[k].lc)
754 end ;
755 emit1(10,0);
756 for k := 1 to j do code[exittab[k]].y := lc;
757 if sy = endsy then insymbol else error(57)
758 end (*casestatement*) ;
759
760 procedure repeatstatement;
761 var x: item; lc1: integer;
762 begin lc1 := lc;
763 insymbol; statement([semicolon,untilsy]+fsys);
764 while sy in [semicolon]+statbegsys do
765 begin if sy = semicolon then insymbol else error(14);
766 statement([semicolon,untilsy]+fsys)
767 end ;
768 if sy = untilsy then
769 begin insymbol; expression(fsys, x);
770 if not (x.typ in [bools,notyp]) then error(17);
771 emit1(11,lc1)
772 end
773 else error(53)
774 end (*repeatstatement*) ;
775
776 procedure whilestatement;
777 var x: item; lc1,lc2: integer;
778 begin insymbol; lc1 := lc;
779 expression(fsys+[dosy], x);
780 if not (x.typ in [bools,notyp]) then error(17);
781 lc2 := lc; emit(11);
782 if sy = dosy then insymbol else error(54);
783 statement(fsys); emit1(10,lc1); code[lc2].y := lc
784 end (*whilestatement*) ;
785
786 procedure forstatement;
787 var cvt: types; x: item;
788 i,f,lc1,lc2: integer;
789 begin insymbol;
790 if sy = ident then
791 begin i := loc(id); insymbol;
792 if i = 0 then cvt := ints else
793 if tab[i].obj = variable then
794 begin cvt := tab[i].typ;
795 if not tab[i].normal then error(37) else
796 emit2(0, tab[i].lev, tab[i].adr);
797 if not (cvt in [notyp,ints,bools,chars]) then error(18)
798 end else
799 begin error(37); cvt := ints
800 end
801 end else skip([becomes,tosy,downtosy,dosy]+fsys, 2);
802 if sy = becomes then
803 begin insymbol; expression([tosy,downtosy,dosy]+fsys, x);
804 if x.typ <> cvt then error(19);
805 end else skip([tosy,downtosy,dosy]+fsys, 51);
806 f := 14;
807 if sy in [tosy, downtosy] then
808 begin if sy = downtosy then f := 16;
809 insymbol; expression([dosy]+fsys, x);
810 if x.typ <> cvt then error(19)
811 end else skip([dosy]+fsys, 55);
812 lc1 := lc; emit(f);
813 if sy = dosy then insymbol else error(54);
814 lc2 := lc; statement(fsys);
815 emit1(f+1,lc2); code[lc1].y := lc
816 end (*forstatement*) ;
817
818 procedure standproc(n: integer);
819 var i,f: integer;
820 x,y: item;
821 begin
822 case n of
823 1,2: begin (*read*)
824 if not iflag then
825 begin error(20); iflag := true
826 end ;
827 if sy = lparent then
828 begin
829 repeat insymbol;
830 if sy <> ident then error(2) else
831 begin i := loc(id); insymbol;
832 if i <> 0 then
833 if tab[i].obj <> variable then error(37) else
834 begin x.typ := tab[i].typ; x.ref := tab[i].ref;
835 if tab[i].normal then f := 0 else f := 1;
836 emit2(f, tab[i].lev, tab[i].adr);
837 if sy in [lbrack,lparent,period] then
838 selector(fsys+[comma,rparent], x);
839 if x.typ in [ints,reals,chars,notyp] then
840 emit1(27, ord(x.typ)) else error(40)
841 end
842 end ;
843 test([comma,rparent], fsys, 6);
844 until sy <> comma;
845 if sy = rparent then insymbol else error(4)
846 end ;
847 if n = 2 then emit(62)
848 end ;
849 3,4: begin (*write*)
850 if sy = lparent then
851 begin
852 repeat insymbol;
853 if sy = string then
854 begin emit1(24,sleng); emit1(28,inum); insymbol
855 end else
856 begin expression(fsys+[comma,colon,rparent], x);
857 if not (x.typ in stantyps) then error(41);
858 if sy = colon then
859 begin insymbol;
860 expression(fsys+[comma,colon,rparent], y);
861 if y.typ <> ints then error(43);
862 if sy = colon then
863 begin if x.typ <> reals then error(42);
864 insymbol; expression(fsys+[comma,rparent], y);
865 if y.typ <> ints then error(43);
866 emit(37)
867 end
868 else emit1(30, ord(x.typ))
869 end
870 else emit1(29, ord(x.typ))
871 end
872 until sy <> comma;
873 if sy = rparent then insymbol else error(4)
874 end ;
875 if n = 4 then emit(63)
876 end ;
877 end (*case*)
878 end (*standproc*) ;
879
880 begin (*statement*)
881 if sy in statbegsys+[ident] then
882 case sy of
883 ident: begin i := loc(id); insymbol;
884 if i <> 0 then
885 case tab[i].obj of
886 konstant, type1: error(45);
887 variable: assignment(tab[i].lev, tab[i].adr);
888 prozedure:
889 if tab[i].lev <> 0 then call(fsys, i)
890 else standproc(tab[i].adr);
891 funktion:
892 if tab[i].ref = display[level] then
893 assignment(tab[i].lev+1, 0) else error(45)
894 end
895 end ;
896 beginsy: compoundstatement;
897 ifsy: ifstatement;
898 casesy: casestatement;
899 whilesy: whilestatement;
900 repeatsy: repeatstatement;
901 forsy: forstatement;
902 end;
903 test(fsys, [], 14)
904 end (*statement*) ;
905
906begin (*block*) dx := 5; prt := t;
907 if level > lmax then fatal(5);
908 test([lparent,colon,semicolon], fsys, 7);
909 enterblock; display[level] := b; prb := b;
910 tab[prt].typ := notyp; tab[prt].ref := prb;
911 if sy = lparent then parameterlist;
912 btab[prb].lastpar := t; btab[prb].psize := dx;
913 if isfun then
914 if sy = colon then
915 begin insymbol; (*function type*)
916 if sy = ident then
917 begin x := loc(id); insymbol;
918 if x <> 0 then
919 if tab[x].obj <> type1 then error(29) else
920 if tab[x].typ in stantyps then tab[prt].typ := tab[x].typ
921 else error(15)
922 end else skip([semicolon]+fsys, 2)
923 end else error(5);
924 if sy = semicolon then insymbol else error(14);
925 repeat
926 if sy = constsy then constantdeclaration;
927 if sy = typesy then typedeclaration;
928 if sy = varsy then variabledeclaration;
929 btab[prb].vsize := dx;
930 while sy in [proceduresy,functionsy] do procdeclaration;
931 test([beginsy], blockbegsys+statbegsys, 56)
932 until sy in statbegsys;
933 tab[prt].adr := lc;
934 insymbol; statement([semicolon,endsy]+fsys);
935 while sy in [semicolon]+statbegsys do
936 begin if sy = semicolon then insymbol else error(14);
937 statement([semicolon,endsy]+fsys)
938 end ;
939 if sy = endsy then insymbol else error(57);
940 test(fsys+[period], [], 6)
941end (*block*) ;
942