PHITEXT.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:11k
源码类别:

编译器/解释器

开发平台:

Others

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