home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume23 / pascal / part02 < prev    next >
Text File  |  1991-09-27  |  57KB  |  1,991 lines

  1. Newsgroups: comp.sources.misc
  2. From: steven@cwi.nl (Steven Pemberton)
  3. Subject:  v23i026:  pascal - Public domain Pascal Compiler and Interpreter, Part02/03
  4. Message-ID: <1991Sep27.041214.15498@sparky.imd.sterling.com>
  5. X-Md4-Signature: 7631e6c5630aff576b3785529c06f66c
  6. Date: Fri, 27 Sep 1991 04:12:14 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: steven@cwi.nl (Steven Pemberton)
  10. Posting-number: Volume 23, Issue 26
  11. Archive-name: pascal/part02
  12. Environment: pascal
  13.  
  14. #!/bin/sh
  15. # do not concatenate these parts, unpack them in order with /bin/sh
  16. # file pcom.p continued
  17. #
  18. if test ! -r _shar_seq_.tmp; then
  19.     echo 'Please unpack part 1 first!'
  20.     exit 1
  21. fi
  22. (read Scheck
  23.  if test "$Scheck" != 2; then
  24.     echo Please unpack part "$Scheck" next!
  25.     exit 1
  26.  else
  27.     exit 0
  28.  fi
  29. ) < _shar_seq_.tmp || exit 1
  30. if test ! -f _shar_wnt_.tmp; then
  31.     echo 'x - still skipping pcom.p'
  32. else
  33. echo 'x - continuing file pcom.p'
  34. sed 's/^X//' << 'SHAR_EOF' >> 'pcom.p' &&
  35. X                end
  36. X            until sy <> comma;
  37. X            if sy = colon then
  38. X              begin insymbol;
  39. X                if sy = ident then
  40. X                  begin searchid([types],lcp);
  41. X                lsp := lcp^.idtype;
  42. X                if lsp <> nil then
  43. X                 if not(lsp^.form in[scalar,subrange,pointer])
  44. X                    then begin error(120); lsp := nil end;
  45. X                lcp3 := lcp2;
  46. X                while lcp2 <> nil do
  47. X                  begin lcp2^.idtype := lsp; lcp := lcp2;
  48. X                    lcp2 := lcp2^.next
  49. X                  end;
  50. X                lcp^.next := lcp1; lcp1 := lcp3;
  51. X                insymbol
  52. X                  end
  53. X                else error(2);
  54. X                if not (sy in fsys + [semicolon,rparent]) then
  55. X                  begin error(7);skip(fsys+[semicolon,rparent])end
  56. X              end
  57. X            else error(5)
  58. X              end
  59. X            else
  60. X              begin
  61. X            if sy = varsy then
  62. X              begin lkind := formal; insymbol end
  63. X            else lkind := actual;
  64. X            lcp2 := nil;
  65. X            count := 0;
  66. X            repeat
  67. X              if sy = ident then
  68. X                begin new(lcp,vars);
  69. X                  with lcp^ do
  70. X                begin name:=id; idtype:=nil; klass:=vars;
  71. X                  vkind := lkind; next := lcp2; vlev := level;
  72. X                end;
  73. X                  enterid(lcp);
  74. X                  lcp2 := lcp; count := count+1;
  75. X                  insymbol;
  76. X                end;
  77. X              if not (sy in [comma,colon] + fsys) then
  78. X                begin error(7);skip(fsys+[comma,semicolon,rparent])
  79. X                end;
  80. X              test := sy <> comma;
  81. X              if not test then insymbol
  82. X            until test;
  83. X            if sy = colon then
  84. X              begin insymbol;
  85. X                if sy = ident then
  86. X                  begin searchid([types],lcp);
  87. X                lsp := lcp^.idtype;
  88. X                lsize := ptrsize;
  89. X                if lsp <> nil then
  90. X                  if lkind=actual then
  91. X                    if lsp^.form<=power then lsize := lsp^.size
  92. X                    else if lsp^.form=files then error(121);
  93. X                align(parmptr,lsize);
  94. X                lcp3 := lcp2;
  95. X                align(parmptr,lc);
  96. X                lc := lc+count*lsize;
  97. X                llc := lc;
  98. X                while lcp2 <> nil do
  99. X                  begin lcp := lcp2;
  100. X                    with lcp2^ do
  101. X                      begin idtype := lsp;
  102. X                    llc := llc-lsize;
  103. X                    vaddr := llc;
  104. X                      end;
  105. X                    lcp2 := lcp2^.next
  106. X                  end;
  107. X                lcp^.next := lcp1; lcp1 := lcp3;
  108. X                insymbol
  109. X                  end
  110. X                else error(2);
  111. X                if not (sy in fsys + [semicolon,rparent]) then
  112. X                  begin error(7);skip(fsys+[semicolon,rparent])end
  113. X              end
  114. X            else error(5);
  115. X              end;
  116. X          end;
  117. X        if sy = semicolon then
  118. X          begin insymbol;
  119. X            if not (sy in fsys + [ident,varsy,procsy,funcsy]) then
  120. X              begin error(7); skip(fsys + [ident,rparent]) end
  121. X          end
  122. X          end (*while*) ;
  123. X        if sy = rparent then
  124. X          begin insymbol;
  125. X        if not (sy in fsy + fsys) then
  126. X          begin error(6); skip(fsy + fsys) end
  127. X          end
  128. X        else error(4);
  129. X        lcp3 := nil;
  130. X        (*reverse pointers and reserve local cells for copies of multiple
  131. X         values*)
  132. X        while lcp1 <> nil do
  133. X          with lcp1^ do
  134. X        begin lcp2 := next; next := lcp3;
  135. X          if klass = vars then
  136. X            if idtype <> nil then
  137. X              if (vkind=actual)and(idtype^.form>power) then
  138. X            begin align(idtype,lc);
  139. X              vaddr := lc;
  140. X              lc := lc+idtype^.size;
  141. X            end;
  142. X          lcp3 := lcp1; lcp1 := lcp2
  143. X        end;
  144. X        fpar := lcp3
  145. X      end
  146. X        else fpar := nil
  147. X    end (*parameterlist*) ;
  148. X
  149. X    begin (*procdeclaration*)
  150. X      llc := lc; lc := lcaftermarkstack; forw := false;
  151. X      if sy = ident then
  152. X    begin searchsection(display[top].fname,lcp); (*decide whether forw.*)
  153. X      if lcp <> nil then
  154. X        begin
  155. X          if lcp^.klass = proc then
  156. X        forw := lcp^.forwdecl and(fsy=procsy)and(lcp^.pfkind=actual)
  157. X          else
  158. X        if lcp^.klass = func then
  159. X          forw:=lcp^.forwdecl and(fsy=funcsy)and(lcp^.pfkind=actual)
  160. X        else forw := false;
  161. X          if not forw then error(160)
  162. X        end;
  163. X      if not forw then
  164. X        begin
  165. X          if fsy = procsy then new(lcp,proc,declared,actual)
  166. X          else new(lcp,func,declared,actual);
  167. X          with lcp^ do
  168. X        begin name := id; idtype := nil;
  169. X          extern := false; pflev := level; genlabel(lbname);
  170. X          pfdeckind := declared; pfkind := actual; pfname := lbname;
  171. X          if fsy = procsy then klass := proc
  172. X          else klass := func
  173. X        end;
  174. X          enterid(lcp)
  175. X        end
  176. X      else
  177. X        begin lcp1 := lcp^.next;
  178. X          while lcp1 <> nil do
  179. X        begin
  180. X          with lcp1^ do
  181. X            if klass = vars then
  182. X              if idtype <> nil then
  183. X            begin lcm := vaddr + idtype^.size;
  184. X              if lcm > lc then lc := lcm
  185. X            end;
  186. X          lcp1 := lcp1^.next
  187. X        end
  188. X        end;
  189. X      insymbol
  190. X    end
  191. X      else
  192. X    begin error(2); lcp := ufctptr end;
  193. X      oldlev := level; oldtop := top;
  194. X      if level < maxlevel then level := level + 1 else error(251);
  195. X      if top < displimit then
  196. X    begin top := top + 1;
  197. X      with display[top] do
  198. X        begin
  199. X          if forw then fname := lcp^.next
  200. X          else fname := nil;
  201. X          flabel := nil;
  202. X          occur := blck
  203. X        end
  204. X    end
  205. X      else error(250);
  206. X      if fsy = procsy then
  207. X    begin parameterlist([semicolon],lcp1);
  208. X      if not forw then lcp^.next := lcp1
  209. X    end
  210. X      else
  211. X    begin parameterlist([semicolon,colon],lcp1);
  212. X      if not forw then lcp^.next := lcp1;
  213. X      if sy = colon then
  214. X        begin insymbol;
  215. X          if sy = ident then
  216. X        begin if forw then error(122);
  217. X          searchid([types],lcp1);
  218. X          lsp := lcp1^.idtype;
  219. X          lcp^.idtype := lsp;
  220. X          if lsp <> nil then
  221. X            if not (lsp^.form in [scalar,subrange,pointer]) then
  222. X              begin error(120); lcp^.idtype := nil end;
  223. X          insymbol
  224. X        end
  225. X          else begin error(2); skip(fsys + [semicolon]) end
  226. X        end
  227. X      else
  228. X        if not forw then error(123)
  229. X    end;
  230. X      if sy = semicolon then insymbol else error(14);
  231. X      if sy = forwardsy then
  232. X    begin
  233. X      if forw then error(161)
  234. X      else lcp^.forwdecl := true;
  235. X      insymbol;
  236. X      if sy = semicolon then insymbol else error(14);
  237. X      if not (sy in fsys) then
  238. X        begin error(6); skip(fsys) end
  239. X    end
  240. X      else
  241. X    begin lcp^.forwdecl := false; mark(markp);
  242. X      repeat block(fsys,semicolon,lcp);
  243. X        if sy = semicolon then
  244. X          begin if prtables then printtables(false); insymbol;
  245. X        if not (sy in [beginsy,procsy,funcsy]) then
  246. X          begin error(6); skip(fsys) end
  247. X          end
  248. X        else error(14)
  249. X      until (sy in [beginsy,procsy,funcsy]) or eof(input);
  250. X      release(markp); (* return local entries on runtime heap *)
  251. X    end;
  252. X      level := oldlev; top := oldtop; lc := llc;
  253. X    end (*procdeclaration*) ;
  254. X
  255. X    procedure body(fsys: setofsys);
  256. X      const cstoccmax=65; cixmax=1000;
  257. X      type oprange = 0..63;
  258. X      var
  259. X      llcp:ctp; saveid:alpha;
  260. X      cstptr: array [1..cstoccmax] of csp;
  261. X      cstptrix: 0..cstoccmax;
  262. X      (*allows referencing of noninteger constants by an index
  263. X       (instead of a pointer), which can be stored in the p2-field
  264. X       of the instruction record until writeout.
  265. X       --> procedure load, procedure writeout*)
  266. X      entname, segsize: integer;
  267. X      stacktop, topnew, topmax: integer;
  268. X      lcmax,llc1: addrrange; lcp: ctp;
  269. X      llp: lbp;
  270. X
  271. X
  272. X      procedure mes(i: integer);
  273. X      begin topnew := topnew + cdx[i]*maxstack;
  274. X    if topnew > topmax then topmax := topnew
  275. X      end;
  276. X
  277. X      procedure putic;
  278. X      begin if ic mod 10 = 0 then writeln(prr,'i',ic:5) end;
  279. X
  280. X      procedure gen0(fop: oprange);
  281. X      begin
  282. X    if prcode then begin putic; writeln(prr,mn[fop]:4) end;
  283. X    ic := ic + 1; mes(fop)
  284. X      end (*gen0*) ;
  285. X
  286. X      procedure gen1(fop: oprange; fp2: integer);
  287. X    var k: integer;
  288. X      begin
  289. X    if prcode then
  290. X      begin putic; write(prr,mn[fop]:4);
  291. X        if fop = 30 then
  292. X          begin writeln(prr,sna[fp2]:12);
  293. X        topnew := topnew + pdx[fp2]*maxstack;
  294. X        if topnew > topmax then topmax := topnew
  295. X          end
  296. X        else
  297. X          begin
  298. X        if fop = 38 then
  299. X           begin write(prr,'''');
  300. X             with cstptr[fp2]^ do
  301. X             begin
  302. X               for k := 1 to slgth do write(prr,sval[k]:1);
  303. X               for k := slgth+1 to strglgth do write(prr,' ');
  304. X             end;
  305. X             writeln(prr,'''')
  306. X           end
  307. X        else if fop = 42 then writeln(prr,chr(fp2))
  308. X             else writeln(prr,fp2:12);
  309. X        mes(fop)
  310. X          end
  311. X      end;
  312. X    ic := ic + 1
  313. X      end (*gen1*) ;
  314. X
  315. X      procedure gen2(fop: oprange; fp1,fp2: integer);
  316. X    var k : integer;
  317. X      begin
  318. X    if prcode then
  319. X      begin putic; write(prr,mn[fop]:4);
  320. X        case fop of
  321. X          45,50,54,56:
  322. X        writeln(prr,' ',fp1:3,fp2:8);
  323. X          47,48,49,52,53,55:
  324. X        begin write(prr,chr(fp1));
  325. X          if chr(fp1) = 'm' then write(prr,fp2:11);
  326. X          writeln(prr)
  327. X        end;
  328. X          51:
  329. X        case fp1 of
  330. X          1: writeln(prr,'i ',fp2);
  331. X          2: begin write(prr,'r ');
  332. X               with cstptr[fp2]^ do
  333. X             for k := 1 to strglgth do write(prr,rval[k]);
  334. X               writeln(prr)
  335. X             end;
  336. X          3: writeln(prr,'b ',fp2);
  337. X          4: writeln(prr,'n');
  338. X          6: writeln(prr,'c ''':3,chr(fp2),'''');
  339. X          5: begin write(prr,'(');
  340. X               with cstptr[fp2]^ do
  341. X             for k := setlow to sethigh do
  342. X               if k in pval then write(prr,k:3);
  343. X               writeln(prr,')')
  344. X             end
  345. X        end
  346. X        end;
  347. X      end;
  348. X    ic := ic + 1; mes(fop)
  349. X      end (*gen2*) ;
  350. X
  351. X      procedure gentypindicator(fsp: stp);
  352. X      begin
  353. X    if fsp<>nil then
  354. X      with fsp^ do
  355. X        case form of
  356. X         scalar: if fsp=intptr then write(prr,'i')
  357. X             else
  358. X               if fsp=boolptr then write(prr,'b')
  359. X               else
  360. X             if fsp=charptr then write(prr,'c')
  361. X             else
  362. X               if scalkind = declared then write(prr,'i')
  363. X               else write(prr,'r');
  364. X         subrange: gentypindicator(rangetype);
  365. X         pointer:  write(prr,'a');
  366. X         power:    write(prr,'s');
  367. X         records,arrays: write(prr,'m');
  368. X         files,tagfld,variant: error(500)
  369. X        end
  370. X      end (*typindicator*);
  371. X
  372. X      procedure gen0t(fop: oprange; fsp: stp);
  373. X      begin
  374. X    if prcode then
  375. X      begin putic;
  376. X        write(prr,mn[fop]:4);
  377. X        gentypindicator(fsp);
  378. X        writeln(prr);
  379. X      end;
  380. X    ic := ic + 1; mes(fop)
  381. X      end (*gen0t*);
  382. X
  383. X      procedure gen1t(fop: oprange; fp2: integer; fsp: stp);
  384. X      begin
  385. X    if prcode then
  386. X      begin putic;
  387. X        write(prr,mn[fop]:4);
  388. X        gentypindicator(fsp);
  389. X        writeln(prr,fp2:11)
  390. X      end;
  391. X    ic := ic + 1; mes(fop)
  392. X      end (*gen1t*);
  393. X
  394. X      procedure gen2t(fop: oprange; fp1,fp2: integer; fsp: stp);
  395. X      begin
  396. X    if prcode then
  397. X      begin putic;
  398. X        write(prr,mn[fop]: 4);
  399. X        gentypindicator(fsp);
  400. X        writeln(prr,fp1:3+5*ord(abs(fp1)>99),fp2:8);
  401. X      end;
  402. X    ic := ic + 1; mes(fop)
  403. X      end (*gen2t*);
  404. X
  405. X      procedure load;
  406. X      begin
  407. X    with gattr do
  408. X      if typtr <> nil then
  409. X        begin
  410. X          case kind of
  411. X        cst:   if (typtr^.form = scalar) and (typtr <> realptr) then
  412. X             if typtr = boolptr then gen2(51(*ldc*),3,cval.ival)
  413. X             else
  414. X               if typtr=charptr then
  415. X                 gen2(51(*ldc*),6,cval.ival)
  416. X               else gen2(51(*ldc*),1,cval.ival)
  417. X               else
  418. X             if typtr = nilptr then gen2(51(*ldc*),4,0)
  419. X             else
  420. X               if cstptrix >= cstoccmax then error(254)
  421. X               else
  422. X                 begin cstptrix := cstptrix + 1;
  423. X                   cstptr[cstptrix] := cval.valp;
  424. X                   if typtr = realptr then
  425. X                 gen2(51(*ldc*),2,cstptrix)
  426. X                   else
  427. X                 gen2(51(*ldc*),5,cstptrix)
  428. X                 end;
  429. X        varbl: case access of
  430. X             drct:   if vlevel<=1 then
  431. X                   gen1t(39(*ldo*),dplmt,typtr)
  432. X                 else gen2t(54(*lod*),level-vlevel,dplmt,typtr);
  433. X             indrct: gen1t(35(*ind*),idplmt,typtr);
  434. X             inxd:   error(400)
  435. X               end;
  436. X        expr:
  437. X          end;
  438. X          kind := expr
  439. X        end
  440. X      end (*load*) ;
  441. X
  442. X      procedure store(var fattr: attr);
  443. X      begin
  444. X    with fattr do
  445. X      if typtr <> nil then
  446. X        case access of
  447. X          drct:   if vlevel <= 1 then gen1t(43(*sro*),dplmt,typtr)
  448. X              else gen2t(56(*str*),level-vlevel,dplmt,typtr);
  449. X          indrct: if idplmt <> 0 then error(400)
  450. X              else gen0t(26(*sto*),typtr);
  451. X          inxd:   error(400)
  452. X        end
  453. X      end (*store*) ;
  454. X
  455. X      procedure loadaddress;
  456. X      begin
  457. X    with gattr do
  458. X      if typtr <> nil then
  459. X        begin
  460. X          case kind of
  461. X        cst:   if string(typtr) then
  462. X             if cstptrix >= cstoccmax then error(254)
  463. X             else
  464. X               begin cstptrix := cstptrix + 1;
  465. X                 cstptr[cstptrix] := cval.valp;
  466. X                 gen1(38(*lca*),cstptrix)
  467. X               end
  468. X               else error(400);
  469. X        varbl: case access of
  470. X             drct:   if vlevel <= 1 then gen1(37(*lao*),dplmt)
  471. X                 else gen2(50(*lda*),level-vlevel,dplmt);
  472. X             indrct: if idplmt <> 0 then
  473. X                   gen1t(34(*inc*),idplmt,nilptr);
  474. X             inxd:   error(400)
  475. X               end;
  476. X        expr:  error(400)
  477. X          end;
  478. X          kind := varbl; access := indrct; idplmt := 0
  479. X        end
  480. X      end (*loadaddress*) ;
  481. X
  482. X
  483. X      procedure genfjp(faddr: integer);
  484. X      begin load;
  485. X    if gattr.typtr <> nil then
  486. X      if gattr.typtr <> boolptr then error(144);
  487. X    if prcode then begin putic; writeln(prr,mn[33]:4,' l':8,faddr:4) end;
  488. X    ic := ic + 1; mes(33)
  489. X      end (*genfjp*) ;
  490. X
  491. X      procedure genujpxjp(fop: oprange; fp2: integer);
  492. X      begin
  493. X       if prcode then
  494. X      begin putic; writeln(prr, mn[fop]:4, ' l':8,fp2:4) end;
  495. X    ic := ic + 1; mes(fop)
  496. X      end (*genujpxjp*);
  497. X
  498. X
  499. X      procedure gencupent(fop: oprange; fp1,fp2: integer);
  500. X      begin
  501. X    if prcode then
  502. X      begin putic;
  503. X        writeln(prr,mn[fop]:4,fp1:4,'l':4,fp2:4)
  504. X      end;
  505. X    ic := ic + 1; mes(fop)
  506. X      end;
  507. X
  508. X
  509. X      procedure checkbnds(fsp: stp);
  510. X    var lmin,lmax: integer;
  511. X      begin
  512. X    if fsp <> nil then
  513. X      if fsp <> intptr then
  514. X        if fsp <> realptr then
  515. X          if fsp^.form <= subrange then
  516. X        begin
  517. X          getbounds(fsp,lmin,lmax);
  518. X          gen2t(45(*chk*),lmin,lmax,fsp)
  519. X        end
  520. X      end (*checkbnds*);
  521. X
  522. X
  523. X      procedure putlabel(labname: integer);
  524. X      begin if prcode then writeln(prr, 'l', labname:4)
  525. X      end (*putlabel*);
  526. X
  527. X      procedure statement(fsys: setofsys);
  528. X    label 1;
  529. X    var lcp: ctp; llp: lbp;
  530. X
  531. X    procedure expression(fsys: setofsys); forward;
  532. X
  533. X    procedure selector(fsys: setofsys; fcp: ctp);
  534. X    var lattr: attr; lcp: ctp; lsize: addrrange; lmin,lmax: integer;
  535. X    begin
  536. X      with fcp^, gattr do
  537. X        begin typtr := idtype; kind := varbl;
  538. X          case klass of
  539. X        vars:
  540. X          if vkind = actual then
  541. X            begin access := drct; vlevel := vlev;
  542. X              dplmt := vaddr
  543. X            end
  544. X          else
  545. X            begin gen2t(54(*lod*),level-vlev,vaddr,nilptr);
  546. X              access := indrct; idplmt := 0
  547. X            end;
  548. X        field:
  549. X          with display[disx] do
  550. X            if occur = crec then
  551. X              begin access := drct; vlevel := clev;
  552. X            dplmt := cdspl + fldaddr
  553. X              end
  554. X            else
  555. X              begin
  556. X            if level = 1 then gen1t(39(*ldo*),vdspl,nilptr)
  557. X            else gen2t(54(*lod*),0,vdspl,nilptr);
  558. X            access := indrct; idplmt := fldaddr
  559. X              end;
  560. X        func:
  561. X          if pfdeckind = standard then
  562. X            begin error(150); typtr := nil end
  563. X          else
  564. X            begin
  565. X              if pfkind = formal then error(151)
  566. X              else
  567. X            if (pflev+1<>level)or(fprocp<>fcp) then error(177);
  568. X            begin access := drct; vlevel := pflev + 1;
  569. X              dplmt := 0   (*impl. relat. addr. of fct. result*)
  570. X            end
  571. X            end
  572. X          end (*case*)
  573. X        end (*with*);
  574. X      if not (sy in selectsys + fsys) then
  575. X        begin error(59); skip(selectsys + fsys) end;
  576. X      while sy in selectsys do
  577. X        begin
  578. X    (*[*) if sy = lbrack then
  579. X        begin
  580. X          repeat lattr := gattr;
  581. X            with lattr do
  582. X              if typtr <> nil then
  583. X            if typtr^.form <> arrays then
  584. X              begin error(138); typtr := nil end;
  585. X            loadaddress;
  586. X            insymbol; expression(fsys + [comma,rbrack]);
  587. X            load;
  588. X            if gattr.typtr <> nil then
  589. X              if gattr.typtr^.form<>scalar then error(113)
  590. X              else if not comptypes(gattr.typtr,intptr) then
  591. X                 gen0t(58(*ord*),gattr.typtr);
  592. X            if lattr.typtr <> nil then
  593. X              with lattr.typtr^ do
  594. X            begin
  595. X              if comptypes(inxtype,gattr.typtr) then
  596. X                begin
  597. X                  if inxtype <> nil then
  598. X                begin getbounds(inxtype,lmin,lmax);
  599. X                  if debug then
  600. X                    gen2t(45(*chk*),lmin,lmax,intptr);
  601. X                  if lmin>0 then gen1t(31(*dec*),lmin,intptr)
  602. X                  else if lmin<0 then
  603. X                    gen1t(34(*inc*),-lmin,intptr);
  604. X                  (*or simply gen1(31,lmin)*)
  605. X                end
  606. X                end
  607. X              else error(139);
  608. X              with gattr do
  609. X                begin typtr := aeltype; kind := varbl;
  610. X                  access := indrct; idplmt := 0
  611. X                end;
  612. X              if gattr.typtr <> nil then
  613. X                begin
  614. X                  lsize := gattr.typtr^.size;
  615. X                  align(gattr.typtr,lsize);
  616. X                  gen1(36(*ixa*),lsize)
  617. X                end
  618. X            end
  619. X          until sy <> comma;
  620. X          if sy = rbrack then insymbol else error(12)
  621. X        end (*if sy = lbrack*)
  622. X          else
  623. X    (*.*)   if sy = period then
  624. X          begin
  625. X            with gattr do
  626. X              begin
  627. X            if typtr <> nil then
  628. X              if typtr^.form <> records then
  629. X                begin error(140); typtr := nil end;
  630. X            insymbol;
  631. X            if sy = ident then
  632. X              begin
  633. X                if typtr <> nil then
  634. X                  begin searchsection(typtr^.fstfld,lcp);
  635. X                if lcp = nil then
  636. X                  begin error(152); typtr := nil end
  637. X                else
  638. X                  with lcp^ do
  639. X                    begin typtr := idtype;
  640. X                      case access of
  641. X                    drct:   dplmt := dplmt + fldaddr;
  642. X                    indrct: idplmt := idplmt + fldaddr;
  643. X                    inxd:   error(400)
  644. X                      end
  645. X                    end
  646. X                  end;
  647. X                insymbol
  648. X              end (*sy = ident*)
  649. X            else error(2)
  650. X              end (*with gattr*)
  651. X          end (*if sy = period*)
  652. X        else
  653. X    (*^*)     begin
  654. X            if gattr.typtr <> nil then
  655. X              with gattr,typtr^ do
  656. X            if form = pointer then
  657. X              begin load; typtr := eltype;
  658. X                if debug then gen2t(45(*chk*),1,maxaddr,nilptr);
  659. X                with gattr do
  660. X                  begin kind := varbl; access := indrct;
  661. X                idplmt := 0
  662. X                  end
  663. X              end
  664. X            else
  665. X              if form = files then typtr := filtype
  666. X              else error(141);
  667. X            insymbol
  668. X          end;
  669. X          if not (sy in fsys + selectsys) then
  670. X        begin error(6); skip(fsys + selectsys) end
  671. X        end (*while*)
  672. X    end (*selector*) ;
  673. X
  674. X    procedure call(fsys: setofsys; fcp: ctp);
  675. X      var lkey: 1..15;
  676. X
  677. X      procedure variable(fsys: setofsys);
  678. X        var lcp: ctp;
  679. X      begin
  680. X        if sy = ident then
  681. X          begin searchid([vars,field],lcp); insymbol end
  682. X        else begin error(2); lcp := uvarptr end;
  683. X        selector(fsys,lcp)
  684. X      end (*variable*) ;
  685. X
  686. X      procedure getputresetrewrite;
  687. X      begin variable(fsys + [rparent]); loadaddress;
  688. X        if gattr.typtr <> nil then
  689. X          if gattr.typtr^.form <> files then error(116);
  690. X        if lkey <= 2 then gen1(30(*csp*),lkey(*get,put*))
  691. X        else error(399)
  692. X      end (*getputresetrewrite*) ;
  693. X
  694. X      procedure read;
  695. X        var llev:levrange; laddr:addrrange;
  696. X        lsp : stp;
  697. X      begin
  698. X        llev := 1; laddr := lcaftermarkstack;
  699. X        if sy = lparent then
  700. X          begin insymbol;
  701. X        variable(fsys + [comma,rparent]);
  702. X        lsp := gattr.typtr; test := false;
  703. X        if lsp <> nil then
  704. X          if lsp^.form = files then
  705. X            with gattr, lsp^ do
  706. X              begin
  707. X            if filtype = charptr then
  708. X              begin llev := vlevel; laddr := dplmt end
  709. X            else error(399);
  710. X            if sy = rparent then
  711. X              begin if lkey = 5 then error(116);
  712. X                test := true
  713. X              end
  714. X            else
  715. X              if sy <> comma then
  716. X                begin error(116); skip(fsys + [comma,rparent]) end;
  717. X            if sy = comma then
  718. X              begin insymbol; variable(fsys + [comma,rparent])
  719. X              end
  720. X            else test := true
  721. X              end;
  722. X           if not test then
  723. X        repeat loadaddress;
  724. X          gen2(50(*lda*),level-llev,laddr);
  725. X          if gattr.typtr <> nil then
  726. X            if gattr.typtr^.form <= subrange then
  727. X              if comptypes(intptr,gattr.typtr) then
  728. X            gen1(30(*csp*),3(*rdi*))
  729. X              else
  730. X            if comptypes(realptr,gattr.typtr) then
  731. X              gen1(30(*csp*),4(*rdr*))
  732. X            else
  733. X              if comptypes(charptr,gattr.typtr) then
  734. X                gen1(30(*csp*),5(*rdc*))
  735. X              else error(399)
  736. X            else error(116);
  737. X          test := sy <> comma;
  738. X          if not test then
  739. X            begin insymbol; variable(fsys + [comma,rparent])
  740. X            end
  741. X        until test;
  742. X        if sy = rparent then insymbol else error(4)
  743. X          end
  744. X        else if lkey = 5 then error(116);
  745. X        if lkey = 11 then
  746. X          begin gen2(50(*lda*),level-llev,laddr);
  747. X        gen1(30(*csp*),21(*rln*))
  748. X          end
  749. X      end (*read*) ;
  750. X
  751. X      procedure write;
  752. X        var lsp: stp; default : boolean; llkey: 1..15;
  753. X        llev:levrange; laddr,len:addrrange;
  754. X      begin llkey := lkey;
  755. X        llev := 1; laddr := lcaftermarkstack + charmax;
  756. X        if sy = lparent then
  757. X        begin insymbol;
  758. X        expression(fsys + [comma,colon,rparent]);
  759. X        lsp := gattr.typtr; test := false;
  760. X        if lsp <> nil then
  761. X          if lsp^.form = files then
  762. X        with gattr, lsp^ do
  763. X          begin
  764. X            if filtype = charptr then
  765. X              begin llev := vlevel; laddr := dplmt end
  766. X            else error(399);
  767. X            if sy = rparent then
  768. X              begin if llkey = 6 then error(116);
  769. X            test := true
  770. X              end
  771. X            else
  772. X              if sy <> comma then
  773. X            begin error(116); skip(fsys+[comma,rparent]) end;
  774. X            if sy = comma then
  775. X              begin insymbol; expression(fsys+[comma,colon,rparent])
  776. X              end
  777. X            else test := true
  778. X          end;
  779. X       if not test then
  780. X        repeat
  781. X          lsp := gattr.typtr;
  782. X          if lsp <> nil then
  783. X        if lsp^.form <= subrange then load else loadaddress;
  784. X          if sy = colon then
  785. X        begin insymbol; expression(fsys + [comma,colon,rparent]);
  786. X          if gattr.typtr <> nil then
  787. X            if gattr.typtr <> intptr then error(116);
  788. X          load; default := false
  789. X        end
  790. X          else default := true;
  791. X          if sy = colon then
  792. X        begin insymbol; expression(fsys + [comma,rparent]);
  793. X          if gattr.typtr <> nil then
  794. X            if gattr.typtr <> intptr then error(116);
  795. X          if lsp <> realptr then error(124);
  796. X          load; error(399);
  797. X        end
  798. X          else
  799. X        if lsp = intptr then
  800. X          begin if default then gen2(51(*ldc*),1,10);
  801. X            gen2(50(*lda*),level-llev,laddr);
  802. X            gen1(30(*csp*),6(*wri*))
  803. X          end
  804. X        else
  805. X          if lsp = realptr then
  806. X            begin if default then gen2(51(*ldc*),1,20);
  807. X              gen2(50(*lda*),level-llev,laddr);
  808. X              gen1(30(*csp*),8(*wrr*))
  809. X            end
  810. X          else
  811. X            if lsp = charptr then
  812. X              begin if default then gen2(51(*ldc*),1,1);
  813. X            gen2(50(*lda*),level-llev,laddr);
  814. X            gen1(30(*csp*),9(*wrc*))
  815. X              end
  816. X            else
  817. X              if lsp <> nil then
  818. X            begin
  819. X              if lsp^.form = scalar then error(399)
  820. X              else
  821. X                if string(lsp) then
  822. X                  begin len := lsp^.size div charmax;
  823. X                if default then
  824. X                      gen2(51(*ldc*),1,len);
  825. X                gen2(51(*ldc*),1,len);
  826. X                gen2(50(*lda*),level-llev,laddr);
  827. X                gen1(30(*csp*),10(*wrs*))
  828. X                  end
  829. X                else error(116)
  830. X            end;
  831. X          test := sy <> comma;
  832. X          if not test then
  833. X        begin insymbol; expression(fsys + [comma,colon,rparent])
  834. X        end
  835. X        until test;
  836. X        if sy = rparent then insymbol else error(4)
  837. X        end
  838. X          else if lkey = 6 then error(116);
  839. X        if llkey = 12 then (*writeln*)
  840. X          begin gen2(50(*lda*),level-llev,laddr);
  841. X        gen1(30(*csp*),22(*wln*))
  842. X          end
  843. X      end (*write*) ;
  844. X
  845. X      procedure pack;
  846. X        var lsp,lsp1: stp;
  847. X      begin error(399); variable(fsys + [comma,rparent]);
  848. X        lsp := nil; lsp1 := nil;
  849. X        if gattr.typtr <> nil then
  850. X          with gattr.typtr^ do
  851. X        if form = arrays then
  852. X          begin lsp := inxtype; lsp1 := aeltype end
  853. X        else error(116);
  854. X        if sy = comma then insymbol else error(20);
  855. X        expression(fsys + [comma,rparent]);
  856. X        if gattr.typtr <> nil then
  857. X          if gattr.typtr^.form <> scalar then error(116)
  858. X          else
  859. X        if not comptypes(lsp,gattr.typtr) then error(116);
  860. X        if sy = comma then insymbol else error(20);
  861. X        variable(fsys + [rparent]);
  862. X        if gattr.typtr <> nil then
  863. X          with gattr.typtr^ do
  864. X        if form = arrays then
  865. X          begin
  866. X            if not comptypes(aeltype,lsp1)
  867. X              or not comptypes(inxtype,lsp) then
  868. X              error(116)
  869. X          end
  870. X        else error(116)
  871. X      end (*pack*) ;
  872. X
  873. X      procedure unpack;
  874. X        var lsp,lsp1: stp;
  875. X      begin error(399); variable(fsys + [comma,rparent]);
  876. X        lsp := nil; lsp1 := nil;
  877. X        if gattr.typtr <> nil then
  878. X          with gattr.typtr^ do
  879. X        if form = arrays then
  880. X          begin lsp := inxtype; lsp1 := aeltype end
  881. X        else error(116);
  882. X        if sy = comma then insymbol else error(20);
  883. X        variable(fsys + [comma,rparent]);
  884. X        if gattr.typtr <> nil then
  885. X          with gattr.typtr^ do
  886. X        if form = arrays then
  887. X          begin
  888. X            if not comptypes(aeltype,lsp1)
  889. X              or not comptypes(inxtype,lsp) then
  890. X              error(116)
  891. X          end
  892. X        else error(116);
  893. X        if sy = comma then insymbol else error(20);
  894. X        expression(fsys + [rparent]);
  895. X        if gattr.typtr <> nil then
  896. X          if gattr.typtr^.form <> scalar then error(116)
  897. X          else
  898. X        if not comptypes(lsp,gattr.typtr) then error(116);
  899. X      end (*unpack*) ;
  900. X
  901. X      procedure new;
  902. X        label 1;
  903. X        var lsp,lsp1: stp; varts: integer;
  904. X        lsize: addrrange; lval: valu;
  905. X      begin variable(fsys + [comma,rparent]); loadaddress;
  906. X        lsp := nil; varts := 0; lsize := 0;
  907. X        if gattr.typtr <> nil then
  908. X          with gattr.typtr^ do
  909. X        if form = pointer then
  910. X          begin
  911. X            if eltype <> nil then
  912. X              begin lsize := eltype^.size;
  913. X            if eltype^.form = records then lsp := eltype^.recvar
  914. X              end
  915. X          end
  916. X        else error(116);
  917. X        while sy = comma do
  918. X          begin insymbol;constant(fsys + [comma,rparent],lsp1,lval);
  919. X        varts := varts + 1;
  920. X        (*check to insert here: is constant in tagfieldtype range*)
  921. X        if lsp = nil then error(158)
  922. X        else
  923. X          if lsp^.form <> tagfld then error(162)
  924. X          else
  925. X            if lsp^.tagfieldp <> nil then
  926. X              if string(lsp1) or (lsp1 = realptr) then error(159)
  927. X              else
  928. X            if comptypes(lsp^.tagfieldp^.idtype,lsp1) then
  929. X              begin
  930. X                lsp1 := lsp^.fstvar;
  931. X                while lsp1 <> nil do
  932. X                  with lsp1^ do
  933. X                if varval.ival = lval.ival then
  934. X                  begin lsize := size; lsp := subvar;
  935. X                    goto 1
  936. X                  end
  937. X                else lsp1 := nxtvar;
  938. X                lsize := lsp^.size; lsp := nil;
  939. X              end
  940. X            else error(116);
  941. X      1:  end (*while*) ;
  942. X        gen2(51(*ldc*),1,lsize);
  943. X        gen1(30(*csp*),12(*new*));
  944. X      end (*new*) ;
  945. X
  946. X      procedure mark;
  947. X      begin variable(fsys+[rparent]);
  948. X         if gattr.typtr <> nil then
  949. X           if gattr.typtr^.form = pointer then
  950. X         begin loadaddress; gen1(30(*csp*),23(*sav*)) end
  951. X           else error(116)
  952. X      end(*mark*);
  953. X
  954. X      procedure release;
  955. X      begin variable(fsys+[rparent]);
  956. X        if gattr.typtr <> nil then
  957. X           if gattr.typtr^.form = pointer then
  958. X              begin load; gen1(30(*csp*),13(*rst*)) end
  959. X           else error(116)
  960. X      end (*release*);
  961. X
  962. X
  963. X
  964. X      procedure abs;
  965. X      begin
  966. X        if gattr.typtr <> nil then
  967. X          if gattr.typtr = intptr then gen0(0(*abi*))
  968. X          else
  969. X        if gattr.typtr = realptr then gen0(1(*abr*))
  970. X        else begin error(125); gattr.typtr := intptr end
  971. X      end (*abs*) ;
  972. X
  973. X      procedure sqr;
  974. X      begin
  975. X        if gattr.typtr <> nil then
  976. X          if gattr.typtr = intptr then gen0(24(*sqi*))
  977. X          else
  978. X        if gattr.typtr = realptr then gen0(25(*sqr*))
  979. X        else begin error(125); gattr.typtr := intptr end
  980. X      end (*sqr*) ;
  981. X
  982. X      procedure trunc;
  983. X      begin
  984. X        if gattr.typtr <> nil then
  985. X          if gattr.typtr <> realptr then error(125);
  986. X        gen0(27(*trc*));
  987. X        gattr.typtr := intptr
  988. X      end (*trunc*) ;
  989. X
  990. X      procedure odd;
  991. X      begin
  992. X        if gattr.typtr <> nil then
  993. X          if gattr.typtr <> intptr then error(125);
  994. X        gen0(20(*odd*));
  995. X        gattr.typtr := boolptr
  996. X      end (*odd*) ;
  997. X
  998. X      procedure ord;
  999. X      begin
  1000. X        if gattr.typtr <> nil then
  1001. X          if gattr.typtr^.form >= power then error(125);
  1002. X        gen0t(58(*ord*),gattr.typtr);
  1003. X        gattr.typtr := intptr
  1004. X      end (*ord*) ;
  1005. X
  1006. X      procedure chr;
  1007. X      begin
  1008. X        if gattr.typtr <> nil then
  1009. X          if gattr.typtr <> intptr then error(125);
  1010. X        gen0(59(*chr*));
  1011. X        gattr.typtr := charptr
  1012. X      end (*chr*) ;
  1013. X
  1014. X      procedure predsucc;
  1015. X      begin
  1016. X        if gattr.typtr <> nil then
  1017. X          if gattr.typtr^.form <> scalar then error(125);
  1018. X        if lkey = 7 then gen1t(31(*dec*),1,gattr.typtr)
  1019. X        else gen1t(34(*inc*),1,gattr.typtr)
  1020. X      end (*predsucc*) ;
  1021. X
  1022. X      procedure eof;
  1023. X      begin
  1024. X        if sy = lparent then
  1025. X          begin insymbol; variable(fsys + [rparent]);
  1026. X        if sy = rparent then insymbol else error(4)
  1027. X          end
  1028. X        else
  1029. X          with gattr do
  1030. X        begin typtr := textptr; kind := varbl; access := drct;
  1031. X          vlevel := 1; dplmt := lcaftermarkstack
  1032. X        end;
  1033. X        loadaddress;
  1034. X        if gattr.typtr <> nil then
  1035. X          if gattr.typtr^.form <> files then error(125);
  1036. X        if lkey = 9 then gen0(8(*eof*)) else gen1(30(*csp*),14(*eln*));
  1037. X          gattr.typtr := boolptr
  1038. X      end (*eof*) ;
  1039. X
  1040. X
  1041. X
  1042. X      procedure callnonstandard;
  1043. X        var nxt,lcp: ctp; lsp: stp; lkind: idkind; lb: boolean;
  1044. X        locpar, llc: addrrange;
  1045. X      begin locpar := 0;
  1046. X        with fcp^ do
  1047. X          begin nxt := next; lkind := pfkind;
  1048. X        if not extern then gen1(41(*mst*),level-pflev)
  1049. X          end;
  1050. X        if sy = lparent then
  1051. X          begin llc := lc;
  1052. X        repeat lb := false; (*decide whether proc/func must be passed*)
  1053. X          if lkind = actual then
  1054. X            begin
  1055. X              if nxt = nil then error(126)
  1056. X              else lb := nxt^.klass in [proc,func]
  1057. X            end else error(399);
  1058. X          (*For formal proc/func, lb is false and expression
  1059. X           will be called, which will always interpret a proc/func id
  1060. X           at its beginning as a call rather than a parameter passing.
  1061. X           In this implementation, parameter procedures/functions
  1062. X           are therefore not allowed to have procedure/function
  1063. X           parameters*)
  1064. X          insymbol;
  1065. X          if lb then   (*pass function or procedure*)
  1066. X            begin error(399);
  1067. X              if sy <> ident then
  1068. X            begin error(2); skip(fsys + [comma,rparent]) end
  1069. X              else
  1070. X            begin
  1071. X              if nxt^.klass = proc then searchid([proc],lcp)
  1072. X              else
  1073. X                begin searchid([func],lcp);
  1074. X                  if not comptypes(lcp^.idtype,nxt^.idtype) then
  1075. X                error(128)
  1076. X                end;
  1077. X              insymbol;
  1078. X              if not (sy in fsys + [comma,rparent]) then
  1079. X                begin error(6); skip(fsys + [comma,rparent]) end
  1080. X            end
  1081. X            end (*if lb*)
  1082. X          else
  1083. X            begin expression(fsys + [comma,rparent]);
  1084. X              if gattr.typtr <> nil then
  1085. X            if lkind = actual then
  1086. X              begin
  1087. X                if nxt <> nil then
  1088. X                  begin lsp := nxt^.idtype;
  1089. X                if lsp <> nil then
  1090. X                  begin
  1091. X                    if (nxt^.vkind = actual) then
  1092. X                      if lsp^.form <= power then
  1093. X                    begin load;
  1094. X                      if debug then checkbnds(lsp);
  1095. X                      if comptypes(realptr,lsp)
  1096. X                         and (gattr.typtr = intptr) then
  1097. X                        begin gen0(10(*flt*));
  1098. X                          gattr.typtr := realptr
  1099. X                        end;
  1100. X                      locpar := locpar+lsp^.size;
  1101. X                      align(parmptr,locpar);
  1102. X                    end
  1103. X                      else
  1104. X                    begin
  1105. X                      loadaddress;
  1106. X                      locpar := locpar+ptrsize;
  1107. X                      align(parmptr,locpar)
  1108. X                    end
  1109. X                    else
  1110. X                      if gattr.kind = varbl then
  1111. X                    begin loadaddress;
  1112. X                      locpar := locpar+ptrsize;
  1113. X                      align(parmptr,locpar);
  1114. X                    end
  1115. X                      else error(154);
  1116. X                    if not comptypes(lsp,gattr.typtr) then
  1117. X                      error(142)
  1118. X                  end
  1119. X                  end
  1120. X              end
  1121. X              else (*lkind = formal*)
  1122. X            begin (*pass formal param*)
  1123. X            end
  1124. X            end;
  1125. X          if (lkind = actual) and (nxt <> nil) then nxt := nxt^.next
  1126. X        until sy <> comma;
  1127. X        lc := llc;
  1128. X        if sy = rparent then insymbol else error(4)
  1129. X          end (*if lparent*);
  1130. X        if lkind = actual then
  1131. X          begin if nxt <> nil then error(126);
  1132. X        with fcp^ do
  1133. X          begin
  1134. X            if extern then gen1(30(*csp*),pfname)
  1135. X            else gencupent(46(*cup*),locpar,pfname);
  1136. X          end
  1137. X          end;
  1138. X        gattr.typtr := fcp^.idtype
  1139. X      end (*callnonstandard*) ;
  1140. X
  1141. X    begin (*call*)
  1142. X      if fcp^.pfdeckind = standard then
  1143. X        begin lkey := fcp^.key;
  1144. X          if fcp^.klass = proc then
  1145. X           begin
  1146. X        if not(lkey in [5,6,11,12]) then
  1147. X          if sy = lparent then insymbol else error(9);
  1148. X        case lkey of
  1149. X          1,2,
  1150. X          3,4:  getputresetrewrite;
  1151. X          5,11: read;
  1152. X          6,12: write;
  1153. X          7:    pack;
  1154. X          8:    unpack;
  1155. X          9:    new;
  1156. X          10:   release;
  1157. X          13:   mark
  1158. X        end;
  1159. X        if not(lkey in [5,6,11,12]) then
  1160. X          if sy = rparent then insymbol else error(4)
  1161. X           end
  1162. X          else
  1163. X        begin
  1164. X          if lkey <= 8 then
  1165. X            begin
  1166. X              if sy = lparent then insymbol else error(9);
  1167. X              expression(fsys+[rparent]); load
  1168. X            end;
  1169. X          case lkey of
  1170. X            1:    abs;
  1171. X            2:    sqr;
  1172. X            3:    trunc;
  1173. X            4:    odd;
  1174. X            5:    ord;
  1175. X            6:    chr;
  1176. X            7,8:  predsucc;
  1177. X            9,10: eof
  1178. X          end;
  1179. X          if lkey <= 8 then
  1180. X            if sy = rparent then insymbol else error(4)
  1181. X        end;
  1182. X        end (*standard procedures and functions*)
  1183. X      else callnonstandard
  1184. X    end (*call*) ;
  1185. X
  1186. X    procedure expression;
  1187. X      var lattr: attr; lop: operator; typind: char; lsize: addrrange;
  1188. X
  1189. X      procedure simpleexpression(fsys: setofsys);
  1190. X        var lattr: attr; lop: operator; signed: boolean;
  1191. X
  1192. X        procedure term(fsys: setofsys);
  1193. X          var lattr: attr; lop: operator;
  1194. X
  1195. X          procedure factor(fsys: setofsys);
  1196. X        var lcp: ctp; lvp: csp; varpart: boolean;
  1197. X            cstpart: setty; lsp: stp;
  1198. X          begin
  1199. X        if not (sy in facbegsys) then
  1200. X          begin error(58); skip(fsys + facbegsys);
  1201. X            gattr.typtr := nil
  1202. X          end;
  1203. X        while sy in facbegsys do
  1204. X          begin
  1205. X            case sy of
  1206. X          (*id*)    ident:
  1207. X            begin searchid([konst,vars,field,func],lcp);
  1208. X              insymbol;
  1209. X              if lcp^.klass = func then
  1210. X                begin call(fsys,lcp);
  1211. X                  with gattr do
  1212. X                begin kind := expr;
  1213. X                  if typtr <> nil then
  1214. X                    if typtr^.form=subrange then
  1215. X                      typtr := typtr^.rangetype
  1216. X                end
  1217. X                end
  1218. X              else
  1219. X                if lcp^.klass = konst then
  1220. X                  with gattr, lcp^ do
  1221. X                begin typtr := idtype; kind := cst;
  1222. X                  cval := values
  1223. X                end
  1224. X                else
  1225. X                  begin selector(fsys,lcp);
  1226. X                if gattr.typtr<>nil then(*elim.subr.types to*)
  1227. X                  with gattr,typtr^ do(*simplify later tests*)
  1228. X                    if form = subrange then
  1229. X                      typtr := rangetype
  1230. X                  end
  1231. X            end;
  1232. X          (*cst*)   intconst:
  1233. X            begin
  1234. X              with gattr do
  1235. X                begin typtr := intptr; kind := cst;
  1236. X                  cval := val
  1237. X                end;
  1238. X              insymbol
  1239. X            end;
  1240. X              realconst:
  1241. X            begin
  1242. X              with gattr do
  1243. X                begin typtr := realptr; kind := cst;
  1244. X                  cval := val
  1245. X                end;
  1246. X              insymbol
  1247. X            end;
  1248. X              stringconst:
  1249. X            begin
  1250. X              with gattr do
  1251. X                begin
  1252. X                  if lgth = 1 then typtr := charptr
  1253. X                  else
  1254. X                begin new(lsp,arrays);
  1255. X                  with lsp^ do
  1256. X                    begin aeltype := charptr; form:=arrays;
  1257. X                      inxtype := nil; size := lgth*charsize
  1258. X                    end;
  1259. X                  typtr := lsp
  1260. X                end;
  1261. X                  kind := cst; cval := val
  1262. X                end;
  1263. X              insymbol
  1264. X            end;
  1265. X          (* ( *)   lparent:
  1266. X            begin insymbol; expression(fsys + [rparent]);
  1267. X              if sy = rparent then insymbol else error(4)
  1268. X            end;
  1269. X          (*not*)   notsy:
  1270. X            begin insymbol; factor(fsys);
  1271. X              load; gen0(19(*not*));
  1272. X              if gattr.typtr <> nil then
  1273. X                if gattr.typtr <> boolptr then
  1274. X                  begin error(135); gattr.typtr := nil end;
  1275. X            end;
  1276. X          (*[*)     lbrack:
  1277. X            begin insymbol; cstpart := [ ]; varpart := false;
  1278. X              new(lsp,power);
  1279. X              with lsp^ do
  1280. X                begin elset:=nil;size:=setsize;form:=power end;
  1281. X              if sy = rbrack then
  1282. X                begin
  1283. X                  with gattr do
  1284. X                begin typtr := lsp; kind := cst end;
  1285. X                  insymbol
  1286. X                end
  1287. X              else
  1288. X                begin
  1289. X                  repeat expression(fsys + [comma,rbrack]);
  1290. X                if gattr.typtr <> nil then
  1291. X                  if gattr.typtr^.form <> scalar then
  1292. X                    begin error(136); gattr.typtr := nil end
  1293. X                  else
  1294. X                    if comptypes(lsp^.elset,gattr.typtr) then
  1295. X                      begin
  1296. X                    if gattr.kind = cst then
  1297. X                      if (gattr.cval.ival < setlow) or
  1298. X                        (gattr.cval.ival > sethigh) then
  1299. X                        error(304)
  1300. X                      else
  1301. X                        cstpart := cstpart+[gattr.cval.ival]
  1302. X                    else
  1303. X                      begin load;
  1304. X                        if not comptypes(gattr.typtr,intptr)
  1305. X                        then gen0t(58(*ord*),gattr.typtr);
  1306. X                        gen0(23(*sgs*));
  1307. X                        if varpart then gen0(28(*uni*))
  1308. X                        else varpart := true
  1309. X                      end;
  1310. X                    lsp^.elset := gattr.typtr;
  1311. X                    gattr.typtr := lsp
  1312. X                      end
  1313. X                    else error(137);
  1314. X                test := sy <> comma;
  1315. X                if not test then insymbol
  1316. X                  until test;
  1317. X                  if sy = rbrack then insymbol else error(12)
  1318. X                end;
  1319. X              if varpart then
  1320. X                begin
  1321. X                  if cstpart <> [ ] then
  1322. X                begin new(lvp,pset); lvp^.pval := cstpart;
  1323. X                  lvp^.cclass := pset;
  1324. X                  if cstptrix = cstoccmax then error(254)
  1325. X                  else
  1326. X                    begin cstptrix := cstptrix + 1;
  1327. X                      cstptr[cstptrix] := lvp;
  1328. X                      gen2(51(*ldc*),5,cstptrix);
  1329. X                      gen0(28(*uni*)); gattr.kind := expr
  1330. X                    end
  1331. X                end
  1332. X                end
  1333. X              else
  1334. X                begin new(lvp,pset); lvp^.pval := cstpart;
  1335. X                  lvp^.cclass := pset;
  1336. X                  gattr.cval.valp := lvp
  1337. X                end
  1338. X            end
  1339. X            end (*case*) ;
  1340. X            if not (sy in fsys) then
  1341. X              begin error(6); skip(fsys + facbegsys) end
  1342. X          end (*while*)
  1343. X          end (*factor*) ;
  1344. X
  1345. X        begin (*term*)
  1346. X          factor(fsys + [mulop]);
  1347. X          while sy = mulop do
  1348. X        begin load; lattr := gattr; lop := op;
  1349. X          insymbol; factor(fsys + [mulop]); load;
  1350. X          if (lattr.typtr <> nil) and (gattr.typtr <> nil) then
  1351. X            case lop of
  1352. X        (***)     mul:  if (lattr.typtr=intptr)and(gattr.typtr=intptr)
  1353. X                then gen0(15(*mpi*))
  1354. X                else
  1355. X                  begin
  1356. X                if lattr.typtr = intptr then
  1357. X                  begin gen0(9(*flo*));
  1358. X                    lattr.typtr := realptr
  1359. X                  end
  1360. X                else
  1361. X                  if gattr.typtr = intptr then
  1362. X                    begin gen0(10(*flt*));
  1363. X                      gattr.typtr := realptr
  1364. X                    end;
  1365. X                if (lattr.typtr = realptr)
  1366. X                  and(gattr.typtr=realptr)then gen0(16(*mpr*))
  1367. X                else
  1368. X                  if(lattr.typtr^.form=power)
  1369. X                    and comptypes(lattr.typtr,gattr.typtr)then
  1370. X                    gen0(12(*int*))
  1371. X                  else begin error(134); gattr.typtr:=nil end
  1372. X                  end;
  1373. X        (* / *)   rdiv: begin
  1374. X                  if gattr.typtr = intptr then
  1375. X                begin gen0(10(*flt*));
  1376. X                  gattr.typtr := realptr
  1377. X                end;
  1378. X                  if lattr.typtr = intptr then
  1379. X                begin gen0(9(*flo*));
  1380. X                  lattr.typtr := realptr
  1381. X                end;
  1382. X                  if (lattr.typtr = realptr)
  1383. X                and (gattr.typtr=realptr)then gen0(7(*dvr*))
  1384. X                  else begin error(134); gattr.typtr := nil end
  1385. X                end;
  1386. X        (*div*)   idiv: if (lattr.typtr = intptr)
  1387. X                  and (gattr.typtr = intptr) then gen0(6(*dvi*))
  1388. X                else begin error(134); gattr.typtr := nil end;
  1389. X        (*mod*)   imod: if (lattr.typtr = intptr)
  1390. X                  and (gattr.typtr = intptr) then gen0(14(*mod*))
  1391. X                else begin error(134); gattr.typtr := nil end;
  1392. X        (*and*)   andop:if (lattr.typtr = boolptr)
  1393. X                  and (gattr.typtr = boolptr) then gen0(4(*and*))
  1394. X                else begin error(134); gattr.typtr := nil end
  1395. X            end (*case*)
  1396. X          else gattr.typtr := nil
  1397. X        end (*while*)
  1398. X        end (*term*) ;
  1399. X
  1400. X      begin (*simpleexpression*)
  1401. X        signed := false;
  1402. X        if (sy = addop) and (op in [plus,minus]) then
  1403. X          begin signed := op = minus; insymbol end;
  1404. X        term(fsys + [addop]);
  1405. X        if signed then
  1406. X          begin load;
  1407. X        if gattr.typtr = intptr then gen0(17(*ngi*))
  1408. X        else
  1409. X          if gattr.typtr = realptr then gen0(18(*ngr*))
  1410. X          else begin error(134); gattr.typtr := nil end
  1411. X          end;
  1412. X        while sy = addop do
  1413. X          begin load; lattr := gattr; lop := op;
  1414. X        insymbol; term(fsys + [addop]); load;
  1415. X        if (lattr.typtr <> nil) and (gattr.typtr <> nil) then
  1416. X          case lop of
  1417. X      (*+*)       plus:
  1418. X              if (lattr.typtr = intptr)and(gattr.typtr = intptr) then
  1419. X            gen0(2(*adi*))
  1420. X              else
  1421. X            begin
  1422. X              if lattr.typtr = intptr then
  1423. X                begin gen0(9(*flo*));
  1424. X                  lattr.typtr := realptr
  1425. X                end
  1426. X              else
  1427. X                if gattr.typtr = intptr then
  1428. X                  begin gen0(10(*flt*));
  1429. X                gattr.typtr := realptr
  1430. X                  end;
  1431. X              if (lattr.typtr = realptr)and(gattr.typtr = realptr)
  1432. X                then gen0(3(*adr*))
  1433. X              else if(lattr.typtr^.form=power)
  1434. X                 and comptypes(lattr.typtr,gattr.typtr) then
  1435. X                 gen0(28(*uni*))
  1436. X                   else begin error(134); gattr.typtr:=nil end
  1437. X            end;
  1438. X      (*-*)       minus:
  1439. X              if (lattr.typtr = intptr)and(gattr.typtr = intptr) then
  1440. X            gen0(21(*sbi*))
  1441. X              else
  1442. X            begin
  1443. X              if lattr.typtr = intptr then
  1444. X                begin gen0(9(*flo*));
  1445. X                  lattr.typtr := realptr
  1446. X                end
  1447. X              else
  1448. X                if gattr.typtr = intptr then
  1449. X                  begin gen0(10(*flt*));
  1450. X                gattr.typtr := realptr
  1451. X                  end;
  1452. X              if (lattr.typtr = realptr)and(gattr.typtr = realptr)
  1453. X                then gen0(22(*sbr*))
  1454. X              else
  1455. X                if (lattr.typtr^.form = power)
  1456. X                  and comptypes(lattr.typtr,gattr.typtr) then
  1457. X                  gen0(5(*dif*))
  1458. X                else begin error(134); gattr.typtr := nil end
  1459. X            end;
  1460. X      (*or*)      orop:
  1461. X              if(lattr.typtr=boolptr)and(gattr.typtr=boolptr)then
  1462. X            gen0(13(*ior*))
  1463. X              else begin error(134); gattr.typtr := nil end
  1464. X          end (*case*)
  1465. X        else gattr.typtr := nil
  1466. X          end (*while*)
  1467. X      end (*simpleexpression*) ;
  1468. X
  1469. X    begin (*expression*)
  1470. X      simpleexpression(fsys + [relop]);
  1471. X      if sy = relop then
  1472. X        begin
  1473. X          if gattr.typtr <> nil then
  1474. X        if gattr.typtr^.form <= power then load
  1475. X        else loadaddress;
  1476. X          lattr := gattr; lop := op;
  1477. X          if lop = inop then
  1478. X        if not comptypes(gattr.typtr,intptr) then
  1479. X          gen0t(58(*ord*),gattr.typtr);
  1480. X          insymbol; simpleexpression(fsys);
  1481. X          if gattr.typtr <> nil then
  1482. X        if gattr.typtr^.form <= power then load
  1483. X        else loadaddress;
  1484. X          if (lattr.typtr <> nil) and (gattr.typtr <> nil) then
  1485. X        if lop = inop then
  1486. X          if gattr.typtr^.form = power then
  1487. X            if comptypes(lattr.typtr,gattr.typtr^.elset) then
  1488. X              gen0(11(*inn*))
  1489. X            else begin error(129); gattr.typtr := nil end
  1490. X          else begin error(130); gattr.typtr := nil end
  1491. X        else
  1492. X          begin
  1493. X            if lattr.typtr <> gattr.typtr then
  1494. X              if lattr.typtr = intptr then
  1495. X            begin gen0(9(*flo*));
  1496. X              lattr.typtr := realptr
  1497. X            end
  1498. X              else
  1499. X            if gattr.typtr = intptr then
  1500. X              begin gen0(10(*flt*));
  1501. X                gattr.typtr := realptr
  1502. X              end;
  1503. X            if comptypes(lattr.typtr,gattr.typtr) then
  1504. X              begin lsize := lattr.typtr^.size;
  1505. X            case lattr.typtr^.form of
  1506. X              scalar:
  1507. X                if lattr.typtr = realptr then typind := 'r'
  1508. X                else
  1509. X                  if lattr.typtr = boolptr then typind := 'b'
  1510. X                  else
  1511. X                if lattr.typtr = charptr then typind := 'c'
  1512. X                else typind := 'i';
  1513. X              pointer:
  1514. X                begin
  1515. X                  if lop in [ltop,leop,gtop,geop] then error(131);
  1516. X                  typind := 'a'
  1517. X                end;
  1518. X              power:
  1519. X                begin if lop in [ltop,gtop] then error(132);
  1520. X                  typind := 's'
  1521. X                end;
  1522. X              arrays:
  1523. X                begin
  1524. X                  if not string(lattr.typtr)
  1525. X                then error(134);
  1526. X                  typind := 'm'
  1527. X                end;
  1528. X              records:
  1529. X                begin
  1530. X                  error(134);
  1531. X                  typind := 'm'
  1532. X                end;
  1533. X              files:
  1534. X                begin error(133); typind := 'f' end
  1535. X            end;
  1536. X            case lop of
  1537. X              ltop: gen2(53(*les*),ord(typind),lsize);
  1538. X              leop: gen2(52(*leq*),ord(typind),lsize);
  1539. X              gtop: gen2(49(*grt*),ord(typind),lsize);
  1540. X              geop: gen2(48(*geq*),ord(typind),lsize);
  1541. X              neop: gen2(55(*neq*),ord(typind),lsize);
  1542. X              eqop: gen2(47(*equ*),ord(typind),lsize)
  1543. X            end
  1544. X              end
  1545. X            else error(129)
  1546. X          end;
  1547. X          gattr.typtr := boolptr; gattr.kind := expr
  1548. X        end (*sy = relop*)
  1549. X    end (*expression*) ;
  1550. X
  1551. X    procedure assignment(fcp: ctp);
  1552. X      var lattr: attr;
  1553. X    begin selector(fsys + [becomes],fcp);
  1554. X      if sy = becomes then
  1555. X        begin
  1556. X          if gattr.typtr <> nil then
  1557. X        if (gattr.access<>drct) or (gattr.typtr^.form>power) then
  1558. X          loadaddress;
  1559. X          lattr := gattr;
  1560. X          insymbol; expression(fsys);
  1561. X          if gattr.typtr <> nil then
  1562. X        if gattr.typtr^.form <= power then load
  1563. X        else loadaddress;
  1564. X          if (lattr.typtr <> nil) and (gattr.typtr <> nil) then
  1565. X        begin
  1566. X          if comptypes(realptr,lattr.typtr)and(gattr.typtr=intptr)then
  1567. X            begin gen0(10(*flt*));
  1568. X              gattr.typtr := realptr
  1569. X            end;
  1570. X          if comptypes(lattr.typtr,gattr.typtr) then
  1571. X            case lattr.typtr^.form of
  1572. X              scalar,
  1573. X              subrange: begin
  1574. X                  if debug then checkbnds(lattr.typtr);
  1575. X                  store(lattr)
  1576. X                end;
  1577. X              pointer: begin
  1578. X                 if debug then
  1579. X                   gen2t(45(*chk*),0,maxaddr,nilptr);
  1580. X                 store(lattr)
  1581. X                   end;
  1582. X              power:   store(lattr);
  1583. X              arrays,
  1584. X              records: gen1(40(*mov*),lattr.typtr^.size);
  1585. X              files: error(146)
  1586. X            end
  1587. X          else error(129)
  1588. X        end
  1589. X        end (*sy = becomes*)
  1590. X      else error(51)
  1591. X    end (*assignment*) ;
  1592. X
  1593. X    procedure gotostatement;
  1594. X      var llp: lbp; found: boolean; ttop,ttop1: disprange;
  1595. X    begin
  1596. X      if sy = intconst then
  1597. X        begin
  1598. X          found := false;
  1599. X          ttop := top;
  1600. X          while display[ttop].occur <> blck do ttop := ttop - 1;
  1601. X          ttop1 := ttop;
  1602. X          repeat
  1603. X        llp := display[ttop].flabel;
  1604. X        while (llp <> nil) and not found do
  1605. X          with llp^ do
  1606. X            if labval = val.ival then
  1607. X              begin found := true;
  1608. X            if ttop = ttop1 then
  1609. X              genujpxjp(57(*ujp*),labname)
  1610. X            else (*goto leads out of procedure*) error(399)
  1611. X              end
  1612. X            else llp := nextlab;
  1613. X        ttop := ttop - 1
  1614. X          until found or (ttop = 0);
  1615. X          if not found then error(167);
  1616. X          insymbol
  1617. X        end
  1618. X      else error(15)
  1619. X    end (*gotostatement*) ;
  1620. X
  1621. X    procedure compoundstatement;
  1622. X    begin
  1623. X      repeat
  1624. X        repeat statement(fsys + [semicolon,endsy])
  1625. X        until not (sy in statbegsys);
  1626. X        test := sy <> semicolon;
  1627. X        if not test then insymbol
  1628. X      until test;
  1629. X      if sy = endsy then insymbol else error(13)
  1630. X    end (*compoundstatemenet*) ;
  1631. X
  1632. X    procedure ifstatement;
  1633. X      var lcix1,lcix2: integer;
  1634. X    begin expression(fsys + [thensy]);
  1635. X      genlabel(lcix1); genfjp(lcix1);
  1636. X      if sy = thensy then insymbol else error(52);
  1637. X      statement(fsys + [elsesy]);
  1638. X      if sy = elsesy then
  1639. X        begin genlabel(lcix2); genujpxjp(57(*ujp*),lcix2);
  1640. X          putlabel(lcix1);
  1641. X          insymbol; statement(fsys);
  1642. X          putlabel(lcix2)
  1643. X        end
  1644. X      else putlabel(lcix1)
  1645. X    end (*ifstatement*) ;
  1646. X
  1647. X    procedure casestatement;
  1648. X      label 1;
  1649. X      type cip = ^caseinfo;
  1650. X           caseinfo = packed
  1651. X              record next: cip;
  1652. X                csstart: integer;
  1653. X                cslab: integer
  1654. X              end;
  1655. X      var lsp,lsp1: stp; fstptr,lpt1,lpt2,lpt3: cip; lval: valu;
  1656. X          laddr, lcix, lcix1, lmin, lmax: integer;
  1657. X    begin expression(fsys + [ofsy,comma,colon]);
  1658. X      load; genlabel(lcix);
  1659. X      lsp := gattr.typtr;
  1660. X      if lsp <> nil then
  1661. X        if (lsp^.form <> scalar) or (lsp = realptr) then
  1662. X          begin error(144); lsp := nil end
  1663. X        else if not comptypes(lsp,intptr) then gen0t(58(*ord*),lsp);
  1664. X      genujpxjp(57(*ujp*),lcix);
  1665. X      if sy = ofsy then insymbol else error(8);
  1666. X      fstptr := nil; genlabel(laddr);
  1667. X      repeat
  1668. X        lpt3 := nil; genlabel(lcix1);
  1669. X        if not(sy in [semicolon,endsy]) then
  1670. X          begin
  1671. X        repeat constant(fsys + [comma,colon],lsp1,lval);
  1672. X          if lsp <> nil then
  1673. X            if comptypes(lsp,lsp1) then
  1674. X              begin lpt1 := fstptr; lpt2 := nil;
  1675. X            while lpt1 <> nil do
  1676. X              with lpt1^ do
  1677. X                begin
  1678. X                  if cslab <= lval.ival then
  1679. X                begin if cslab = lval.ival then error(156);
  1680. X                  goto 1
  1681. X                end;
  1682. X                  lpt2 := lpt1; lpt1 := next
  1683. X                end;
  1684. X        1:      new(lpt3);
  1685. X            with lpt3^ do
  1686. X              begin next := lpt1; cslab := lval.ival;
  1687. X                csstart := lcix1
  1688. X              end;
  1689. X            if lpt2 = nil then fstptr := lpt3
  1690. X            else lpt2^.next := lpt3
  1691. X              end
  1692. X            else error(147);
  1693. X          test := sy <> comma;
  1694. X          if not test then insymbol
  1695. X        until test;
  1696. X        if sy = colon then insymbol else error(5);
  1697. X        putlabel(lcix1);
  1698. X        repeat statement(fsys + [semicolon])
  1699. X        until not (sy in statbegsys);
  1700. X        if lpt3 <> nil then
  1701. X          genujpxjp(57(*ujp*),laddr);
  1702. X          end;
  1703. X        test := sy <> semicolon;
  1704. X        if not test then insymbol
  1705. X      until test;
  1706. X      putlabel(lcix);
  1707. X      if fstptr <> nil then
  1708. X        begin lmax := fstptr^.cslab;
  1709. X          (*reverse pointers*)
  1710. X          lpt1 := fstptr; fstptr := nil;
  1711. X          repeat lpt2 := lpt1^.next; lpt1^.next := fstptr;
  1712. X        fstptr := lpt1; lpt1 := lpt2
  1713. X          until lpt1 = nil;
  1714. X          lmin := fstptr^.cslab;
  1715. X          if lmax - lmin < cixmax then
  1716. X        begin
  1717. X          gen2t(45(*chk*),lmin,lmax,intptr);
  1718. X          gen2(51(*ldc*),1,lmin); gen0(21(*sbi*)); genlabel(lcix);
  1719. X          genujpxjp(44(*xjp*),lcix); putlabel(lcix);
  1720. X          repeat
  1721. X            with fstptr^ do
  1722. X              begin
  1723. X            while cslab > lmin do
  1724. X               begin gen0(60(*ujc error*));
  1725. X                 lmin := lmin+1
  1726. X               end;
  1727. X            genujpxjp(57(*ujp*),csstart);
  1728. X            fstptr := next; lmin := lmin + 1
  1729. X              end
  1730. X          until fstptr = nil;
  1731. X          putlabel(laddr)
  1732. X        end
  1733. X          else error(157)
  1734. X        end;
  1735. X        if sy = endsy then insymbol else error(13)
  1736. X    end (*casestatement*) ;
  1737. X
  1738. X    procedure repeatstatement;
  1739. X      var laddr: integer;
  1740. X    begin genlabel(laddr); putlabel(laddr);
  1741. X      repeat statement(fsys + [semicolon,untilsy]);
  1742. X        if sy in statbegsys then error(14)
  1743. X      until not(sy in statbegsys);
  1744. X      while sy = semicolon do
  1745. X        begin insymbol;
  1746. X          repeat statement(fsys + [semicolon,untilsy]);
  1747. X        if sy in statbegsys then error(14)
  1748. X          until not (sy in statbegsys);
  1749. X        end;
  1750. X      if sy = untilsy then
  1751. X        begin insymbol; expression(fsys); genfjp(laddr)
  1752. X        end
  1753. X      else error(53)
  1754. X    end (*repeatstatement*) ;
  1755. X
  1756. X    procedure whilestatement;
  1757. X      var laddr, lcix: integer;
  1758. X    begin genlabel(laddr); putlabel(laddr);
  1759. X      expression(fsys + [dosy]); genlabel(lcix); genfjp(lcix);
  1760. X      if sy = dosy then insymbol else error(54);
  1761. X      statement(fsys); genujpxjp(57(*ujp*),laddr); putlabel(lcix)
  1762. X    end (*whilestatement*) ;
  1763. X
  1764. X    procedure forstatement;
  1765. X      var lattr: attr;  lsy: symbol;
  1766. X          lcix, laddr: integer;
  1767. X            llc: addrrange;
  1768. X    begin llc := lc;
  1769. X      with lattr do
  1770. X        begin typtr := nil; kind := varbl;
  1771. X          access := drct; vlevel := level; dplmt := 0
  1772. X        end;
  1773. X      if sy = ident then
  1774. X        begin searchid([vars],lcp);
  1775. X          with lcp^, lattr do
  1776. X        begin typtr := idtype; kind := varbl;
  1777. X          if vkind = actual then
  1778. X            begin access := drct; vlevel := vlev;
  1779. X              dplmt := vaddr
  1780. X            end
  1781. X          else begin error(155); typtr := nil end
  1782. X        end;
  1783. X          if lattr.typtr <> nil then
  1784. X        if (lattr.typtr^.form > subrange)
  1785. X           or comptypes(realptr,lattr.typtr) then
  1786. X          begin error(143); lattr.typtr := nil end;
  1787. X          insymbol
  1788. X        end
  1789. X      else
  1790. X        begin error(2); skip(fsys + [becomes,tosy,downtosy,dosy]) end;
  1791. X      if sy = becomes then
  1792. X        begin insymbol; expression(fsys + [tosy,downtosy,dosy]);
  1793. X          if gattr.typtr <> nil then
  1794. X          if gattr.typtr^.form <> scalar then error(144)
  1795. X          else
  1796. X            if comptypes(lattr.typtr,gattr.typtr) then
  1797. X              begin load; store(lattr) end
  1798. X            else error(145)
  1799. X        end
  1800. X      else
  1801. X        begin error(51); skip(fsys + [tosy,downtosy,dosy]) end;
  1802. X      if sy in [tosy,downtosy] then
  1803. X        begin lsy := sy; insymbol; expression(fsys + [dosy]);
  1804. X          if gattr.typtr <> nil then
  1805. X          if gattr.typtr^.form <> scalar then error(144)
  1806. X        else
  1807. X          if comptypes(lattr.typtr,gattr.typtr) then
  1808. X            begin load;
  1809. X              if not comptypes(lattr.typtr,intptr) then
  1810. X            gen0t(58(*ord*),gattr.typtr);
  1811. X              align(intptr,lc);
  1812. X              gen2t(56(*str*),0,lc,intptr);
  1813. X              genlabel(laddr); putlabel(laddr);
  1814. X              gattr := lattr; load;
  1815. X              if not comptypes(gattr.typtr,intptr) then
  1816. X            gen0t(58(*ord*),gattr.typtr);
  1817. X              gen2t(54(*lod*),0,lc,intptr);
  1818. X              lc := lc + intsize;
  1819. X              if lc > lcmax then lcmax := lc;
  1820. X              if lsy = tosy then gen2(52(*leq*),ord('i'),1)
  1821. X              else gen2(48(*geq*),ord('i'),1);
  1822. X            end
  1823. X          else error(145)
  1824. X        end
  1825. X      else begin error(55); skip(fsys + [dosy]) end;
  1826. X      genlabel(lcix); genujpxjp(33(*fjp*),lcix);
  1827. X      if sy = dosy then insymbol else error(54);
  1828. X      statement(fsys);
  1829. X      gattr := lattr; load;
  1830. X      if lsy=tosy then gen1t(34(*inc*),1,gattr.typtr)
  1831. X      else  gen1t(31(*dec*),1,gattr.typtr);
  1832. X      store(lattr); genujpxjp(57(*ujp*),laddr); putlabel(lcix);
  1833. X      lc := llc;
  1834. X    end (*forstatement*) ;
  1835. X
  1836. X
  1837. X    procedure withstatement;
  1838. X      var lcp: ctp; lcnt1: disprange; llc: addrrange;
  1839. X    begin lcnt1 := 0; llc := lc;
  1840. X      repeat
  1841. X        if sy = ident then
  1842. X          begin searchid([vars,field],lcp); insymbol end
  1843. X        else begin error(2); lcp := uvarptr end;
  1844. X        selector(fsys + [comma,dosy],lcp);
  1845. X        if gattr.typtr <> nil then
  1846. X          if gattr.typtr^.form = records then
  1847. X        if top < displimit then
  1848. X          begin top := top + 1; lcnt1 := lcnt1 + 1;
  1849. X            with display[top] do
  1850. X              begin fname := gattr.typtr^.fstfld;
  1851. X            flabel := nil
  1852. X              end;
  1853. X            if gattr.access = drct then
  1854. X              with display[top] do
  1855. X            begin occur := crec; clev := gattr.vlevel;
  1856. X              cdspl := gattr.dplmt
  1857. X            end
  1858. X            else
  1859. X              begin loadaddress;
  1860. X            align(nilptr,lc);
  1861. X            gen2t(56(*str*),0,lc,nilptr);
  1862. X            with display[top] do
  1863. X              begin occur := vrec; vdspl := lc end;
  1864. X            lc := lc+ptrsize;
  1865. X            if lc > lcmax then lcmax := lc
  1866. X              end
  1867. X          end
  1868. X        else error(250)
  1869. X          else error(140);
  1870. X        test := sy <> comma;
  1871. X        if not test then insymbol
  1872. X      until test;
  1873. X      if sy = dosy then insymbol else error(54);
  1874. X      statement(fsys);
  1875. X      top := top-lcnt1; lc := llc;
  1876. X    end (*withstatement*) ;
  1877. X
  1878. X      begin (*statement*)
  1879. X    if sy = intconst then (*label*)
  1880. X      begin llp := display[level].flabel;
  1881. X        while llp <> nil do
  1882. X          with llp^ do
  1883. X        if labval = val.ival then
  1884. X          begin if defined then error(165);
  1885. X            putlabel(labname); defined := true;
  1886. X            goto 1
  1887. X          end
  1888. X        else llp := nextlab;
  1889. X        error(167);
  1890. X      1:    insymbol;
  1891. X        if sy = colon then insymbol else error(5)
  1892. X      end;
  1893. X    if not (sy in fsys + [ident]) then
  1894. X      begin error(6); skip(fsys) end;
  1895. X    if sy in statbegsys + [ident] then
  1896. X      begin
  1897. X        case sy of
  1898. X          ident:    begin searchid([vars,field,func,proc],lcp); insymbol;
  1899. X              if lcp^.klass = proc then call(fsys,lcp)
  1900. X              else assignment(lcp)
  1901. X            end;
  1902. X          beginsy:  begin insymbol; compoundstatement end;
  1903. X          gotosy:   begin insymbol; gotostatement end;
  1904. X          ifsy:     begin insymbol; ifstatement end;
  1905. X          casesy:   begin insymbol; casestatement end;
  1906. X          whilesy:  begin insymbol; whilestatement end;
  1907. X          repeatsy: begin insymbol; repeatstatement end;
  1908. X          forsy:    begin insymbol; forstatement end;
  1909. X          withsy:   begin insymbol; withstatement end
  1910. X        end;
  1911. X        if not (sy in [semicolon,endsy,elsesy,untilsy]) then
  1912. X          begin error(6); skip(fsys) end
  1913. X      end
  1914. X      end (*statement*) ;
  1915. X
  1916. X    begin (*body*)
  1917. X      if fprocp <> nil then entname := fprocp^.pfname
  1918. X      else genlabel(entname);
  1919. X      cstptrix := 0; topnew := lcaftermarkstack; topmax := lcaftermarkstack;
  1920. X      putlabel(entname); genlabel(segsize); genlabel(stacktop);
  1921. X      gencupent(32(*ent1*),1,segsize); gencupent(32(*ent2*),2,stacktop);
  1922. X      if fprocp <> nil then (*copy multiple values into local cells*)
  1923. X    begin llc1 := lcaftermarkstack;
  1924. X      lcp := fprocp^.next;
  1925. X      while lcp <> nil do
  1926. X        with lcp^ do
  1927. X          begin
  1928. X        align(parmptr,llc1);
  1929. X        if klass = vars then
  1930. X          if idtype <> nil then
  1931. X            if idtype^.form > power then
  1932. X              begin
  1933. X            if vkind = actual then
  1934. X              begin
  1935. X                gen2(50(*lda*),0,vaddr);
  1936. X                gen2t(54(*lod*),0,llc1,nilptr);
  1937. X                gen1(40(*mov*),idtype^.size);
  1938. X              end;
  1939. X            llc1 := llc1 + ptrsize
  1940. X              end
  1941. X            else llc1 := llc1 + idtype^.size;
  1942. X        lcp := lcp^.next;
  1943. X          end;
  1944. X    end;
  1945. X      lcmax := lc;
  1946. X      repeat
  1947. X    repeat statement(fsys + [semicolon,endsy])
  1948. X    until not (sy in statbegsys);
  1949. X    test := sy <> semicolon;
  1950. X    if not test then insymbol
  1951. X      until test;
  1952. X      if sy = endsy then insymbol else error(13);
  1953. X      llp := display[top].flabel; (*test for undefined labels*)
  1954. X      while llp <> nil do
  1955. X    with llp^ do
  1956. X      begin
  1957. X        if not defined then
  1958. X          begin error(168);
  1959. X        writeln(output); writeln(output,' label ',labval);
  1960. X        write(output,' ':chcnt+16)
  1961. X          end;
  1962. X        llp := nextlab
  1963. X      end;
  1964. X      if fprocp <> nil then
  1965. X    begin
  1966. X      if fprocp^.idtype = nil then gen1(42(*ret*),ord('p'))
  1967. X      else gen0t(42(*ret*),fprocp^.idtype);
  1968. X      align(parmptr,lcmax);
  1969. X      if prcode then
  1970. X        begin writeln(prr,'l',segsize:4,'=',lcmax);
  1971. X          writeln(prr,'l',stacktop:4,'=',topmax)
  1972. X        end
  1973. X    end
  1974. X      else
  1975. X    begin gen1(42(*ret*),ord('p'));
  1976. X      align(parmptr,lcmax);
  1977. X      if prcode then
  1978. SHAR_EOF
  1979. true || echo 'restore of pcom.p failed'
  1980. fi
  1981. echo 'End of  part 2'
  1982. echo 'File pcom.p is continued in part 3'
  1983. echo 3 > _shar_seq_.tmp
  1984. exit 0
  1985. exit 0 # Just in case...
  1986. -- 
  1987. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1988. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1989. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1990. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1991.