mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-22 16:04:18 +00:00
247 lines
4.2 KiB
C
247 lines
4.2 KiB
C
#include "stdio.h"
|
|
/*
|
|
* Changed to use the Standard I/O library 9/13/82 FZ
|
|
*/
|
|
#include "acom.h"
|
|
|
|
/*
|
|
* Version 3.3, 8/20/82. Made colon a real token and got rid of the TKLAB
|
|
* token type, to accomodate 8086 version.
|
|
*
|
|
* Version 3.2, 7/5/82. Performance enhancements.
|
|
*/
|
|
|
|
static char ident[] = "@(#)a.token.c 3.3";
|
|
|
|
/*
|
|
* stresc - Processes a string escape. This routine is called after the
|
|
* escape character (normally '\') has been seen. It scans off the remainder
|
|
* of the escape and returns its value.
|
|
*/
|
|
stresc() {
|
|
|
|
int ct,
|
|
val;
|
|
|
|
scanc();
|
|
if('0'<=ch && ch<='7') { /* an octal escape */
|
|
val = 0; ct = 3;
|
|
do {
|
|
val = (val<<3)+ch-'0';
|
|
scanc();
|
|
} while(--ct>0 && '0'<=ch && ch<='7');
|
|
unscanc();
|
|
return(val);
|
|
}
|
|
switch(ch) { /* a single-character escape */
|
|
|
|
case 'b':
|
|
case 'B':
|
|
return('\b');
|
|
|
|
case 'f':
|
|
case 'F':
|
|
return('\f');
|
|
|
|
case 'n':
|
|
case 'N':
|
|
return('\n');
|
|
|
|
case 'r':
|
|
case 'R':
|
|
return('\r');
|
|
|
|
case 't':
|
|
case 'T':
|
|
return('\t');
|
|
|
|
default:
|
|
return(ch);
|
|
|
|
}
|
|
}
|
|
|
|
/*
|
|
* token - Scans the next token and returns its type. Also sets up the
|
|
* token's type and value information in the global cells toktyp, tokval,
|
|
* and tokstr.
|
|
*/
|
|
token() {
|
|
|
|
int c;
|
|
struct chent *chp;
|
|
char radix;
|
|
char *strp;
|
|
|
|
strp = tokstr;
|
|
scanc();
|
|
#ifdef DEBUG
|
|
printf("%c(%o)",ch,ch);
|
|
#endif
|
|
if(white(ch)) { /* white space */
|
|
do {
|
|
scanc();
|
|
} while(white(ch));
|
|
if(ch!=';' && ch!='\n') {
|
|
unscanc();
|
|
return(toktyp = TKSPC);
|
|
}
|
|
}
|
|
if(ch == ';') { /* comment */
|
|
do {
|
|
scanc();
|
|
} while(ch != '\n');
|
|
return(toktyp = TKEOL);
|
|
}
|
|
if('a'<=ch&&ch<='z' || 'A'<=ch&&ch<='Z' || ch=='$' || ch=='_'
|
|
|| ch=='.') { /* symbol */
|
|
do {
|
|
if(strp < tokstr+SYMSIZ) *strp++ = ch;
|
|
scanc();
|
|
} while('a'<=ch&&ch<='z' || 'A'<=ch&&ch<='Z' ||
|
|
'0'<=ch&&ch<='9' || ch=='$' || ch=='_' || ch=='.');
|
|
*strp = '\0';
|
|
unscanc();
|
|
return(toktyp = TKSYM);
|
|
}
|
|
if('0'<=ch && ch<='9') { /* constant */
|
|
do {
|
|
*strp++ = ch;
|
|
scanc();
|
|
if('A'<=ch && ch<='Z') ch += 'a'-'A';
|
|
} while('0'<=ch&&ch<='9' || 'a'<=ch&&ch<='z');
|
|
unscanc();
|
|
*strp = '\0';
|
|
c = *--strp;
|
|
if('0'<=c && c<='9') radix = 10;
|
|
else {
|
|
switch(c) {
|
|
|
|
case 'b':
|
|
radix = 2;
|
|
break;
|
|
|
|
case 'd':
|
|
radix = 10;
|
|
break;
|
|
|
|
case 'h':
|
|
radix = 16;
|
|
break;
|
|
|
|
case 'o':
|
|
case 'q':
|
|
radix = 8;
|
|
break;
|
|
|
|
default:
|
|
return(toktyp = TKERR);
|
|
}
|
|
*strp = '\0';
|
|
}
|
|
tokval = 0; strp = tokstr;
|
|
while(c = *strp++) {
|
|
if('0'<=c && c<='9') c -= '0';
|
|
else c += 10-'a';
|
|
if(c >= radix) return(toktyp = TKERR);
|
|
tokval = tokval*radix+c;
|
|
}
|
|
return(toktyp = TKCON);
|
|
}
|
|
if(ch == '\'') { /* character constant */
|
|
scanc();
|
|
if(ch == '\n') {
|
|
unscanc();
|
|
return(toktyp = TKERR);
|
|
}
|
|
tokval = (ch==escchr)?stresc():ch;
|
|
scanc();
|
|
if(ch != '\'') {
|
|
unscanc();
|
|
return(toktyp = TKERR);
|
|
}
|
|
return(toktyp = TKCON);
|
|
}
|
|
if(ch == '"') { /* quoted string */
|
|
scanc();
|
|
while(ch != '"') {
|
|
if(ch == '\n') {
|
|
unscanc();
|
|
return(toktyp = TKERR);
|
|
}
|
|
if(strp < tokstr+STRSIZ) {
|
|
*strp++ = (ch==escchr)?stresc():ch;
|
|
}
|
|
scanc();
|
|
}
|
|
*strp = '\0';
|
|
tokval = strp-tokstr;
|
|
return(toktyp = TKSTR);
|
|
}
|
|
if(ch == '<') {
|
|
scanc();
|
|
if(ch == '<') {
|
|
tokval = TVSHL;
|
|
return(toktyp = TKMULOP);
|
|
}
|
|
if(ch == '=') {
|
|
tokval = TVLE;
|
|
return(toktyp = TKRELOP);
|
|
}
|
|
unscanc();
|
|
tokval = TVLT;
|
|
return(toktyp = TKRELOP);
|
|
}
|
|
if(ch == '>') {
|
|
scanc();
|
|
if(ch == '>') {
|
|
tokval = TVSHR;
|
|
return(toktyp = TKMULOP);
|
|
}
|
|
if(ch == '=') {
|
|
tokval = TVGE;
|
|
return(toktyp = TKRELOP);
|
|
}
|
|
unscanc();
|
|
tokval = TVGT;
|
|
return(toktyp = TKRELOP);
|
|
}
|
|
if(ch == '!') {
|
|
scanc();
|
|
if(ch == '=') {
|
|
tokval = TVNE;
|
|
return(toktyp = TKRELOP);
|
|
}
|
|
unscanc();
|
|
return(toktyp = TKERR);
|
|
}
|
|
/* single character token */
|
|
for(chp=chtab ; chp->ch_chr ; chp++) {
|
|
if(ch == chp->ch_chr) break;
|
|
}
|
|
tokval = chp->ch_val;
|
|
return(toktyp = chp->ch_typ);
|
|
}
|
|
|
|
/*
|
|
* xscanc - Takes care of the cases of character scanning which would be
|
|
* difficult for the macro scanc() to handle. Namely, these are end of line
|
|
* processing and continuation processing.
|
|
*/
|
|
xscanc() {
|
|
|
|
top:
|
|
if(ch == '\0') {
|
|
getline();
|
|
ch = *scanpt++;
|
|
goto top;
|
|
}
|
|
if(ch==escchr && *scanpt=='\n') { /* continuation */
|
|
scanpt++;
|
|
putline();
|
|
ch = *scanpt++;
|
|
goto top;
|
|
}
|
|
return(ch);
|
|
}
|