home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 25 / nopv25.iso / 040A / CCDL151S.ZIP / SOURCE / PHITEXT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-10  |  10.6 KB  |  489 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. /*
  23.  * This module is the phi-text interface for the compiler.  Files are
  24.  * orignilly read in as shorts to accomdate phi-text.
  25.  */
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <memory.h>
  29. #include <ctype.h>
  30. #include "utype.h"
  31. #include "interp.h"
  32.  
  33. extern BYTE startchars[];
  34. extern BYTE symchars[];
  35. extern BYTE whitespacechars[];
  36. extern BYTE commentchars[];
  37.  
  38. PHITEXT phiparms = { 4,0,0x0f,0,0,0,0x7f };
  39. BOOL phiused = FALSE;
  40. BOOL putback = FALSE;
  41.  
  42. int currentphifg = 0;
  43.  
  44. static PHITEXT phidefaults = { 4,0,0x0f,0,0,0,0x7f };
  45. static int pbchar = 0;
  46.  
  47. int repeat = 0;
  48.  
  49. void PhiInit(void)
  50. {
  51.     phiparms = phidefaults;
  52.     putback = FALSE;
  53.     phiused = FALSE;
  54.     currentphifg = phidefaults.fgc;
  55. }
  56. void BadString(void)
  57. {
  58.     Error("Bad escape sequence in string");
  59. }
  60. /* Get a char from file */
  61. static BOOL phichar(BYTE *ch, FILE *file)
  62. {
  63.     while (TRUE) {
  64.         *ch = fgetc(file);
  65.         if (feof(file))
  66.             return(FALSE);
  67.         if (*ch == 0x1f) {
  68.             phiused = TRUE;
  69.             continue;
  70.         }
  71.         break;
  72.     }
  73.     return(TRUE);        
  74. }
  75. /*
  76.  * Get a line from the file.  At this point the line is still streamed
  77.  * phi-text
  78.  */
  79. BOOL philine(BYTE *buf, int len, FILE *file)
  80. {
  81.     if (len < 2 || !phichar(buf,file)) {
  82.         *buf = 0;
  83.         return(FALSE);
  84.     }
  85.     while (len>2) {
  86.         if (*buf == 0x0a || (phiused && (*buf == 0x14 || *buf == 0x15 || *buf == 0x16)))
  87.             break;
  88.         if (!phichar(++buf,file))
  89.             break;
  90.         len--;
  91.     }
  92.     *buf++ =0x0a;
  93.     *buf++ = 0;
  94.     return(TRUE);
  95. }
  96. /*
  97.  * Parse the phi-text stream and get the next character.  Attributes are
  98.  * stripped at this stage so all we get is the bank and char info
  99.  */
  100. short parsechar(BYTE **buf)
  101. {
  102.     short rv;
  103.     if (putback) {
  104.         (*buf)++;
  105.         putback = FALSE;
  106.         return(pbchar);
  107.     }
  108.     if (!phiused)
  109.         return(*(*buf)++);
  110.     while (TRUE) {
  111.         if (repeat) {
  112.             repeat--;
  113.             rv = phiparms.cwb + (phiparms.bank << 7);
  114.             break;
  115.         }
  116.         rv = *(*buf)++;
  117.         if (rv & 0x80) {
  118.             char grp = rv & 0x70;
  119.             switch (grp) {
  120.                 case 0: {
  121.                             int repeatlevel = 0;
  122.                             (*buf)--;
  123.                             while (((rv = **buf)& 0xf0) == 0x80) {
  124.                                 (*buf)++;
  125.                                 repeat += ((rv & 0x0f)<<(repeatlevel++ * 4)) +1;
  126.                             }
  127.                             repeat++;
  128.                         }
  129.                         break;
  130.                 case 0x10:
  131.                         phiparms.bank = rv & 0x0f;
  132.                         break;
  133.                 case 0x20:
  134.                 case 0x30:
  135.                         phiparms.attrib = rv & 0x1f;
  136.                         break;
  137.                 case 0x40:
  138.                         phiparms.fgc = rv & 0x0f;
  139.                         break;
  140.                 case 0x50:
  141.                         phiparms.bgc = rv & 0x0f;
  142.                         break;
  143.                 case 0x60:
  144.                         phiparms.style = rv & 0x0f;
  145.                         break;
  146.                 case 0x70:
  147.                         phiparms.size = rv & 0x0f;
  148.                         break;
  149.             }
  150.         }
  151.         else {
  152.             if (rv)
  153.                 phiparms.cwb = rv;
  154.             if (rv & 0x60) {
  155.                 if (phiparms.attrib & HIDDEN || phiparms.style)
  156.                     continue;
  157.                 rv = rv + (phiparms.bank << 7);
  158.             }
  159.             else
  160.                 if (rv == 0x0a)
  161.                     phiparms = phidefaults;
  162.             break;
  163.         }
  164.     }
  165.     return(rv);
  166. }
  167. /*
  168.  * In case we have to step back one char
  169.  */
  170. void putphiback(short ch)
  171. {
  172.     putback = TRUE;
  173.     pbchar = ch;
  174. }
  175. /* The next few routines check for specific symbol types, sort of analogous
  176.  * to the ctype library
  177.  */
  178. BOOL isstartchar(short val)
  179. {
  180.     int bit = 1 << (7 - (val & 0x07));
  181.     int byte = val >> 3;
  182.     return (startchars[byte] & bit);
  183. }
  184. BOOL issymchar(short val)
  185. {
  186.     int bit = 1 << (7 - (val & 0x07));
  187.     int byte = val >> 3;
  188.     return (symchars[byte] & bit);
  189. }
  190. BOOL iswhitespacechar(short val)
  191. {
  192.     int bit = 1 << (7 - (val & 0x07));
  193.     int byte = val >> 3;
  194.     return (whitespacechars[byte] & bit);
  195. }
  196. BOOL iscommentchar(short val)
  197. {
  198.     int bit = 1 << (7 - (val & 0x07));
  199.     int byte = val >> 3;
  200.     return (commentchars[byte] & bit);
  201. }
  202. /* These reads in a char for a C style string lit */
  203. static BYTE *getstringchar(BYTE *rv,BYTE *bufptr)
  204. {
  205.     putback = FALSE;
  206.     if (phiused) {
  207.         if (repeat) {
  208.             repeat--;
  209.             *rv = phiparms.cwb;
  210.             return(bufptr);
  211.         }
  212.         if ((*bufptr > 0x7f) || phiparms.bank) {
  213.             *rv = *bufptr;
  214.             if (*rv & 0x80) {
  215.                 char grp = *rv & 0x70;
  216.                 switch (grp) {
  217.                     case 0:
  218.                             break;
  219.                     case 0x10:
  220.                             phiparms.bank = *rv & 0x0f;
  221.                             break;
  222.                     case 0x20:
  223.                     case 0x30:
  224.                             phiparms.attrib = *rv & 0x1f;
  225.                             break;
  226.                     case 0x40:
  227.                             phiparms.fgc = *rv & 0x0f;
  228.                             break;
  229.                     case 0x50:
  230.                             phiparms.bgc = *rv & 0x0f;
  231.                             break;
  232.                     case 0x60:
  233.                             phiparms.style = *rv & 0x0f;
  234.                             break;
  235.                     case 0x70:
  236.                             phiparms.size = *rv & 0x0f;
  237.                             break;
  238.                 }
  239.             }
  240.             return(++bufptr);
  241.         }
  242.     }
  243.  
  244.             if (*bufptr == '\\') {
  245.                 bufptr++;
  246.                 if (isdigit(*bufptr) && (*bufptr < '8')) {
  247.                     unsigned temp = 0;
  248.                     while (isdigit(*bufptr) && *bufptr < '8')
  249.                         temp = (temp << 3) + (*bufptr++ - '0');
  250.                     if (temp > 255)
  251.                         BadString();
  252.                         
  253.                     *rv = (BYTE)temp;
  254.                 }
  255.                 else 
  256.                     switch(*bufptr++) {
  257.                         case 'b':
  258.                             *rv = 8;
  259.                             break;
  260.                         case 'f':
  261.                             *rv = 12;
  262.                             break;
  263.                         case 'n':
  264.                             *rv = 10;
  265.                             break;
  266.                         case 'r':
  267.                             *rv = 13;
  268.                             break;
  269.                         case 't':
  270.                             *rv = 9;
  271.                             break;
  272.                         case '\'':
  273.                             *rv = '\'';
  274.                             break;
  275.                         case '"':
  276.                             *rv = '"';
  277.                             break;
  278.                         case '\\':
  279.                             *rv = '\\';
  280.                             break;
  281.                         case 'x': {
  282.                             unsigned temp = 0;
  283.                             while (isxdigit(*bufptr)) {
  284.                                 temp = (temp << 4) + (*bufptr - '0');
  285.                               if (*bufptr++ > '9')
  286.                                     temp -= 7;
  287.                             }
  288.                             if (temp > 255)
  289.                                 BadString();
  290.                             *rv = (BYTE)temp;
  291.                         }
  292.                             break;
  293.                         default:
  294.                             BadString();
  295.                     }
  296.             }
  297.             else
  298.               *rv = *bufptr++;
  299.     return(bufptr);
  300. }
  301. /* This reads in a string lit */
  302. short getphistring(BYTE *obuf, BYTE **ibuf, short endchar)
  303. {
  304.     BYTE rv;
  305.     if (phiused) {
  306.         if (phidefaults.size != phiparms.size)
  307.             *obuf++ = 0xf0 | phiparms.size;
  308.         if (phidefaults.style != phiparms.style)
  309.             *obuf++ = 0xe0 | phiparms.style;
  310.         if (phidefaults.bgc != phiparms.bgc)
  311.             *obuf++ = 0xd0 | phiparms.bgc;
  312.         if (phidefaults.fgc != phiparms.fgc)
  313.             *obuf++ = 0xc0 | phiparms.fgc;
  314.         if (phidefaults.attrib != phiparms.attrib)
  315.             *obuf++ = 0xa0 | phiparms.attrib;
  316.         if (repeat) {
  317.             BadString();
  318.             repeat = 0;
  319.             return(endchar);
  320.         }
  321.     }
  322.     *ibuf = getstringchar(&rv,*ibuf);
  323.     while (rv && ((rv + (phiparms.bank << 7)) != endchar)) {
  324.         if (phiused && (rv <0x20)) {
  325.             if ((rv == 0x0a)) {
  326.                 while (((BYTE) *(obuf-1)) & 0x80)
  327.                     obuf--;
  328.             }
  329.         }
  330.         *obuf++ = rv;
  331.         if (phiused && (rv == 0x0a)) {
  332.             if (phidefaults.size != phiparms.size)
  333.                 *obuf++ = 0xf0 | phiparms.size;
  334.             if (phidefaults.style != phiparms.style)
  335.                 *obuf++ = 0xe0 | phiparms.style;
  336.             if (phidefaults.bgc != phiparms.bgc)
  337.                 *obuf++ = 0xd0 | phiparms.bgc;
  338.             if (phidefaults.fgc != phiparms.fgc)
  339.                 *obuf++ = 0xc0 | phiparms.fgc;
  340.             if (phidefaults.attrib != phiparms.attrib)
  341.                 *obuf++ = 0xa0 | phiparms.attrib;
  342.         }
  343.         *ibuf = getstringchar(&rv,*ibuf);
  344.     }
  345.     *obuf = 0;
  346.     phiparms.cwb = rv;
  347.     return(rv + (phiparms.bank << 7));
  348. }    
  349. /* This is for reading in phi-stream literal strings
  350.  */
  351. long getphichar(BYTE **ibuf)
  352. {
  353.     BYTE rv;
  354.     *ibuf = getstringchar(&rv,*ibuf);
  355.     if (!phiused)
  356.         return(rv);
  357.     while (rv & 0x80)
  358.         *ibuf = getstringchar(&rv,*ibuf);
  359.     if (!rv)
  360.         return(0);
  361.     phiparms.cwb = rv;
  362.     return(((long)phiparms.size << 28) + ((long)phiparms.style << 24) + ((long)phiparms.fgc << 20)
  363.                     + ((long)phiparms.bgc << 16) + ((long)phiparms.attrib << 11) + ((long)phiparms.bank << 7)
  364.                     + (rv & 0x7f));
  365. }
  366. /* The next one writes a color index to a streamed file */
  367. void phifg(int color, BYTE *file)
  368. {
  369.     currentphifg = color;
  370.     if (phiused)
  371.         fputc(color | 0xc0, file);
  372. }
  373. /* Now conver to upper case */
  374. short phiupper(short val)
  375. {
  376.     if (val > 0x60 && val < 0x7b)
  377.         return val &~0x20;
  378.     return(val);
  379. }
  380. /* Convert the short stream back to streamed one char at a time */
  381. int installphichar(short curchar, BYTE *buf, int i)
  382. {
  383.     short rv = 0;
  384.     int bank = curchar >> 7;
  385.     int cwb = curchar & 0x7f;
  386.     buf = buf+i;
  387.     if (!phiused) {
  388.         *buf = curchar;
  389.         return(1);
  390.     }
  391.     if (i) {
  392.         buf--;
  393.         if (((*buf) & 0xf0) == 0x90)
  394.             if ((*buf & 0x0f) != bank) {
  395.                 *buf++ = 0x90 | bank;
  396.             }
  397.             else
  398.                 rv--;
  399.         else {
  400.             buf++;    
  401.             if (bank) {
  402.                 *buf++ = 0x90 | bank;
  403.                 rv++;
  404.             }
  405.         }
  406.     }
  407.     else
  408.         if (bank) {
  409.             *buf++ = 0x90 | bank;
  410.             rv++;
  411.         }
  412.     *buf++ = cwb;
  413.     rv++;
  414.     if (bank) {
  415.         *buf++ = 0x90 | bank;
  416.         rv++;
  417.     }
  418.     return(rv);
  419. }
  420. /* Convert a stream to flats */
  421. short phistreamtoflat(BYTE *out, BYTE *in, int size, BOOL useparms)
  422. {
  423.     int count = 0,fcount;
  424.     long rv;
  425.     PHITEXT oparms = phiparms;
  426.     PHITEXT lastphiparms = phiparms;
  427.     int orepeat = repeat;
  428.  
  429.     if (!phiused) {
  430.         count = strlen(in);
  431.         strcpy(out,in);
  432.         return(count);
  433.     }
  434.     repeat = 0;
  435.     while (rv = parsechar(&in)) {
  436.         if ((rv > 0x1f) && useparms)
  437.             rv |= ((long)phiparms.attrib << 11) + ((long)phiparms.fgc << 16) + ((long)phiparms.bgc << 20)
  438.                         + ((long)phiparms.style << 24) + ((long)phiparms.size << 28);
  439.         if (rv == 0x0a || rv == 0x14 || rv == 0x15 || rv == 0x16)
  440.             phiparms = lastphiparms;
  441.         if (size > 2) {
  442.             out[count++] = rv >> 24;
  443.             out[count++] = (rv >>16) & 0xff;
  444.         }
  445.         if (size > 1)
  446.             out[count++] = (rv >>8) & 0xff;
  447.         out[count++] = (rv) & 0xff;
  448.         lastphiparms = phiparms;
  449.     }
  450.     fcount = count;
  451.     out[count++] = 0;
  452.     if (size > 1)
  453.         out[count++] = 0;
  454.     if (size > 2) {
  455.         out[count++] = 0;
  456.         out[count++] = 0;
  457.     }
  458.  
  459.     repeat = orepeat;
  460.     phiparms = oparms;
  461.     return(fcount);
  462. }
  463. /* Compare two phi-text streams */
  464. int phicmp(BYTE *str1, BYTE *str2)
  465. {
  466.     BYTE buf1[400], buf2[400], *p1=buf1, *p2=buf2;
  467.     int count1, count2;
  468.     if (!phiused)
  469.         return(strcmp(str1,str2));
  470.  
  471.     count1 = phistreamtoflat(buf1,str1,FALSE,FALSE);
  472.     count2 = phistreamtoflat(buf2,str2,FALSE,FALSE);
  473.     
  474.     while(count1 && count2) {
  475.         int val1 = ((*p1++) << 8) + *p1++;
  476.         int val2 = ((*p2++) << 8) + *p2++;
  477.         if (val1 > val2)
  478.             return(1);
  479.         if (val1 < val2)
  480.             return(-1);
  481.         count1--;
  482.         count2--;
  483.     }
  484.     if (count1 == count2)
  485.         return(0);
  486.     if (count1)
  487.         return(1);
  488.     return(2);
  489. }