?? getsym.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
*
*/
/* scanner
*/
/* Trigraphs implemented, won't work for token pasting though */
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include "list.h"
#include "expr.h"
#include "c.h"
#include "errors.h"
#include "utype.h"
#include "interp.h"
extern int prm_errfile;
extern int version;
extern LIST *clist;
extern FILE *cppFile, *listFile, *inputFile;
extern int prm_cplusplus,prm_cmangle,prm_ansi;
extern int ifskip,elsetaken;
extern IFSTRUCT *ifs;
extern char *errfile;
extern int errlineno;
extern int phiused;
extern char *infile;
extern short *lptr; /* shared with preproc */
extern FILE *inclfile[10]; /* shared with preproc */
extern char *inclfname[10]; /* shared with preproc */
extern IFSTRUCT *ifshold[10];
extern int inclline[10]; /* shared with preproc */
extern int incldepth; /* shared with preproc */
extern int prm_listfile;
int lineno;
short inputline[4096];
int lastch;
enum e_sym lastst;
char lastid[100] = "";
char laststr[MAX_STRLEN + 1] = "";
long ival = 0;
long double rval = 0.0;
char *linstack[20]; /* stack for substitutions */
char chstack[20]; /* place to save lastch */
int lstackptr = 0; /* substitution stack pointer */
int cantnewline = FALSE;
int incconst = FALSE;
int backupchar = -1;
static int phiputcpp,phiputlist,phiputerror;
static int commentlevel;
void initsym(void)
{ lptr = inputline;
inputline[0] = 0;
lineno = 0; errlineno = 0;
lastid[0] = 0;
laststr[0] = 0;
ival = 0;
rval = 0.0;
cantnewline=FALSE;
incconst = FALSE;
backupchar = -1;
phiputcpp=phiputlist = phiputerror = FALSE;
}
void lineToCpp(void)
/*
* line has been preprocessed, dump it to a file
*/
{
if (cppFile) {
char buf[100],*q=buf;
short *p = inputline;
*q = 0;
if (!phiputcpp) {
phiputcpp = TRUE;
if (phiused)
fputc('\x1f',cppFile);
fprintf(cppFile,"/* LADsoft C compiler Version %d.%02d */\n\n",version / 100, version %100);
}
while (*p) {
int i;
if (*q) {
buf[0] = *q;
i = 1;
}
else
i = 0;
i+=installphichar(*p++,buf,i);
buf[i] = 0;
q = buf;
while (*q && (*(q+1) || ((*q &0xf0) != 0x90)))
fputc(*q++,cppFile);
}
}
}
/* Strips comments and also the newline char at the end of the line */
static void stripcomment (short *line)
{
short *s = line, *e = s;
while (*e) {
if (*e == '/' && (!commentlevel || !prm_ansi || prm_cplusplus)) {
if (*(e+1) == '*') {
e++;
commentlevel++;
}
else if (*(e+1) == '/' && !commentlevel && (!prm_ansi || prm_cplusplus)) {
*s = 0;
return;
}
else if (!commentlevel)
*s++ = *e;
}
else if (commentlevel && *e == '*' && *(e+1) == '/') {
commentlevel--;
e++;
if (commentlevel == 0) {
*s++ = ' '; /* Comments are whitespace */
}
}
else if (!commentlevel)
*s++ = *e;
e++;
}
*s = 0;
}
/* strip trigraphs */
void striptrigraph(short *buf)
{
short *cp = buf;
while (*cp) {
if (*cp == '?' && *(cp+1) == '?') {
cp +=2;
switch (*cp++) {
case '=':
*buf++='#';
break;
case '(':
*buf++='[';
break;
case '/':
*buf++='\\';
break;
case ')':
*buf++=']';
break;
case '\'':
*buf++='^';
break;
case '<':
*buf++='{';
break;
case '!':
*buf++='|';
break;
case '>':
*buf++='}';
break;
case '-':
*buf++='~';
break;
default:
cp-=2;
break;
}
}
else *buf++ = *cp++;
}
*buf = 0;
}
int getline(int listflag)
/*
* Read in a line, preprocess it, and dump it to the list and preproc files
* Also strip comments and alter trigraphs
*/
{ int rv,rvc,i,prepping,temp;
char ibuf[4096];
int *ptr = ibuf;
if (cantnewline) {
return(0);
}
do {
rv = FALSE;
prepping = FALSE;
rvc = 0;
if( lineno > 0 && listflag && prm_listfile) {
if (!phiputlist) {
if (phiused) {
fputc('\x1f',listFile);
}
phiputlist = TRUE;
}
}
if( lineno > 0 && prm_errfile) {
if (!phiputerror) {
if (phiused) {
fputc('\x1f',listFile);
}
phiputerror = TRUE;
}
}
lferror();
while(rvc +131 < 4096 && !rv) {
++lineno; ++errlineno;
rv = (philine(ibuf+rvc,200,inputFile) == NULL);
if (rv)
break;
rvc = strlen(ibuf);
if (ibuf[rvc-1] != '\n') {
ibuf[rvc++] = '\n';
ibuf[rvc] = 0;
}
rvc-=2;
while (ibuf[rvc]==' ')
rvc--;
if (ibuf[rvc] != '\\')
break;
}
if (rvc)
rv = FALSE;
if(prm_listfile) {
if (!phiputlist) {
if (phiused) {
fputc('\x1f',listFile);
}
fprintf(listFile,"LADsoft C compiler Version %d.%02d - %s\n\n",version / 100, version % 100,clist->data);
phiputlist = TRUE;
}
fprintf(listFile,"%5d: %s",lineno, ibuf);
}
if( rv) {
if (ifs)
generror(ERR_PREPROCMATCH,0,0);
if (commentlevel)
generror(ERR_COMMENTMATCH,0,0);
if (incldepth > 0) {
fclose(inputFile);
inputFile = inclfile[--incldepth];
lineno = inclline[incldepth];
infile = inclfname[incldepth];
errlineno = lineno;
errfile = infile;
ifs = ifshold[incldepth];
commentlevel = 0;
popif();
return getline(0);
}
}
if( rv )
return 1;
lptr = inputline;
ptr = ibuf;
while((temp = parsechar(&ptr)) != 0)
*lptr++ = temp;
*lptr = 0;
stripcomment(inputline);
striptrigraph(inputline);
lptr = inputline;
while (iswhitespacechar(*lptr))
lptr++;
if(lptr[0] == '#') {
listflag = preprocess();
prepping = TRUE;
}
} while (ifskip || prepping);
defcheck(inputline);
lineToCpp();
return 0;
}
/*
* getch - basic get character routine.
*/
int getch(void)
{ while( (lastch = *lptr++) == '\0') {
if( lstackptr > 0 ) {
lptr = linstack[--lstackptr];
lastch = chstack[lstackptr];
return lastch;
}
if (cantnewline) {
lptr--;
return lastch = ' ';
}
if(getline(incldepth == 0))
return lastch = -1;
}
return lastch;
}
/*
* getid - get an identifier.
*
* identifiers are any isidch conglomerate
* that doesn't start with a numeric character.
* this set INCLUDES keywords.
*/
void getid()
{ register int i;
i = 0;
if (prm_cmangle)
lastid[i++] = '_'; /* Mangling */
if (lastch == 'L') {
lastid[i++] = 'L';
getch();
if (lastch == '\"') {
getch();
i=0;
while (lastch != '\"' && lastch) {
*(((short*)(laststr))+i++) = lastch;
getch();
}
if ((lastch & 0x7f) != '\"')
generror(ERR_NEEDCHAR,'\"',0);
else
getch();
*(((short*)(laststr))+i) = 0;
lastst = lsconst;
return;
}
}
while(issymchar(lastch)) {
if (i < 100)
i+=installphichar(lastch,lastid,i);
getch();
}
if ((lastid[i-1] & 0xf0) == 0x90)
lastid[i-1] = 0x90;
lastid[i] = '\0';
lastst = id;
}
/*
* getsch - get a character in a quoted string.
*
* this routine handles all of the escape mechanisms
* for characters in strings and character constants.
*/
int getsch(void) /* return an in-quote character */
{ register int i, j;
if(lastch == '\n')
return -1;
if(lastch != '\\') {
i = lastch;
getch();
return i;
}
getch(); /* get an escaped character */
if(isdigit(lastch)) {
for(i = 0,j=0;j < 3;++j) {
if(lastch <= '7' && lastch >= '0')
i = (i << 3) + lastch - '0';
else
break;
getch();
}
return i;
}
i = lastch;
getch();
switch(i) {
case '\n':
getch();
return getsch();
case 'a':
return '\a';
case 'b':
return '\b';
case 'f':
return '\f';
case 'n':
return '\n';
case 'r':
return '\r';
case 't':
return '\t';
case '\'':
return '\'';
case '\"':
return '\"';
case '\\':
return '\\';
case 'x':
{
int n=0,count=0;
while (isxdigit(lastch)) {
count++;
lastch-=0x30;
if (lastch > 10) lastch -=7;
if (lastch > 10) lastch -=32;
n*=16;
n+=lastch;
getch();
}
if (count > 2)
generror(ERR_CONSTTOOLARGE,0,0);
return n;
}
default:
if (isdigit(i) && i < '9') {
int n = 0;
while (isdigit(i) && i < '9') {
n = n * 8 + (lastch - '0');
getch();
}
return n;
}
return i;
}
}
int radix36(char c)
{ if(isdigit(c))
return c - '0';
if(c >= 'a' && c <= 'z')
return c - 'a' + 10;
if(c >= 'A' && c <= 'Z')
return c - 'A' + 10;
return -1;
}
/*
* getbase - get an integer in any base.
*/
void getbase(int b,char **ptr)
{ register long i, j;
int errd = 0;
i = 0;
while(isalnum(**ptr)) {
if((j = radix36(*(*ptr)++)) < b) {
if (i > (ULONG_MAX-j)/b)
if (!errd) {
generror(ERR_CONSTTOOLARGE,0,0);
errd++;
}
i = i * b + j;
}
else break;
}
ival = i;
lastst = iconst;
}
/*
* getfrac - get fraction part of a floating number.
*/
void getfrac(char **ptr)
{ double frmul;
frmul = 0.1;
while(isdigit(**ptr)) {
rval += frmul * (*(*ptr)++ - '0');
frmul *= 0.1;
}
}
/*
* getexp - get exponent part of floating number.
*
* this algorithm is primative but usefull. Floating
* exponents are limited to +/-255 but most hardware
* won't support more anyway.
*/
void getexp(char **ptr)
{ double expo, exmul;
expo = 1.0;
if(lastst != rconst)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -