home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Pascal / Applications / P4⁄Mac 1.0 / Mac source / pcom⁄m.p < prev    next >
Encoding:
Text File  |  1994-07-29  |  20.2 KB  |  975 lines  |  [TEXT/PJMM]

  1. (*$c+,t-,d-,l-*)
  2.  (***********************************************}
  3. {  *                        *}
  4. {  *     Portable Pascal compiler        *}
  5. {  *     ************************        *}
  6. {  *                        *}
  7. {  *        Pascal P4            *}
  8. {  *                        *}
  9. {  *     Authors:                *}
  10. {  *          Urs Ammann            *}
  11. {  *          Kesav Nori            *}
  12. {  *          Christian Jacobi            *}
  13. {  *     Address:                *}
  14. {  *      Institut Fuer Informatik        *}
  15. {  *      Eidg. Technische Hochschule        *}
  16. {  *      CH-8096 Zuerich            *}
  17. {  *                        *}
  18. {  *  This code is fully documented in the book    *}
  19. {  *       "Pascal Implementation"        *}
  20. {  *   by Steven Pemberton and Martin Daniels    *}
  21. {  * published by Ellis Horwood, Chichester, UK    *}
  22. {  *        ISBN: 0-13-653-0311            *}
  23. {  *       (also available in Japanese)        *}
  24. {  *                        *}
  25. {  * Steven Pemberton, CWI/AA,            *}
  26. {  * Kruislaan 413, 1098 SJ Amsterdam, NL    *}
  27. {  * Steven.Pemberton@cwi.nl            *}
  28. {  *                        *}
  29. {  ***********************************************)
  30.  
  31. program pascalcompiler (input, output, prr);
  32.     uses
  33.         pcom1, block;
  34.  
  35.     procedure programme (fsys: setofsys);
  36.         var
  37.             extfp: extfilep;
  38.     begin
  39.         if sy = progsy then
  40.             begin
  41.                 insymbol;
  42.                 if sy <> ident then
  43.                     error(2);
  44.                 insymbol;
  45.                 if not (sy in [lparent, semicolon]) then
  46.                     error(14);
  47.                 if sy = lparent then
  48.                     begin
  49.                         repeat
  50.                             insymbol;
  51.                             if sy = ident then
  52.                                 begin
  53.                                     new(extfp);
  54.                                     with extfp^ do
  55.                                         begin
  56.                                             filename := id;
  57.                                             nextfile := fextfilep
  58.                                         end;
  59.                                     fextfilep := extfp;
  60.                                     insymbol;
  61.                                     if not (sy in [comma, rparent]) then
  62.                                         error(20)
  63.                                 end
  64.                             else
  65.                                 error(2)
  66.                         until sy <> comma;
  67.                         if sy <> rparent then
  68.                             error(4);
  69.                         insymbol
  70.                     end;
  71.                 if sy <> semicolon then
  72.                     error(14)
  73.                 else
  74.                     insymbol;
  75.             end;
  76.         repeat
  77.             block(fsys, period, nil);
  78.             if sy <> period then
  79.                 error(21)
  80.         until (sy = period) or eof(input);
  81.         if list then
  82.             writeln(output);
  83.         if errinx <> 0 then
  84.             begin
  85.                 list := false;
  86.                 endofline
  87.             end
  88.     end; (*programme*)
  89.  
  90.  
  91.     procedure stdnames;
  92.     begin
  93.         na[1] := 'false   ';
  94.         na[2] := 'true    ';
  95.         na[3] := 'input   ';
  96.         na[4] := 'output  ';
  97.         na[5] := 'get     ';
  98.         na[6] := 'put     ';
  99.         na[7] := 'reset   ';
  100.         na[8] := 'rewrite ';
  101.         na[9] := 'read    ';
  102.         na[10] := 'write   ';
  103.         na[11] := 'pack    ';
  104.         na[12] := 'unpack  ';
  105.         na[13] := 'new     ';
  106.         na[14] := 'release ';
  107.         na[15] := 'readln  ';
  108.         na[16] := 'writeln ';
  109.         na[17] := 'abs     ';
  110.         na[18] := 'sqr     ';
  111.         na[19] := 'trunc   ';
  112.         na[20] := 'odd     ';
  113.         na[21] := 'ord     ';
  114.         na[22] := 'chr     ';
  115.         na[23] := 'pred    ';
  116.         na[24] := 'succ    ';
  117.         na[25] := 'eof     ';
  118.         na[26] := 'eoln    ';
  119.         na[27] := 'sin     ';
  120.         na[28] := 'cos     ';
  121.         na[29] := 'exp     ';
  122.         na[30] := 'sqrt    ';
  123.         na[31] := 'ln      ';
  124.         na[32] := 'arctan  ';
  125.         na[33] := 'prd     ';
  126.         na[34] := 'prr     ';
  127.         na[35] := 'mark    ';
  128.     end; (*stdnames*)
  129.  
  130.     procedure enterstdtypes;
  131.  
  132.     begin                         (*type underlying:*)
  133.                             (******************)
  134.  
  135.         new(intptr, scalar, standard);                  (*integer*)
  136.         with intptr^ do
  137.             begin
  138.                 size := intsize;
  139.                 form := scalar;
  140.                 scalkind := standard
  141.             end;
  142.         new(realptr, scalar, standard);                 (*real*)
  143.         with realptr^ do
  144.             begin
  145.                 size := realsize;
  146.                 form := scalar;
  147.                 scalkind := standard
  148.             end;
  149.         new(charptr, scalar, standard);                 (*char*)
  150.         with charptr^ do
  151.             begin
  152.                 size := charsize;
  153.                 form := scalar;
  154.                 scalkind := standard
  155.             end;
  156.         new(boolptr, scalar, declared);                 (*boolean*)
  157.         with boolptr^ do
  158.             begin
  159.                 size := boolsize;
  160.                 form := scalar;
  161.                 scalkind := declared
  162.             end;
  163.         new(nilptr, pointer);                      (*nil*)
  164.         with nilptr^ do
  165.             begin
  166.                 eltype := nil;
  167.                 size := ptrsize;
  168.                 form := pointer
  169.             end;
  170.         new(parmptr, scalar, standard); (*for alignment of parameters*)
  171.         with parmptr^ do
  172.             begin
  173.                 size := parmsize;
  174.                 form := scalar;
  175.                 scalkind := standard
  176.             end;
  177.         new(textptr, files);                       (*text*)
  178.         with textptr^ do
  179.             begin
  180.                 filtype := charptr;
  181.                 size := charsize;
  182.                 form := files
  183.             end
  184.     end; (*enterstdtypes*)
  185.  
  186.     procedure entstdnames;
  187.         var
  188.             cp, cp1: ctp;
  189.             i: integer;
  190.     begin                               (*name:*)
  191.                                   (*******)
  192.  
  193.         new(cp, types);                        (*integer*)
  194.         with cp^ do
  195.             begin
  196.                 name := 'integer ';
  197.                 idtype := intptr;
  198.                 klass := types
  199.             end;
  200.         enterid(cp);
  201.         new(cp, types);                        (*real*)
  202.         with cp^ do
  203.             begin
  204.                 name := 'real    ';
  205.                 idtype := realptr;
  206.                 klass := types
  207.             end;
  208.         enterid(cp);
  209.         new(cp, types);                        (*char*)
  210.         with cp^ do
  211.             begin
  212.                 name := 'char    ';
  213.                 idtype := charptr;
  214.                 klass := types
  215.             end;
  216.         enterid(cp);
  217.         new(cp, types);                        (*boolean*)
  218.         with cp^ do
  219.             begin
  220.                 name := 'boolean ';
  221.                 idtype := boolptr;
  222.                 klass := types
  223.             end;
  224.         enterid(cp);
  225.         cp1 := nil;
  226.         for i := 1 to 2 do
  227.             begin
  228.                 new(cp, konst);                    (*false,true*)
  229.                 with cp^ do
  230.                     begin
  231.                         name := na[i];
  232.                         idtype := boolptr;
  233.                         next := cp1;
  234.                         values.ival := i - 1;
  235.                         klass := konst
  236.                     end;
  237.                 enterid(cp);
  238.                 cp1 := cp
  239.             end;
  240.         boolptr^.fconst := cp;
  241.         new(cp, konst);                        (*nil*)
  242.         with cp^ do
  243.             begin
  244.                 name := 'nil     ';
  245.                 idtype := nilptr;
  246.                 next := nil;
  247.                 values.ival := 0;
  248.                 klass := konst
  249.             end;
  250.         enterid(cp);
  251.         for i := 3 to 4 do
  252.             begin
  253.                 new(cp, vars);                     (*input,output*)
  254.                 with cp^ do
  255.                     begin
  256.                         name := na[i];
  257.                         idtype := textptr;
  258.                         klass := vars;
  259.                         vkind := actual;
  260.                         next := nil;
  261.                         vlev := 1;
  262.                         vaddr := lcaftermarkstack + (i - 3) * charmax;
  263.                     end;
  264.                 enterid(cp)
  265.             end;
  266.         for i := 33 to 34 do
  267.             begin
  268.                 new(cp, vars);                     (*prd,prr files*)
  269.                 with cp^ do
  270.                     begin
  271.                         name := na[i];
  272.                         idtype := textptr;
  273.                         klass := vars;
  274.                         vkind := actual;
  275.                         next := nil;
  276.                         vlev := 1;
  277.                         vaddr := lcaftermarkstack + (i - 31) * charmax;
  278.                     end;
  279.                 enterid(cp)
  280.             end;
  281.         for i := 5 to 16 do
  282.             begin
  283.                 new(cp, proc, standard);                (*get,put,reset*)
  284.                 with cp^ do                       (*rewrite,read*)
  285.                     begin
  286.                         name := na[i];
  287.                         idtype := nil;         (*write,pack*)
  288.                         next := nil;
  289.                         key := i - 4;            (*unpack,pack*)
  290.                         klass := proc;
  291.                         pfdeckind := standard
  292.                     end;
  293.                 enterid(cp)
  294.             end;
  295.         new(cp, proc, standard);
  296.         with cp^ do
  297.             begin
  298.                 name := na[35];
  299.                 idtype := nil;
  300.                 next := nil;
  301.                 key := 13;
  302.                 klass := proc;
  303.                 pfdeckind := standard
  304.             end;
  305.         enterid(cp);
  306.         for i := 17 to 26 do
  307.             begin
  308.                 new(cp, func, standard);                (*abs,sqr,trunc*)
  309.                 with cp^ do                       (*odd,ord,chr*)
  310.                     begin
  311.                         name := na[i];
  312.                         idtype := nil;         (*pred,succ,eof*)
  313.                         next := nil;
  314.                         key := i - 16;
  315.                         klass := func;
  316.                         pfdeckind := standard
  317.                     end;
  318.                 enterid(cp)
  319.             end;
  320.         new(cp, vars);              (*parameter of predeclared functions*)
  321.         with cp^ do
  322.             begin
  323.                 name := '        ';
  324.                 idtype := realptr;
  325.                 klass := vars;
  326.                 vkind := actual;
  327.                 next := nil;
  328.                 vlev := 1;
  329.                 vaddr := 0
  330.             end;
  331.         for i := 27 to 32 do
  332.             begin
  333.                 new(cp1, func, declared, actual);            (*sin,cos,exp*)
  334.                 with cp1^ do                      (*sqrt,ln,arctan*)
  335.                     begin
  336.                         name := na[i];
  337.                         idtype := realptr;
  338.                         next := cp;
  339.                         forwdecl := false;
  340.                         externl := true;
  341.                         pflev := 0;
  342.                         pfname := i - 12;
  343.                         klass := func;
  344.                         pfdeckind := declared;
  345.                         pfkind := actual
  346.                     end;
  347.                 enterid(cp1)
  348.             end
  349.     end; (*entstdnames*)
  350.  
  351.     procedure enterundecl;
  352.         var
  353.             temp: integer;
  354.     begin
  355.         new(utypptr, types);
  356.         with utypptr^ do
  357.             begin
  358.                 name := '        ';
  359.                 idtype := nil;
  360.                 klass := types
  361.             end;
  362.         new(ucstptr, konst);
  363.         with ucstptr^ do
  364.             begin
  365.                 name := '        ';
  366.                 idtype := nil;
  367.                 next := nil;
  368.                 values.ival := 0;
  369.                 klass := konst
  370.             end;
  371.         new(uvarptr, vars);
  372.         with uvarptr^ do
  373.             begin
  374.                 name := '        ';
  375.                 idtype := nil;
  376.                 vkind := actual;
  377.                 next := nil;
  378.                 vlev := 0;
  379.                 vaddr := 0;
  380.                 klass := vars
  381.             end;
  382.         new(ufldptr, field);
  383.         with ufldptr^ do
  384.             begin
  385.                 name := '        ';
  386.                 idtype := nil;
  387.                 next := nil;
  388.                 fldaddr := 0;
  389.                 klass := field
  390.             end;
  391.         new(uprcptr, proc, declared, actual);
  392.         with uprcptr^ do
  393.             begin
  394.                 name := '        ';
  395.                 idtype := nil;
  396.                 forwdecl := false;
  397.                 next := nil;
  398.                 externl := false;
  399.                 pflev := 0;
  400.  
  401. {Think Pascal won't pass a component of a packed record as var parameter!}
  402. {genlabel(pfname);}
  403.                 temp := pfname; {FIX}
  404.                 genlabel(temp); {FIX}
  405.                 pfname := temp; {FIX}
  406.  
  407.                 klass := proc;
  408.                 pfdeckind := declared;
  409.                 pfkind := actual
  410.             end;
  411.         new(ufctptr, func, declared, actual);
  412.         with ufctptr^ do
  413.             begin
  414.                 name := '        ';
  415.                 idtype := nil;
  416.                 next := nil;
  417.                 forwdecl := false;
  418.                 externl := false;
  419.                 pflev := 0;
  420.  
  421. {Think Pascal won't pass a component of a packed record as var parameter!}
  422. {genlabel(pfname);}
  423.                 temp := pfname; {FIX}
  424.                 genlabel(temp); {FIX}
  425.                 pfname := temp; {FIX}
  426.  
  427.                 klass := func;
  428.                 pfdeckind := declared;
  429.                 pfkind := actual
  430.             end
  431.     end; (*enterundecl*)
  432.  
  433.     procedure initscalars;
  434.     begin
  435.         fwptr := nil;
  436.         prtables := false;
  437.         list := true;
  438.         prcode := true;
  439.         debug := true;
  440.         dp := true;
  441.         prterr := true;
  442.         errinx := 0;
  443.         intlabel := 0;
  444.         kk := 8;
  445.         fextfilep := nil;
  446.         lc := lcaftermarkstack + filebuffer * charmax;
  447.     (* note in the above reservation of buffer store for 2 text files *)
  448.         ic := 3;
  449.         eol := true;
  450.         linecount := 0;
  451.         ch := ' ';
  452.         chcnt := 0;
  453.         globtestp := nil;
  454.         mxint10 := maxint div 10;
  455.         digmax := strglgth - 1;
  456.     end; (*initscalars*)
  457.  
  458.     procedure initsets;
  459.     begin
  460.         constbegsys := [addop, intconst, realconst, stringconst, ident];
  461.         simptypebegsys := [lparent] + constbegsys;
  462.         typebegsys := [arrow, packedsy, arraysy, recordsy, setsy, filesy] + simptypebegsys;
  463.         typedels := [arraysy, recordsy, setsy, filesy];
  464.         blockbegsys := [labelsy, constsy, typesy, varsy, procsy, funcsy, beginsy];
  465.         selectsys := [arrow, period, lbrack];
  466.         facbegsys := [intconst, realconst, stringconst, ident, lparent, lbrack, notsy];
  467.         statbegsys := [beginsy, gotosy, ifsy, whilesy, repeatsy, forsy, withsy, casesy];
  468.     end; (*initsets*)
  469.  
  470.     procedure inittables;
  471.         procedure reswords;
  472.         begin
  473.             rw[1] := 'if      ';
  474.             rw[2] := 'do      ';
  475.             rw[3] := 'of      ';
  476.             rw[4] := 'to      ';
  477.             rw[5] := 'in      ';
  478.             rw[6] := 'or      ';
  479.             rw[7] := 'end     ';
  480.             rw[8] := 'for     ';
  481.             rw[9] := 'var     ';
  482.             rw[10] := 'div     ';
  483.             rw[11] := 'mod     ';
  484.             rw[12] := 'set     ';
  485.             rw[13] := 'and     ';
  486.             rw[14] := 'not     ';
  487.             rw[15] := 'then    ';
  488.             rw[16] := 'else    ';
  489.             rw[17] := 'with    ';
  490.             rw[18] := 'goto    ';
  491.             rw[19] := 'case    ';
  492.             rw[20] := 'type    ';
  493.             rw[21] := 'file    ';
  494.             rw[22] := 'begin   ';
  495.             rw[23] := 'until   ';
  496.             rw[24] := 'while   ';
  497.             rw[25] := 'array   ';
  498.             rw[26] := 'const   ';
  499.             rw[27] := 'label   ';
  500.             rw[28] := 'repeat  ';
  501.             rw[29] := 'record  ';
  502.             rw[30] := 'downto  ';
  503.             rw[31] := 'packed  ';
  504.             rw[32] := 'forward ';
  505.             rw[33] := 'program ';
  506.             rw[34] := 'function';
  507.             rw[35] := 'procedur';
  508.             frw[1] := 1;
  509.             frw[2] := 1;
  510.             frw[3] := 7;
  511.             frw[4] := 15;
  512.             frw[5] := 22;
  513.             frw[6] := 28;
  514.             frw[7] := 32;
  515.             frw[8] := 34;
  516.             frw[9] := 36;
  517.         end; (*reswords*)
  518.  
  519.         procedure symbols;
  520.         begin
  521.             rsy[1] := ifsy;
  522.             rsy[2] := dosy;
  523.             rsy[3] := ofsy;
  524.             rsy[4] := tosy;
  525.             rsy[5] := relop;
  526.             rsy[6] := addop;
  527.             rsy[7] := endsy;
  528.             rsy[8] := forsy;
  529.             rsy[9] := varsy;
  530.             rsy[10] := mulop;
  531.             rsy[11] := mulop;
  532.             rsy[12] := setsy;
  533.             rsy[13] := mulop;
  534.             rsy[14] := notsy;
  535.             rsy[15] := thensy;
  536.             rsy[16] := elsesy;
  537.             rsy[17] := withsy;
  538.             rsy[18] := gotosy;
  539.             rsy[19] := casesy;
  540.             rsy[20] := typesy;
  541.             rsy[21] := filesy;
  542.             rsy[22] := beginsy;
  543.             rsy[23] := untilsy;
  544.             rsy[24] := whilesy;
  545.             rsy[25] := arraysy;
  546.             rsy[26] := constsy;
  547.             rsy[27] := labelsy;
  548.             rsy[28] := repeatsy;
  549.             rsy[29] := recordsy;
  550.             rsy[30] := downtosy;
  551.             rsy[31] := packedsy;
  552.             rsy[32] := forwardsy;
  553.             rsy[33] := progsy;
  554.             rsy[34] := funcsy;
  555.             rsy[35] := procsy;
  556.             ssy['+'] := addop;
  557.             ssy['-'] := addop;
  558.             ssy['*'] := mulop;
  559.             ssy['/'] := mulop;
  560.             ssy['('] := lparent;
  561.             ssy[')'] := rparent;
  562.             ssy['$'] := othersy;
  563.             ssy['='] := relop;
  564.             ssy[' '] := othersy;
  565.             ssy[','] := comma;
  566.             ssy['.'] := period;
  567.             ssy[''''] := othersy;
  568.             ssy['['] := lbrack;
  569.             ssy[']'] := rbrack;
  570.             ssy[':'] := colon;
  571.             ssy['^'] := arrow;
  572.             ssy['<'] := relop;
  573.             ssy['>'] := relop;
  574.             ssy[';'] := semicolon;
  575.         end; (*symbols*)
  576.  
  577.         procedure rators;
  578.             var
  579.                 i: integer;
  580.         begin
  581.             for i := 1 to 35 do (*nr of res words*)
  582.                 rop[i] := noop;
  583.             rop[5] := inop;
  584.             rop[10] := idiv;
  585.             rop[11] := imod;
  586.             rop[6] := orop;
  587.             rop[13] := andop;
  588.             for i := ordminchar to ordmaxchar do
  589.                 sop[chr(i)] := noop;
  590.             sop['+'] := plus;
  591.             sop['-'] := minus;
  592.             sop['*'] := mul;
  593.             sop['/'] := rdiv;
  594.             sop['='] := eqop;
  595.             sop['<'] := ltop;
  596.             sop['>'] := gtop;
  597.         end; (*rators*)
  598.  
  599.         procedure procmnemonics;
  600.         begin
  601.             sna[1] := ' get';
  602.             sna[2] := ' put';
  603.             sna[3] := ' rdi';
  604.             sna[4] := ' rdr';
  605.             sna[5] := ' rdc';
  606.             sna[6] := ' wri';
  607.             sna[7] := ' wro';
  608.             sna[8] := ' wrr';
  609.             sna[9] := ' wrc';
  610.             sna[10] := ' wrs';
  611.             sna[11] := ' pak';
  612.             sna[12] := ' new';
  613.             sna[13] := ' rst';
  614.             sna[14] := ' eln';
  615.             sna[15] := ' sin';
  616.             sna[16] := ' cos';
  617.             sna[17] := ' exp';
  618.             sna[18] := ' sqt';
  619.             sna[19] := ' log';
  620.             sna[20] := ' atn';
  621.             sna[21] := ' rln';
  622.             sna[22] := ' wln';
  623.             sna[23] := ' sav';
  624.         end; (*procmnemonics*)
  625.  
  626.         procedure instrmnemonics;
  627.         begin
  628.             mn[0] := ' abi';
  629.             mn[1] := ' abr';
  630.             mn[2] := ' adi';
  631.             mn[3] := ' adr';
  632.             mn[4] := ' and';
  633.             mn[5] := ' dif';
  634.             mn[6] := ' dvi';
  635.             mn[7] := ' dvr';
  636.             mn[8] := ' eof';
  637.             mn[9] := ' flo';
  638.             mn[10] := ' flt';
  639.             mn[11] := ' inn';
  640.             mn[12] := ' int';
  641.             mn[13] := ' ior';
  642.             mn[14] := ' mod';
  643.             mn[15] := ' mpi';
  644.             mn[16] := ' mpr';
  645.             mn[17] := ' ngi';
  646.             mn[18] := ' ngr';
  647.             mn[19] := ' not';
  648.             mn[20] := ' odd';
  649.             mn[21] := ' sbi';
  650.             mn[22] := ' sbr';
  651.             mn[23] := ' sgs';
  652.             mn[24] := ' sqi';
  653.             mn[25] := ' sqr';
  654.             mn[26] := ' sto';
  655.             mn[27] := ' trc';
  656.             mn[28] := ' uni';
  657.             mn[29] := ' stp';
  658.             mn[30] := ' csp';
  659.             mn[31] := ' dec';
  660.             mn[32] := ' ent';
  661.             mn[33] := ' fjp';
  662.             mn[34] := ' inc';
  663.             mn[35] := ' ind';
  664.             mn[36] := ' ixa';
  665.             mn[37] := ' lao';
  666.             mn[38] := ' lca';
  667.             mn[39] := ' ldo';
  668.             mn[40] := ' mov';
  669.             mn[41] := ' mst';
  670.             mn[42] := ' ret';
  671.             mn[43] := ' sro';
  672.             mn[44] := ' xjp';
  673.             mn[45] := ' chk';
  674.             mn[46] := ' cup';
  675.             mn[47] := ' equ';
  676.             mn[48] := ' geq';
  677.             mn[49] := ' grt';
  678.             mn[50] := ' lda';
  679.             mn[51] := ' ldc';
  680.             mn[52] := ' leq';
  681.             mn[53] := ' les';
  682.             mn[54] := ' lod';
  683.             mn[55] := ' neq';
  684.             mn[56] := ' str';
  685.             mn[57] := ' ujp';
  686.             mn[58] := ' ord';
  687.             mn[59] := ' chr';
  688.             mn[60] := ' ujc';
  689.         end; (*instrmnemonics*)
  690.  
  691.         procedure chartypes;
  692.             var
  693.                 i: integer;
  694.         begin
  695.             for i := ordminchar to ordmaxchar do
  696.                 chartp[chr(i)] := illegal;
  697.             chartp['a'] := letter;
  698.             chartp['b'] := letter;
  699.             chartp['c'] := letter;
  700.             chartp['d'] := letter;
  701.             chartp['e'] := letter;
  702.             chartp['f'] := letter;
  703.             chartp['g'] := letter;
  704.             chartp['h'] := letter;
  705.             chartp['i'] := letter;
  706.             chartp['j'] := letter;
  707.             chartp['k'] := letter;
  708.             chartp['l'] := letter;
  709.             chartp['m'] := letter;
  710.             chartp['n'] := letter;
  711.             chartp['o'] := letter;
  712.             chartp['p'] := letter;
  713.             chartp['q'] := letter;
  714.             chartp['r'] := letter;
  715.             chartp['s'] := letter;
  716.             chartp['t'] := letter;
  717.             chartp['u'] := letter;
  718.             chartp['v'] := letter;
  719.             chartp['w'] := letter;
  720.             chartp['x'] := letter;
  721.             chartp['y'] := letter;
  722.             chartp['z'] := letter;
  723.             chartp['0'] := number;
  724.             chartp['1'] := number;
  725.             chartp['2'] := number;
  726.             chartp['3'] := number;
  727.             chartp['4'] := number;
  728.             chartp['5'] := number;
  729.             chartp['6'] := number;
  730.             chartp['7'] := number;
  731.             chartp['8'] := number;
  732.             chartp['9'] := number;
  733.             chartp['+'] := special;
  734.             chartp['-'] := special;
  735.             chartp['*'] := special;
  736.             chartp['/'] := special;
  737.             chartp['('] := chlparen;
  738.             chartp[')'] := special;
  739.             chartp['$'] := special;
  740.             chartp['='] := special;
  741.             chartp[' '] := chspace;
  742.             chartp[','] := special;
  743.             chartp['.'] := chperiod;
  744.             chartp[''''] := chstrquo;
  745.             chartp['['] := special;
  746.             chartp[']'] := special;
  747.             chartp[':'] := chcolon;
  748.             chartp['^'] := special;
  749.             chartp[';'] := special;
  750.             chartp['<'] := chlt;
  751.             chartp['>'] := chgt;
  752.             ordint['0'] := 0;
  753.             ordint['1'] := 1;
  754.             ordint['2'] := 2;
  755.             ordint['3'] := 3;
  756.             ordint['4'] := 4;
  757.             ordint['5'] := 5;
  758.             ordint['6'] := 6;
  759.             ordint['7'] := 7;
  760.             ordint['8'] := 8;
  761.             ordint['9'] := 9;
  762.         end;
  763.  
  764.         procedure initdx;
  765.         begin
  766.             cdx[0] := 0;
  767.             cdx[1] := 0;
  768.             cdx[2] := -1;
  769.             cdx[3] := -1;
  770.             cdx[4] := -1;
  771.             cdx[5] := -1;
  772.             cdx[6] := -1;
  773.             cdx[7] := -1;
  774.             cdx[8] := 0;
  775.             cdx[9] := 0;
  776.             cdx[10] := 0;
  777.             cdx[11] := -1;
  778.             cdx[12] := -1;
  779.             cdx[13] := -1;
  780.             cdx[14] := -1;
  781.             cdx[15] := -1;
  782.             cdx[16] := -1;
  783.             cdx[17] := 0;
  784.             cdx[18] := 0;
  785.             cdx[19] := 0;
  786.             cdx[20] := 0;
  787.             cdx[21] := -1;
  788.             cdx[22] := -1;
  789.             cdx[23] := 0;
  790.             cdx[24] := 0;
  791.             cdx[25] := 0;
  792.             cdx[26] := -2;
  793.             cdx[27] := 0;
  794.             cdx[28] := -1;
  795.             cdx[29] := 0;
  796.             cdx[30] := 0;
  797.             cdx[31] := 0;
  798.             cdx[32] := 0;
  799.             cdx[33] := -1;
  800.             cdx[34] := 0;
  801.             cdx[35] := 0;
  802.             cdx[36] := -1;
  803.             cdx[37] := +1;
  804.             cdx[38] := +1;
  805.             cdx[39] := +1;
  806.             cdx[40] := -2;
  807.             cdx[41] := 0;
  808.             cdx[42] := 0;
  809.             cdx[43] := -1;
  810.             cdx[44] := -1;
  811.             cdx[45] := 0;
  812.             cdx[46] := 0;
  813.             cdx[47] := -1;
  814.             cdx[48] := -1;
  815.             cdx[49] := -1;
  816.             cdx[50] := +1;
  817.             cdx[51] := +1;
  818.             cdx[52] := -1;
  819.             cdx[53] := -1;
  820.             cdx[54] := +1;
  821.             cdx[55] := -1;
  822.             cdx[56] := -1;
  823.             cdx[57] := 0;
  824.             cdx[58] := 0;
  825.             cdx[59] := 0;
  826.             cdx[60] := 0;
  827.             pdx[1] := -1;
  828.             pdx[2] := -1;
  829.             pdx[3] := -2;
  830.             pdx[4] := -2;
  831.             pdx[5] := -2;
  832.             pdx[6] := -3;
  833.             pdx[7] := -3;
  834.             pdx[8] := -3;
  835.             pdx[9] := -3;
  836.             pdx[10] := -4;
  837.             pdx[11] := 0;
  838.             pdx[12] := -2;
  839.             pdx[13] := -1;
  840.             pdx[14] := 0;
  841.             pdx[15] := 0;
  842.             pdx[16] := 0;
  843.             pdx[17] := 0;
  844.             pdx[18] := 0;
  845.             pdx[19] := 0;
  846.             pdx[20] := 0;
  847.             pdx[21] := -1;
  848.             pdx[22] := -1;
  849.             pdx[23] := -1;
  850.         end;
  851.  
  852.     begin (*inittables*)
  853.         reswords;
  854.         symbols;
  855.         rators;
  856.         instrmnemonics;
  857.         procmnemonics;
  858.         chartypes;
  859.         initdx;
  860.     end; (*inittables*)
  861.  
  862.     function GetInFile: Str255;
  863.         var
  864.             message, count: Integer;
  865.             theAppFile: AppFile;
  866.     begin
  867.         CountAppFiles(message, count);
  868.         if count > 0 then
  869.             begin
  870.                 GetAppFiles(1, theAppFile);
  871.                 if SetVol(nil, theAppFile.vRefNum) <> noErr then
  872.                     ; {We ignore errors for now}
  873.                 GetInFile := theAppFile.fname;
  874.             end
  875.         else
  876.             begin
  877.                 GetInFile := OldFileName('');
  878.             end;
  879.     end;
  880.  
  881. {We can't use NewFileName, since we want a default file name.}
  882.     function GetOutFile (prompt, default: Str255): Str255;
  883.         var
  884.             reply: SFReply;
  885.     begin
  886.         SFPutFile(Point($00800080), prompt, default, nil, reply);
  887.         if reply.good then
  888.             begin
  889.                 if SetVol(nil, reply.vRefNum) <> noErr then
  890.                     ; {We ignore errors for now}
  891.                 GetOutFile := reply.fName;
  892.             end
  893.         else
  894.             GetOutFile := '';
  895.     end;
  896.  
  897. {For Stdfile-dialogs:}
  898.     var
  899.         oldFile, newFile: Str255;
  900.         theTextRect: Rect;
  901.         i: integer;
  902. begin
  903.     theTextRect := screenBits.bounds;
  904.     theTextRect.top := theTextRect.top + 40; {For menu bar and window top}
  905.     InsetRect(theTextRect, 10, 10);
  906.     SetTextRect(theTextRect);
  907.     ShowText;
  908.     Writeln('Welcome to the P4Mac p-code compiler!');
  909.     Writeln('This program is based on the Public Domain compiler P4.');
  910.     Writeln('Quick port for the Mac by Ingemar Ragnemalm - and don''t ask me why.');
  911.  
  912.     close(input);
  913.     oldFile := GetInFile;
  914.     reset(input, oldFile);
  915.  
  916.   (*initialize*)
  917.   (************)
  918.     initscalars;
  919.     initsets;
  920.     inittables;
  921.  
  922.  
  923.   (*enter standard names and standard types:*)
  924.   (******************************************)
  925.     level := 0;
  926.     top := 0;
  927.     with display[0] do
  928.         begin
  929.             fname := nil;
  930.             flabel := nil;
  931.             occur := blck
  932.         end;
  933.     enterstdtypes;
  934.     stdnames;
  935.     entstdnames;
  936.     enterundecl;
  937.     top := 1;
  938.     level := 1;
  939.     with display[1] do
  940.         begin
  941.             fname := nil;
  942.             flabel := nil;
  943.             occur := blck
  944.         end;
  945.  
  946.  
  947. {default = string between LAST ":" and LAST ".", plus ".pcode"}
  948.     i := length(oldFile) + 1;
  949.     repeat
  950.         i := i - 1;
  951.     until (i < 2) or (oldFile[i] = '.') or (oldFile[i] = ':');
  952.     if i > 1 then
  953.         if oldFile[i] = '.' then
  954.             delete(oldFile, i, length(oldFile) - i + 1);
  955.     repeat
  956.         i := i - 1
  957.     until (i < 2) or (oldFile[i] = ':');
  958.     if i > 1 then
  959.         if oldFile[i] = ':' then
  960.             delete(oldFile, 1, i);
  961.  
  962.     oldFile := concat(oldFile, '.pcode');
  963.     newFile := GetOutFile('Output file?', oldFile);
  964.     if newFile = '' then
  965.         halt;
  966. (*compile:*)
  967.     rewrite(prr, newFile); (*comment this out when compiling with pcom *)
  968.   (**********)
  969.     insymbol;
  970.     programme(blockbegsys + statbegsys - [casesy]);
  971.  
  972.     writeln('Done! Click mouse to exit.');
  973.     while not Button do
  974.         ;
  975. end.