📄 phitext.c
字号:
/*
* 68K/386 32-bit C compiler.
*
* copyright (c) 1997, David Lindauer
*
* This compiler is intended for educational use. It may not be used
* for profit without the express written consent of the author.
*
* It may be freely redistributed, as long as this notice remains intact
* and either the original sources or derived sources
* are distributed along with any executables derived from the originals.
*
* The author is not responsible for any damages that may arise from use
* of this software, either idirect or consequential.
*
* v1.35 March 1997
* David Lindauer, gclind01@starbase.spd.louisville.edu
*
* Credits to Mathew Brandt for original K&R C compiler
*
*/
/*
* This module is the phi-text interface for the compiler. Files are
* orignilly read in as shorts to accomdate phi-text.
*/
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <ctype.h>
#include "utype.h"
#include "interp.h"
extern BYTE startchars[];
extern BYTE symchars[];
extern BYTE whitespacechars[];
extern BYTE commentchars[];
PHITEXT phiparms = { 4,0,0x0f,0,0,0,0x7f };
BOOL phiused = FALSE;
BOOL putback = FALSE;
int currentphifg = 0;
static PHITEXT phidefaults = { 4,0,0x0f,0,0,0,0x7f };
static int pbchar = 0;
int repeat = 0;
void PhiInit(void)
{
phiparms = phidefaults;
putback = FALSE;
phiused = FALSE;
currentphifg = phidefaults.fgc;
}
void BadString(void)
{
Error("Bad escape sequence in string");
}
/* Get a char from file */
static BOOL phichar(BYTE *ch, FILE *file)
{
while (TRUE) {
*ch = fgetc(file);
if (feof(file))
return(FALSE);
if (*ch == 0x1f) {
phiused = TRUE;
continue;
}
break;
}
return(TRUE);
}
/*
* Get a line from the file. At this point the line is still streamed
* phi-text
*/
BOOL philine(BYTE *buf, int len, FILE *file)
{
if (len < 2 || !phichar(buf,file)) {
*buf = 0;
return(FALSE);
}
while (len>2) {
if (*buf == 0x0a || (phiused && (*buf == 0x14 || *buf == 0x15 || *buf == 0x16)))
break;
if (!phichar(++buf,file))
break;
len--;
}
*buf++ =0x0a;
*buf++ = 0;
return(TRUE);
}
/*
* Parse the phi-text stream and get the next character. Attributes are
* stripped at this stage so all we get is the bank and char info
*/
short parsechar(BYTE **buf)
{
short rv;
if (putback) {
(*buf)++;
putback = FALSE;
return(pbchar);
}
if (!phiused)
return(*(*buf)++);
while (TRUE) {
if (repeat) {
repeat--;
rv = phiparms.cwb + (phiparms.bank << 7);
break;
}
rv = *(*buf)++;
if (rv & 0x80) {
char grp = rv & 0x70;
switch (grp) {
case 0: {
int repeatlevel = 0;
(*buf)--;
while (((rv = **buf)& 0xf0) == 0x80) {
(*buf)++;
repeat += ((rv & 0x0f)<<(repeatlevel++ * 4)) +1;
}
repeat++;
}
break;
case 0x10:
phiparms.bank = rv & 0x0f;
break;
case 0x20:
case 0x30:
phiparms.attrib = rv & 0x1f;
break;
case 0x40:
phiparms.fgc = rv & 0x0f;
break;
case 0x50:
phiparms.bgc = rv & 0x0f;
break;
case 0x60:
phiparms.style = rv & 0x0f;
break;
case 0x70:
phiparms.size = rv & 0x0f;
break;
}
}
else {
if (rv)
phiparms.cwb = rv;
if (rv & 0x60) {
if (phiparms.attrib & HIDDEN || phiparms.style)
continue;
rv = rv + (phiparms.bank << 7);
}
else
if (rv == 0x0a)
phiparms = phidefaults;
break;
}
}
return(rv);
}
/*
* In case we have to step back one char
*/
void putphiback(short ch)
{
putback = TRUE;
pbchar = ch;
}
/* The next few routines check for specific symbol types, sort of analogous
* to the ctype library
*/
BOOL isstartchar(short val)
{
int bit = 1 << (7 - (val & 0x07));
int byte = val >> 3;
return (startchars[byte] & bit);
}
BOOL issymchar(short val)
{
int bit = 1 << (7 - (val & 0x07));
int byte = val >> 3;
return (symchars[byte] & bit);
}
BOOL iswhitespacechar(short val)
{
int bit = 1 << (7 - (val & 0x07));
int byte = val >> 3;
return (whitespacechars[byte] & bit);
}
BOOL iscommentchar(short val)
{
int bit = 1 << (7 - (val & 0x07));
int byte = val >> 3;
return (commentchars[byte] & bit);
}
/* These reads in a char for a C style string lit */
static BYTE *getstringchar(BYTE *rv,BYTE *bufptr)
{
putback = FALSE;
if (phiused) {
if (repeat) {
repeat--;
*rv = phiparms.cwb;
return(bufptr);
}
if ((*bufptr > 0x7f) || phiparms.bank) {
*rv = *bufptr;
if (*rv & 0x80) {
char grp = *rv & 0x70;
switch (grp) {
case 0:
break;
case 0x10:
phiparms.bank = *rv & 0x0f;
break;
case 0x20:
case 0x30:
phiparms.attrib = *rv & 0x1f;
break;
case 0x40:
phiparms.fgc = *rv & 0x0f;
break;
case 0x50:
phiparms.bgc = *rv & 0x0f;
break;
case 0x60:
phiparms.style = *rv & 0x0f;
break;
case 0x70:
phiparms.size = *rv & 0x0f;
break;
}
}
return(++bufptr);
}
}
if (*bufptr == '\\') {
bufptr++;
if (isdigit(*bufptr) && (*bufptr < '8')) {
unsigned temp = 0;
while (isdigit(*bufptr) && *bufptr < '8')
temp = (temp << 3) + (*bufptr++ - '0');
if (temp > 255)
BadString();
*rv = (BYTE)temp;
}
else
switch(*bufptr++) {
case 'b':
*rv = 8;
break;
case 'f':
*rv = 12;
break;
case 'n':
*rv = 10;
break;
case 'r':
*rv = 13;
break;
case 't':
*rv = 9;
break;
case '\'':
*rv = '\'';
break;
case '"':
*rv = '"';
break;
case '\\':
*rv = '\\';
break;
case 'x': {
unsigned temp = 0;
while (isxdigit(*bufptr)) {
temp = (temp << 4) + (*bufptr - '0');
if (*bufptr++ > '9')
temp -= 7;
}
if (temp > 255)
BadString();
*rv = (BYTE)temp;
}
break;
default:
BadString();
}
}
else
*rv = *bufptr++;
return(bufptr);
}
/* This reads in a string lit */
short getphistring(BYTE *obuf, BYTE **ibuf, short endchar)
{
BYTE rv;
if (phiused) {
if (phidefaults.size != phiparms.size)
*obuf++ = 0xf0 | phiparms.size;
if (phidefaults.style != phiparms.style)
*obuf++ = 0xe0 | phiparms.style;
if (phidefaults.bgc != phiparms.bgc)
*obuf++ = 0xd0 | phiparms.bgc;
if (phidefaults.fgc != phiparms.fgc)
*obuf++ = 0xc0 | phiparms.fgc;
if (phidefaults.attrib != phiparms.attrib)
*obuf++ = 0xa0 | phiparms.attrib;
if (repeat) {
BadString();
repeat = 0;
return(endchar);
}
}
*ibuf = getstringchar(&rv,*ibuf);
while (rv && ((rv + (phiparms.bank << 7)) != endchar)) {
if (phiused && (rv <0x20)) {
if ((rv == 0x0a)) {
while (((BYTE) *(obuf-1)) & 0x80)
obuf--;
}
}
*obuf++ = rv;
if (phiused && (rv == 0x0a)) {
if (phidefaults.size != phiparms.size)
*obuf++ = 0xf0 | phiparms.size;
if (phidefaults.style != phiparms.style)
*obuf++ = 0xe0 | phiparms.style;
if (phidefaults.bgc != phiparms.bgc)
*obuf++ = 0xd0 | phiparms.bgc;
if (phidefaults.fgc != phiparms.fgc)
*obuf++ = 0xc0 | phiparms.fgc;
if (phidefaults.attrib != phiparms.attrib)
*obuf++ = 0xa0 | phiparms.attrib;
}
*ibuf = getstringchar(&rv,*ibuf);
}
*obuf = 0;
phiparms.cwb = rv;
return(rv + (phiparms.bank << 7));
}
/* This is for reading in phi-stream literal strings
*/
long getphichar(BYTE **ibuf)
{
BYTE rv;
*ibuf = getstringchar(&rv,*ibuf);
if (!phiused)
return(rv);
while (rv & 0x80)
*ibuf = getstringchar(&rv,*ibuf);
if (!rv)
return(0);
phiparms.cwb = rv;
return(((long)phiparms.size << 28) + ((long)phiparms.style << 24) + ((long)phiparms.fgc << 20)
+ ((long)phiparms.bgc << 16) + ((long)phiparms.attrib << 11) + ((long)phiparms.bank << 7)
+ (rv & 0x7f));
}
/* The next one writes a color index to a streamed file */
void phifg(int color, BYTE *file)
{
currentphifg = color;
if (phiused)
fputc(color | 0xc0, file);
}
/* Now conver to upper case */
short phiupper(short val)
{
if (val > 0x60 && val < 0x7b)
return val &~0x20;
return(val);
}
/* Convert the short stream back to streamed one char at a time */
int installphichar(short curchar, BYTE *buf, int i)
{
short rv = 0;
int bank = curchar >> 7;
int cwb = curchar & 0x7f;
buf = buf+i;
if (!phiused) {
*buf = curchar;
return(1);
}
if (i) {
buf--;
if (((*buf) & 0xf0) == 0x90)
if ((*buf & 0x0f) != bank) {
*buf++ = 0x90 | bank;
}
else
rv--;
else {
buf++;
if (bank) {
*buf++ = 0x90 | bank;
rv++;
}
}
}
else
if (bank) {
*buf++ = 0x90 | bank;
rv++;
}
*buf++ = cwb;
rv++;
if (bank) {
*buf++ = 0x90 | bank;
rv++;
}
return(rv);
}
/* Convert a stream to flats */
short phistreamtoflat(BYTE *out, BYTE *in, int size, BOOL useparms)
{
int count = 0,fcount;
long rv;
PHITEXT oparms = phiparms;
PHITEXT lastphiparms = phiparms;
int orepeat = repeat;
if (!phiused) {
count = strlen(in);
strcpy(out,in);
return(count);
}
repeat = 0;
while (rv = parsechar(&in)) {
if ((rv > 0x1f) && useparms)
rv |= ((long)phiparms.attrib << 11) + ((long)phiparms.fgc << 16) + ((long)phiparms.bgc << 20)
+ ((long)phiparms.style << 24) + ((long)phiparms.size << 28);
if (rv == 0x0a || rv == 0x14 || rv == 0x15 || rv == 0x16)
phiparms = lastphiparms;
if (size > 2) {
out[count++] = rv >> 24;
out[count++] = (rv >>16) & 0xff;
}
if (size > 1)
out[count++] = (rv >>8) & 0xff;
out[count++] = (rv) & 0xff;
lastphiparms = phiparms;
}
fcount = count;
out[count++] = 0;
if (size > 1)
out[count++] = 0;
if (size > 2) {
out[count++] = 0;
out[count++] = 0;
}
repeat = orepeat;
phiparms = oparms;
return(fcount);
}
/* Compare two phi-text streams */
int phicmp(BYTE *str1, BYTE *str2)
{
BYTE buf1[400], buf2[400], *p1=buf1, *p2=buf2;
int count1, count2;
if (!phiused)
return(strcmp(str1,str2));
count1 = phistreamtoflat(buf1,str1,FALSE,FALSE);
count2 = phistreamtoflat(buf2,str2,FALSE,FALSE);
while(count1 && count2) {
int val1 = ((*p1++) << 8) + *p1++;
int val2 = ((*p2++) << 8) + *p2++;
if (val1 > val2)
return(1);
if (val1 < val2)
return(-1);
count1--;
count2--;
}
if (count1 == count2)
return(0);
if (count1)
return(1);
return(2);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -