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