mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 17:04:19 +00:00
Upload
Digital Research
This commit is contained in:
@@ -0,0 +1,342 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "preproc.h"
|
||||
|
||||
#define OPPRI 077
|
||||
#define OPBIN 0100
|
||||
#define STKLEN 64
|
||||
int oprstk[STKLEN]={0}; /*operator stack*/
|
||||
int opnstk[STKLEN]={0}; /*operand stack*/
|
||||
int pristk[STKLEN]={0}; /*operator priority stack*/
|
||||
int *oprptr=0; /*pointer to operator stack*/
|
||||
int *opnptr=0; /*pointer to operand stack*/
|
||||
int *priptr=0; /*pointer to priority stack*/
|
||||
int cvalue=0;
|
||||
|
||||
int opinfo[] {
|
||||
0, /*EOF=0*/
|
||||
16|OPBIN, /*SUB=1*/
|
||||
16|OPBIN, /*ADD=2*/
|
||||
20, /*NOT=3*/
|
||||
20, /*NEG=4*/
|
||||
22, /*LPAREN=5*/
|
||||
2, /*RPAREN=6*/
|
||||
6|OPBIN, /*QMARK=7*/
|
||||
6|OPBIN, /*COLON=8*/
|
||||
8|OPBIN, /*OR=9*/
|
||||
10|OPBIN, /*AND=10*/
|
||||
8|OPBIN, /*XOR=11*/
|
||||
12|OPBIN, /*EQUAL=12*/
|
||||
12|OPBIN, /*NEQUAL=13*/
|
||||
14|OPBIN, /*LESS=14*/
|
||||
14|OPBIN, /*LSEQUAL=15*/
|
||||
14|OPBIN, /*GREAT=16*/
|
||||
14|OPBIN, /*GREQUAL=17*/
|
||||
4|OPBIN, /*LSHIFT=18*/
|
||||
4|OPBIN, /*RSHIFT=19*/
|
||||
18|OPBIN, /*MULT=20*/
|
||||
18|OPBIN, /*DIV=21*/
|
||||
18|OPBIN, /*MOD=22*/
|
||||
20, /*COMPL=23*/
|
||||
};
|
||||
|
||||
/* cexpr - constant expression evaluation*/
|
||||
/* Does priority-driven operator/operand stack evaluation of*/
|
||||
/* constant expressions.*/
|
||||
cexpr() /* returns constant evaluated*/
|
||||
{
|
||||
register int lop, type;
|
||||
|
||||
oprptr = &oprstk[0];
|
||||
opnptr = &opnstk[0];
|
||||
priptr = &pristk[0];
|
||||
*priptr = 0;
|
||||
lop = -1;
|
||||
while(1) {
|
||||
switch( type = getctok() ) {
|
||||
|
||||
case CONST:
|
||||
if( lop == 0 ) /*last was not operator*/
|
||||
goto syntax;
|
||||
if( opnptr >= &opnstk[STKLEN] ) {
|
||||
error("expression stack overflow");
|
||||
cexit();
|
||||
}
|
||||
lop = 0;
|
||||
*++opnptr = cvalue;
|
||||
continue;
|
||||
|
||||
case SUB:
|
||||
if( lop )
|
||||
type = NEG; /*unary minus*/
|
||||
break;
|
||||
|
||||
case ADD:
|
||||
if( lop )
|
||||
continue; /*ignore unary +*/
|
||||
break;
|
||||
|
||||
case COMPL:
|
||||
case LPAREN:
|
||||
case NOT:
|
||||
if( lop == 0 )
|
||||
goto syntax;
|
||||
break;
|
||||
|
||||
case RPAREN:
|
||||
if( lop )
|
||||
goto syntax;
|
||||
lop = 0;
|
||||
if( stkop(type) == 0 )
|
||||
goto syntax;
|
||||
continue;
|
||||
|
||||
case NEWL:
|
||||
case EOF:
|
||||
if( lop || stkop(EOF) == 0 || opnptr != &opnstk[1] )
|
||||
goto syntax;
|
||||
type = opnstk[1];
|
||||
putback('\n');
|
||||
return(type);
|
||||
|
||||
default:
|
||||
if( lop || type > LASTOP )
|
||||
goto syntax;
|
||||
break;
|
||||
}
|
||||
lop = 1;
|
||||
if( stkop(type) == 0 )
|
||||
goto syntax;
|
||||
}
|
||||
syntax:
|
||||
error("expression syntax");
|
||||
if( type == NEWL )
|
||||
putback('\n');
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* getctok - get a constant expression token*/
|
||||
/* Handles conversion of quoted character strings and numbers.*/
|
||||
getctok()
|
||||
{
|
||||
register int type, c, count;
|
||||
register char *p;
|
||||
char token[TOKSIZE];
|
||||
|
||||
while( 1 ) {
|
||||
switch( type = getntok(token) ) {
|
||||
|
||||
case DIGIT:
|
||||
cvalue = const(token);
|
||||
return(CONST);
|
||||
|
||||
case SQUOTE:
|
||||
for( cvalue = 0, p = &token[1], count = 2; --count >= 0; ) {
|
||||
if( (c= *p++) == '\'' )
|
||||
break;
|
||||
if( c == '\\' ) {
|
||||
if( *p >= '0' && *p <= '7' ) {
|
||||
for( c = 0; *p >= '0' && *p <= '7'; )
|
||||
c = (c<<3) + (*p++ - '0');
|
||||
}
|
||||
else switch( c = *p++ ) {
|
||||
|
||||
case 'n':
|
||||
c = '\n';
|
||||
break;
|
||||
|
||||
case 't':
|
||||
c = '\t';
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
c = '\b';
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
c = '\r';
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
c = '\f';
|
||||
break;
|
||||
}
|
||||
}
|
||||
cvalue = (cvalue<<8) | c;
|
||||
}
|
||||
return(CONST);
|
||||
|
||||
case ALPHA:
|
||||
if( p = lookup(token) )
|
||||
expand(p);
|
||||
else
|
||||
return(ALPHA);
|
||||
break;
|
||||
|
||||
default:
|
||||
return(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* stkop - stack an operator on the operand stack*/
|
||||
/* Unstack all operators of lower priority, evaluating them as*/
|
||||
/* they are unstacked.*/
|
||||
stkop(opr) /* returns 1 if ok, 0 otherwise*/
|
||||
int opr; /* operator to stack*/
|
||||
{
|
||||
register int i, j, op1, op2, pri;
|
||||
|
||||
for( pri = opinfo[opr]&OPPRI; pri < *priptr; ) {
|
||||
if( *oprptr == LPAREN ) {
|
||||
if( opr == RPAREN ) {
|
||||
oprptr--;
|
||||
priptr--;
|
||||
return(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
op1 = *opnptr;
|
||||
if( (i=opinfo[*oprptr]) & OPBIN ) {
|
||||
op2 = op1;
|
||||
op1 = *--opnptr;
|
||||
}
|
||||
switch(*oprptr) { /*operator*/
|
||||
|
||||
case ADD:
|
||||
op1 =+ op2;
|
||||
break;
|
||||
|
||||
case SUB:
|
||||
op1 =- op2;
|
||||
break;
|
||||
|
||||
case COLON:
|
||||
priptr--;
|
||||
if( *--oprptr != QMARK )
|
||||
return(0);
|
||||
op1 = (*--opnptr ? op1 : op2);
|
||||
break;
|
||||
|
||||
case QMARK:
|
||||
return(0);
|
||||
|
||||
case XOR:
|
||||
op1 =^ op2;
|
||||
break;
|
||||
|
||||
case OR:
|
||||
op1 =| op2;
|
||||
break;
|
||||
|
||||
case AND:
|
||||
op1 =& op2;
|
||||
break;
|
||||
|
||||
case EQUAL:
|
||||
op1 = (op1 == op2);
|
||||
break;
|
||||
|
||||
case NEQUAL:
|
||||
op1 = (op1 != op2);
|
||||
break;
|
||||
|
||||
case LESS:
|
||||
op1 = (op1 < op2);
|
||||
break;
|
||||
|
||||
case LSEQUAL:
|
||||
op1 = (op1 <= op2);
|
||||
break;
|
||||
|
||||
case GREAT:
|
||||
op1 = (op1 > op2);
|
||||
break;
|
||||
|
||||
case GREQUAL:
|
||||
op1 = (op1 >= op2);
|
||||
break;
|
||||
|
||||
case LSHIFT:
|
||||
op1 = (op1 << op2);
|
||||
break;
|
||||
|
||||
case RSHIFT:
|
||||
op1 = (op1 >> op2);
|
||||
break;
|
||||
|
||||
case NEG:
|
||||
op1 = -op1;
|
||||
break;
|
||||
|
||||
case NOT:
|
||||
op1 = !op1;
|
||||
break;
|
||||
|
||||
case COMPL:
|
||||
op1 = ~ op1;
|
||||
break;
|
||||
|
||||
case MULT:
|
||||
op1 =* op2;
|
||||
break;
|
||||
|
||||
case DIV:
|
||||
op1 =/ op2;
|
||||
break;
|
||||
|
||||
case MOD:
|
||||
op1 =% op2;
|
||||
break;
|
||||
|
||||
}
|
||||
*opnptr = op1;
|
||||
priptr--;
|
||||
oprptr--;
|
||||
}
|
||||
if( priptr >= &pristk[STKLEN-1] ) {
|
||||
error("expression operator stack overflow");
|
||||
cexit();
|
||||
}
|
||||
*++oprptr = opr; /*operator value*/
|
||||
*++priptr = pri; /*operator priority*/
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* const - alpha to int conversion, handles octal and hexidecimal*/
|
||||
/* Uses Horner's method to evaluate number.*/
|
||||
const(str) /* returns number evaluated*/
|
||||
char *str; /* pointer to string to convert*/
|
||||
{
|
||||
register int c, i, radix;
|
||||
|
||||
i = 0;
|
||||
radix = 10;
|
||||
if( *str == '0' ) {
|
||||
radix = 8;
|
||||
if( *++str == 'x' || *str == 'X' ) {
|
||||
radix = 16;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
while( c = *str++ ) {
|
||||
if( c >= 'a' && c <= 'f' )
|
||||
c =- 'a'-10;
|
||||
else if( c >= 'A' && c <= 'F' )
|
||||
c =- 'A'-10;
|
||||
else if( c >= '0' && c <= '9' )
|
||||
c =- '0';
|
||||
else
|
||||
break;
|
||||
if( c >= radix )
|
||||
break;
|
||||
i = i*radix + c;
|
||||
}
|
||||
return(i);
|
||||
}
|
||||
325
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/preproc/lex.c
Normal file
325
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/preproc/lex.c
Normal file
@@ -0,0 +1,325 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "preproc.h"
|
||||
char null[] "";
|
||||
|
||||
char ctype[] {
|
||||
EOF, ANYC, ANYC, ANYC, ANYC, ANYC, ANYC, ANYC, /*BUG 2*/
|
||||
ANYC, WHITE, NEWL, ANYC, ANYC, ANYC, ANYC, ANYC, /*BUG 2*/
|
||||
ANYC, ANYC, ANYC, ANYC, NEWL, ANYC, ANYC, ANYC, /*BUG 2*/
|
||||
ANYC, ANYC, ANYC, ANYC, ANYC, ANYC, ANYC, ANYC, /*BUG 2*/
|
||||
WHITE, NOT, DQUOTE, POUND, ANYC, MOD, AND, SQUOTE, /*BUG 2*/
|
||||
LPAREN, RPAREN, MULT, ADD, COMMA, SUB, ANYC, DIV,
|
||||
DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
|
||||
DIGIT, DIGIT, COLON, ANYC, LESS, EQUAL, GREAT, QMARK,
|
||||
ANYC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /*BUG 2*/
|
||||
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
|
||||
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
|
||||
ALPHA, ALPHA, ALPHA, ANYC, BSLASH, ANYC, XOR, ALPHA,
|
||||
ANYC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, /*BUG 2*/
|
||||
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
|
||||
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
|
||||
ALPHA, ALPHA, ALPHA, ANYC, OR, ANYC, COMPL, ANYC /*BUG 2*/
|
||||
};
|
||||
|
||||
/* symhash - compute hash value for symbol*/
|
||||
/* Sums the symbols characters and takes that modulus the hash table*/
|
||||
/* size.*/
|
||||
symhash(sym) /* returns hash value for symbol*/
|
||||
char *sym; /* pointer to symbol*/
|
||||
{
|
||||
register char *p;
|
||||
register int hashval, i;
|
||||
|
||||
for( p = sym, i = SSIZE, hashval = 0; *p != '\0' && i > 0; i-- )
|
||||
hashval =+ *p++;
|
||||
return( hashval % HSIZE );
|
||||
}
|
||||
|
||||
/* symequal - check for symbol equality*/
|
||||
/* Does comparison between two symbols.*/
|
||||
symequal(sym1,sym2) /* returns 1 if equal, 0 otherwise*/
|
||||
char *sym1; /* pointer to first symbol*/
|
||||
char *sym2; /* pointer to second symbol*/
|
||||
{
|
||||
register char *p, *q;
|
||||
register int i;
|
||||
|
||||
q = sym2;
|
||||
i = SSIZE;
|
||||
for( p = sym1; *p == *q++; )
|
||||
if( *p++ == '\0' || --i == 0 )
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* symcopy - symbol copy*/
|
||||
/* Copies one symbol to another.*/
|
||||
symcopy(sym1,sym2) /* returns - none*/
|
||||
char *sym1; /* pointer to symbol to copy*/
|
||||
char *sym2; /* pointer to area to copy to*/
|
||||
{
|
||||
register char *p, *q;
|
||||
register int i;
|
||||
|
||||
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
|
||||
if( *p )
|
||||
*q++ = *p++;
|
||||
else
|
||||
*q++ = '\0';
|
||||
}
|
||||
|
||||
/* error - output error message*/
|
||||
/* Outputs line number and error message and keeps track of errors.*/
|
||||
error(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
|
||||
char *s; /* printf string*/
|
||||
int x1, x2, x3, x4, x5, x6; /* printf args*/
|
||||
{
|
||||
printf("# %d: ",lineno);
|
||||
printf(s,x1,x2,x3,x4,x5,x6);
|
||||
putchar('\n');
|
||||
mfail++;
|
||||
}
|
||||
|
||||
/* putback - puts back a single character*/
|
||||
/* Checks for push back buffer overflow.*/
|
||||
putback(c)
|
||||
int c;
|
||||
{
|
||||
if( pbp >= &pbbuf[PBSIZE] ) {
|
||||
error("too many characters pushed back");
|
||||
cexit();
|
||||
}
|
||||
*pbp++ = c;
|
||||
}
|
||||
|
||||
/* pbtok - push back a token*/
|
||||
/* Reverses token as its pushing it back.*/
|
||||
pbtok(s)
|
||||
char *s;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
for( p = s + strlen(s); p > s ; )
|
||||
putback(*--p);
|
||||
}
|
||||
|
||||
/* ngetch - get a (possibly) pushed back character*/
|
||||
/* This handles the include file stack and incrementing the line*/
|
||||
/* number for the lowest level file.*/
|
||||
ngetch() /* returns character or EOF*/
|
||||
{
|
||||
register int c;
|
||||
|
||||
if( pbp > &pbbuf[0] )
|
||||
return(*--pbp);
|
||||
pbflag = 0;
|
||||
while( (c=getc(&inbuf[filep])) <= 0 ) {
|
||||
if( filep <= 0 )
|
||||
return(EOF);
|
||||
close(inbuf[filep].fd);
|
||||
filep--;
|
||||
if( filep <= 0 ) {
|
||||
putc('\n',&outbuf);
|
||||
lineno++;
|
||||
}
|
||||
}
|
||||
return( c );
|
||||
}
|
||||
|
||||
/* getsp - get symbol pointer*/
|
||||
/* Calculates the symbol table pointer for a given symbol, if symbol*/
|
||||
/* is not defined, will point to appropriate place to insert symbol.*/
|
||||
struct symbol *getsp(name)
|
||||
char *name;
|
||||
{
|
||||
register int wrap;
|
||||
register struct symbol *sp, *asp;
|
||||
|
||||
wrap = 0;
|
||||
asp = 0;
|
||||
for( sp = &symtab[symhash(name)]; sp->s_def ; ) {
|
||||
if( symequal(sp->s_name,name) )
|
||||
return(sp);
|
||||
if( asp == 0 && sp->s_def == null )
|
||||
asp = sp;
|
||||
if( ++sp >= &symtab[HSIZE] ) {
|
||||
if( wrap++ ) {
|
||||
error("symbol table overflow");
|
||||
cexit();
|
||||
}
|
||||
sp = &symtab[0];
|
||||
}
|
||||
}
|
||||
return( asp ? asp : sp );
|
||||
}
|
||||
|
||||
/* lookup - looks up a symbol to see if it is defined*/
|
||||
/* Returns pointer to definition if found.*/
|
||||
char *lookup(name) /* returns 0 or ptr to symbol*/
|
||||
char *name; /* symbol name*/
|
||||
{
|
||||
register struct symbol *sp;
|
||||
|
||||
sp = getsp(name);
|
||||
if( sp->s_def == 0 || sp->s_def == null )
|
||||
return(0);
|
||||
return(sp);
|
||||
}
|
||||
|
||||
/* gettok - gets next token from input*/
|
||||
/* Collects character string in token and handles special tokens for*/
|
||||
/* the expression evaluator.*/
|
||||
gettok(token) /* returns token type*/
|
||||
char *token;
|
||||
{
|
||||
register char *p, c;
|
||||
register int type, count, t, l;
|
||||
|
||||
p = token;
|
||||
c = ngetch();
|
||||
*p++ = c;
|
||||
switch( type = ctype[c] ) {
|
||||
|
||||
case SQUOTE:
|
||||
case DQUOTE:
|
||||
getstr(token,TOKSIZE,c);
|
||||
return(type);
|
||||
|
||||
case DIGIT:
|
||||
case ALPHA:
|
||||
for( ; p < &token[TOKSIZE]; p++ ) {
|
||||
*p = ngetch();
|
||||
if( (t=ctype[*p]) != ALPHA && t != DIGIT )
|
||||
break;
|
||||
}
|
||||
putback(*p);
|
||||
break;
|
||||
|
||||
case NOT:
|
||||
if( peekis('=') ) {
|
||||
type = NEQUAL;
|
||||
*p++ = '=';
|
||||
}
|
||||
break;
|
||||
|
||||
case GREAT:
|
||||
if( peekis('>') ) {
|
||||
type = RSHIFT;
|
||||
*p++ = '>';
|
||||
}
|
||||
else if( peekis('=') ) {
|
||||
type = GREQUAL;
|
||||
*p++ = '=';
|
||||
}
|
||||
break;
|
||||
|
||||
case LESS:
|
||||
if( peekis('<') ) {
|
||||
type = LSHIFT;
|
||||
*p++ = '<';
|
||||
}
|
||||
else if( peekis('=') ) {
|
||||
type = LSEQUAL;
|
||||
*p++ = '=';
|
||||
}
|
||||
break;
|
||||
|
||||
case EQUAL:
|
||||
if( peekis('=') )
|
||||
*p++ = '=';
|
||||
else
|
||||
type = ANYC;
|
||||
break;
|
||||
|
||||
case DIV:
|
||||
if( peekis('*') ) {
|
||||
l = lineno;
|
||||
while( (c=ngetch()) != EOF )
|
||||
if( c == '\n' ) {
|
||||
if( filep == 0 && pbp == pbbuf ) {
|
||||
lineno++;
|
||||
putc('\n',&outbuf);
|
||||
}
|
||||
}
|
||||
else if( c == '*' && peekis('/') )
|
||||
break;
|
||||
if( c == EOF ) {
|
||||
lineno = l;
|
||||
error("no */ before EOF");
|
||||
}
|
||||
type = WHITE;
|
||||
token[0] = ' ';
|
||||
}
|
||||
else if( peekis('/') ) {
|
||||
while( (c=ngetch()) != EOF && c != '\n' )
|
||||
;
|
||||
type = NEWL;
|
||||
token[0] = '\n';
|
||||
}
|
||||
break;
|
||||
|
||||
case BADC:
|
||||
error("bad character 0%o",c);
|
||||
break;
|
||||
|
||||
}
|
||||
*p = '\0';
|
||||
return(type);
|
||||
}
|
||||
|
||||
/* getstr - get a quoted (single or double) character string*/
|
||||
/* Gets specified number of characters, handling escapes.*/
|
||||
getstr(str,nchars,endc) /* returns - none*/
|
||||
char *str; /* pointer to string buffer*/
|
||||
int nchars; /* max number of characters*/
|
||||
char endc; /* ending string character*/
|
||||
{
|
||||
register char *p;
|
||||
register int i;
|
||||
register int c;
|
||||
register int j;
|
||||
|
||||
p = str;
|
||||
*p++ = endc;
|
||||
for( i = nchars-2; (c=ngetch()) != endc; ) {
|
||||
if( c == EOF || c == '\n' ) {
|
||||
error("string cannot cross line");
|
||||
break;
|
||||
}
|
||||
if( --i > 0 ) /*BUG 1*/
|
||||
*p++ = c;
|
||||
else if( i == 0 )
|
||||
error("string too long");
|
||||
if( c == '\\' ) {
|
||||
c = ngetch();
|
||||
if( --i > 0 ) /*BUG 1*/
|
||||
*p++ = c;
|
||||
else if( i == 0 )
|
||||
error("string too long");
|
||||
}
|
||||
}
|
||||
*p++ = endc;
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
/* peekis - peeks at next character for specific character*/
|
||||
/* Gets next (possibly pushed back) character, if it matches*/
|
||||
/* the given character 1 is returned, otherwise the character*/
|
||||
/* is put back.*/
|
||||
peekis(tc) /* returns 1 if match, 0 otherwise*/
|
||||
int tc; /* test character*/
|
||||
{
|
||||
register int c;
|
||||
|
||||
if( (c=ngetch()) == tc )
|
||||
return(1);
|
||||
putback(c);
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
lo68 -r -s -o cp68.rel startup.o cexpr.o lex.o macro.o main.o util.o lib6.a
|
||||
@@ -0,0 +1,27 @@
|
||||
$ num
|
||||
CEXPR.C
|
||||
CEXPR.lis
|
||||
$ num
|
||||
LEX.C
|
||||
LEX.lis
|
||||
$ num
|
||||
MACRO.C
|
||||
MACRO.lis
|
||||
$ num
|
||||
MAIN.C
|
||||
MAIN.lis
|
||||
$ num
|
||||
MAKETASK.C
|
||||
MAKETASK.lis
|
||||
$ num
|
||||
PREPROC.C
|
||||
PREPROC.lis
|
||||
$ num
|
||||
UTIL.C
|
||||
UTIL.lis
|
||||
$ num
|
||||
MACHINE.H
|
||||
MACHINE.lst
|
||||
$ num
|
||||
PREPROC.H
|
||||
PREPROC.lst
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
/*#define MC68000 1*/ /* 68000 version */
|
||||
/*#define VAX 1*/ /* VAX Version */
|
||||
#define PDP11 1 /* PDP-11 Version*/
|
||||
/*#define CPM 1*/ /* CP/M Operating System*/
|
||||
#define UNIX 1 /* UNIX Operating System*/
|
||||
/*#define VMS 1*/ /* VMS Operating System*/
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
#define MC68000 1 /* 68000 version */
|
||||
/*#define VAX 1*/ /* VAX Version */
|
||||
/*#define PDP11 1*/ /* PDP-11 Version*/
|
||||
#define CPM 1 /* CP/M Operating System*/
|
||||
/*#define UNIX 1*/ /* UNIX Operating System*/
|
||||
/*#define VMS 1*/ /* VMS Operating System*/
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
/*#define MC68000 1*/ /* 68000 version */
|
||||
/*#define VAX 1*/ /* VAX Version */
|
||||
#define PDP11 1 /* PDP-11 Version*/
|
||||
/*#define CPM 1*/ /* CP/M Operating System*/
|
||||
#define UNIX 1 /* UNIX Operating System*/
|
||||
/*#define VMS 1*/ /* VMS Operating System*/
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Use this file to determine what kind of machine you want the
|
||||
* Alcyon stuff to run on ....
|
||||
*/
|
||||
/*#define MC68000 1*/ /* 68000 version */
|
||||
#define VAX 1 /* VAX Version */
|
||||
/*#define PDP11 1*/ /* PDP-11 Version*/
|
||||
/*#define CPM 1*/ /* CP/M Operating System*/
|
||||
/*#define UNIX 1*/ /* UNIX Operating System*/
|
||||
#define VMS 1 /* VMS Operating System*/
|
||||
@@ -0,0 +1,577 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "preproc.h"
|
||||
#define CSTKSIZE 20
|
||||
|
||||
#ifdef VAX
|
||||
char *stdincl "lib:"; /*standard include directory*/
|
||||
#endif
|
||||
|
||||
#ifdef UNIX
|
||||
char *stdincl ="/usr/include/";
|
||||
#endif
|
||||
|
||||
#ifdef MC68000
|
||||
char *stdincl "";
|
||||
#endif
|
||||
|
||||
int clabel =1000;
|
||||
int nlabel =1001;
|
||||
int lineno = 0;
|
||||
|
||||
struct builtin {
|
||||
char *b_name;
|
||||
int b_type;
|
||||
} btab[] {
|
||||
"define", DEFINE,
|
||||
"include", INCLUDE,
|
||||
"undef", UNDEF,
|
||||
"ifdef", IFDEF,
|
||||
"ifndef", IFNDEF,
|
||||
"else", ELSE,
|
||||
"endif", ENDIF,
|
||||
"if", IF,
|
||||
0,
|
||||
};
|
||||
|
||||
char cstack[CSTKSIZE]={0};
|
||||
char *cstkptr=0;
|
||||
|
||||
/* domacro - do macro processing*/
|
||||
/* Does the macro pre-processing on the input file and leaves the*/
|
||||
/* result on the output file.*/
|
||||
domacro(infile,outfile,nd,nds) /* returns 1 if ok, 0 otherwise*/
|
||||
char *infile; /* input file name*/
|
||||
char *outfile; /* output file name*/
|
||||
int nd; /* number of defines*/
|
||||
char *nds[]; /*points to defines*/
|
||||
{
|
||||
register struct builtin *bp;
|
||||
register char *l;
|
||||
|
||||
filep = 0;
|
||||
if( fopen(infile,&inbuf[filep],0) < 0 ) {
|
||||
error("can't open %s\n",infile);
|
||||
return(0);
|
||||
}
|
||||
if( fcreat(outfile,&outbuf,0666) < 0 ) {
|
||||
error("can't creat %s\n",outfile);
|
||||
return(0);
|
||||
}
|
||||
if( defap == 0 ) {
|
||||
defp = defap = sbrk(1024);
|
||||
defmax = defcount = 1024;
|
||||
}
|
||||
else {
|
||||
defcount = defmax;
|
||||
defp = defap;
|
||||
}
|
||||
lineno = 1;
|
||||
defused = 0;
|
||||
mfail = 0;
|
||||
pbp = &pbbuf[0];
|
||||
cstkptr = &cstack[0];
|
||||
install("Newlabel",NEWLABEL);
|
||||
install("Label",LABEL);
|
||||
while( --nd >= 0 )
|
||||
install(nds[nd],0);
|
||||
while( getline() ) {
|
||||
l = line;
|
||||
if( filep == 0 && pbp == pbbuf )
|
||||
lineno++;
|
||||
else if( pflag == 0 && asflag == 0 )
|
||||
putc(SOH,&outbuf);
|
||||
while( *l )
|
||||
putc(*l++,&outbuf);
|
||||
putc('\n',&outbuf);
|
||||
}
|
||||
if( cstkptr != &cstack[0] )
|
||||
error("unmatched conditional");
|
||||
if( defused > defmax )
|
||||
defmax = defused;
|
||||
myfflush(&outbuf);
|
||||
close(outbuf.fd);
|
||||
close(inbuf[0].fd);
|
||||
return(mfail==0);
|
||||
}
|
||||
|
||||
/* kwlook - look up the macro built-in names*/
|
||||
/* Searches thru the built-in table for the name.*/
|
||||
kwlook(name) /* returns keyword index or 0*/
|
||||
char *name; /* keyword name to lookup*/
|
||||
{
|
||||
register struct builtin *bp;
|
||||
|
||||
for( bp = &btab[0]; bp->b_name; bp++ )
|
||||
if( strcmp(bp->b_name,name) == 0 )
|
||||
return(bp->b_type);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* getline - get input line handling macro statements*/
|
||||
/* Checks for a preprocessor statement on the line and if there*/
|
||||
/* is one there, it processes it. Note that most of the work is*/
|
||||
/* in determining whether we need to skip the current line or not.*/
|
||||
/* This is all handled with the condition stack and the skip variable.*/
|
||||
/* The skip variable is non-zero if any condition on the condition*/
|
||||
/* stack is SKIP.*/
|
||||
getline() /* returns 0 for EOF, 1 otherwise*/
|
||||
{
|
||||
char token[TOKSIZE];
|
||||
register int type, i;
|
||||
register char *p;
|
||||
|
||||
initl();
|
||||
if( (type=gettok(token)) == EOF )
|
||||
return(0);
|
||||
if( type == POUND ) {
|
||||
if( (type=getntok(token)) == NEWL )
|
||||
return(1);
|
||||
switch( kwlook(token) ) {
|
||||
|
||||
case IFDEF:
|
||||
if( getntok(token) == ALPHA && lookup(token) )
|
||||
push(NOSKIP);
|
||||
else {
|
||||
push(SKIP);
|
||||
skip++;
|
||||
}
|
||||
break;
|
||||
|
||||
case IFNDEF:
|
||||
if( getntok(token) == ALPHA && lookup(token) ) {
|
||||
push(SKIP);
|
||||
skip++;
|
||||
}
|
||||
else
|
||||
push(NOSKIP);
|
||||
break;
|
||||
|
||||
case ENDIF:
|
||||
if( (i=pop()) == SKIP )
|
||||
skip--;
|
||||
else if( i != NOSKIP )
|
||||
error("invalid #endif");
|
||||
break;
|
||||
|
||||
case ELSE:
|
||||
if( (i=pop()) == SKIP ) {
|
||||
skip--;
|
||||
push(NOSKIP);
|
||||
}
|
||||
else if( i == NOSKIP ) {
|
||||
skip++;
|
||||
push(SKIP);
|
||||
}
|
||||
else
|
||||
error("invalid #else");
|
||||
break;
|
||||
|
||||
case DEFINE:
|
||||
if( skip == 0 ) /*if in skip, don't do define*/
|
||||
dodefine();
|
||||
break;
|
||||
|
||||
case UNDEF:
|
||||
if( skip == 0 ) { /*if in skip, don't undef*/
|
||||
if( (type=getntok(token)) == ALPHA )
|
||||
undefine(token);
|
||||
}
|
||||
break;
|
||||
|
||||
case INCLUDE:
|
||||
if( skip == 0 ) /*if in skip, don't do include*/
|
||||
doinclude();
|
||||
break;
|
||||
|
||||
case IF:
|
||||
if( cexpr() ) /*evaluate constant expression*/
|
||||
push(NOSKIP); /*non-zero, so don't skip*/
|
||||
else {
|
||||
push(SKIP);
|
||||
skip++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error("invalid preprocessor command");
|
||||
break;
|
||||
}
|
||||
eatup();
|
||||
}
|
||||
else if( type == NEWL )
|
||||
;
|
||||
else if( skip )
|
||||
eatup();
|
||||
else {
|
||||
for( ; type != NEWL && type != EOF ; type = gettok(token) ) {
|
||||
if( type == ALPHA && (p=lookup(token)) )
|
||||
expand(p);
|
||||
else {
|
||||
for( p = token; *p ; )
|
||||
putl(*p++);
|
||||
}
|
||||
}
|
||||
}
|
||||
putl('\0');
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* eatup - eat up the rest of the input line until a newline or EOF*/
|
||||
/* Does gettok calls.*/
|
||||
eatup() /* returns - none*/
|
||||
{
|
||||
register int type;
|
||||
char token[TOKSIZE];
|
||||
|
||||
while( (type=gettok(token)) != NEWL && type != EOF )
|
||||
;
|
||||
}
|
||||
|
||||
/* putl - put a character to the current output line*/
|
||||
/* Checks for line overflow.*/
|
||||
putl(c) /* returns - none*/
|
||||
int c; /* character to put on line*/
|
||||
{
|
||||
if( linep < &line[LINESIZE] )
|
||||
*linep++ = c;
|
||||
else if( loverflow == 0 ) {
|
||||
loverflow++;
|
||||
error("line overflow");
|
||||
}
|
||||
}
|
||||
|
||||
/* initl - initialize current line*/
|
||||
/* Sets the line pointer and the line overflow flag.*/
|
||||
initl() /* returns - none*/
|
||||
{
|
||||
*(linep= &line[0]) = '\0';
|
||||
loverflow = 0;
|
||||
}
|
||||
|
||||
/* putd - put a character to the define buffer*/
|
||||
/* Does dynamic allocation for define buffer*/
|
||||
putd(c) /* returns - none*/
|
||||
int c; /* character to put in buffer*/
|
||||
{
|
||||
if( defcount == 0 ) {
|
||||
if( sbrk(DEFSIZE) == -1 ) {
|
||||
error("define table overflow");
|
||||
cexit();
|
||||
}
|
||||
defcount = DEFSIZE;
|
||||
}
|
||||
defused++;
|
||||
defcount--;
|
||||
*defp++ = c;
|
||||
}
|
||||
|
||||
/* undefine - does undef command*/
|
||||
/* Sets the symbols definition to the null pointer*/
|
||||
undefine(name) /* returns - none*/
|
||||
char *name; /* pointer to name to undef*/
|
||||
{
|
||||
register struct symbol *sp;
|
||||
|
||||
sp = getsp(name);
|
||||
if( sp->s_def )
|
||||
sp->s_def = null;
|
||||
}
|
||||
|
||||
/* dodefine - do #define processing*/
|
||||
/* Checks the define name, collects formal arguements and saves*/
|
||||
/* macro definition, substituting for formal arguments as it goes.*/
|
||||
dodefine() /* returns - none*/
|
||||
{
|
||||
char token[TOKSIZE], *args[MAXARGS], argbuf[ARGBSIZE];
|
||||
register char *abp, *p;
|
||||
register int type, nargs, i;
|
||||
register struct symbol *sp;
|
||||
|
||||
if( (type=getntok(token)) != ALPHA ) {
|
||||
error("bad define name: %s",token);
|
||||
return;
|
||||
}
|
||||
sp = getsp(token);
|
||||
symcopy(token,sp->s_name);
|
||||
sp->s_def = defp;
|
||||
nargs = 0;
|
||||
abp = argbuf;
|
||||
if( (type=gettok(token)) == LPAREN ) {
|
||||
for( ; (type=getfarg(token)) != RPAREN; nargs++ ) {
|
||||
if( nargs >= MAXARGS ) {
|
||||
error("too many arguments");
|
||||
break;
|
||||
}
|
||||
args[nargs] = abp;
|
||||
for( p = token; *abp++ = *p++; ) {
|
||||
if( abp >= &argbuf[ARGBSIZE] ) {
|
||||
error("argument buffer overflow");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
putd(nargs);
|
||||
}
|
||||
else {
|
||||
pbtok(token);
|
||||
putd(NOARGS);
|
||||
}
|
||||
type = getntok(token); /*get next non-white token*/
|
||||
for( ; type != NEWL && type != EOF; type = gettok(token) ) {
|
||||
if( type == ALPHA ) {
|
||||
for( i = 0; i < nargs; i++ ) {
|
||||
if( strcmp(args[i],token) == 0 )
|
||||
break;
|
||||
}
|
||||
if( i < nargs ) { /*sub ARG marker for formal arg*/
|
||||
putd(i+1);
|
||||
putd(ARG);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if( type == BSLASH ) {
|
||||
if( (i=ngetch()) == '\n' ) { /*multi-line macro?*/
|
||||
if( filep == 0 && pbp == pbbuf ) {
|
||||
lineno++;
|
||||
putc('\n',&outbuf);
|
||||
}
|
||||
}
|
||||
putd(i);
|
||||
continue;
|
||||
}
|
||||
for( p = token; *p ; )
|
||||
putd(*p++);
|
||||
}
|
||||
pbtok(token);
|
||||
putd('\0');
|
||||
}
|
||||
|
||||
/* expand - expands the macro definition*/
|
||||
/* Checks for define recursion and #define x x problems, collects*/
|
||||
/* the actual arguments using getaarg, and then expands the macro*/
|
||||
/* by pushing it onto the push back buffer, substituting arguments*/
|
||||
/* as it goes.*/
|
||||
expand(sp) /* returns - none*/
|
||||
struct symbol *sp; /* pointer to macro to expand*/
|
||||
{
|
||||
char argbuf[ARGBSIZE], *args[MAXARGS], token[TOKSIZE];
|
||||
register char *p, *abp, *mdef;
|
||||
register int i, j, nargs, type;
|
||||
|
||||
if( pbflag++ > 100 ) {
|
||||
error("define recursion");
|
||||
return;
|
||||
}
|
||||
if( strcmp(sp->s_name,mdef=sp->s_def) == 0 ) { /*handle #define x x*/
|
||||
while( *mdef )
|
||||
putl(*mdef++);
|
||||
return;
|
||||
}
|
||||
nargs = 0;
|
||||
if( *mdef == NOARGS ) /*suppress grabbing of args*/
|
||||
;
|
||||
else if( gettok(token) != LPAREN )
|
||||
pbtok(token);
|
||||
else {
|
||||
abp = &argbuf[0];
|
||||
while( (type=getaarg(token)) != EOF ) {
|
||||
if( nargs >= MAXARGS ) {
|
||||
error("too many arguments");
|
||||
return;
|
||||
}
|
||||
args[nargs++] = abp;
|
||||
for( p = token; *abp++ = *p++; ) {
|
||||
if( abp >= &argbuf[ARGBSIZE] ) {
|
||||
error("argument buffer overflow");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if( type == RPAREN )
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( *mdef == NEWLABEL ) {
|
||||
clabel = nlabel;
|
||||
if( nargs == 0 )
|
||||
nlabel++;
|
||||
else
|
||||
nlabel =+ atoi(args[0]);
|
||||
}
|
||||
else if( *mdef == LABEL ) {
|
||||
if( nargs == 0 )
|
||||
i = clabel;
|
||||
else
|
||||
i = clabel + atoi(args[0]);
|
||||
pbnum(i);
|
||||
pbtok("_L");
|
||||
}
|
||||
else {
|
||||
mdef++; /*skip no. of args*/
|
||||
for( p = mdef + strlen(mdef) - 1; p >= mdef; p-- ) {
|
||||
if( *p == ARG ) {
|
||||
if( (j= *--p) <= nargs )
|
||||
pbtok(args[j-1]);
|
||||
}
|
||||
else
|
||||
putback(*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* getfarg - get macro formal parameters*/
|
||||
/* Skips blanks and handles "," and ")".*/
|
||||
getfarg(token) /* returns token type*/
|
||||
char *token; /* token returned*/
|
||||
{
|
||||
register int type;
|
||||
|
||||
if( (type=getntok(token)) == RPAREN || type == ALPHA )
|
||||
return(type);
|
||||
if( type != COMMA || (type=getntok(token)) != ALPHA )
|
||||
error("bad argument:%s",token);
|
||||
return(type);
|
||||
}
|
||||
|
||||
/* getntok - get next token, suppressing white space*/
|
||||
/* Merely gettok's until non-white space is there*/
|
||||
getntok(token) /* returns token type*/
|
||||
char *token; /* token returned*/
|
||||
{
|
||||
register int type;
|
||||
|
||||
while( (type=gettok(token)) == WHITE )
|
||||
;
|
||||
return(type);
|
||||
}
|
||||
|
||||
/* getaarg - get macro actual argument*/
|
||||
/* This handles the collecting of the macro's call arguments.*/
|
||||
/* Note that you may have parenthesis as part of the macro argument,*/
|
||||
/* hence you need to keep track of them.*/
|
||||
getaarg(argp) /* returns token type*/
|
||||
char *argp; /* argument returned*/
|
||||
{
|
||||
int type, plevel, i;
|
||||
register char *p, *ap;
|
||||
char token[TOKSIZE];
|
||||
|
||||
ap = argp;
|
||||
*ap = '\0';
|
||||
plevel = 0;
|
||||
i = TOKSIZE;
|
||||
while( ((type=gettok(token)) != COMMA && type != RPAREN) || plevel ) {
|
||||
for( p = token; *ap = *p++; ap++ )
|
||||
if( --i <= 0 ) {
|
||||
error("macro argument too long");
|
||||
return(EOF);
|
||||
}
|
||||
if( type == LPAREN )
|
||||
plevel++;
|
||||
else if( type == RPAREN )
|
||||
plevel--;
|
||||
else if( type == EOF ) {
|
||||
error("unexpected EOF");
|
||||
cexit();
|
||||
}
|
||||
}
|
||||
if( ap == argp )
|
||||
type = EOF;
|
||||
return(type);
|
||||
}
|
||||
|
||||
/* push - push a #ifdef condition value on condition stack*/
|
||||
/* Checks for stack overflow.*/
|
||||
push(val) /* returns - none*/
|
||||
int val; /* value to push*/
|
||||
{
|
||||
if( cstkptr >= &cstack[CSTKSIZE] ) {
|
||||
error("condition stack overflow");
|
||||
cexit();
|
||||
}
|
||||
*cstkptr++ = val;
|
||||
}
|
||||
|
||||
/* pop - pop the #ifdef, etc. condition stack*/
|
||||
/* Checks for stack undeflow.*/
|
||||
pop() /* returns - top of condition stack*/
|
||||
{
|
||||
if( cstkptr <= &cstack[0] )
|
||||
return(-1);
|
||||
return( *--cstkptr );
|
||||
}
|
||||
|
||||
/* doinclude - handle #include command*/
|
||||
/* Checks for file name or library file name and pushes file on*/
|
||||
/* include file stack.*/
|
||||
doinclude() /* returns - none*/
|
||||
{
|
||||
register int type, fd;
|
||||
char token[TOKSIZE], fname[TOKSIZE];
|
||||
register char *p, *q, c;
|
||||
|
||||
p = fname;
|
||||
if( (type=getntok(token)) == SQUOTE || type == DQUOTE ) {
|
||||
for( c = token[0], q = &token[1]; *q != c; )
|
||||
*p++ = *q++;
|
||||
*p = '\0';
|
||||
}
|
||||
else if( type != LESS ) {
|
||||
error("bad include file");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
for( q = stdincl; *p = *q++; p++ )
|
||||
;
|
||||
while( (type=gettok(token))!=GREAT && type!=NEWL && type!=EOF )
|
||||
for( q = token; *p = *q++; p++ )
|
||||
;
|
||||
if( type != GREAT ) {
|
||||
error("bad include file name");
|
||||
pbtok(token);
|
||||
return;
|
||||
}
|
||||
}
|
||||
eatup(); /*need here...*/
|
||||
if( filep >= NINCS-1 )
|
||||
error("includes nested too deeply");
|
||||
else {
|
||||
filep++;
|
||||
if( fopen(fname,&inbuf[filep],0) < 0 ) {
|
||||
error("can't open %s",fname);
|
||||
filep--;
|
||||
}
|
||||
}
|
||||
putback('\n'); /*for eatup in domacro*/
|
||||
}
|
||||
|
||||
install(name,def) /* returns - none*/
|
||||
char *name; /* macro name*/
|
||||
char def; /* pointer to definition*/
|
||||
{
|
||||
register struct symbol *sp;
|
||||
|
||||
sp = getsp(name);
|
||||
symcopy(name,sp->s_name);
|
||||
sp->s_def = defp;
|
||||
putd(def);
|
||||
putd('\0');
|
||||
}
|
||||
|
||||
pbnum(num) /* returns - none*/
|
||||
int num;
|
||||
{
|
||||
register int digit;
|
||||
|
||||
do {
|
||||
digit = num % 10;
|
||||
num =/ 10;
|
||||
putback(digit+'0');
|
||||
} while( num > 0 );
|
||||
}
|
||||
116
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/preproc/main.c
Normal file
116
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/preproc/main.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
int status = 0;
|
||||
int filep = 0;
|
||||
char *stdincl; /* Include prefix for macro processor */
|
||||
/* cexit - exit from C compiler driver*/
|
||||
/* This deletes any existing temps and exits with the error status.*/
|
||||
cexit() /* returns - none*/
|
||||
{
|
||||
|
||||
exit(status);
|
||||
}
|
||||
|
||||
/* main - main routine for C68 Compiler system*/
|
||||
/* Handles the C68 arguments. For each C file given, the macro*/
|
||||
/* pre-processor is called, then the parser, code generator and*/
|
||||
/* assember are fexec'd. The loader arguments are collected and*/
|
||||
/* the loader is fexec'd.*/
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
|
||||
if(argc < 3)
|
||||
usage();
|
||||
|
||||
if (*argv[1] == '-')
|
||||
{
|
||||
if(argc != 5 || argv[1][1] != 'i')
|
||||
usage();
|
||||
|
||||
stdincl = argv[2];
|
||||
domacro(argv[3],argv[4],0,0L);
|
||||
cexit();
|
||||
}
|
||||
if(argc != 3)
|
||||
usage();
|
||||
domacro(argv[1],argv[2],0,0L);
|
||||
cexit();
|
||||
}
|
||||
usage()
|
||||
{
|
||||
error("usage: c68 [-i x:] inputfile outputfile\n");
|
||||
exit();
|
||||
}
|
||||
|
||||
/* strcmp - string comparison*/
|
||||
/* Compares two strings for equality, less or greater.*/
|
||||
strcmp(s,t) /* returns 0 for equality,*/
|
||||
/* neg for < and pos for >.*/
|
||||
char *s; /* first string*/
|
||||
char *t; /* second string*/
|
||||
{
|
||||
for( ; *s == *t; s++, t++ )
|
||||
if( *s == '\0' )
|
||||
return(0);
|
||||
return( *s - *t );
|
||||
}
|
||||
|
||||
/* strlen - string length*/
|
||||
/* Computes number of bytes in string.*/
|
||||
strlen(s) /* returns string length*/
|
||||
char *s; /* string to compute length*/
|
||||
{
|
||||
register int n;
|
||||
|
||||
for( n = 0; *s++ != '\0'; )
|
||||
n++;
|
||||
return(n);
|
||||
}
|
||||
|
||||
/* itoa - integer to ASCII conversion*/
|
||||
/* Converts integer to ASCII string, handles '-'.*/
|
||||
itoa(n,s,w) /* returns - none*/
|
||||
int n; /* number to convert*/
|
||||
char *s; /* resulting string*/
|
||||
int w; /* minimum width of string*/
|
||||
{
|
||||
register int sign, i;
|
||||
char temp[6];
|
||||
|
||||
if( (sign=n) < 0 )
|
||||
n = -n;
|
||||
i = 0;
|
||||
do {
|
||||
temp[i++] = n % 10 + '0';
|
||||
} while( (n =/ 10) > 0 );
|
||||
if( sign < 0 )
|
||||
temp[i++] = '-';
|
||||
while( --w >= i ) /*pad on left with blanks*/
|
||||
*s++ = ' ';
|
||||
while( --i >= 0 ) /*move chars reversed*/
|
||||
*s++ = temp[i];
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
/* strend - set string end*/
|
||||
/* This is used to compare the endings of file names for ".c", etc.*/
|
||||
strend(s,t) /* returns 1 if match, 0 otherwise*/
|
||||
char *s; /* string to compare*/
|
||||
char *t; /* string ending*/
|
||||
{
|
||||
int ls, lt;
|
||||
|
||||
if( (ls=strlen(s)) < (lt=strlen(t)) )
|
||||
return(0);
|
||||
if( strcmp(&s[ls-lt],t) == 0 )
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
#
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
#include "preproc.h"
|
||||
|
||||
#define NARGS 64
|
||||
#define ARGSIZE 1024
|
||||
#define ICODE 0
|
||||
#define STRINGS 1
|
||||
#define MTEMP 2
|
||||
#define ASTEMP 3
|
||||
#define NTEMPS 4
|
||||
|
||||
|
||||
char *fargs[NARGS+1];
|
||||
char **fargp;
|
||||
char argbuf[ARGSIZE];
|
||||
char *cfiles[NARGS+1];
|
||||
char *loadargs[NARGS+1];
|
||||
char *fns[NTEMPS];
|
||||
char *tfns[NTEMPS];
|
||||
char *defs[NARGS];
|
||||
int ndefs;
|
||||
char *argp &argbuf[0];
|
||||
int cflag;
|
||||
int nflag;
|
||||
int lflag;
|
||||
int oflag;
|
||||
int pflag;
|
||||
int sflag;
|
||||
int xflag;
|
||||
int status;
|
||||
int oneflag;
|
||||
int errno;
|
||||
char *parser "/lib/c068";
|
||||
char *cgen "/lib/c168";
|
||||
char *onepass "/lib/c0168";
|
||||
char *pref "/lib/c680.o";
|
||||
char *clib6 "/lib/lib6.a";
|
||||
char *loader "/bin/lo68";
|
||||
char *asm "/bin/as68";
|
||||
#ifdef NOMMU
|
||||
int nommu 1;
|
||||
#else
|
||||
int nommu 0;
|
||||
#endif
|
||||
|
||||
|
||||
// cexit - exit from C compiler driver
|
||||
// This deletes any existing temps and exits with the error status.
|
||||
cexit() // returns - none
|
||||
{
|
||||
register int i;
|
||||
|
||||
if( pflag == 0 ) {
|
||||
for( i = 0; i < NTEMPS; i++ )
|
||||
if( fns[i] )
|
||||
unlink(fns[i]);
|
||||
}
|
||||
exit(status);
|
||||
}
|
||||
|
||||
// main - main routine for C68 Compiler system
|
||||
// Handles the C68 arguments. For each C file given, the macro
|
||||
// pre-processor is called, then the parser, code generator and
|
||||
// assember are fexec'd. The loader arguments are collected and
|
||||
// the loader is fexec'd.
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
register char *arg, **p, **cfilep, **loadp;
|
||||
register int nloadfiles, c, i;
|
||||
|
||||
cfilep = &cfiles[0];
|
||||
loadp = &loadargs[0];
|
||||
nloadfiles = 0;
|
||||
for( p = argv; --argc > 0; ) { //process arguments
|
||||
if( *(arg= *++p) == '-' ) {
|
||||
arg++;
|
||||
for( i = 0; c = *arg++; i++ ) {
|
||||
switch( c ) {
|
||||
|
||||
case 'c':
|
||||
cflag++;
|
||||
continue;
|
||||
|
||||
case '1':
|
||||
oneflag++;
|
||||
parser = onepass;
|
||||
continue;
|
||||
|
||||
case 'D':
|
||||
defs[ndefs++] = arg;
|
||||
i++;
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
nflag++;
|
||||
continue;
|
||||
|
||||
case 'f':
|
||||
printf("floating point not yet implemented\n");
|
||||
continue;
|
||||
|
||||
case 'L':
|
||||
lflag++;
|
||||
continue;
|
||||
|
||||
case 'o':
|
||||
if( --argc <= 0 )
|
||||
ferror("bad -o option");
|
||||
*loadp++ = *p++;
|
||||
*loadp++ = *p;
|
||||
continue;
|
||||
|
||||
case 'P':
|
||||
pflag++;
|
||||
cflag++;
|
||||
continue;
|
||||
|
||||
case 'S':
|
||||
sflag++;
|
||||
cflag++;
|
||||
nflag++;
|
||||
continue;
|
||||
|
||||
case 't':
|
||||
if( (c= *arg++) == '0' )
|
||||
parser = "/usr/c68/c068";
|
||||
else if( c == '1' )
|
||||
cgen = "/usr/c68/c168";
|
||||
else if( c == '\0' )
|
||||
arg--;
|
||||
continue;
|
||||
|
||||
default:
|
||||
if( loadp >= &loadargs[NARGS] )
|
||||
ferror("too many loader args");
|
||||
*loadp++ = *p;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if( i )
|
||||
continue;
|
||||
}
|
||||
if( strend(arg,".c") || strend(arg,".s") ) {
|
||||
|
||||
//C or Assembler files to process
|
||||
|
||||
if( cfilep >= &cfiles[NARGS] )
|
||||
ferror("too many files");
|
||||
*cfilep++ = arg;
|
||||
}
|
||||
else if( chkdup(arg) == 0 ) { //check for loader args
|
||||
if( loadp >= &loadargs[NARGS] )
|
||||
ferror("too many loader args");
|
||||
*loadp++ = arg;
|
||||
if( strend(arg,".o") )
|
||||
nloadfiles++;
|
||||
}
|
||||
}
|
||||
if( cfilep != &cfiles[0] ) { //had a C file?
|
||||
signal(2,&cexit); //catch rubouts
|
||||
for( i = 0; i < NTEMPS; i++ ) //allocate temps
|
||||
fns[i] = maketemp(i);
|
||||
for( p = &cfiles[0]; arg = *p++; ) { //handle each C file
|
||||
for( i = 0; i < NTEMPS; i++ )
|
||||
tfns[i] = fns[i];
|
||||
if( cfilep != &cfiles[1] )
|
||||
printf("%s:\n",arg);
|
||||
|
||||
//the following sets things up for the parser, the macro pre-processor
|
||||
//is called (not forked), then the parser is fexec'd.
|
||||
|
||||
asflag = strend(arg,".s");
|
||||
if( pflag || asflag )
|
||||
tfns[MTEMP] = setend(arg,'i');
|
||||
if( domacro(arg,tfns[MTEMP],ndefs,defs) == 0 || pflag ) {
|
||||
cflag++;
|
||||
continue;
|
||||
}
|
||||
if( asflag == 0 ) {
|
||||
tfns[ASTEMP] = setend(arg,'s');
|
||||
initfargs();
|
||||
addfarg(parser);
|
||||
addfarg(tfns[MTEMP]);
|
||||
if( oneflag ) {
|
||||
addfarg(tfns[ASTEMP]);
|
||||
addfarg(tfns[STRINGS]);
|
||||
if( lflag || nommu )
|
||||
addfarg("-L");
|
||||
if( sflag || nflag )
|
||||
addfarg("-D");
|
||||
addfarg("-1");
|
||||
}
|
||||
else {
|
||||
addfarg(tfns[ICODE]);
|
||||
addfarg(tfns[STRINGS]);
|
||||
}
|
||||
endfargs();
|
||||
if( fexec(parser,fargs) ) {
|
||||
status++;
|
||||
cflag++;
|
||||
continue;
|
||||
}
|
||||
|
||||
//this sets things up for the code generator
|
||||
|
||||
if( oneflag == 0 ) {
|
||||
initfargs();
|
||||
addfarg(cgen);
|
||||
addfarg(tfns[ICODE]);
|
||||
addfarg(tfns[ASTEMP]);
|
||||
if( sflag == 0 )
|
||||
fns[ASTEMP] = tfns[ASTEMP];
|
||||
if( lflag || nommu )
|
||||
addfarg("-L");
|
||||
if( nflag || sflag )
|
||||
addfarg("-D");
|
||||
endfargs();
|
||||
if( fexec(cgen,fargs) ) {
|
||||
status++;
|
||||
cflag++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( sflag )
|
||||
continue;
|
||||
}
|
||||
else
|
||||
tfns[ASTEMP] = tfns[MTEMP];
|
||||
|
||||
//this sets things up for the assembler
|
||||
|
||||
initfargs();
|
||||
addfarg(asm);
|
||||
if( asflag == 0 )
|
||||
addfarg("-u");
|
||||
if( lflag || nommu )
|
||||
addfarg("-L");
|
||||
addfarg(tfns[ASTEMP]);
|
||||
endfargs();
|
||||
if( fexec(asm,fargs) ) {
|
||||
cflag++;
|
||||
status++;
|
||||
}
|
||||
unlink(tfns[ASTEMP]);
|
||||
}
|
||||
}
|
||||
if( cflag == 0 && (loadp != &loadargs[0] || cfilep != &cfiles[0] )) {
|
||||
|
||||
//set things up for the loader, this means that we need to add the
|
||||
//C preface at the beginning of the program which has the jsr to
|
||||
//main and then exits after return from main.
|
||||
|
||||
initfargs();
|
||||
addfarg(loader);
|
||||
addfarg("-X");
|
||||
if( nommu )
|
||||
addfarg("-r");
|
||||
for( p = loadargs; (arg = *p) && *arg == '-'; p++ ) {
|
||||
addfarg(arg);
|
||||
if( arg[1] == 'o' )
|
||||
addfarg(*++p);
|
||||
}
|
||||
addfarg(pref); //C preface to jsr to main
|
||||
for( cfilep = &cfiles[0]; *cfilep; nloadfiles++ ) {
|
||||
arg = setend(*cfilep++,'o');
|
||||
if( chkdup(arg) == 0 )
|
||||
addfarg(arg);
|
||||
}
|
||||
while( *p )
|
||||
addfarg(*p++);
|
||||
addfarg(clib6);
|
||||
endfargs();
|
||||
status =| fexec(loader,fargs);
|
||||
|
||||
//if we were given one C file and there is one ".o" file, we remove
|
||||
//the ".o" file.
|
||||
|
||||
if( cfilep == &cfiles[1] && nloadfiles == 1 )
|
||||
unlink(setend(cfiles[0],'o'));
|
||||
}
|
||||
cexit();
|
||||
}
|
||||
|
||||
// fexec - fork and exec
|
||||
// This forks a new task, then does an execv to execute the given
|
||||
// program with the given arguements.
|
||||
fexec(fname,args) // returns 1 if error, 0 otherwise
|
||||
char *fname; // file to execute
|
||||
char **args; // arguments to pass
|
||||
{
|
||||
register int pid, i;
|
||||
int fstat;
|
||||
|
||||
// if( (pid=fork()) == 0 ) { //child process
|
||||
// execv(fname,args);
|
||||
// printf("can't execv %s errno=%d\n",fname,errno);
|
||||
// exit(1);
|
||||
// }
|
||||
pid = maketask(fname,0,0,args); //do fork & exec
|
||||
if( pid < 0 ) {
|
||||
printf("can't fork errno=%d\n",errno);
|
||||
return(1);
|
||||
}
|
||||
while( pid != wait(&fstat) ) //wait for child
|
||||
;
|
||||
if( (i=fstat&0377) != 0 && i != 14 ) {
|
||||
if( i != 2 )
|
||||
printf("%s error terminated\n",fname);
|
||||
status++;
|
||||
cexit();
|
||||
}
|
||||
return( (fstat>>8) & 0377 );
|
||||
}
|
||||
|
||||
// setend - set the end character of a string
|
||||
// This grabs a copy of the string and sets the last character to
|
||||
// the given character. This is used to generate ".o", ".i" and
|
||||
// ".s" file names.
|
||||
char *setend(s,c) // returns pointer to string
|
||||
char *s; // pointer to old string
|
||||
int c; // character to end string with
|
||||
{
|
||||
register char *p;
|
||||
|
||||
p = makecopy(s);
|
||||
p[strlen(p)-1] = c;
|
||||
return(p);
|
||||
}
|
||||
|
||||
// chkdup - checks for duplicate ".o" files in file list
|
||||
// Goes thru the loader argument list checking for the given
|
||||
// ".o" file name.
|
||||
chkdup(s) // returns 1 if found, 0 otherwise
|
||||
char *s; // pointer to argument
|
||||
{
|
||||
register char **l;
|
||||
|
||||
if( strend(s,".o") ) {
|
||||
for( l = &loadargs[0]; *l; )
|
||||
if( strcmp(*l++,s) == 0 )
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
// makecopy - makes a copy of a string
|
||||
// This allows for manipulating the file name, while allowing the
|
||||
// saving of the old file name.
|
||||
char *makecopy(s) // returns pointer to string
|
||||
char *s; // string to copy
|
||||
{
|
||||
register char *p;
|
||||
|
||||
for( p = argp; *argp++ = *s++; )
|
||||
;
|
||||
return(p);
|
||||
}
|
||||
|
||||
// initfargs - initialize fexec arg block
|
||||
// This sets the arg block pointer to the beginning of the block.
|
||||
initfargs() // returns - none
|
||||
{
|
||||
fargp = &fargs[0];
|
||||
}
|
||||
|
||||
// addfarg - add fexec argument
|
||||
// This takes the given arguement and adds it to the argment block
|
||||
addfarg(s)
|
||||
char *s;
|
||||
{
|
||||
if( fargp >= &fargs[NARGS] )
|
||||
ferror("too many args");
|
||||
*fargp++ = s;
|
||||
}
|
||||
|
||||
// endfargs - end fexec argument block
|
||||
// This ends the argument block with a zero pointer.
|
||||
endfargs() // returns - none
|
||||
{
|
||||
*fargp = 0;
|
||||
}
|
||||
|
||||
// ferror - fatal error
|
||||
// Outputs error message and exits with error status.
|
||||
ferror(s,x1,x2,x3,x4,x5,x6) // returns - none
|
||||
char *s; // printf string
|
||||
int x1, x2, x3, x4, x5, x6; // printf args
|
||||
{
|
||||
printf(s,x1,x2,x3,x4,x5,x6);
|
||||
printf("\n");
|
||||
status++;
|
||||
cexit();
|
||||
}
|
||||
|
||||
// maketemp - make a temporary file name
|
||||
// Generates unique file name with process id
|
||||
char *maketemp(arb) // returns file name
|
||||
int arb; // arbitrary number
|
||||
{
|
||||
char *p, tmp[6];
|
||||
|
||||
p = makecopy("/tmp/ct6");
|
||||
argp--;
|
||||
itoa(getpid(),tmp,1);
|
||||
makecopy(tmp);
|
||||
argp--;
|
||||
makecopy(".");
|
||||
argp--;
|
||||
itoa(arb,tmp,1);
|
||||
makecopy(tmp);
|
||||
return(p);
|
||||
}
|
||||
|
||||
// strcmp - string comparison
|
||||
// Compares two strings for equality, less or greater.
|
||||
strcmp(s,t) // returns 0 for equality,
|
||||
// neg for < and pos for >.
|
||||
char *s; // first string
|
||||
char *t; // second string
|
||||
{
|
||||
for( ; *s == *t; s++, t++ )
|
||||
if( *s == '\0' )
|
||||
return(0);
|
||||
return( *s - *t );
|
||||
}
|
||||
|
||||
// strlen - string length
|
||||
// Computes number of bytes in string.
|
||||
strlen(s) // returns string length
|
||||
char *s; // string to compute length
|
||||
{
|
||||
register int n;
|
||||
|
||||
for( n = 0; *s++ != '\0'; )
|
||||
n++;
|
||||
return(n);
|
||||
}
|
||||
|
||||
// itoa - integer to ASCII conversion
|
||||
// Converts integer to ASCII string, handles '-'.
|
||||
itoa(n,s,w) // returns - none
|
||||
int n; // number to convert
|
||||
char *s; // resulting string
|
||||
int w; // minimum width of string
|
||||
{
|
||||
register int sign, i;
|
||||
char temp[6];
|
||||
|
||||
if( (sign=n) < 0 )
|
||||
n = -n;
|
||||
i = 0;
|
||||
do {
|
||||
temp[i++] = n % 10 + '0';
|
||||
} while( (n =/ 10) > 0 );
|
||||
if( sign < 0 )
|
||||
temp[i++] = '-';
|
||||
while( --w >= i ) //pad on left with blanks
|
||||
*s++ = ' ';
|
||||
while( --i >= 0 ) //move chars reversed
|
||||
*s++ = temp[i];
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
// strend - set string end
|
||||
// This is used to compare the endings of file names for ".c", etc.
|
||||
strend(s,t) // returns 1 if match, 0 otherwise
|
||||
char *s; // string to compare
|
||||
char *t; // string ending
|
||||
{
|
||||
int ls, lt;
|
||||
|
||||
if( (ls=strlen(s)) < (lt=strlen(t)) )
|
||||
return(0);
|
||||
if( strcmp(&s[ls-lt],t) == 0 )
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
$ set noon
|
||||
$ set def [steve.cpm68k.c.preproc]
|
||||
$ copy machine.68k machine.h
|
||||
$ cc68 cexpr
|
||||
$ cc68 lex
|
||||
$ cc68 macro
|
||||
$ cc68 main
|
||||
$ cc68 preproc
|
||||
$ cc68 util
|
||||
$ @reload
|
||||
@@ -0,0 +1,55 @@
|
||||
cp68 cexpr.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic cexpr.s -l
|
||||
as68 -l -u cexpr.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era cexpr.s
|
||||
|
||||
cp68 lex.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic lex.s -l
|
||||
as68 -l -u lex.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era lex.s
|
||||
|
||||
cp68 macro.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic macro.s -l
|
||||
as68 -l -u macro.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era macro.s
|
||||
|
||||
cp68 main.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic main.s -l
|
||||
as68 -l -u main.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era main.s
|
||||
|
||||
cp68 preproc.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic preproc.s -l
|
||||
as68 -l -u preproc.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era preproc.s
|
||||
|
||||
cp68 util.c x.i
|
||||
c068 x.i x.ic x.st
|
||||
c168 x.ic util.s -l
|
||||
as68 -l -u util.s
|
||||
era x.i
|
||||
era x.ic
|
||||
era x.st
|
||||
era util.s
|
||||
|
||||
submit link
|
||||
@@ -0,0 +1,26 @@
|
||||
// maketask call for unix
|
||||
int maketask(fname,flags,priority,argptrs)
|
||||
char *fname;
|
||||
int flags,priority;
|
||||
char **argptrs;
|
||||
{
|
||||
|
||||
register int pid;
|
||||
|
||||
if(flags==0) { //fork and exec
|
||||
if((pid=fork()) == 0) { //child process
|
||||
doexecv:
|
||||
execv(fname,argptrs);
|
||||
printf("execv failed\n");
|
||||
exit(-1);
|
||||
}
|
||||
return(pid); //return child process id
|
||||
}
|
||||
if(flags==2) { //fork only
|
||||
return(fork());
|
||||
}
|
||||
if(flags==4) { //exec only
|
||||
goto doexecv;
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// maketask call for unix
|
||||
int maketask(fname,flags,priority,argptrs)
|
||||
char *fname;
|
||||
int flags,priority;
|
||||
char **argptrs;
|
||||
{
|
||||
|
||||
register int pid;
|
||||
|
||||
if(flags==0) { //fork and exec
|
||||
if((pid=fork()) == 0) { //child process
|
||||
doexecv:
|
||||
execv(fname,argptrs);
|
||||
printf("execv failed\n");
|
||||
exit(-1);
|
||||
}
|
||||
return(pid); //return child process id
|
||||
}
|
||||
if(flags==2) { //fork only
|
||||
return(fork());
|
||||
}
|
||||
if(flags==4) { //exec only
|
||||
goto doexecv;
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#
|
||||
#define MMU 0
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
#include "preproc.h"
|
||||
|
||||
struct symbol symtab[HSIZE]={0};
|
||||
|
||||
/*buffered I/O structure*/
|
||||
struct {
|
||||
int fd;
|
||||
int nc;
|
||||
char *bp;
|
||||
char buffer[512];
|
||||
} inbuf[NINCS]={0}, outbuf={0};
|
||||
int mfail=0; /*macro error flag*/
|
||||
int skip=0; /*skipping current line*/
|
||||
char *defap=0; /*pointer to available define area*/
|
||||
char *defp=0; /*pointer to next available define byte*/
|
||||
int defcount=0; /*bytes left in define area*/
|
||||
int defused=0; /*number of bytes used in define area*/
|
||||
int defmax=0; /*maximum define area used*/
|
||||
int pflag=0;
|
||||
int asflag=0;
|
||||
|
||||
/*line to output after macro substitution*/
|
||||
char line[LINESIZE+2]={0}; /*line buffer*/
|
||||
char *linep=0; /*current line pointer*/
|
||||
int loverflow=0; /*line overflow flag*/
|
||||
|
||||
/*push back buffer*/
|
||||
char pbbuf[PBSIZE]={0}; /*push back buffer*/
|
||||
char *pbp=0; /*push back pointer*/
|
||||
int pbflag=0; /*checks for recursive definition*/
|
||||
@@ -0,0 +1,112 @@
|
||||
#
|
||||
#define MMU 0
|
||||
#include "machine.h"
|
||||
/*
|
||||
Copyright 1981
|
||||
Alcyon Corporation
|
||||
8474 Commerce Av.
|
||||
San Diego, Ca. 92121
|
||||
*/
|
||||
|
||||
/*cexpr operators*/
|
||||
#define EOF 0
|
||||
#define SUB 1
|
||||
#define ADD 2
|
||||
#define NOT 3
|
||||
#define NEG 4
|
||||
#define LPAREN 5
|
||||
#define RPAREN 6
|
||||
#define QMARK 7
|
||||
#define COLON 8
|
||||
#define OR 9
|
||||
#define AND 10
|
||||
#define XOR 11
|
||||
#define EQUAL 12
|
||||
#define NEQUAL 13
|
||||
#define LESS 14
|
||||
#define LSEQUAL 15
|
||||
#define GREAT 16
|
||||
#define GREQUAL 17
|
||||
#define LSHIFT 18
|
||||
#define RSHIFT 19
|
||||
#define MULT 20
|
||||
#define DIV 21
|
||||
#define MOD 22
|
||||
#define COMPL 23
|
||||
#define CONST 24
|
||||
#define LASTOP COMPL /*up to here used by cexpr*/
|
||||
#define SQUOTE 25
|
||||
#define DQUOTE 26
|
||||
#define ANYC 27
|
||||
#define BADC 28
|
||||
#define COMMA 29
|
||||
#define NEWL 30
|
||||
#define POUND 31
|
||||
#define ALPHA 32
|
||||
#define DIGIT 33
|
||||
#define BSLASH 34
|
||||
#define WHITE 35
|
||||
#define LINESIZE 512
|
||||
#define ARG -1
|
||||
#define NEWLABEL -2
|
||||
#define LABEL -3
|
||||
#define NOARGS -4
|
||||
#define MAXARGS 60
|
||||
#define ARGBSIZE 1000
|
||||
#define TOKSIZE 300 /*BUG 4/20/82 was 128*/
|
||||
#define DEFSIZE 1024
|
||||
#define PBSIZE 1000
|
||||
#define DEFINE 1
|
||||
#define UNDEF 2
|
||||
#define INCLUDE 3
|
||||
#define IFDEF 4
|
||||
#define IFNDEF 5
|
||||
#define ELSE 6
|
||||
#define ENDIF 7
|
||||
#define IF 8
|
||||
#define SKIP 0
|
||||
#define NOSKIP 1
|
||||
#define SOH '\01'
|
||||
#define SSIZE 8
|
||||
#define HSIZE 512
|
||||
#define NINCS 8
|
||||
|
||||
struct symbol {
|
||||
char s_name[SSIZE];
|
||||
char *s_def;
|
||||
} symtab[HSIZE];
|
||||
|
||||
/*buffered I/O structure*/
|
||||
struct {
|
||||
int fd;
|
||||
int nc;
|
||||
char *bp;
|
||||
char buffer[512];
|
||||
} inbuf[NINCS], outbuf;
|
||||
int filep;
|
||||
int mfail; /*macro error flag*/
|
||||
int skip; /*skipping current line*/
|
||||
char *defap; /*pointer to available define area*/
|
||||
char *defp; /*pointer to next available define byte*/
|
||||
int defcount; /*bytes left in define area*/
|
||||
int defused; /*number of bytes used in define area*/
|
||||
int defmax; /*maximum define area used*/
|
||||
int pflag;
|
||||
int asflag;
|
||||
|
||||
/*line to output after macro substitution*/
|
||||
char line[LINESIZE+2]; /*line buffer*/
|
||||
char *linep; /*current line pointer*/
|
||||
int loverflow; /*line overflow flag*/
|
||||
int lineno;
|
||||
|
||||
/*push back buffer*/
|
||||
char pbbuf[PBSIZE]; /*push back buffer*/
|
||||
char *pbp; /*push back pointer*/
|
||||
int pbflag; /*checks for recursive definition*/
|
||||
|
||||
char null[]; /*used for undef'd symbols*/
|
||||
|
||||
char *lookup();
|
||||
char *sbrk();
|
||||
struct symbol *getsp();
|
||||
@@ -0,0 +1 @@
|
||||
$clink cexpr,lex,macro,main,preproc,util,lib:klutz/lib c68
|
||||
@@ -0,0 +1,7 @@
|
||||
$ set noon
|
||||
$ lo68 -r -s -o cp68.out lib:startup.o cexpr.o lex.o macro.o main.o -
|
||||
preproc.o util.o lib:lib6.a
|
||||
$ conv :== $bin:conv
|
||||
$ conv
|
||||
cp68.out
|
||||
[--.asc]cp68.asc
|
||||
@@ -0,0 +1,14 @@
|
||||
atoi(s)
|
||||
char *s;
|
||||
{
|
||||
register int n, sign;
|
||||
|
||||
while( *s==' ' || *s=='\n' || *s == '\t')
|
||||
s++;
|
||||
sign = 1;
|
||||
if( *s == '+' || *s == '-' )
|
||||
sign = (*s++=='+') ? 1 : -1;
|
||||
for( n = 0; *s >= '0' && *s <= '9'; s++ )
|
||||
n = (n * 10) + (*s - '0');
|
||||
return( sign * n );
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
$ set noon
|
||||
$ set def [steve.cpm68k.c.preproc]
|
||||
$ copy machine.vax machine.h
|
||||
$ cx cexpr
|
||||
$ cx lex
|
||||
$ cx macro
|
||||
$ cx main
|
||||
$ cx preproc
|
||||
$ cx util
|
||||
$ @relink
|
||||
$ copy c68.exe bin:
|
||||
Reference in New Issue
Block a user