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

  1. Newsgroups: comp.sources.misc
  2. From: steven@cwi.nl (Steven Pemberton)
  3. Subject:  v23i027:  pascal - Public domain Pascal Compiler and Interpreter, Part03/03
  4. Message-ID: <1991Sep27.041235.15614@sparky.imd.sterling.com>
  5. X-Md4-Signature: 914824487502c49b912d6c64cc68b9ef
  6. Date: Fri, 27 Sep 1991 04:12:35 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: steven@cwi.nl (Steven Pemberton)
  10. Posting-number: Volume 23, Issue 27
  11. Archive-name: pascal/part03
  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" != 3; 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        begin writeln(prr,'l',segsize:4,'=',lcmax);
  36. X          writeln(prr,'l',stacktop:4,'=',topmax);
  37. X          writeln(prr,'q')
  38. X        end;
  39. X      ic := 0;
  40. X      (*generate call of main program; note that this call must be loaded
  41. X        at absolute address zero*)
  42. X      gen1(41(*mst*),0); gencupent(46(*cup*),0,entname); gen0(29(*stp*));
  43. X      if prcode then
  44. X        writeln(prr,'q');
  45. X      saveid := id;
  46. X      while fextfilep <> nil do
  47. X        begin
  48. X          with fextfilep^ do
  49. X        if not ((filename = 'input   ') or (filename = 'output  ') or
  50. X            (filename = 'prd     ') or (filename = 'prr     '))
  51. X        then begin id := filename;
  52. X               searchid([vars],llcp);
  53. X               if llcp^.idtype<>nil then
  54. X             if llcp^.idtype^.form<>files then
  55. X               begin writeln(output);
  56. X                 writeln(output,' ':8,'undeclared ','external ',
  57. X                   'file',fextfilep^.filename:8);
  58. X                 write(output,' ':chcnt+16)
  59. X               end
  60. X             end;
  61. X        fextfilep := fextfilep^.nextfile
  62. X        end;
  63. X      id := saveid;
  64. X      if prtables then
  65. X        begin writeln(output); printtables(true)
  66. X        end
  67. X    end;
  68. X    end (*body*) ;
  69. X
  70. X  begin (*block*)
  71. X    dp := true;
  72. X    repeat
  73. X      if sy = labelsy then
  74. X    begin insymbol; labeldeclaration end;
  75. X      if sy = constsy then
  76. X    begin insymbol; constdeclaration end;
  77. X      if sy = typesy then
  78. X    begin insymbol; typedeclaration end;
  79. X      if sy = varsy then
  80. X    begin insymbol; vardeclaration end;
  81. X      while sy in [procsy,funcsy] do
  82. X    begin lsy := sy; insymbol; procdeclaration(lsy) end;
  83. X      if sy <> beginsy then
  84. X    begin error(18); skip(fsys) end
  85. X    until (sy in statbegsys) or eof(input);
  86. X    dp := false;
  87. X    if sy = beginsy then insymbol else error(17);
  88. X    repeat body(fsys + [casesy]);
  89. X      if sy <> fsy then
  90. X    begin error(6); skip(fsys) end
  91. X    until ((sy = fsy) or (sy in blockbegsys)) or eof(input);
  92. X  end (*block*) ;
  93. X
  94. X  procedure programme(fsys:setofsys);
  95. X    var extfp:extfilep;
  96. X  begin
  97. X    if sy = progsy then
  98. X      begin insymbol; if sy <> ident then error(2); insymbol;
  99. X    if not (sy in [lparent,semicolon]) then error(14);
  100. X    if sy = lparent  then
  101. X      begin
  102. X        repeat insymbol;
  103. X          if sy = ident then
  104. X        begin new(extfp);
  105. X          with extfp^ do
  106. X            begin filename := id; nextfile := fextfilep end;
  107. X          fextfilep := extfp;
  108. X          insymbol;
  109. X          if not ( sy in [comma,rparent] ) then error(20)
  110. X        end
  111. X          else error(2)
  112. X        until sy <> comma;
  113. X        if sy <> rparent then error(4);
  114. X        insymbol
  115. X      end;
  116. X    if sy <> semicolon then error(14)
  117. X    else insymbol;
  118. X      end;
  119. X    repeat block(fsys,period,nil);
  120. X      if sy <> period then error(21)
  121. X    until (sy = period) or eof(input);
  122. X    if list then writeln(output);
  123. X    if errinx <> 0 then
  124. X      begin list := false; endofline end
  125. X  end (*programme*) ;
  126. X
  127. X
  128. X  procedure stdnames;
  129. X  begin
  130. X    na[ 1] := 'false   '; na[ 2] := 'true    '; na[ 3] := 'input   ';
  131. X    na[ 4] := 'output  '; na[ 5] := 'get     '; na[ 6] := 'put     ';
  132. X    na[ 7] := 'reset   '; na[ 8] := 'rewrite '; na[ 9] := 'read    ';
  133. X    na[10] := 'write   '; na[11] := 'pack    '; na[12] := 'unpack  ';
  134. X    na[13] := 'new     '; na[14] := 'release '; na[15] := 'readln  ';
  135. X    na[16] := 'writeln ';
  136. X    na[17] := 'abs     '; na[18] := 'sqr     '; na[19] := 'trunc   ';
  137. X    na[20] := 'odd     '; na[21] := 'ord     '; na[22] := 'chr     ';
  138. X    na[23] := 'pred    '; na[24] := 'succ    '; na[25] := 'eof     ';
  139. X    na[26] := 'eoln    ';
  140. X    na[27] := 'sin     '; na[28] := 'cos     '; na[29] := 'exp     ';
  141. X    na[30] := 'sqrt    '; na[31] := 'ln      '; na[32] := 'arctan  ';
  142. X    na[33] := 'prd     '; na[34] := 'prr     '; na[35] := 'mark    ';
  143. X  end (*stdnames*) ;
  144. X
  145. X  procedure enterstdtypes;
  146. X
  147. X  begin                         (*type underlying:*)
  148. X                            (******************)
  149. X
  150. X    new(intptr,scalar,standard);                  (*integer*)
  151. X    with intptr^ do
  152. X      begin size := intsize; form := scalar; scalkind := standard end;
  153. X    new(realptr,scalar,standard);                 (*real*)
  154. X    with realptr^ do
  155. X      begin size := realsize; form := scalar; scalkind := standard end;
  156. X    new(charptr,scalar,standard);                 (*char*)
  157. X    with charptr^ do
  158. X      begin size := charsize; form := scalar; scalkind := standard end;
  159. X    new(boolptr,scalar,declared);                 (*boolean*)
  160. X    with boolptr^ do
  161. X      begin size := boolsize; form := scalar; scalkind := declared end;
  162. X    new(nilptr,pointer);                      (*nil*)
  163. X    with nilptr^ do
  164. X      begin eltype := nil; size := ptrsize; form := pointer end;
  165. X    new(parmptr,scalar,standard); (*for alignment of parameters*)
  166. X    with parmptr^ do
  167. X      begin size := parmsize; form := scalar; scalkind := standard end ;
  168. X    new(textptr,files);                       (*text*)
  169. X    with textptr^ do
  170. X      begin filtype := charptr; size := charsize; form := files end
  171. X  end (*enterstdtypes*) ;
  172. X
  173. X  procedure entstdnames;
  174. X    var cp,cp1: ctp; i: integer;
  175. X  begin                               (*name:*)
  176. X                                  (*******)
  177. X
  178. X    new(cp,types);                        (*integer*)
  179. X    with cp^ do
  180. X      begin name := 'integer '; idtype := intptr; klass := types end;
  181. X    enterid(cp);
  182. X    new(cp,types);                        (*real*)
  183. X    with cp^ do
  184. X      begin name := 'real    '; idtype := realptr; klass := types end;
  185. X    enterid(cp);
  186. X    new(cp,types);                        (*char*)
  187. X    with cp^ do
  188. X      begin name := 'char    '; idtype := charptr; klass := types end;
  189. X    enterid(cp);
  190. X    new(cp,types);                        (*boolean*)
  191. X    with cp^ do
  192. X      begin name := 'boolean '; idtype := boolptr; klass := types end;
  193. X    enterid(cp);
  194. X    cp1 := nil;
  195. X    for i := 1 to 2 do
  196. X      begin new(cp,konst);                    (*false,true*)
  197. X    with cp^ do
  198. X      begin name := na[i]; idtype := boolptr;
  199. X        next := cp1; values.ival := i - 1; klass := konst
  200. X      end;
  201. X    enterid(cp); cp1 := cp
  202. X      end;
  203. X    boolptr^.fconst := cp;
  204. X    new(cp,konst);                        (*nil*)
  205. X    with cp^ do
  206. X      begin name := 'nil     '; idtype := nilptr;
  207. X    next := nil; values.ival := 0; klass := konst
  208. X      end;
  209. X    enterid(cp);
  210. X    for i := 3 to 4 do
  211. X      begin new(cp,vars);                     (*input,output*)
  212. X    with cp^ do
  213. X      begin name := na[i]; idtype := textptr; klass := vars;
  214. X        vkind := actual; next := nil; vlev := 1;
  215. X        vaddr := lcaftermarkstack+(i-3)*charmax;
  216. X      end;
  217. X    enterid(cp)
  218. X      end;
  219. X    for i:=33 to 34 do
  220. X      begin new(cp,vars);                     (*prd,prr files*)
  221. X     with cp^ do
  222. X       begin name := na[i]; idtype := textptr; klass := vars;
  223. X          vkind := actual; next := nil; vlev := 1;
  224. X          vaddr := lcaftermarkstack+(i-31)*charmax;
  225. X       end;
  226. X     enterid(cp)
  227. X      end;
  228. X    for i := 5 to 16 do
  229. X      begin new(cp,proc,standard);                (*get,put,reset*)
  230. X    with cp^ do                       (*rewrite,read*)
  231. X      begin name := na[i]; idtype := nil;         (*write,pack*)
  232. X        next := nil; key := i - 4;            (*unpack,pack*)
  233. X        klass := proc; pfdeckind := standard
  234. X      end;
  235. X    enterid(cp)
  236. X      end;
  237. X    new(cp,proc,standard);
  238. X    with cp^ do
  239. X      begin name:=na[35]; idtype:=nil;
  240. X        next:= nil; key:=13;
  241. X        klass:=proc; pfdeckind:= standard
  242. X      end; enterid(cp);
  243. X    for i := 17 to 26 do
  244. X      begin new(cp,func,standard);                (*abs,sqr,trunc*)
  245. X    with cp^ do                       (*odd,ord,chr*)
  246. X      begin name := na[i]; idtype := nil;         (*pred,succ,eof*)
  247. X        next := nil; key := i - 16;
  248. X        klass := func; pfdeckind := standard
  249. X      end;
  250. X    enterid(cp)
  251. X      end;
  252. X    new(cp,vars);              (*parameter of predeclared functions*)
  253. X    with cp^ do
  254. X      begin name := '        '; idtype := realptr; klass := vars;
  255. X    vkind := actual; next := nil; vlev := 1; vaddr := 0
  256. X      end;
  257. X    for i := 27 to 32 do
  258. X      begin new(cp1,func,declared,actual);            (*sin,cos,exp*)
  259. X    with cp1^ do                      (*sqrt,ln,arctan*)
  260. X      begin name := na[i]; idtype := realptr; next := cp;
  261. X        forwdecl := false; extern := true; pflev := 0; pfname := i - 12;
  262. X        klass := func; pfdeckind := declared; pfkind := actual
  263. X      end;
  264. X    enterid(cp1)
  265. X      end
  266. X  end (*entstdnames*) ;
  267. X
  268. X  procedure enterundecl;
  269. X  begin
  270. X    new(utypptr,types);
  271. X    with utypptr^ do
  272. X      begin name := '        '; idtype := nil; klass := types end;
  273. X    new(ucstptr,konst);
  274. X    with ucstptr^ do
  275. X      begin name := '        '; idtype := nil; next := nil;
  276. X    values.ival := 0; klass := konst
  277. X      end;
  278. X    new(uvarptr,vars);
  279. X    with uvarptr^ do
  280. X      begin name := '        '; idtype := nil; vkind := actual;
  281. X    next := nil; vlev := 0; vaddr := 0; klass := vars
  282. X      end;
  283. X    new(ufldptr,field);
  284. X    with ufldptr^ do
  285. X      begin name := '        '; idtype := nil; next := nil; fldaddr := 0;
  286. X    klass := field
  287. X      end;
  288. X    new(uprcptr,proc,declared,actual);
  289. X    with uprcptr^ do
  290. X      begin name := '        '; idtype := nil; forwdecl := false;
  291. X    next := nil; extern := false; pflev := 0; genlabel(pfname);
  292. X    klass := proc; pfdeckind := declared; pfkind := actual
  293. X      end;
  294. X    new(ufctptr,func,declared,actual);
  295. X    with ufctptr^ do
  296. X      begin name := '        '; idtype := nil; next := nil;
  297. X    forwdecl := false; extern := false; pflev := 0; genlabel(pfname);
  298. X    klass := func; pfdeckind := declared; pfkind := actual
  299. X      end
  300. X  end (*enterundecl*) ;
  301. X
  302. X  procedure initscalars;
  303. X  begin fwptr := nil;
  304. X    prtables := false; list := true; prcode := true; debug := true;
  305. X    dp := true; prterr := true; errinx := 0;
  306. X    intlabel := 0; kk := 8; fextfilep := nil;
  307. X    lc := lcaftermarkstack+filebuffer*charmax;
  308. X    (* note in the above reservation of buffer store for 2 text files *)
  309. X    ic := 3; eol := true; linecount := 0;
  310. X    ch := ' '; chcnt := 0;
  311. X    globtestp := nil;
  312. X    mxint10 := maxint div 10; digmax := strglgth - 1;
  313. X  end (*initscalars*) ;
  314. X
  315. X  procedure initsets;
  316. X  begin
  317. X    constbegsys := [addop,intconst,realconst,stringconst,ident];
  318. X    simptypebegsys := [lparent] + constbegsys;
  319. X    typebegsys:=[arrow,packedsy,arraysy,recordsy,setsy,filesy]+simptypebegsys;
  320. X    typedels := [arraysy,recordsy,setsy,filesy];
  321. X    blockbegsys := [labelsy,constsy,typesy,varsy,procsy,funcsy,beginsy];
  322. X    selectsys := [arrow,period,lbrack];
  323. X    facbegsys := [intconst,realconst,stringconst,ident,lparent,lbrack,notsy];
  324. X    statbegsys := [beginsy,gotosy,ifsy,whilesy,repeatsy,forsy,withsy,casesy];
  325. X  end (*initsets*) ;
  326. X
  327. X  procedure inittables;
  328. X    procedure reswords;
  329. X    begin
  330. X      rw[ 1] := 'if      '; rw[ 2] := 'do      '; rw[ 3] := 'of      ';
  331. X      rw[ 4] := 'to      '; rw[ 5] := 'in      '; rw[ 6] := 'or      ';
  332. X      rw[ 7] := 'end     '; rw[ 8] := 'for     '; rw[ 9] := 'var     ';
  333. X      rw[10] := 'div     '; rw[11] := 'mod     '; rw[12] := 'set     ';
  334. X      rw[13] := 'and     '; rw[14] := 'not     '; rw[15] := 'then    ';
  335. X      rw[16] := 'else    '; rw[17] := 'with    '; rw[18] := 'goto    ';
  336. X      rw[19] := 'case    '; rw[20] := 'type    ';
  337. X      rw[21] := 'file    '; rw[22] := 'begin   ';
  338. X      rw[23] := 'until   '; rw[24] := 'while   '; rw[25] := 'array   ';
  339. X      rw[26] := 'const   '; rw[27] := 'label   ';
  340. X      rw[28] := 'repeat  '; rw[29] := 'record  '; rw[30] := 'downto  ';
  341. X      rw[31] := 'packed  '; rw[32] := 'forward '; rw[33] := 'program ';
  342. X      rw[34] := 'function'; rw[35] := 'procedur';
  343. X      frw[1] :=  1; frw[2] :=  1; frw[3] :=  7; frw[4] := 15; frw[5] := 22;
  344. X      frw[6] := 28; frw[7] := 32; frw[8] := 34; frw[9] := 36;
  345. X    end (*reswords*) ;
  346. X
  347. X    procedure symbols;
  348. X    begin
  349. X      rsy[ 1] := ifsy;      rsy[ 2] := dosy;      rsy[ 3] := ofsy;
  350. X      rsy[ 4] := tosy;      rsy[ 5] := relop;     rsy[ 6] := addop;
  351. X      rsy[ 7] := endsy;     rsy[ 8] := forsy;     rsy[ 9] := varsy;
  352. X      rsy[10] := mulop;     rsy[11] := mulop;     rsy[12] := setsy;
  353. X      rsy[13] := mulop;     rsy[14] := notsy;     rsy[15] := thensy;
  354. X      rsy[16] := elsesy;    rsy[17] := withsy;    rsy[18] := gotosy;
  355. X      rsy[19] := casesy;    rsy[20] := typesy;
  356. X      rsy[21] := filesy;    rsy[22] := beginsy;
  357. X      rsy[23] := untilsy;   rsy[24] := whilesy;   rsy[25] := arraysy;
  358. X      rsy[26] := constsy;   rsy[27] := labelsy;
  359. X      rsy[28] := repeatsy;  rsy[29] := recordsy;  rsy[30] := downtosy;
  360. X      rsy[31] := packedsy;  rsy[32] := forwardsy; rsy[33] := progsy;
  361. X      rsy[34] := funcsy;    rsy[35] := procsy;
  362. X      ssy['+'] := addop ;   ssy['-'] := addop;    ssy['*'] := mulop;
  363. X      ssy['/'] := mulop ;   ssy['('] := lparent;  ssy[')'] := rparent;
  364. X      ssy['$'] := othersy ; ssy['='] := relop;    ssy[' '] := othersy;
  365. X      ssy[','] := comma ;   ssy['.'] := period;   ssy['''']:= othersy;
  366. X      ssy['['] := lbrack ;  ssy[']'] := rbrack;   ssy[':'] := colon;
  367. X      ssy['^'] := arrow ;   ssy['<'] := relop;    ssy['>'] := relop;
  368. X      ssy[';'] := semicolon;
  369. X    end (*symbols*) ;
  370. X
  371. X    procedure rators;
  372. X      var i: integer;
  373. X    begin
  374. X      for i := 1 to 35 (*nr of res words*) do rop[i] := noop;
  375. X      rop[5] := inop; rop[10] := idiv; rop[11] := imod;
  376. X      rop[6] := orop; rop[13] := andop;
  377. X      for i := ordminchar to ordmaxchar do sop[chr(i)] := noop;
  378. X      sop['+'] := plus; sop['-'] := minus; sop['*'] := mul; sop['/'] := rdiv;
  379. X      sop['='] := eqop; sop['<'] := ltop;  sop['>'] := gtop;
  380. X    end (*rators*) ;
  381. X
  382. X    procedure procmnemonics;
  383. X    begin
  384. X      sna[ 1] :=' get'; sna[ 2] :=' put'; sna[ 3] :=' rdi'; sna[ 4] :=' rdr';
  385. X      sna[ 5] :=' rdc'; sna[ 6] :=' wri'; sna[ 7] :=' wro'; sna[ 8] :=' wrr';
  386. X      sna[ 9] :=' wrc'; sna[10] :=' wrs'; sna[11] :=' pak'; sna[12] :=' new';
  387. X      sna[13] :=' rst'; sna[14] :=' eln'; sna[15] :=' sin'; sna[16] :=' cos';
  388. X      sna[17] :=' exp'; sna[18] :=' sqt'; sna[19] :=' log'; sna[20] :=' atn';
  389. X      sna[21] :=' rln'; sna[22] :=' wln'; sna[23] :=' sav';
  390. X    end (*procmnemonics*) ;
  391. X
  392. X    procedure instrmnemonics;
  393. X    begin
  394. X      mn[ 0] :=' abi'; mn[ 1] :=' abr'; mn[ 2] :=' adi'; mn[ 3] :=' adr';
  395. X      mn[ 4] :=' and'; mn[ 5] :=' dif'; mn[ 6] :=' dvi'; mn[ 7] :=' dvr';
  396. X      mn[ 8] :=' eof'; mn[ 9] :=' flo'; mn[10] :=' flt'; mn[11] :=' inn';
  397. X      mn[12] :=' int'; mn[13] :=' ior'; mn[14] :=' mod'; mn[15] :=' mpi';
  398. X      mn[16] :=' mpr'; mn[17] :=' ngi'; mn[18] :=' ngr'; mn[19] :=' not';
  399. X      mn[20] :=' odd'; mn[21] :=' sbi'; mn[22] :=' sbr'; mn[23] :=' sgs';
  400. X      mn[24] :=' sqi'; mn[25] :=' sqr'; mn[26] :=' sto'; mn[27] :=' trc';
  401. X      mn[28] :=' uni'; mn[29] :=' stp'; mn[30] :=' csp'; mn[31] :=' dec';
  402. X      mn[32] :=' ent'; mn[33] :=' fjp'; mn[34] :=' inc'; mn[35] :=' ind';
  403. X      mn[36] :=' ixa'; mn[37] :=' lao'; mn[38] :=' lca'; mn[39] :=' ldo';
  404. X      mn[40] :=' mov'; mn[41] :=' mst'; mn[42] :=' ret'; mn[43] :=' sro';
  405. X      mn[44] :=' xjp'; mn[45] :=' chk'; mn[46] :=' cup'; mn[47] :=' equ';
  406. X      mn[48] :=' geq'; mn[49] :=' grt'; mn[50] :=' lda'; mn[51] :=' ldc';
  407. X      mn[52] :=' leq'; mn[53] :=' les'; mn[54] :=' lod'; mn[55] :=' neq';
  408. X      mn[56] :=' str'; mn[57] :=' ujp'; mn[58] :=' ord'; mn[59] :=' chr';
  409. X      mn[60] :=' ujc';
  410. X    end (*instrmnemonics*) ;
  411. X
  412. X    procedure chartypes;
  413. X    var i : integer;
  414. X    begin
  415. X      for i := ordminchar to ordmaxchar do chartp[chr(i)] := illegal;
  416. X      chartp['a'] := letter  ;
  417. X      chartp['b'] := letter  ; chartp['c'] := letter  ;
  418. X      chartp['d'] := letter  ; chartp['e'] := letter  ;
  419. X      chartp['f'] := letter  ; chartp['g'] := letter  ;
  420. X      chartp['h'] := letter  ; chartp['i'] := letter  ;
  421. X      chartp['j'] := letter  ; chartp['k'] := letter  ;
  422. X      chartp['l'] := letter  ; chartp['m'] := letter  ;
  423. X      chartp['n'] := letter  ; chartp['o'] := letter  ;
  424. X      chartp['p'] := letter  ; chartp['q'] := letter  ;
  425. X      chartp['r'] := letter  ; chartp['s'] := letter  ;
  426. X      chartp['t'] := letter  ; chartp['u'] := letter  ;
  427. X      chartp['v'] := letter  ; chartp['w'] := letter  ;
  428. X      chartp['x'] := letter  ; chartp['y'] := letter  ;
  429. X      chartp['z'] := letter  ; chartp['0'] := number  ;
  430. X      chartp['1'] := number  ; chartp['2'] := number  ;
  431. X      chartp['3'] := number  ; chartp['4'] := number  ;
  432. X      chartp['5'] := number  ; chartp['6'] := number  ;
  433. X      chartp['7'] := number  ; chartp['8'] := number  ;
  434. X      chartp['9'] := number  ; chartp['+'] := special ;
  435. X      chartp['-'] := special ; chartp['*'] := special ;
  436. X      chartp['/'] := special ; chartp['('] := chlparen;
  437. X      chartp[')'] := special ; chartp['$'] := special ;
  438. X      chartp['='] := special ; chartp[' '] := chspace ;
  439. X      chartp[','] := special ; chartp['.'] := chperiod;
  440. X      chartp['''']:= chstrquo; chartp['['] := special ;
  441. X      chartp[']'] := special ; chartp[':'] := chcolon ;
  442. X      chartp['^'] := special ; chartp[';'] := special ;
  443. X      chartp['<'] := chlt    ; chartp['>'] := chgt    ;
  444. X      ordint['0'] := 0; ordint['1'] := 1; ordint['2'] := 2;
  445. X      ordint['3'] := 3; ordint['4'] := 4; ordint['5'] := 5;
  446. X      ordint['6'] := 6; ordint['7'] := 7; ordint['8'] := 8;
  447. X      ordint['9'] := 9;
  448. X    end;
  449. X
  450. X    procedure initdx;
  451. X    begin
  452. X      cdx[ 0] :=  0; cdx[ 1] :=  0; cdx[ 2] := -1; cdx[ 3] := -1;
  453. X      cdx[ 4] := -1; cdx[ 5] := -1; cdx[ 6] := -1; cdx[ 7] := -1;
  454. X      cdx[ 8] :=  0; cdx[ 9] :=  0; cdx[10] :=  0; cdx[11] := -1;
  455. X      cdx[12] := -1; cdx[13] := -1; cdx[14] := -1; cdx[15] := -1;
  456. X      cdx[16] := -1; cdx[17] :=  0; cdx[18] :=  0; cdx[19] :=  0;
  457. X      cdx[20] :=  0; cdx[21] := -1; cdx[22] := -1; cdx[23] :=  0;
  458. X      cdx[24] :=  0; cdx[25] :=  0; cdx[26] := -2; cdx[27] :=  0;
  459. X      cdx[28] := -1; cdx[29] :=  0; cdx[30] :=  0; cdx[31] :=  0;
  460. X      cdx[32] :=  0; cdx[33] := -1; cdx[34] :=  0; cdx[35] :=  0;
  461. X      cdx[36] := -1; cdx[37] := +1; cdx[38] := +1; cdx[39] := +1;
  462. X      cdx[40] := -2; cdx[41] :=  0; cdx[42] :=  0; cdx[43] := -1;
  463. X      cdx[44] := -1; cdx[45] :=  0; cdx[46] :=  0; cdx[47] := -1;
  464. X      cdx[48] := -1; cdx[49] := -1; cdx[50] := +1; cdx[51] := +1;
  465. X      cdx[52] := -1; cdx[53] := -1; cdx[54] := +1; cdx[55] := -1;
  466. X      cdx[56] := -1; cdx[57] :=  0; cdx[58] :=  0; cdx[59] :=  0;
  467. X      cdx[60] :=  0;
  468. X      pdx[ 1] := -1; pdx[ 2] := -1; pdx[ 3] := -2; pdx[ 4] := -2;
  469. X      pdx[ 5] := -2; pdx[ 6] := -3; pdx[ 7] := -3; pdx[ 8] := -3;
  470. X      pdx[ 9] := -3; pdx[10] := -4; pdx[11] :=  0; pdx[12] := -2;
  471. X      pdx[13] := -1; pdx[14] :=  0; pdx[15] :=  0; pdx[16] :=  0;
  472. X      pdx[17] :=  0; pdx[18] :=  0; pdx[19] :=  0; pdx[20] :=  0;
  473. X      pdx[21] := -1; pdx[22] := -1; pdx[23] := -1;
  474. X    end;
  475. X
  476. X  begin (*inittables*)
  477. X    reswords; symbols; rators;
  478. X    instrmnemonics; procmnemonics;
  479. X    chartypes; initdx;
  480. X  end (*inittables*) ;
  481. X
  482. begin
  483. X  (*initialize*)
  484. X  (************)
  485. X  initscalars; initsets; inittables;
  486. X
  487. X
  488. X  (*enter standard names and standard types:*)
  489. X  (******************************************)
  490. X  level := 0; top := 0;
  491. X  with display[0] do
  492. X    begin fname := nil; flabel := nil; occur := blck end;
  493. X  enterstdtypes;   stdnames; entstdnames;   enterundecl;
  494. X  top := 1; level := 1;
  495. X  with display[1] do
  496. X    begin fname := nil; flabel := nil; occur := blck end;
  497. X
  498. X
  499. X  (*compile:*) (*rewrite(prr); (*comment this out when compiling with pcom *)
  500. X  (**********)
  501. X  insymbol;
  502. X  programme(blockbegsys+statbegsys-[casesy]);
  503. X
  504. end.
  505. SHAR_EOF
  506. echo 'File pcom.p is complete' &&
  507. chmod 0644 pcom.p ||
  508. echo 'restore of pcom.p failed'
  509. Wc_c="`wc -c < 'pcom.p'`"
  510. test 117626 -eq "$Wc_c" ||
  511.     echo 'pcom.p: original size 117626, current size' "$Wc_c"
  512. rm -f _shar_wnt_.tmp
  513. fi
  514. # ============= pint.p ==============
  515. if test -f 'pint.p' -a X"$1" != X"-c"; then
  516.     echo 'x - skipping pint.p (File already exists)'
  517.     rm -f _shar_wnt_.tmp
  518. else
  519. > _shar_wnt_.tmp
  520. echo 'x - extracting pint.p (Text)'
  521. sed 's/^X//' << 'SHAR_EOF' > 'pint.p' &&
  522. (*Assembler and interpreter of Pascal code*)
  523. (*K. Jensen, N. Wirth, Ch. Jacobi, ETH May 76*)
  524. X
  525. program pcode(input,output,prd,prr);
  526. X
  527. (* Note for the implementation.
  528. X   ===========================
  529. This interpreter is written for the case where all the fundamental types
  530. take one storage unit.
  531. In an actual implementation, the handling of the sp pointer has to take
  532. into account the fact that the types may have lengths different from one:
  533. in push and pop operations the sp has to be increased and decreased not
  534. by 1, but by a number depending on the type concerned.
  535. However, where the number of units of storage has been computed by the
  536. compiler, the value must not be corrected, since the lengths of the types
  537. involved have already been taken into account.
  538. X                                 *)
  539. X
  540. X
  541. X
  542. X
  543. label 1;
  544. const codemax     = 8650;
  545. X      pcmax       = 17500;
  546. X      maxstk      = 13650; (* size of variable store *)
  547. X      overi       = 13655; (* size of integer constant table = 5 *)
  548. X      overr       = 13660; (* size of real constant table = 5 *)
  549. X      overs       = 13730; (* size of set constant table = 70 *)
  550. X      overb       = 13820;
  551. X      overm       = 18000;
  552. X      maxstr      = 18001;
  553. X      largeint    = 26144;
  554. X      begincode   = 3;
  555. X      inputadr    = 5;
  556. X      outputadr   = 6;
  557. X      prdadr      = 7;
  558. X      prradr      = 8;
  559. X      duminst     = 62;
  560. X
  561. type  bit4    = 0..15;
  562. X      bit6    = 0..127;
  563. X      bit20       = -26143..26143;
  564. X      datatype    = (undef,int,reel,bool,sett,adr,mark,car);
  565. X      address     = -1..maxstr;
  566. X      beta    = packed array[1..25] of char; (*error message*)
  567. X      settype     = set of 0..58;
  568. X
  569. var   code    : array[0..codemax] of   (* the program *)
  570. X              packed record  op1    :bit6;
  571. X                     p1     :bit4;
  572. X                     q1     :bit20;
  573. X                     op2    :bit6;
  574. X                     p2     :bit4;
  575. X                     q2     :bit20
  576. X                 end;
  577. X      pc       : 0..pcmax;     (*program address register*)
  578. X      op : bit6; p : bit4; q : bit20;  (*instruction register*)
  579. X
  580. X      store    : array [0..overm] of
  581. X               record case datatype of
  582. X                int    :(vi :integer);
  583. X                reel       :(vr :real);
  584. X                bool       :(vb :boolean);
  585. X                sett       :(vs :settype);
  586. X                car    :(vc :char);
  587. X                adr    :(va :address);
  588. X                         (*address in store*)
  589. X                mark       :(vm :integer)
  590. X            end;
  591. X       mp,sp,np,ep : address;  (* address registers *)
  592. X       (*mp  points to beginning of a data segment
  593. X     sp  points to top of the stack
  594. X     ep  points to the maximum extent of the stack
  595. X     np  points to top of the dynamically allocated area*)
  596. X
  597. X       interpreting: boolean;
  598. X       prd,prr     : text;(*prd for read only, prr for write only *)
  599. X
  600. X       instr       : array[bit6] of alfa; (* mnemonic instruction codes *)
  601. X       cop     : array[bit6] of integer;
  602. X       sptable     : array[0..20] of alfa; (*standard functions and procedures*)
  603. X
  604. X      (*locally used for interpreting one instruction*)
  605. X       ad,ad1      : address;
  606. X       b       : boolean;
  607. X       i,j,i1,i2   : integer;
  608. X       c       : char;
  609. X
  610. (*--------------------------------------------------------------------*)
  611. X
  612. procedure load;
  613. X   const maxlabel = 1850;
  614. X   type  labelst  = (entered,defined); (*label situation*)
  615. X     labelrg  = 0..maxlabel;       (*label range*)
  616. X     labelrec = record
  617. X              val: address;
  618. X               st: labelst
  619. X            end;
  620. X   var  icp,rcp,scp,bcp,mcp  : address;  (*pointers to next free position*)
  621. X    word : array[1..10] of char; i  : integer;  ch  : char;
  622. X    labeltab: array[labelrg] of labelrec;
  623. X    labelvalue: address;
  624. X
  625. X   procedure init;
  626. X      var i: integer;
  627. X   begin instr[ 0]:='lod       ';       instr[ 1]:='ldo       ';
  628. X     instr[ 2]:='str       ';       instr[ 3]:='sro       ';
  629. X     instr[ 4]:='lda       ';       instr[ 5]:='lao       ';
  630. X     instr[ 6]:='sto       ';       instr[ 7]:='ldc       ';
  631. X     instr[ 8]:='...       ';       instr[ 9]:='ind       ';
  632. X     instr[10]:='inc       ';       instr[11]:='mst       ';
  633. X     instr[12]:='cup       ';       instr[13]:='ent       ';
  634. X     instr[14]:='ret       ';       instr[15]:='csp       ';
  635. X     instr[16]:='ixa       ';       instr[17]:='equ       ';
  636. X     instr[18]:='neq       ';       instr[19]:='geq       ';
  637. X     instr[20]:='grt       ';       instr[21]:='leq       ';
  638. X     instr[22]:='les       ';       instr[23]:='ujp       ';
  639. X     instr[24]:='fjp       ';       instr[25]:='xjp       ';
  640. X     instr[26]:='chk       ';       instr[27]:='eof       ';
  641. X     instr[28]:='adi       ';       instr[29]:='adr       ';
  642. X     instr[30]:='sbi       ';       instr[31]:='sbr       ';
  643. X     instr[32]:='sgs       ';       instr[33]:='flt       ';
  644. X     instr[34]:='flo       ';       instr[35]:='trc       ';
  645. X     instr[36]:='ngi       ';       instr[37]:='ngr       ';
  646. X     instr[38]:='sqi       ';       instr[39]:='sqr       ';
  647. X     instr[40]:='abi       ';       instr[41]:='abr       ';
  648. X     instr[42]:='not       ';       instr[43]:='and       ';
  649. X     instr[44]:='ior       ';       instr[45]:='dif       ';
  650. X     instr[46]:='int       ';       instr[47]:='uni       ';
  651. X     instr[48]:='inn       ';       instr[49]:='mod       ';
  652. X     instr[50]:='odd       ';       instr[51]:='mpi       ';
  653. X     instr[52]:='mpr       ';       instr[53]:='dvi       ';
  654. X     instr[54]:='dvr       ';       instr[55]:='mov       ';
  655. X     instr[56]:='lca       ';       instr[57]:='dec       ';
  656. X     instr[58]:='stp       ';       instr[59]:='ord       ';
  657. X     instr[60]:='chr       ';       instr[61]:='ujc       ';
  658. X
  659. X     sptable[ 0]:='get       ';     sptable[ 1]:='put       ';
  660. X     sptable[ 2]:='rst       ';     sptable[ 3]:='rln       ';
  661. X     sptable[ 4]:='new       ';     sptable[ 5]:='wln       ';
  662. X     sptable[ 6]:='wrs       ';     sptable[ 7]:='eln       ';
  663. X     sptable[ 8]:='wri       ';     sptable[ 9]:='wrr       ';
  664. X     sptable[10]:='wrc       ';     sptable[11]:='rdi       ';
  665. X     sptable[12]:='rdr       ';     sptable[13]:='rdc       ';
  666. X     sptable[14]:='sin       ';     sptable[15]:='cos       ';
  667. X     sptable[16]:='exp       ';     sptable[17]:='log       ';
  668. X     sptable[18]:='sqt       ';     sptable[19]:='atn       ';
  669. X     sptable[20]:='sav       ';
  670. X
  671. X     cop[ 0] := 105;  cop[ 1] :=  65;
  672. X     cop[ 2] :=  70;  cop[ 3] :=  75;
  673. X     cop[ 6] :=  80;  cop[ 9] :=  85;
  674. X     cop[10] :=  90;  cop[26] :=  95;
  675. X     cop[57] := 100;
  676. X
  677. X     pc  := begincode;
  678. X     icp := maxstk + 1;
  679. X     rcp := overi + 1;
  680. X     scp := overr + 1;
  681. X     bcp := overs + 2;
  682. X     mcp := overb + 1;
  683. X     for i:= 1 to 10 do word[i]:= ' ';
  684. X     for i:= 0 to maxlabel do
  685. X         with labeltab[i] do begin val:=-1; st:= entered end;
  686. X     reset(prd);
  687. X   end;(*init*)
  688. X
  689. X   procedure errorl(string: beta); (*error in loading*)
  690. X   begin writeln;
  691. X      write(string);
  692. X      halt
  693. X   end; (*errorl*)
  694. X
  695. X   procedure update(x: labelrg); (*when a label definition lx is found*)
  696. X      var curr,succ: -1..pcmax;  (*resp. current element and successor element
  697. X                   of a list of future references*)
  698. X      endlist: boolean;
  699. X   begin
  700. X      if labeltab[x].st=defined then errorl(' duplicated label    ')
  701. X      else begin
  702. X         if labeltab[x].val<>-1 then (*forward reference(s)*)
  703. X         begin curr:= labeltab[x].val; endlist:= false;
  704. X        while not endlist do
  705. X              with code[curr div 2] do
  706. X              begin
  707. X             if odd(curr) then begin succ:= q2;
  708. X                         q2:= labelvalue
  709. X                       end
  710. X                      else begin succ:= q1;
  711. X                         q1:= labelvalue
  712. X                       end;
  713. X             if succ=-1 then endlist:= true
  714. X                    else curr:= succ
  715. X              end;
  716. X          end;
  717. X          labeltab[x].st := defined;
  718. X          labeltab[x].val:= labelvalue;
  719. X       end
  720. X   end;(*update*)
  721. X
  722. X   procedure assemble; forward;
  723. X
  724. X   procedure generate;(*generate segment of code*)
  725. X      var x: integer; (* label number *)
  726. X      again: boolean;
  727. X   begin
  728. X      again := true;
  729. X      while again do
  730. X        begin read(prd,ch);(* first character of line*)
  731. X          case ch of
  732. X               'i': readln(prd);
  733. X               'l': begin read(prd,x);
  734. X                  if not eoln(prd) then read(prd,ch);
  735. X                  if ch='=' then read(prd,labelvalue)
  736. X                        else labelvalue:= pc;
  737. X                  update(x); readln(prd);
  738. X                end;
  739. X               'q': begin again := false; readln(prd) end;
  740. X               ' ': begin read(prd,ch); assemble end
  741. X          end;
  742. X        end
  743. X   end; (*generate*)
  744. X
  745. X   procedure assemble; (*translate symbolic code into machine code and store*)
  746. X      label 1;     (*goto 1 for instructions without code generation*)
  747. X      var name :alfa;  b :boolean;  r :real;  s :settype;
  748. X      c1 :char;  i,s1,lb,ub :integer;
  749. X
  750. X      procedure lookup(x: labelrg); (* search in label table*)
  751. X      begin case labeltab[x].st of
  752. X        entered: begin q := labeltab[x].val;
  753. X               labeltab[x].val := pc
  754. X             end;
  755. X        defined: q:= labeltab[x].val
  756. X        end(*case label..*)
  757. X      end;(*lookup*)
  758. X
  759. X      procedure labelsearch;
  760. X     var x: labelrg;
  761. X      begin while (ch<>'l') and not eoln(prd) do read(prd,ch);
  762. X        read(prd,x); lookup(x)
  763. X      end;(*labelsearch*)
  764. X
  765. X      procedure getname;
  766. X      begin  word[1] := ch;
  767. X     read(prd,word[2],word[3]);
  768. X     if not eoln(prd) then read(prd,ch) (*next character*);
  769. X     pack(word,1,name)
  770. X      end; (*getname*)
  771. X
  772. X      procedure typesymbol;
  773. X    var i: integer;
  774. X      begin
  775. X    if ch <> 'i' then
  776. X      begin
  777. X        case ch of
  778. X          'a': i := 0;
  779. X          'r': i := 1;
  780. X          's': i := 2;
  781. X          'b': i := 3;
  782. X          'c': i := 4;
  783. X        end;
  784. X        op := cop[op]+i;
  785. X      end;
  786. X      end (*typesymbol*) ;
  787. X
  788. X   begin  p := 0;  q := 0;  op := 0;
  789. X      getname;
  790. X      instr[duminst] := name;
  791. X      while instr[op]<>name do op := op+1;
  792. X      if op = duminst then errorl(' illegal instruction     ');
  793. X
  794. X      case op of  (* get parameters p,q *)
  795. X
  796. X      (*equ,neq,geq,grt,leq,les*)
  797. X      17,18,19,
  798. X      20,21,22: begin case ch of
  799. X                  'a': ; (*p = 0*)
  800. X                  'i': p := 1;
  801. X                  'r': p := 2;
  802. X                  'b': p := 3;
  803. X                  's': p := 4;
  804. X                  'c': p := 6;
  805. X                  'm': begin p := 5;
  806. X                     read(prd,q)
  807. X                   end
  808. X              end
  809. X            end;
  810. X
  811. X      (*lod,str*)
  812. X      0,2: begin typesymbol; read(prd,p,q)
  813. X           end;
  814. X
  815. X      4  (*lda*): read(prd,p,q);
  816. X
  817. X      12 (*cup*): begin read(prd,p); labelsearch end;
  818. X
  819. X      11 (*mst*): read(prd,p);
  820. X
  821. X      14 (*ret*): case ch of
  822. X                'p': p:=0;
  823. X                'i': p:=1;
  824. X                'r': p:=2;
  825. X                'c': p:=3;
  826. X                'b': p:=4;
  827. X                'a': p:=5
  828. X              end;
  829. X
  830. X      (*lao,ixa,mov*)
  831. X      5,16,55: read(prd,q);
  832. X
  833. X      (*ldo,sro,ind,inc,dec*)
  834. X      1,3,9,10,57: begin typesymbol; read(prd,q)
  835. X               end;
  836. X
  837. X      (*ujp,fjp,xjp*)
  838. X      23,24,25: labelsearch;
  839. X
  840. X      13 (*ent*): begin read(prd,p); labelsearch end;
  841. X
  842. X      15 (*csp*): begin for i:=1 to 9 do read(prd,ch); getname;
  843. X               while name<>sptable[q] do  q := q+1
  844. X              end;
  845. X
  846. X      7 (*ldc*): begin case ch of  (*get q*)
  847. X               'i': begin  p := 1;  read(prd,i);
  848. X                   if abs(i)>=largeint then
  849. X                   begin  op := 8;
  850. X                      store[icp].vi := i;  q := maxstk;
  851. X                      repeat  q := q+1  until store[q].vi=i;
  852. X                      if q=icp then
  853. X                      begin  icp := icp+1;
  854. X                    if icp=overi then
  855. X                      errorl(' integer table overflow  ');
  856. X                      end
  857. X                   end  else q := i
  858. X                end;
  859. X
  860. X               'r': begin  op := 8; p := 2;
  861. X                   read(prd,r);
  862. X                   store[rcp].vr := r;  q := overi;
  863. X                   repeat  q := q+1  until store[q].vr=r;
  864. X                   if q=rcp then
  865. X                   begin  rcp := rcp+1;
  866. X                     if rcp = overr then
  867. X                       errorl(' real table overflow     ');
  868. X                   end
  869. X                end;
  870. X
  871. X               'n': ; (*p,q = 0*)
  872. X
  873. X               'b': begin p := 3;  read(prd,q)  end;
  874. X
  875. X               'c': begin p := 6;
  876. X                  repeat read(prd,ch); until ch <> ' ';
  877. X                  if ch <> '''' then
  878. X                    errorl(' illegal character       ');
  879. X                  read(prd,ch);  q := ord(ch);
  880. X                  read(prd,ch);
  881. X                  if ch <> '''' then
  882. X                    errorl(' illegal character       ');
  883. X                end;
  884. X               '(': begin  op := 8;  p := 4;
  885. X                   s := [ ];  read(prd,ch);
  886. X                   while ch<>')' do
  887. X                   begin read(prd,s1,ch); s := s + [s1]
  888. X                   end;
  889. X                   store[scp].vs := s;  q := overr;
  890. X                   repeat  q := q+1  until store[q].vs=s;
  891. X                   if q=scp then
  892. X                   begin  scp := scp+1;
  893. X                      if scp=overs then
  894. X                    errorl(' set table overflow      ');
  895. X                   end
  896. X                end
  897. X               end (*case*)
  898. X             end;
  899. X
  900. X       26 (*chk*): begin typesymbol;
  901. X             read(prd,lb,ub);
  902. X             if op = 95 then q := lb
  903. X             else
  904. X             begin
  905. X               store[bcp-1].vi := lb; store[bcp].vi := ub;
  906. X               q := overs;
  907. X               repeat  q := q+2
  908. X               until (store[q-1].vi=lb)and (store[q].vi=ub);
  909. X               if q=bcp then
  910. X               begin  bcp := bcp+2;
  911. X                  if bcp=overb then
  912. X                errorl(' boundary table overflow ');
  913. X               end
  914. X             end
  915. X               end;
  916. X
  917. X       56 (*lca*): begin
  918. X             if mcp + 16 >= overm then
  919. X               errorl(' multiple table overflow ');
  920. X             mcp := mcp+16;
  921. X             q := mcp;
  922. X             for i := 0 to 15 (*stringlgth*) do
  923. X             begin read(prd,ch);
  924. X               store[q+i].vc := ch
  925. X             end;
  926. X               end;
  927. X
  928. X      6 (*sto*): typesymbol;
  929. X
  930. X      27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
  931. X      48,49,50,51,52,53,54,58:  ;
  932. X
  933. X      (*ord,chr*)
  934. X      59,60: goto 1;
  935. X
  936. X      61 (*ujc*): ; (*must have same length as ujp*)
  937. X
  938. X      end; (*case*)
  939. X
  940. X      (* store instruction *)
  941. X      with code[pc div 2] do
  942. X     if odd(pc) then
  943. X     begin  op2 := op; p2 := p; q2 := q
  944. X     end  else
  945. X     begin  op1 := op; p1 := p; q1 := q
  946. X     end;
  947. X      pc := pc+1;
  948. X      1: readln(prd);
  949. X   end; (*assemble*)
  950. X
  951. begin (*load*)
  952. X   init;
  953. X   generate;
  954. X   pc := 0;
  955. X   generate;
  956. end; (*load*)
  957. X
  958. (*------------------------------------------------------------------------*)
  959. X
  960. procedure pmd;
  961. X   var s :integer; i: integer;
  962. X
  963. X   procedure pt;
  964. X   begin  write(s:6);
  965. X      if abs(store[s].vi) < maxint then write(store[s].vi)
  966. X      else write('too big ');
  967. X      s := s - 1;
  968. X      i := i + 1;
  969. X      if i = 4 then
  970. X     begin writeln(output); i := 0 end;
  971. X   end; (*pt*)
  972. X
  973. begin
  974. X   write(' pc =',pc-1:5,' op =',op:3,'  sp =',sp:5,'  mp =',mp:5,
  975. X    '  np =',np:5);
  976. X   writeln; writeln('--------------------------------------');
  977. X
  978. X   s := sp; i := 0;
  979. X   while s>=0 do pt;
  980. X   s := maxstk;
  981. X   while s>=np do pt;
  982. end; (*pmd*)
  983. X
  984. procedure errori(string: beta);
  985. begin writeln; writeln(string);
  986. X      pmd; goto 1
  987. end;(*errori*)
  988. X
  989. function base(ld :integer):address;
  990. X   var ad :address;
  991. begin  ad := mp;
  992. X   while ld>0 do
  993. X   begin  ad := store[ad+1].vm;  ld := ld-1
  994. X   end;
  995. X   base := ad
  996. end; (*base*)
  997. X
  998. procedure compare;
  999. (*comparing is only correct if result by comparing integers will be*)
  1000. begin
  1001. X  i1 := store[sp].va;
  1002. X  i2 := store[sp+1].va;
  1003. X  i := 0; b := true;
  1004. X  while b and (i<>q) do
  1005. X    if store[i1+i].vi = store[i2+i].vi then i := i+1
  1006. X    else b := false
  1007. end; (*compare*)
  1008. X
  1009. procedure callsp;
  1010. X   var line: boolean; adptr,adelnt: address;
  1011. X       i: integer;
  1012. X
  1013. X   procedure readi(var f:text);
  1014. X      var ad: address;
  1015. X   begin ad:= store[sp-1].va;
  1016. X     read(f,store[ad].vi);
  1017. X     store[store[sp].va].vc := f^;
  1018. X     sp:= sp-2
  1019. X   end;(*readi*)
  1020. X
  1021. X   procedure readr(var f: text);
  1022. X      var ad: address;
  1023. X   begin ad:= store[sp-1].va;
  1024. X     read(f,store[ad].vr);
  1025. X     store[store[sp].va].vc := f^;
  1026. X     sp:= sp-2
  1027. X   end;(*readr*)
  1028. X
  1029. X   procedure readc(var f: text);
  1030. X      var c: char; ad: address;
  1031. X   begin read(f,c);
  1032. X     ad:= store[sp-1].va;
  1033. X     store[ad].vc := c;
  1034. X     store[store[sp].va].vc := f^;
  1035. X     store[store[sp].va].vi := ord(f^);
  1036. X     sp:= sp-2
  1037. X   end;(*readc*)
  1038. X
  1039. X   procedure writestr(var f: text);
  1040. X      var i,j,k: integer;
  1041. X      ad: address;
  1042. X   begin ad:= store[sp-3].va;
  1043. X     k := store[sp-2].vi; j := store[sp-1].vi;
  1044. X     (* j and k are numbers of characters *)
  1045. X     if k>j then for i:=1 to k-j do write(f,' ')
  1046. X        else j:= k;
  1047. X     for i := 0 to j-1 do write(f,store[ad+i].vc);
  1048. X     sp:= sp-4
  1049. X   end;(*writestr*)
  1050. X
  1051. X   procedure getfile(var f: text);
  1052. X      var ad: address;
  1053. X   begin ad:=store[sp].va;
  1054. X     get(f); store[ad].vc := f^;
  1055. X     sp:=sp-1
  1056. X   end;(*getfile*)
  1057. X
  1058. X   procedure putfile(var f: text);
  1059. X      var ad: address;
  1060. X   begin ad:= store[sp].va;
  1061. X     f^:= store[ad].vc; put(f);
  1062. X     sp:= sp-1;
  1063. X   end;(*putfile*)
  1064. X
  1065. begin (*callsp*)
  1066. X      case q of
  1067. X       0 (*get*): case store[sp].va of
  1068. X               5: getfile(input);
  1069. X               6: errori(' get on output file      ');
  1070. X               7: getfile(prd);
  1071. X               8: errori(' get on prr file     ')
  1072. X              end;
  1073. X       1 (*put*): case store[sp].va of
  1074. X               5: errori(' put on read file    ');
  1075. X               6: putfile(output);
  1076. X               7: errori(' put on prd file     ');
  1077. X               8: putfile(prr)
  1078. X              end;
  1079. X       2 (*rst*): begin
  1080. X            (*for testphase*)
  1081. X            np := store[sp].va; sp := sp-1
  1082. X              end;
  1083. X       3 (*rln*): begin case store[sp].va of
  1084. X                 5: begin readln(input);
  1085. X                      store[inputadr].vc := input^
  1086. X                    end;
  1087. X                 6: errori(' readln on output file   ');
  1088. X                 7: begin readln(input);
  1089. X                      store[inputadr].vc := input^
  1090. X                    end;
  1091. X                 8: errori(' readln on prr file      ')
  1092. X                end;
  1093. X                sp:= sp-1
  1094. X              end;
  1095. X       4 (*new*): begin ad:= np-store[sp].va;
  1096. X              (*top of stack gives the length in units of storage *)
  1097. X                if ad <= ep then
  1098. X                  errori(' store overflow      ');
  1099. X                np:= ad; ad:= store[sp-1].va;
  1100. X                store[ad].va := np;
  1101. X                sp:=sp-2
  1102. X              end;
  1103. X       5 (*wln*): begin case store[sp].va of
  1104. X                 5: errori(' writeln on input file   ');
  1105. X                 6: writeln(output);
  1106. X                 7: errori(' writeln on prd file     ');
  1107. X                 8: writeln(prr)
  1108. X                end;
  1109. X                sp:= sp-1
  1110. X              end;
  1111. X       6 (*wrs*): case store[sp].va of
  1112. X               5: errori(' write on input file     ');
  1113. X               6: writestr(output);
  1114. X               7: errori(' write on prd file       ');
  1115. X               8: writestr(prr)
  1116. X              end;
  1117. X       7 (*eln*): begin case store[sp].va of
  1118. X                 5: line:= eoln(input);
  1119. X                 6: errori(' eoln output file    ');
  1120. X                 7: line:=eoln(prd);
  1121. X                 8: errori(' eoln on prr file    ')
  1122. X                end;
  1123. X                store[sp].vb := line
  1124. X              end;
  1125. X       8 (*wri*): begin case store[sp].va of
  1126. X                 5: errori(' write on input file     ');
  1127. X                 6: write(output,
  1128. X                      store[sp-2].vi: store[sp-1].vi);
  1129. X                 7: errori(' write on prd file       ');
  1130. X                 8: write(prr,
  1131. X                      store[sp-2].vi: store[sp-1].vi)
  1132. X                end;
  1133. X                sp:=sp-3
  1134. X              end;
  1135. X       9 (*wrr*): begin case store[sp].va of
  1136. X                 5: errori(' write on input file     ');
  1137. X                 6: write(output,
  1138. X                      store[sp-2].vr: store[sp-1].vi);
  1139. X                 7: errori(' write on prd file       ');
  1140. X                 8: write(prr,
  1141. X                      store[sp-2].vr: store[sp-1].vi)
  1142. X                end;
  1143. X                sp:=sp-3
  1144. X              end;
  1145. X       10(*wrc*): begin case store[sp].va of
  1146. X                 5: errori(' write on input file     ');
  1147. X                 6: write(output,store[sp-2].vc:
  1148. X                      store[sp-1].vi);
  1149. X                 7: errori(' write on prd file       ');
  1150. X                 8: write(prr,chr(store[sp-2].vi):
  1151. X                      store[sp-1].vi);
  1152. X                end;
  1153. X                sp:=sp-3
  1154. X              end;
  1155. X       11(*rdi*): case store[sp].va of
  1156. X               5: readi(input);
  1157. X               6: errori(' read on output file     ');
  1158. X               7: readi(prd);
  1159. X               8: errori(' read on prr file    ')
  1160. X              end;
  1161. X       12(*rdr*): case store[sp].va of
  1162. X               5: readr(input);
  1163. X               6: errori(' read on output file     ');
  1164. X               7: readr(prd);
  1165. X               8: errori(' read on prr file    ')
  1166. X              end;
  1167. X       13(*rdc*): case store[sp].va of
  1168. X               5: readc(input);
  1169. X               6: errori(' read on output file     ');
  1170. X               7: readc(prd);
  1171. X               8: errori(' read on prr file    ')
  1172. X              end;
  1173. X       14(*sin*): store[sp].vr:= sin(store[sp].vr);
  1174. X       15(*cos*): store[sp].vr:= cos(store[sp].vr);
  1175. X       16(*exp*): store[sp].vr:= exp(store[sp].vr);
  1176. X       17(*log*): store[sp].vr:= ln(store[sp].vr);
  1177. X       18(*sqt*): store[sp].vr:= sqrt(store[sp].vr);
  1178. X       19(*atn*): store[sp].vr:= arctan(store[sp].vr);
  1179. X       20(*sav*): begin ad:=store[sp].va;
  1180. X             store[ad].va := np;
  1181. X             sp:= sp-1
  1182. X              end;
  1183. X      end;(*case q*)
  1184. end;(*callsp*)
  1185. X
  1186. begin (* main *)
  1187. X  rewrite(prr);
  1188. X  load; (* assembles and stores code *)
  1189. X  writeln(output); (* for testing *)
  1190. X  pc := 0; sp := -1; mp := 0; np := maxstk+1; ep := 5;
  1191. X  store[inputadr].vc := input^;
  1192. X  store[prdadr].vc := prd^;
  1193. X  interpreting := true;
  1194. X
  1195. X  while interpreting do
  1196. X  begin
  1197. X    (*fetch*)
  1198. X    with code[pc div 2] do
  1199. X      if odd(pc) then
  1200. X      begin op := op2; p := p2; q := q2
  1201. X      end else
  1202. X      begin op := op1; p := p1; q := q1
  1203. X      end;
  1204. X    pc := pc+1;
  1205. X
  1206. X    (*execute*)
  1207. X    case op of
  1208. X
  1209. X      105,106,107,108,109,
  1210. X      0 (*lod*): begin  ad := base(p) + q;
  1211. X              sp := sp+1;
  1212. X              store[sp] := store[ad]
  1213. X             end;
  1214. X
  1215. X      65,66,67,68,69,
  1216. X      1 (*ldo*): begin
  1217. X              sp := sp+1;
  1218. X              store[sp] := store[q]
  1219. X             end;
  1220. X
  1221. X      70,71,72,73,74,
  1222. X      2 (*str*): begin  store[base(p)+q] := store[sp];
  1223. X              sp := sp-1
  1224. X             end;
  1225. X
  1226. X      75,76,77,78,79,
  1227. X      3 (*sro*): begin  store[q] := store[sp];
  1228. X              sp := sp-1
  1229. X             end;
  1230. X
  1231. X      4 (*lda*): begin sp := sp+1;
  1232. X              store[sp].va := base(p) + q
  1233. X             end;
  1234. X
  1235. X      5 (*lao*): begin sp := sp+1;
  1236. X              store[sp].va := q
  1237. X             end;
  1238. X
  1239. X      80,81,82,83,84,
  1240. X      6 (*sto*): begin
  1241. X              store[store[sp-1].va] := store[sp];
  1242. X              sp := sp-2;
  1243. X             end;
  1244. X
  1245. X      7 (*ldc*): begin sp := sp+1;
  1246. X              if p=1 then
  1247. X              begin store[sp].vi := q;
  1248. X              end else
  1249. X              if p = 6 then store[sp].vc := chr(q)
  1250. X              else
  1251. X                if p = 3 then store[sp].vb := q = 1
  1252. X                else (* load nil *) store[sp].va := maxstr
  1253. X             end;
  1254. X
  1255. X      8 (*lci*): begin sp := sp+1;
  1256. X              store[sp] := store[q]
  1257. X             end;
  1258. X
  1259. X      85,86,87,88,89,
  1260. X      9 (*ind*): begin ad := store[sp].va + q;
  1261. X              (* q is a number of storage units *)
  1262. X              store[sp] := store[ad]
  1263. X             end;
  1264. X
  1265. X      90,91,92,93,94,
  1266. X      10 (*inc*): store[sp].vi := store[sp].vi+q;
  1267. X
  1268. X      11 (*mst*): begin (*p=level of calling procedure minus level of called
  1269. X                  procedure + 1;  set dl and sl, increment sp*)
  1270. X               (* then length of this element is
  1271. X              max(intsize,realsize,boolsize,charsize,ptrsize *)
  1272. X               store[sp+2].vm := base(p);
  1273. X               (* the length of this element is ptrsize *)
  1274. X               store[sp+3].vm := mp;
  1275. X               (* idem *)
  1276. X               store[sp+4].vm := ep;
  1277. X               (* idem *)
  1278. X               sp := sp+5
  1279. X              end;
  1280. X
  1281. X      12 (*cup*): begin (*p=no of locations for parameters, q=entry point*)
  1282. X               mp := sp-(p+4);
  1283. X               store[mp+4].vm := pc;
  1284. X               pc := q
  1285. X              end;
  1286. X
  1287. X      13 (*ent*): if p = 1 then
  1288. X            begin sp := mp + q; (*q = length of dataseg*)
  1289. X              if sp > np then errori(' store overflow      ');
  1290. X            end
  1291. X              else
  1292. X            begin ep := sp+q;
  1293. X              if ep > np then errori(' store overflow      ');
  1294. X            end;
  1295. X            (*q = max space required on stack*)
  1296. X
  1297. X      14 (*ret*): begin case p of
  1298. X                 0: sp:= mp-1;
  1299. X                 1,2,3,4,5: sp:= mp
  1300. X                end;
  1301. X                pc := store[mp+4].vm;
  1302. X                ep := store[mp+3].vm;
  1303. X                mp:= store[mp+2].vm;
  1304. X              end;
  1305. X
  1306. X      15 (*csp*): callsp;
  1307. X
  1308. X      16 (*ixa*): begin
  1309. X               i := store[sp].vi;
  1310. X               sp := sp-1;
  1311. X               store[sp].va := q*i+store[sp].va;
  1312. X              end;
  1313. X
  1314. X      17 (*equ*): begin  sp := sp-1;
  1315. X               case p of
  1316. X             1: store[sp].vb := store[sp].vi = store[sp+1].vi;
  1317. X             0: store[sp].vb := store[sp].va = store[sp+1].va;
  1318. X             6: store[sp].vb := store[sp].vc = store[sp+1].vc;
  1319. X             2: store[sp].vb := store[sp].vr = store[sp+1].vr;
  1320. X             3: store[sp].vb := store[sp].vb = store[sp+1].vb;
  1321. X             4: store[sp].vb := store[sp].vs = store[sp+1].vs;
  1322. X             5: begin  compare;
  1323. X                   store[sp].vb := b;
  1324. X                end;
  1325. X               end; (*case p*)
  1326. X              end;
  1327. X
  1328. X      18 (*neq*): begin  sp := sp-1;
  1329. X               case p of
  1330. X             0: store[sp].vb := store[sp].va <> store[sp+1].va;
  1331. X             1: store[sp].vb := store[sp].vi <> store[sp+1].vi;
  1332. X             6: store[sp].vb := store[sp].vc <> store[sp+1].vc;
  1333. X             2: store[sp].vb := store[sp].vr <> store[sp+1].vr;
  1334. X             3: store[sp].vb := store[sp].vb <> store[sp+1].vb;
  1335. X             4: store[sp].vb := store[sp].vs <> store[sp+1].vs;
  1336. X             5: begin  compare;
  1337. X                   store[sp].vb := not b;
  1338. X                end
  1339. X               end; (*case p*)
  1340. X              end;
  1341. X
  1342. X      19 (*geq*): begin  sp := sp-1;
  1343. X               case p of
  1344. X             0: errori(' <,<=,>,>= for address   ');
  1345. X             1: store[sp].vb := store[sp].vi >= store[sp+1].vi;
  1346. X             6: store[sp].vb := store[sp].vc >= store[sp+1].vc;
  1347. X             2: store[sp].vb := store[sp].vr >= store[sp+1].vr;
  1348. X             3: store[sp].vb := store[sp].vb >= store[sp+1].vb;
  1349. X             4: store[sp].vb := store[sp].vs >= store[sp+1].vs;
  1350. X             5: begin compare;
  1351. X                  store[sp].vb := b or
  1352. X                (store[i1+i].vi >= store[i2+i].vi)
  1353. X                end
  1354. X               end; (*case p*)
  1355. X              end;
  1356. X
  1357. X      20 (*grt*): begin  sp := sp-1;
  1358. X               case p of
  1359. X             0: errori(' <,<=,>,>= for address   ');
  1360. X             1: store[sp].vb := store[sp].vi > store[sp+1].vi;
  1361. X             6: store[sp].vb := store[sp].vc > store[sp+1].vc;
  1362. X             2: store[sp].vb := store[sp].vr > store[sp+1].vr;
  1363. X             3: store[sp].vb := store[sp].vb > store[sp+1].vb;
  1364. X             4: errori(' set inclusion       ');
  1365. X             5: begin  compare;
  1366. X                  store[sp].vb := not b and
  1367. X                (store[i1+i].vi > store[i2+i].vi)
  1368. X                end
  1369. X               end; (*case p*)
  1370. X              end;
  1371. X
  1372. X      21 (*leq*): begin  sp := sp-1;
  1373. X               case p of
  1374. X             0: errori(' <,<=,>,>= for address   ');
  1375. X             1: store[sp].vb := store[sp].vi <= store[sp+1].vi;
  1376. X             6: store[sp].vb := store[sp].vc <= store[sp+1].vc;
  1377. X             2: store[sp].vb := store[sp].vr <= store[sp+1].vr;
  1378. X             3: store[sp].vb := store[sp].vb <= store[sp+1].vb;
  1379. X             4: store[sp].vb := store[sp].vs <= store[sp+1].vs;
  1380. X             5: begin  compare;
  1381. X                  store[sp].vb := b or
  1382. X                (store[i1+i].vi <= store[i2+i].vi)
  1383. X                end;
  1384. X               end; (*case p*)
  1385. X              end;
  1386. X
  1387. X      22 (*les*): begin  sp := sp-1;
  1388. X               case p of
  1389. X             0: errori(' <,<=,>,>= for address   ');
  1390. X             1: store[sp].vb := store[sp].vi < store[sp+1].vi;
  1391. X             6: store[sp].vb := store[sp].vc < store[sp+1].vc;
  1392. X             2: store[sp].vb := store[sp].vr < store[sp+1].vr;
  1393. X             3: store[sp].vb := store[sp].vb < store[sp+1].vb;
  1394. X             5: begin  compare;
  1395. X                  store[sp].vb := not b and
  1396. X                (store[i1+i].vi < store[i2+i].vi)
  1397. X                end
  1398. X               end; (*case p*)
  1399. X              end;
  1400. X
  1401. X      23 (*ujp*): pc := q;
  1402. X
  1403. X      24 (*fjp*): begin  if not store[sp].vb then pc := q;
  1404. X               sp := sp-1
  1405. X              end;
  1406. X
  1407. X      25 (*xjp*): begin
  1408. X               pc := store[sp].vi + q;
  1409. X               sp := sp-1
  1410. X              end;
  1411. X
  1412. X      95 (*chka*): if (store[sp].va < np) or
  1413. X              (store[sp].va > (maxstr-q)) then
  1414. X             errori(' bad pointer value       ');
  1415. X
  1416. X      96,97,98,99,
  1417. X      26 (*chk*): if (store[sp].vi < store[q-1].vi) or
  1418. X             (store[sp].vi > store[q].vi) then
  1419. X            errori(' value out of range      ');
  1420. X
  1421. X      27 (*eof*): begin  i := store[sp].vi;
  1422. X               if i=inputadr then
  1423. X               begin store[sp].vb := eof(input);
  1424. X               end else errori(' code in error       ')
  1425. X              end;
  1426. X
  1427. X      28 (*adi*): begin  sp := sp-1;
  1428. X               store[sp].vi := store[sp].vi + store[sp+1].vi
  1429. X              end;
  1430. X
  1431. X      29 (*adr*): begin  sp := sp-1;
  1432. X               store[sp].vr := store[sp].vr + store[sp+1].vr
  1433. X              end;
  1434. X
  1435. X      30 (*sbi*): begin sp := sp-1;
  1436. X               store[sp].vi := store[sp].vi - store[sp+1].vi
  1437. X              end;
  1438. X
  1439. X      31 (*sbr*): begin  sp := sp-1;
  1440. X               store[sp].vr := store[sp].vr - store[sp+1].vr
  1441. X              end;
  1442. X
  1443. X      32 (*sgs*): store[sp].vs := [store[sp].vi];
  1444. X
  1445. X      33 (*flt*): store[sp].vr := store[sp].vi;
  1446. X
  1447. X      34 (*flo*): store[sp-1].vr := store[sp-1].vi;
  1448. X
  1449. X      35 (*trc*): store[sp].vi := trunc(store[sp].vr);
  1450. X
  1451. X      36 (*ngi*): store[sp].vi := -store[sp].vi;
  1452. X
  1453. X      37 (*ngr*): store[sp].vr := -store[sp].vr;
  1454. X
  1455. X      38 (*sqi*): store[sp].vi := sqr(store[sp].vi);
  1456. X
  1457. X      39 (*sqr*): store[sp].vr := sqr(store[sp].vr);
  1458. X
  1459. X      40 (*abi*): store[sp].vi := abs(store[sp].vi);
  1460. X
  1461. X      41 (*abr*): store[sp].vr := abs(store[sp].vr);
  1462. X
  1463. X      42 (*not*): store[sp].vb := not store[sp].vb;
  1464. X
  1465. X      43 (*and*): begin  sp := sp-1;
  1466. X               store[sp].vb := store[sp].vb and store[sp+1].vb
  1467. X              end;
  1468. X
  1469. X      44 (*ior*): begin  sp := sp-1;
  1470. X               store[sp].vb := store[sp].vb or store[sp+1].vb
  1471. X              end;
  1472. X
  1473. X      45 (*dif*): begin  sp := sp-1;
  1474. X               store[sp].vs := store[sp].vs - store[sp+1].vs
  1475. X              end;
  1476. X
  1477. X      46 (*int*): begin  sp := sp-1;
  1478. X               store[sp].vs := store[sp].vs * store[sp+1].vs
  1479. X              end;
  1480. X
  1481. X      47 (*uni*): begin  sp := sp-1;
  1482. X               store[sp].vs := store[sp].vs + store[sp+1].vs
  1483. X              end;
  1484. X
  1485. X      48 (*inn*): begin
  1486. X               sp := sp - 1; i := store[sp].vi;
  1487. X               store[sp].vb := i in store[sp+1].vs;
  1488. X              end;
  1489. X
  1490. X      49 (*mod*): begin  sp := sp-1;
  1491. X               store[sp].vi := store[sp].vi mod store[sp+1].vi
  1492. X              end;
  1493. X
  1494. X      50 (*odd*): store[sp].vb := odd(store[sp].vi);
  1495. X
  1496. X      51 (*mpi*): begin  sp := sp-1;
  1497. X               store[sp].vi := store[sp].vi * store[sp+1].vi
  1498. X              end;
  1499. X
  1500. X      52 (*mpr*): begin  sp := sp-1;
  1501. X               store[sp].vr := store[sp].vr * store[sp+1].vr
  1502. X              end;
  1503. X
  1504. X      53 (*dvi*): begin  sp := sp-1;
  1505. X               store[sp].vi := store[sp].vi div store[sp+1].vi
  1506. X              end;
  1507. X
  1508. X      54 (*dvr*): begin  sp := sp-1;
  1509. X               store[sp].vr := store[sp].vr / store[sp+1].vr
  1510. X              end;
  1511. X
  1512. X      55 (*mov*): begin i1 := store[sp-1].va;
  1513. X               i2 := store[sp].va; sp := sp-2;
  1514. X               for i := 0 to q-1 do store[i1+i] := store[i2+i]
  1515. X               (* q is a number of storage units *)
  1516. X              end;
  1517. X
  1518. X      56 (*lca*): begin  sp := sp+1;
  1519. X               store[sp].va := q;
  1520. X              end;
  1521. X
  1522. X      100,101,102,103,104,
  1523. X      57 (*dec*): store[sp].vi := store[sp].vi-q;
  1524. X
  1525. X      58 (*stp*): interpreting := false;
  1526. X
  1527. X      59 (*ord*): (*only used to change the tagfield*)
  1528. X              begin
  1529. X              end;
  1530. X
  1531. X      60 (*chr*): begin
  1532. X              end;
  1533. X
  1534. X      61 (*ujc*): errori(' case - error        ');
  1535. X    end
  1536. X  end; (*while interpreting*)
  1537. X
  1538. 1 :
  1539. end.
  1540. SHAR_EOF
  1541. chmod 0644 pint.p ||
  1542. echo 'restore of pint.p failed'
  1543. Wc_c="`wc -c < 'pint.p'`"
  1544. test 28139 -eq "$Wc_c" ||
  1545.     echo 'pint.p: original size 28139, current size' "$Wc_c"
  1546. rm -f _shar_wnt_.tmp
  1547. fi
  1548. rm -f _shar_seq_.tmp
  1549. echo You have unpacked the last part
  1550. exit 0
  1551. exit 0 # Just in case...
  1552. -- 
  1553. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1554. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1555. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1556. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1557.