Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
$ diff DECL.C drb1:[cpm68k.release.parser]DECL.C
$ diff EXPR.C drb1:[cpm68k.release.parser]EXPR.C
$ diff ICODE.C drb1:[cpm68k.release.parser]ICODE.C
$ diff INIT.C drb1:[cpm68k.release.parser]INIT.C
$ diff INITX.C drb1:[cpm68k.release.parser]INITX.C
$ diff INTERF.C drb1:[cpm68k.release.parser]INTERF.C
$ diff LEX.C drb1:[cpm68k.release.parser]LEX.C
$ diff MAIN.C drb1:[cpm68k.release.parser]MAIN.C
$ diff STMT.C drb1:[cpm68k.release.parser]STMT.C
$ diff TABL.C drb1:[cpm68k.release.parser]TABL.C
$ diff ICODE.H drb1:[cpm68k.release.parser]ICODE.H
$ diff PARSER.H drb1:[cpm68k.release.parser]PARSER.H

View File

@@ -0,0 +1,18 @@
Directory DRB0:[STEVE.CPM68K.C.PARSER]
DECL.C;2
EXPR.C;2
ICODE.C;6
INIT.C;10
INITX.C;2
INTERF.C;2
LEX.C;5
MAIN.C;4
PRINTF.C;15
STMT.C;2
TABL.C;2
ICODE.H;3
PARSER.H;4
Total of 13 files.

View File

@@ -0,0 +1,948 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "parser.h"
int opdontop;
/* expr - expression evaluator*/
/* This handles all the expression syntax in C. This is a straight-*/
/* forward operator-stack/oppri scheme for translating infix into*/
/* a binary expression tree.*/
char *expr() /* returns 0 or ptr to node*/
{
register char *p;
register char *opdsave, *oprsave;
register int token, op, oppri, i, opdotsave;
int type, sc, size;
opdsave = opdp;
oprsave = opp;
opdotsave = opdontop;
if( opp == 0 || opdp == 0 ) {
opp = opstack;
opdp = opdstack;
}
else
opp++;
opp->o_op = STACKEND;
opp->o_pri = STKPRI;
opap = exprp;
opdontop = 0;
while( (token=gettok()) != EOF ) {
switch( token ) {
/*the following are the terminal nodes of the expresion tree,*/
/*note that when we see a terminal node, we push it and then go*/
/*and get the next token. When we see an operator, we need to*/
/*check the operator stack to see if we can do a reduction.*/
case CINT:
if( doopd(cnalloc(INT,cvalue)) ) {
exprerr:
if( token == SEMI || token == RCURBR )
pbtok(token);
error("invalid expression");
opdp = opdsave;
opp = oprsave;
opdontop = opdotsave;
return(0);
}
continue;
case CLONG:
if( doopd(lcnalloc(LONG,clvalue)) )
goto exprerr;
continue;
case SYMBOL:
if( ((p=csp)->s_attrib&SDEFINED) == 0 ) {
if( peek(LPAREN) ) { /*assume function call*/
p->s_sc = EXTERNAL;
p->s_type = FUNCTION|INT;
}
else if( commastop ) /*in initialization?*/
p->s_sc = EXTERNAL;
else
error("undefined symbol: %.8s",p->s_symbol);
p->s_attrib =| SDEFINED;
}
if( p->s_sc == EXTERNAL || function(p->t_type) ) {
p = enalloc(p);
p->t_sc = EXTERNAL;
}
else
p = snalloc(p->s_type,p->s_sc,p->s_offset,p->s_dp,
p->s_ssp);
if( doopd(p) )
goto exprerr;
continue;
case STRING:
outtstr(cvalue);
if( doopd(snalloc(ARRAY|CHAR,STATIC,cvalue,0,0)) )
goto exprerr;
continue;
/*do special checking for unary ops and operators that can be*/
/*either unary or binary operators, such as -, &, *, etc.*/
case RESWORD:
if( cvalue != R_SIZEOF )
goto exprerr;
token = SIZEOF;
case COMPL:
case NOT:
if( opdontop ) /*can't have: operand unary-op*/
goto exprerr;
break;
case LBRACK:
opdontop = 0;
break;
case RBRACK:
case RPAREN:
if( opdontop == 0 ) /*can't be: operator )*/
goto exprerr;
break;
case PREINC:
if( opdontop ) /*assume its lvalue++*/
token = POSTINC;
break;
case PREDEC:
if( opdontop ) /*assume its lvalue--*/
token = POSTDEC;
break;
case SUB:
if( opdontop == 0 ) { /*if no operand, assume unary*/
if( peek(CINT) ) {
cvalue = -cvalue;
continue;
}
if( peek(CLONG) ) {
clvalue = -clvalue;
continue;
}
token = UMINUS;
}
break;
case AND:
if( opdontop == 0 )
token = ADDR;
break;
case MULT:
if( opdontop == 0 )
token = INDR;
break;
/*for left parenthesis, we need to see if this is a casting operator.*/
case LPAREN:
if( opdontop == 0 ) { /*see if casting or abstract declarator*/
sc = 0;
type = 0;
if( gettype(&sc,&type,&size) ) {
if( type == STRUCT )
sc = dalloc(size);
else
sc = cdp;
p = snalloc(type,0,0,sc,sc);
p->t_type =| declarator(1);
if( next(RPAREN) == 0 )
goto exprerr;
if( tdp )
p->t_type = addtdtype(tdp,p->t_type,p->t_dp,
&(p->t_ssp));
pushopd(p);
token = CAST;
if( opp->o_op == SIZEOF ) {
opdontop++;
continue;
}
}
}
else if( next(RPAREN) )
token = MPARENS; /*we've seen (), look for NACALL*/
else
token = CALL;
break;
case PERIOD:
case APTR:
smember++; /*next token needs to be struct member*/
break;
}
/*we have seen an operator, get its info and then check the operator*/
/*stack.*/
if( binop(token) ) {
/*handle special binary operators, such as CAST and post-inc and*/
/*post-dec.*/
if( opdontop == 0 ) {
if( token != PREDEC && token != PREINC && token != CAST )
goto exprerr;
}
if( token != POSTDEC && token != POSTINC && token != MPARENS )
opdontop = 0; /*this fixes x++ op problem.*/
}
oppri = oppriority(token);
if( commastop && token == COMMA ) /*need to stop at comma (init)*/
oppri = COLPRI;
if( colonstop && token == COLON ) /*need to stop at colon (case)*/
oppri = COLPRI;
while( 1 ) {
if( oppri > opp->o_pri ||
(oppri == opp->o_pri && rasop(token)) ) {
/*we have encountered a higher priority (or right-associative)*/
/*operator, hence we need to stack it.*/
if( ++opp >= &opstack[OPSSIZE] )
ferror("expression too complex");
if( token == POSTINC || token == POSTDEC )
oppri = PSTPRI;
else if( token == LPAREN || token == LBRACK ||
token == CALL )
oppri = CALPRI;
opp->o_op = token;
opp->o_pri = oppri;
break;
}
/*we have encountered a lower priority operator, hence we need to*/
/*do a reduction.*/
op = opp->o_op;
opp--;
type = CINT;
switch( op ) {
case STACKEND: /*we accept the expression...*/
pbtok(token);
if( maketree(0) == 0 || (p=popopd()) == 0 )
goto exprerr;
opdp = opdsave;
opp = oprsave;
opdontop = opdotsave;
return(p);
case LPAREN: /*assure these have matching )*/
case CALL:
if( token != RPAREN )
goto exprerr;
break;
case MPARENS:
if( maketree(NACALL) == 0 )
goto exprerr;
continue;
case LBRACK:
if( token != RBRACK )
goto exprerr;
if( maketree(ADD) == 0 ) /*array[index]->*(array+index)*/
goto exprerr;
op = INDR;
break;
case PREINC: /*turn these into binary operators*/
case POSTINC: /*which in reality they are...*/
case PREDEC:
case POSTDEC:
pushopd(cnalloc(INT,1));
default:
if( maketree(op) == 0 )
goto exprerr;
continue; /*see if we can reduce some more...*/
}
if( op != LPAREN && maketree(op) == 0 )
goto exprerr;
break;
}
}
error("unexpected EOF");
return(0);
}
/* talloc - expression area tree node allocation*/
/* Allocates area and checks for overflow.*/
char *talloc(size) /* returns pointer to node*/
int size; /* size of node to alloc*/
{
register char *p;
p = opap;
if( p + size >= &exprarea[EXPSIZE] )
ferror("expression too complex");
opap = p + size;
return(p);
}
/* enalloc - external name alloc*/
/* Allocates an expression tree node for an external name and*/
/* copies symbol table info and symbol into tree node.*/
char *enalloc(sp) /* returns - none*/
struct symbol *sp; /* pointer to symbol table entry*/
{
register struct extnode *ep;
ep = talloc(sizeof(*ep));
ep->t_op = SYMBOL;
ep->t_sc = sp->s_sc;
ep->t_type = sp->s_type;
ep->t_dp = sp->s_dp;
ep->t_ssp = sp->s_ssp;
ep->t_offset = sp->s_offset;
symcopy(sp->s_symbol,ep->t_symbol);
return(ep);
}
/* cnalloc - constant node allocation*/
/* Allocates a constant tree node and fills the info fields.*/
char *cnalloc(type,value) /* returns pointer to node*/
int type; /* data type*/
int value; /* constant value*/
{
register struct conode *cp;
cp = talloc(sizeof(*cp));
cp->t_op = CINT;
cp->t_type = type;
cp->t_dp = 0;
cp->t_ssp = 0;
cp->t_value = value;
return(cp);
}
/* lcnalloc - long constant node allocation*/
/* Allocates a constant tree node and fills the info fields.*/
char *lcnalloc(type,value) /* returns pointer to node*/
int type; /* data type*/
long value; /* constant value*/
{
register struct lconode *cp;
cp = talloc(sizeof(*cp));
cp->t_op = CLONG;
cp->t_type = type;
cp->t_dp = 0;
cp->t_ssp = 0;
cp->t_lvalue = value;
return(cp);
}
/* tnalloc - tree node allocation*/
/* Allocates an operator tree node and fills the info fields*/
char *tnalloc(op,type,dp,ssp,left,right) /* returns pointer to node*/
int op; /* operator*/
int type; /* operator type*/
int dp; /* dimension pointer or other info*/
int ssp; /* structure length pointer*/
char *left; /* left subtree*/
char *right; /* right subtree*/
{
register struct tnode *tp;
tp = talloc(sizeof(*tp));
tp->t_op = op;
tp->t_type = type;
tp->t_dp = dp;
tp->t_ssp = ssp;
tp->t_left = left;
tp->t_right = right;
return(tp);
}
/* pushopd - put operand node onto operand stack*/
/* Checks for operand stack overflow.*/
pushopd(tp) /* returns - none*/
struct tnode *tp; /* pointer to tree node to push*/
{
if( opdp >= &opdstack[OPDSIZE] )
ferror("expression too complex");
*opdp++ = tp;
}
/* popopd - pop operand stack*/
/* Checks for stack underflow*/
char *popopd() /* returns ptr to top operand*/
{
register struct tnode *tp;
if( opdp <= &opdstack[0] )
return(0);
tp = *--opdp;
return(tp);
}
/* doopd - handle constant or symbol node operand*/
/* Pushes node onto operand stack and handles opdontop flag.*/
doopd(tp) /* returns 1 if syntax error, 0 for ok*/
struct tnode *tp; /* pointer to tree node*/
{
pushopd(tp);
if( opdontop )
return(1);
opdontop++;
return(0);
}
/*This indicates if a conversion operator is needed given the types*/
/*of the two operands. The upper diagonal is applied ONLY if this*/
/*is an assignment operator and the indexes are swapped so the lower*/
/*diagonal is used otherwise.*/
/*INT UNSN LONG DOUB PTR*/
char cvmap[5][5] {
0, UNSN_INT, LONG_INT, DOUB_INT, PTR_INT, /*INT*/
INT_UNSN, 0, LONG_UNSN, DOUB_UNSN, PTR_UNSN, /*UNSN*/
INT_LONG, UNSN_LONG, 0, DOUB_LONG, PTR_LONG, /*LONG*/
INT_DOUB, UNSN_DOUB, LONG_DOUB, 0, BADCONV, /*DOUB*/
INT_PTR, UNSN_PTR, LONG_PTR, BADCONV, PTR_PTR, /*PTR*/
};
/* maketree - given operator, takes operands and builds up tree*/
/* This takes the given operator, allocates a node for it*/
/* and links up the subtrees on the operand stack. A lot of*/
/* work is in inserting the proper conversions.*/
maketree(op) /* returns - none*/
int op; /* new root operator*/
{
register struct tnode *ltp, *rtp, *p;
register int type, ltype, rtype, lconv, conv, pconv;
if( binop(op) ) {
if( (rtp=popopd()) == 0 )
return(0);
rtype = (rtp=funcref(arrayref(rtp)))->t_type;
}
if( (ltp=popopd()) == 0 )
return(0);
if( op == SIZEOF ) {
pushopd(cnalloc(INT,dsize(ltp->t_type,ltp->t_dp,ltp->t_ssp)));
return(1);
}
if( op != ADDR ) {
ltp = arrayref(ltp);
if( op != CALL && op != NACALL )
ltp = funcref(ltp);
}
if( specops(op,ltp,rtp) )
return( 1 );
ltype = ltp->t_type;
if( lintegral(op) )
integral(ltp,LONG);
if( rintegral(op) )
integral(rtp,LONG);
if( lvalop(op) && ltp->t_op != SYMBOL && ltp->t_op != INDR &&
ltp->t_op != BFIELD )
error("assignable operand required");
if( unaryop(op) ) {
if( unopeval(op,ltp) == 0 )
pushopd(tnalloc(op,ltype,ltp->t_dp,ltp->t_ssp,ltp));
return;
}
if( ltype == STRUCT || rtype == STRUCT ) {
error("structure operation not yet implemented");
ltype = rtype = INT;
}
type = ltype;
if( rtype == TYPELESS ) {
rtp->t_type = rtype = INT;
lconv = conv = 0;
}
else {
lconv = ttoconv(ltype);
conv = ttoconv(rtype);
if( asgop(op) == 0 && conv > lconv ) {
conv = cvmap[conv][lconv];
lconv = 1;
type = rtype;
}
else {
conv = cvmap[lconv][conv];
lconv = 0;
}
}
if( asgop(op) ) {
if( op == ASSIGN && (conv == INT_PTR || conv == UNSN_PTR) &&
rtp->t_op != CINT )
error("illegal type conversion");
if( ((op == ASSIGN && loadreg == 0) || op == CAST )
&& (conv == LONG_PTR||conv == PTR_LONG||conv == INT_PTR||
conv == UNSN_PTR||conv == PTR_PTR) )
conv = 0;
}
else if( op == COLON && suptype(ltype) != 0 && ltype == rtype )
conv = 0;
else if( relop(op) && conv == PTR_PTR )
conv = 0;
pconv = 0;
if( conv == PTR_PTR ) {
if( op == SUB ) {
conv = 0;
type = LONG;
pconv++;
}
else if( (alltype(ltype) != alltype(rtype) ||
alltype(ltype) != (POINTER|CHAR)) && loadreg == 0 )
conv = BADCONV;
else
conv = 0;
}
if( conv ) {
if( conv == BADCONV )
error("illegal type conversion");
else if( lconv )
ltp = cvopgen(ltp,type,conv,psize(rtp),op);
else
rtp = cvopgen(rtp,type,conv,psize(ltp),op);
}
else if( op == CAST && rtp->t_type != CHAR )
rtp->t_type = ltp->t_type;
if( relop(op) )
type = INT;
if( op == CAST )
pushopd(rtp);
else {
if( binopeval(op,ltp,rtp) == 0 ) {
if( btype(ltype) == STRUCT || btype(rtype) != STRUCT )
p = ltp;
else
p = rtp;
pushopd(tnalloc(op,type,p->t_dp,p->t_ssp,ltp,rtp));
}
if( pconv && ltype != (POINTER|CHAR) ) {
if( (ltp=popopd()) == 0 )
return(0);
pushopd(cvopgen(ltp,LONG,PTR_LONG,psize(ltp->t_left),op));
}
}
return(1);
}
/* specops - handle special operators in building tree*/
specops(op,ltp,rtp) /* returns 1 if op special, 0 otherwise*/
int op; /* operator*/
struct tnode *ltp; /* left subtree pointer*/
struct tnode *rtp; /* right subtree pointer*/
{
register int type;
type = ltp->t_type;
switch (op) {
case 0:
break;
default:
return(0);
case APTR: /*expr -> name*/
integral(ltp,LONG); /*we need to turn expr into a*/
ltp->t_type = POINTER|STRUCT; /*pointer to a structure, then use*/
pushopd(ltp); /*expr . name stuff*/
maketree(INDR);
ltp = popopd(); /*ltp cannot be 0*/
case PERIOD: /*expr . name*/
if( isstel(rtp) == 0 )
error("invalid structure member name");
type = rtp->t_type;
if( array(type) ) {
type = delspchk(type);
rtp->t_dp++;
}
tadjust(ltp,type,rtp->t_dp,rtp->t_ssp);
pushopd(ltp);
maketree(ADDR);
pushopd(cnalloc(TYPELESS,rtp->t_offset));
maketree(ADD);
if( notarray(rtp->t_type) )
maketree(INDR);
ltp = popopd();
if( rtp->t_sc == BFIELDCL ) /*ltp cannot be 0*/
ltp = tnalloc(BFIELD,type,rtp->t_dp,rtp->t_ssp,ltp);
break;
case QMARK:
if( rtp->t_op != COLON )
error("invalid ?: operator syntax");
if( ltp->t_op == CINT && rtp->t_left->t_op == CINT &&
rtp->t_right->t_op == CINT )
ltp->t_value = (ltp->t_value ? rtp->t_left->t_value :
rtp->t_right->t_value);
else
ltp = tnalloc(op,rtp->t_type,0,0,ltp,rtp);
break;
case LAND:
case LOR:
case COMMA: /*don't need conversions here*/
ltp = tnalloc(op,INT,0,0,ltp,rtp);
break;
case INDR:
if( ltp->t_op == ADDR ) /**& is null op*/
ltp = ltp->t_left;
else {
if( function(type) )
error("indirection on function invalid");
ltp = tnalloc(INDR,delspchk(type),ltp->t_dp,ltp->t_ssp,ltp);
}
break;
case NACALL:
case CALL:
if( notfunction(type) )
error("illegal call");
ltp = tnalloc(op,delspchk(type),ltp->t_dp,ltp->t_ssp,ltp,rtp);
break;
case ADDR:
if( ltp->t_op == INDR ) { /*&* is null op*/
ltp->t_left->t_type = addsp(type,POINTER);
ltp->t_left->t_dp = ltp->t_dp;
ltp->t_left->t_ssp = ltp->t_ssp;
ltp = ltp->t_left;
}
else {
if( ltp->t_op != SYMBOL )
error("& operand illegal");
else if( ltp->t_sc == REGISTER )
error("address of register");
ltp = tnalloc(ADDR,addsp(type,POINTER),ltp->t_dp,ltp->t_ssp,
ltp);
}
break;
}
pushopd(ltp);
return(1);
}
/* cvopgen - generate a conversion operator*/
/* Generates conversions necessary for integers, pointers and longs.*/
char *cvopgen(tp,type,conv,len,op) /* returns pointer to conv node*/
struct tnode *tp; /* pointer to node to do conversion*/
int type; /* type to convert to*/
int conv; /* specified conversion*/
int len; /* object length*/
int op; /* for cast operator*/
{
register int cop;
register struct tnode *rtp;
switch(conv) {
case INT_PTR:
case UNSN_PTR:
if(op == CAST || loadreg) { /*need to generate mult or div*/
cop = INT2L; /*of the ptd to objects length plus*/
if( len != 1 ) { /*an integer to long covnversion*/
rtp = cnalloc(INT,len);
rtp = tnalloc(MULT,type,0,0,tp,rtp);
}
break;
}
case PTR_LONG: /*need to generate mult or div*/
case LONG_PTR: /*of the ptd to objects length*/
if( len == 1 )
return(tp);
cop = (conv == PTR_LONG ? DIV : MULT);
rtp = cnalloc(INT,len);
break;
case INT_LONG:
case UNSN_LONG:
cop = INT2L;
break;
case LONG_INT:
case LONG_UNSN:
cop = LONG2I;
break;
default:
error("invalid conversion");
return(tp);
}
return( tnalloc(cop,type,0,0,tp,rtp) );
}
/* tadjust - expression tree type adjustment*/
/* Adjusts the types of subtrees to agree with the top of the tree.*/
tadjust(tp,type,dp,ssp) /* returns - none*/
struct tnode *tp; /* pointer to tree*/
int type; /* type to adjust to*/
int dp; /* dimension pointer or info*/
int ssp; /* structure pointer*/
{
register int op;
tp->t_type = type;
if( dp >= 0 ) {
tp->t_dp = dp;
tp->t_ssp = ssp;
}
if( (op=tp->t_op) == ADDR )
type = delspchk(type);
else if( op == INDR )
type = addsp(type,POINTER);
else if( op != ADD && op != SUB )
return;
tadjust(tp->t_left,type,dp,ssp);
}
/* funcref - handle tree function reference*/
/* Turns a reference to a function into the address of the function.*/
char *funcref(tp) /* returns pointer to node*/
struct tnode *tp; /* pointer to old node*/
{
if( function(tp->t_type) )
tp = tnalloc(ADDR,addsp(tp->t_type,POINTER),tp->t_dp,tp->t_ssp,tp);
return(tp);
}
/* arrayref - handle tree array reference*/
/* Turns a reference to an array into the address of the array.*/
char *arrayref(tp) /* returns pointer to tree node*/
struct tnode *tp; /* tree node pointer*/
{
if( array(tp->t_type) && isstel(tp) == 0 ) {
tp->t_dp++;
pushopd(tp);
tadjust(tp,delspchk(tp->t_type),-1,0);
maketree(ADDR);
tp = popopd(); /*tp cannot be 0*/
}
return(tp);
}
/* isstel - test for structure element*/
/* Checks for symbol with right storage class*/
isstel(tp) /* returns 1 if is struct el, else 0*/
struct tnode *tp; /* pointer to tree node*/
{
register int sc;
if( tp->t_op == SYMBOL ) {
switch( tp->t_sc ) {
case STELCL:
case UNELCL:
case BFIELDCL:
return(1);
}
}
return(0);
}
/* integral - checks operand for integral type*/
/* This checks for needing an integral operand.*/
integral(tp,atype) /* returns - none*/
struct tnode *tp; /* pointer to tree node*/
int atype; /* alternate type allowable*/
{
register int type;
if( (type=tp->t_type) != INT && type != UNSIGNED && type != CHAR &&
suptype(type) == 0 && type != atype )
error("invalid operand type");
}
/* ttoconv - maps normal type into conversion table type*/
ttoconv(type) /* returns conversion type*/
int type; /* type to convert*/
{
switch(type) {
case CHAR:
case INT:
return(0);
case UNSIGNED:
return(1);
case LONG:
return(2);
case FLOAT:
case DOUBLE:
return(3);
default:
return(4);
}
}
/* binopeval - does binary operator constant expression evaluation*/
/* Does the constant expression evaluation for binary operators.*/
binopeval(op,ltp,rtp) /* returns 1 if done, 0 if not*/
int op; /* operator to evaluate*/
struct tnode *ltp; /* pointer to left subtree*/
struct tnode *rtp; /* pointer to right subtree*/
{
register int lvalue, rvalue;
if( ltp->t_op != CINT )
return(0);
lvalue = ltp->t_value;
if( rtp->t_op != CINT )
return(0);
rvalue = rtp->t_value;
switch (op) {
case ADD:
lvalue =+ rvalue;
break;
case SUB:
lvalue =- rvalue;
break;
case MULT:
lvalue =* rvalue;
break;
case DIV:
lvalue =/ rvalue;
break;
case MOD:
lvalue =% rvalue;
break;
case AND:
lvalue =& rvalue;
break;
case OR:
lvalue =| rvalue;
break;
case XOR:
lvalue =^ rvalue;
break;
case LSH:
lvalue =<< rvalue;
break;
case RSH:
lvalue =>> rvalue;
break;
case EQUALS:
lvalue = (lvalue == rvalue);
break;
case NEQUALS:
lvalue = (lvalue != rvalue);
break;
case GREAT:
lvalue = (lvalue > rvalue);
break;
case LESS:
lvalue = (lvalue < rvalue);
break;
case GREATEQ:
lvalue = (lvalue >= rvalue);
break;
case LESSEQ:
lvalue = (lvalue <= rvalue);
break;
default:
return(0);
}
ltp->t_value = lvalue;
pushopd(ltp);
return(1);
}
/* unopeval - unary operator constant expression evaluation*/
/* Does constant expression evaluation for unary operators.*/
unopeval(op,tp) /* returns 1 if done, 0 otherwise*/
int op; /* operator to evaluate*/
struct tnode *tp; /* pointer to subexpression*/
{
register int value;
if( tp->t_op != CINT )
return(0);
value = tp->t_value;
switch( op ) {
case COMPL:
value = ~ value;
break;
case UMINUS:
value = - value;
break;
case NOT:
value = ! value;
break;
default:
return(0);
}
tp->t_value = value;
pushopd(tp);
return(1);
}
/* cexpr - evaluate a constant integer expression*/
/* Used in evaluating array bounds, bit field numbers, etc.*/
cexpr()
{
register struct tnode *tp;
register char *savep;
savep = exprp;
exprp = opap;
commastop++;
if( (tp=expr()) && tp->t_op != CINT )
error("constant required");
commastop--;
exprp = savep;
return( tp->t_value );
}
/* delspchk - delete one special reference and check if non-zero*/
/* Checks super-type and issues error message.*/
delspchk(type) /* returns new special type*/
int type; /* type to modify*/
{
if( suptype(type) == 0 )
error("bad indirection");
return( delsp(type) );
}
/* psize - return size of object pointed at by pointer*/
psize(tp) /* returns size of object*/
struct tnode *tp; /* pointer to tree node*/
{
if( suptype(tp->t_type) != 0 )
return(dsize(delsp(tp->t_type),tp->t_dp,tp->t_ssp));
return(1);
}

View File

@@ -0,0 +1,372 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "parser.h"
int inittype;
int begseq;
int bol 1;
int onepass;
/*
This interfaces the Parser and the Code Generator, note that these
allow you to link together the Parser and the Code Generator.
*/
/* outbdata - set up for byte data*/
outbdata() /* returns - none*/
{
inittype = CHAR;
printf("\t.dc.b ");
}
/* outc - output a constant*/
outc(type,value) /* returns - none*/
int type;
int value;
{
if( type == CHAR )
outbdata();
else
outwdata();
printf("%d\n",value);
}
/* outwdata - set up for word data*/
outwdata() /* returns - none*/
{
inittype = INT;
printf("\t.dc.w ");
}
/* outtext - change to text segment*/
outtext() /* returns - none*/
{
printf("\t.text\n");
}
/* outdata - set up for data output*/
outdata() /* returns - none*/
{
inittype = INT;
printf("\t.data\n");
}
/* outldata - set up for long data output*/
outldata() /* returns - none*/
{
inittype = LONG;
printf("\t.data\n");
}
/* outbss - change segment to bss*/
outbss() /* returns - none*/
{
printf("\t.bss\n");
}
/* outextdef - output global symbol reference*/
outextdef(sym) /* returns - none*/
char *sym; /* symbol name*/
{
printf("\t.globl _%.8s\n",sym);
}
/* outcommon - output common reference*/
outcommon(sym,size) /* returns - none*/
char *sym; /* common symbol name*/
int size; /* common size in bytes*/
{
printf("\t.comm _%.8s,%ld\n",sym,((long)size & 0xffffL));
}
/* outresmem - outputs reserved memory*/
outresmem(size) /* returns - none*/
int size; /* size in bytes*/
{
printf("\t.ds.b %d\n",size);
}
/* outpad - output padding for word allignment*/
outpad() /* returns - none*/
{
printf("\t.even\n");
}
/* outbentry - outputs block/function entry code*/
outbentry(nlocs,nds,nas) /* returns - none*/
int nlocs; /* local size*/
int nds; /* number of D registers*/
int nas; /* number of A registers*/
{
if( nds == 0 && nas == 0 ) /* adjust for 1 arg*/
nlocs =+ 4;
printf("\tlink R14,#%d\n",-nlocs);
if( nds || nas ) {
printf("\tmovem.l R%d-R7",7-nds); /*7 for one arg*/
if( nas ) {
putchar('/');
printf("R%d-R13",14-nas);
}
printf(",-(sp)\n");
}
}
/* outbexit - output function exit code*/
outbexit(nds,nas) /* returns - none*/
int nds; /* number of D registers*/
int nas; /* number of A registers*/
{
if( nds || nas ) {
printf("\ttst.l (sp)+\n\tmovem.l (sp)+,"); /*1 arg stuff*/
if( nds ) {
printf("R%d-R7",8-nds);
if( nas )
putchar('/');
}
if( nas )
printf("R%d-R13",14-nas);
putchar('\n');
}
printf("\tunlk R14\n\trts\n");
}
/* outlocal - output local symbol for debugger*/
outlocal(type,sc,sym,val)
int type; /* local name type*/
int sc; /* storage type*/
char *sym; /* symbol name*/
int val;
{
switch( sc ) {
case STATIC:
if( notfunction(type) )
printf("\t~%.8s=L%d\n",sym,val);
break;
case REGISTER:
printf("\t~%.8s=R%d\n",sym,val);
break;
case AUTO:
printf("\t~%.8s=%d\n",sym,val);
break;
}
}
/* outswitch - output switch table info*/
outswitch(ncases,deflab,sp) /* returns - none*/
int ncases; /* number of cases in switch*/
int deflab; /* default label*/
struct swtch *sp; /* switch table pointer*/
{
register int vdif, val, hval, i, tlab;
register struct swtch *s;
val = sp->sw_value;
hval = sp[ncases-1].sw_value;
vdif = hval - val;
if( ncases <= 4 ) {
/*simple switch, do compares and brances, followed by branch to default*/
for( s = sp; --ncases >= 0; s++ ) {
if( s->sw_value == 0 )
printf("\ttst R0\n");
else
printf("\tcmp #%d,R0\n",s->sw_value);
printf("\tbeq L%d\n",s->sw_label);
}
outgoto(deflab);
}
else if( vdif > 0 && vdif <= ncases*3 ) {
/*jump switch, uses value in R0 to index into table of labels*/
if( val )
printf("\tsub #%d,R0\n",val);
tlab = nextlabel++;
printf("\tcmp #%d,R0\n\tbhi L%d\n",vdif,deflab); /*check for max*/
printf("\tasl #2,R0\n\tmove R0,R8\n\tadd.l #L%d,R8\n",tlab);
printf("\tmove.l (R8),R8\n\tjmp (R8)\n");
outdata();
outlab(tlab);
for( s = sp; val <= hval; val++ ) {
if( val == s->sw_value ) {
outclab(s->sw_label);
s++;
}
else
outclab(deflab);
}
outtext();
}
else {
/*direct switch, searches down table of values for match, if match*/
/*found, branches to corresponding label in label table.*/
tlab = nextlabel++;
printf("\text.l R0\n\tmove.l #L%d,R8\n\tmove #%d,R1\n",tlab,ncases);
i = nextlabel++;
outlab(i); /*loop label*/
printf("\tcmp.l (R8)+,R0\n\tdbeq R1,L%d\n",i);
printf("\tmove.l %d(R8),R8\n\tjmp (R8)\n",ncases*4);
outdata();
outlab(tlab);
for( s = sp, i = ncases; --i >= 0; s++ )
outlcon(s->sw_value);
outlcon(0); /* mark for default label*/
for( s = sp, i = ncases; --i >= 0; s++ )
outclab(s->sw_label);
outclab(deflab);
outtext();
}
}
/* outlcon - output long constant to assembler*/
outlcon(val) /* returns - none*/
int val; /* word value*/
{
printf("\t.dc.l %d\n",val);
}
/* outclab - output label consant*/
outclab(lab) /* returns - none*/
int lab; /* label*/
{
printf("\t.dc.l L%d\n",lab);
}
/* outlab - output a label*/
outlab(lab) /* returns - none*/
int lab; /* label*/
{
printf("\tL%d:",lab);
}
/* outflab - output function label*/
outflab(sym) /* returns - none*/
char *sym; /* function name*/
{
printf("\t_%.8s:\n\t~~%.8s:\n",sym,sym);
}
/* outdlab - output data label*/
outdlab(sym) /* returns - none*/
char *sym; /* data symbol name*/
{
printf("\t_%.8s:\n",sym);
}
outeof()
{
register int c;
fflush(&sbuf);
fflush(&obuf);
}
/* copysfile - copy string file to end of output file*/
copysfile(fname)
char *fname;
{
register int c;
close(sbuf.io_fd);
if( fopen(fname,&sbuf,0) < 0 )
ferror("can't copy %s",fname);
while( (c=getc(&sbuf)) > 0 )
putc(c,&obuf);
fflush(&obuf);
}
/* outword - output a word of data*/
outword(w) /* word expression*/
int w;
{
if( begseq )
putchar(',');
begseq++;
printf("%d",w);
}
/* outlong - output a long data*/
outlong(l) /* returns - none*/
long l; /* long data to output*/
{
outwdata();
outword(l.hiword);
outword(l.loword);
outendseq();
}
outendseq() /* returns - none*/
{
begseq = 0;
putchar('\n');
}
outgoto(lab)
int lab;
{
if( lab > 0 )
printf("\tbra L%d\n",lab);
}
/* outtstr - output text string*/
/* This outputs a string to the string file, this is used wherever*/
/* you cannot output the string directly to data space, such as in*/
/* the middle of expressions.*/
outtstr(lab)
int lab;
{
char *savep;
int sbol;
savep = obp; /*save to restore later...*/
obp = &sbuf;
sbol = bol;
bol = 1;
printf("\tL%d:",lab);
outstr();
obp = savep;
bol = sbol;
}
/* outstr - output a string as a sequence of bytes*/
/* Outputs ".dc.b <byte1>,<byte2>,...,<0>*/
outstr()
{
register char *s;
register int i;
outbdata();
for( s = cstr, i = cstrsize; i > 0; i-- )
outword(*s++ & 0xff);
outendseq();
}
/* putchar - handle outputting to intermediate or error files*/
/* This catches tabs to allow for the integration of the parser*/
/* and code generator into one pass. By merely throwing away the*/
/* tabs here, the output will be OK for the assembler.*/
putchar(c)
char c;
{
if( obp == 0 )
write(1,&c,1);
else if( c == '\t' ) {
if( bol && onepass == 0 )
putc('(',obp); /*for code generator*/
}
else {
bol = (c == '\n');
putc(c,obp);
}
}

View File

@@ -0,0 +1,215 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
/*intermediate code operators*/
/*0=>EOF, special operator*/
#define EOF 0
/*1-59=>operators that generate code (entries in code gen optab)*/
#define ADD 1
#define SUB 2
#define MULT 3
#define DIV 4
#define MOD 5
#define RSH 6
#define LSH 7
#define AND 8
#define OR 9
#define XOR 10
#define NOT 11
#define UMINUS 12
#define COMPL 13
#define PREDEC 14
#define PREINC 15
#define POSTDEC 16
#define POSTINC 17
#define ASSIGN 18
#define EQADD 19
#define EQSUB 20
#define EQMULT 21
#define EQDIV 22
#define EQMOD 23
#define EQRSH 24
#define EQLSH 25
#define EQAND 26
#define EQOR 27
#define EQXOR 28
#define FJSR 29
#define EQUALS 30
#define NEQUALS 31
#define GREAT 32
#define GREATEQ 33
#define LESS 34
#define LESSEQ 35
#define INT2L 36
#define LONG2I 37
/*machine dependent operators that generate code*/
#define BTST 38
#define LOAD 39
#define LMULT 40
#define LDIV 41
#define LMOD 42
#define LEQMULT 43
#define LEQDIV 44
#define LEQMOD 45
#define EQADDR 46
#define LCGENOP 47 /*change if adding more operators...*/
/*intermediate code operators that do not generate code*/
#define ADDR 60
#define INDR 61
#define LAND 62
#define LOR 63
#define QMARK 64
#define COLON 65
#define COMMA 66
#define CINT 67
#define CLONG 68
#define SYMBOL 69
#define AUTOINC 70
#define AUTODEC 71
#define CALL 72
#define NACALL 73
#define BFIELD 74
#define IFGOTO 75
#define INIT 76
#define CFORREG 77
#define DCLONG 78
/*operators local to parser*/
#define CAST 80
#define SEMI 81
#define LCURBR 82
#define RCURBR 83
#define LBRACK 84
#define RBRACK 85
#define LPAREN 86
#define RPAREN 87
#define STRING 88
#define RESWORD 89
#define APTR 90
#define PERIOD 91
#define SIZEOF 92
#define MPARENS 93
#define STACKEND 100
/*data types*/
#define TYPELESS 0
#define CHAR 1
#define SHORT 2
#define INT 3
#define LONG 4
#define UCHAR 5
#define USHORT 6
#define UNSIGNED 7
#define ULONG 8
#define FLOAT 9
#define DOUBLE 10
/*data types local to parser*/
#define STRUCT 11
#define FRSTRUCT 12
#define LLABEL 13
/*type flags and definitions*/
#define TYPE 017
#define SUPTYP 060
#define ALLTYPE 077
#define POINTER 020
#define FUNCTION 040
#define ARRAY 060
#define SUTYPLEN 2
/* data registers*/
#define DREG2 2
#define DREG3 3
#define DREG4 4
#define DREG5 5
#define DREG6 6
#define DREG7 7
#define AREG3 11
#define AREG4 12
#define AREG5 13
/*storage classes*/
#define AUTO 1
#define REGISTER 2
#define EXTERNAL 3
#define STATIC 4
#define REGOFF 5
#define EXTOFF 6
#define STATOFF 7
#define INDEXED 8
/*exclusively code generator storage classes*/
#define CINDR 9
#define CLINDR 10
/*exclusively parser storage classes*/
#define STRPROTO 9
#define PDECLIST 10
#define PARMLIST 11
#define BFIELDCL 12
#define UNELCL 13
#define STELCL 14
/*opinfo table bits*/
#define OPPRI 077
#define OPBIN 0100
#define OPLVAL 0200
#define OPREL 0400
#define OPASSIGN 01000
#define OPLWORD 02000
#define OPRWORD 04000
#define OPCOM 010000
#define OPRAS 020000
#define OPTERM 040000
#define OPCONVS 0100000
/*68000 definitions*/
#define PTRSIZE 4
#define INTSIZE 2
#define LONGSIZE 4
#define SSIZE 8
#define TRUE 1
#define FALSE 0
#define BITSPBYTE 8
/*operator class priorities*/
#define TRMPRI 0 /*terminal nodes*/
#define RPNPRI 1 /*) and ]*/
#define CALPRI 2 /*in-stack call, ( or [*/
#define COLPRI 3 /*init or case priority for : or ,*/
#define STKPRI 4 /*priority of end of stack*/
#define COMPRI 5 /*normal priority for ,*/
#define ASGPRI 6 /*=, +=, -=, *=, /=, %=, ...*/
#define QMKPRI 7 /*?:*/
#define LORPRI 8 /*||*/
#define LNDPRI 9 /*&&*/
#define ORPRI 10 /*|, !*/
#define ANDPRI 11 /*&*/
#define EQLPRI 12 /*==, !=*/
#define RELPRI 13 /*>, <, >=, <=*/
#define SHFPRI 14 /*<<, >>*/
#define ADDPRI 15 /*+, -*/
#define MULPRI 16 /**, /, %*/
#define UNOPRI 17 /*++, --, &, *, -, ~, sizeof*/
#define LPNPRI 18 /*., ->, [, (, function call*/
#define PSTPRI 19 /*in-stack post--, post++*/
struct io_buf {
int io_fd;
int io_nc;
char *io_p;
char io_b[512];
};
struct { int hiword; int loword; };
#define EXPSIZE 1024
int exprarea[EXPSIZE];

View File

@@ -0,0 +1,485 @@
/*
* Copies of header files used for initialization
*/
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
/*intermediate code operators*/
/*0=>EOF, special operator*/
#define EOF 0
/*1-59=>operators that generate code (entries in code gen optab)*/
#define ADD 1
#define SUB 2
#define MULT 3
#define DIV 4
#define MOD 5
#define RSH 6
#define LSH 7
#define AND 8
#define OR 9
#define XOR 10
#define NOT 11
#define UMINUS 12
#define COMPL 13
#define PREDEC 14
#define PREINC 15
#define POSTDEC 16
#define POSTINC 17
#define ASSIGN 18
#define EQADD 19
#define EQSUB 20
#define EQMULT 21
#define EQDIV 22
#define EQMOD 23
#define EQRSH 24
#define EQLSH 25
#define EQAND 26
#define EQOR 27
#define EQXOR 28
#define FJSR 29
#define EQUALS 30
#define NEQUALS 31
#define GREAT 32
#define GREATEQ 33
#define LESS 34
#define LESSEQ 35
#define INT2L 36
#define LONG2I 37
/*machine dependent operators that generate code*/
#define BTST 38
#define LOAD 39
#define LMULT 40
#define LDIV 41
#define LMOD 42
#define LEQMULT 43
#define LEQDIV 44
#define LEQMOD 45
#define EQADDR 46
#define LCGENOP 47 /*change if adding more operators...*/
/*intermediate code operators that do not generate code*/
#define ADDR 60
#define INDR 61
#define LAND 62
#define LOR 63
#define QMARK 64
#define COLON 65
#define COMMA 66
#define CINT 67
#define CLONG 68
#define SYMBOL 69
#define AUTOINC 70
#define AUTODEC 71
#define CALL 72
#define NACALL 73
#define BFIELD 74
#define IFGOTO 75
#define INIT 76
#define CFORREG 77
#define DCLONG 78
/*operators local to parser*/
#define CAST 80
#define SEMI 81
#define LCURBR 82
#define RCURBR 83
#define LBRACK 84
#define RBRACK 85
#define LPAREN 86
#define RPAREN 87
#define STRING 88
#define RESWORD 89
#define APTR 90
#define PERIOD 91
#define SIZEOF 92
#define MPARENS 93
#define STACKEND 100
/*data types*/
#define TYPELESS 0
#define CHAR 1
#define SHORT 2
#define INT 3
#define LONG 4
#define UCHAR 5
#define USHORT 6
#define UNSIGNED 7
#define ULONG 8
#define FLOAT 9
#define DOUBLE 10
/*data types local to parser*/
#define STRUCT 11
#define FRSTRUCT 12
#define LLABEL 13
/*type flags and definitions*/
#define TYPE 017
#define SUPTYP 060
#define ALLTYPE 077
#define POINTER 020
#define FUNCTION 040
#define ARRAY 060
#define SUTYPLEN 2
/* data registers*/
#define DREG2 2
#define DREG3 3
#define DREG4 4
#define DREG5 5
#define DREG6 6
#define DREG7 7
#define AREG3 11
#define AREG4 12
#define AREG5 13
/*storage classes*/
#define AUTO 1
#define REGISTER 2
#define EXTERNAL 3
#define STATIC 4
#define REGOFF 5
#define EXTOFF 6
#define STATOFF 7
#define INDEXED 8
/*exclusively code generator storage classes*/
#define CINDR 9
#define CLINDR 10
/*exclusively parser storage classes*/
#define STRPROTO 9
#define PDECLIST 10
#define PARMLIST 11
#define BFIELDCL 12
#define UNELCL 13
#define STELCL 14
/*opinfo table bits*/
#define OPPRI 077
#define OPBIN 0100
#define OPLVAL 0200
#define OPREL 0400
#define OPASSIGN 01000
#define OPLWORD 02000
#define OPRWORD 04000
#define OPCOM 010000
#define OPRAS 020000
#define OPTERM 040000
#define OPCONVS 0100000
/*68000 definitions*/
#define PTRSIZE 4
#define INTSIZE 2
#define LONGSIZE 4
#define SSIZE 8
#define TRUE 1
#define FALSE 0
#define BITSPBYTE 8
/*operator class priorities*/
#define TRMPRI 0 /*terminal nodes*/
#define RPNPRI 1 /*) and ]*/
#define CALPRI 2 /*in-stack call, ( or [*/
#define COLPRI 3 /*init or case priority for : or ,*/
#define STKPRI 4 /*priority of end of stack*/
#define COMPRI 5 /*normal priority for ,*/
#define ASGPRI 6 /*=, +=, -=, *=, /=, %=, ...*/
#define QMKPRI 7 /*?:*/
#define LORPRI 8 /*||*/
#define LNDPRI 9 /*&&*/
#define ORPRI 10 /*|, !*/
#define ANDPRI 11 /*&*/
#define EQLPRI 12 /*==, !=*/
#define RELPRI 13 /*>, <, >=, <=*/
#define SHFPRI 14 /*<<, >>*/
#define ADDPRI 15 /*+, -*/
#define MULPRI 16 /**, /, %*/
#define UNOPRI 17 /*++, --, &, *, -, ~, sizeof*/
#define LPNPRI 18 /*., ->, [, (, function call*/
#define PSTPRI 19 /*in-stack post--, post++*/
struct io_buf {
int io_fd;
int io_nc;
char *io_p;
char io_b[512];
};
struct { int hiword; int loword; };
#define EXPSIZE 1024
int exprarea[EXPSIZE]= {0}
/*symbol attribute fields*/
#define SRESWORD 001 /*is symbol a reserved word?*/
#define SGLOBAL 002 /*is symbol global?*/
#define STYPEDEF 004 /*typedef declaration?*/
#define SDEFINED 010 /*symbol defined?*/
/*reserved words*/
#define R_AUTO 1
#define R_BREAK 2
#define R_CASE 3
#define R_CHAR 4
#define R_CONTINUE 5
#define R_DO 6
#define R_DEFAULT 7
#define R_DOUBLE 8
#define R_GOTO 9
#define R_ELSE 10
#define R_EXTERNAL 11
#define R_FLOAT 12
#define R_FOR 13
#define R_IF 14
#define R_INT 15
#define R_LONG 16
#define R_REGISTER 17
#define R_RETURN 18
#define R_SHORT 19
#define R_SIZEOF 20
#define R_STATIC 21
#define R_STRUCT 22
#define R_SWITCH 23
#define R_TYPEDEF 24
#define R_UNION 25
#define R_UNSIGNED 26
#define R_WHILE 27
/*mixed-mode conversions, entries in 2-d array indexed by:*/
/*(int,unsn,long,doub,ptr)*/
#define INT_UNSN 0 /*no conversion is generated*/
#define INT_LONG 2
#define INT_DOUB 3
#define INT_PTR 4
#define UNSN_INT 0 /*no conversion is generated*/
#define UNSN_LONG 6
#define UNSN_DOUB 7
#define UNSN_PTR 8
#define LONG_INT 9
#define LONG_UNSN 10
#define LONG_DOUB 11
#define LONG_PTR 12
#define DOUB_INT 13
#define DOUB_UNSN 14
#define DOUB_LONG 15
#define PTR_INT 16
#define PTR_UNSN 17
#define PTR_LONG 18
#define PTR_PTR 19
#define BADCONV 20
#define SSIZE 8 /*chars per symbol*/
#define OPSSIZE 40 /*operator stack size*/
#define OPDSIZE 80 /*operand stack size*/
#define HSIZE 512 /*hash table size*/
#define SYMSIZE 1024 /*size to alloc for symbol structures*/
#define SWSIZE 256 /*max no. of cases in a switch*/
#define DSIZE 1000 /*dimension table size*/
#define BITSPWORD 16 /*bits per word*/
#define AREGLO 010 /*A reg flag*/
#define HICREG 2 /*highest reg # used for code generation*/
#define BITSPCHAR 8 /*bits per char*/
#define CHRSPWORD 2 /*chars per word*/
#define STRSIZE 300 /*max string length*/
#define NFARGS 40 /*max no. of args to function*/
#define NFRSTR 20 /*max no. of forward ref struct proto*/
/*symbol table node*/
struct symbol {
char s_attrib;
char s_sc;
int s_type;
int s_dp;
int s_ssp;
int s_offset;
char s_symbol[SSIZE];
struct symbol *s_next;
};
/*expression tree operator node*/
struct tnode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
struct tnode *t_left;
struct tnode *t_right;
};
/*expression tree node for symbol - only keeps location*/
struct symnode {
int t_op;
int t_type; /*data type of symbol*/
int t_dp; /*dimension pointer of symbol*/
int t_ssp; /*structure size index to dtab*/
int t_sc; /*storage class of symbol*/
int t_offset; /*offset of symbol*/
int t_label;
};
/*expression tree node for external symbol - need to keep name*/
struct extnode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
int t_sc;
int t_offset;
int t_reg;
int t_symbol[SSIZE]; /*symbol name*/
};
/*expression tree node for integer constant*/
struct conode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
int t_value; /*constant value*/
};
struct lconode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
long t_lvalue; /*constant value*/
};
struct swtch {
int sw_label;
int sw_value;
} swtab[SWSIZE] = {0};
/*operator and operand stack used by expr*/
struct ops { /*operator stack*/
int o_op; /*operator*/
int o_pri; /*priority*/
} opstack[OPSSIZE] = {0},
*opp=0;
char *opdstack[OPDSIZE]={0}; /*operand stack*/
char **opdp=0; /*operand stack pointer*/
char *opap=0; /*pointer to next available loc in exprarea*/
char *exprp; /*place to start building expression*/
int opinfo[]; /*operator info table*/
struct tnode *frp={0}; /*pointer to function return info node*/
int swp; /*current entry in switch table*/
int cswp=0; /*current low switch table index*/
int nextlabel; /*generates unique label numbers*/
int clabel=0; /*continue label*/
int blabel=0; /*break label*/
int rlabel=0; /*return label*/
int dlabel=0; /*default label*/
int lineno=0; /*current line number of input*/
int errcnt=0; /*count of errors*/
int equalstop=0; /*stop lex at '=', used for external init*/
int commastop=0; /*stop parse at comma(used for const expr)*/
int colonstop=0; /*stop parser at colon(used for case value)*/
int instruct=0; /*set when in structure declaration*/
int infunc=0; /*set when in function body*/
int smember=0; /*set when seen . or ->*/
int tdflag=0; /*declaration is a typedef proto*/
char *tdp=0; /*points to typedef prototype*/
int localsize=0; /*length of local variables*/
int naregs=0; /*keeps track of pointer registers alloc'd*/
int ndregs=0; /*keep track of data registers alloc'd*/
int loadreg=0; /*need to load registers...*/
int boffset=0; /*current bit offset in structure*/
int xflag=0; /*translate int's to long's*/
/*dimension table*/
int dtab[DSIZE]={0};
int cdp=0; /*next entry in dtab to alloc*/
/*lexical analyzer values*/
int cvalue=0; /*current token value if keyword or CINT*/
int cstrsize=0; /*current string size*/
long clvalue=0; /*current token value if long constant*/
struct symbol *csp=0; /*current token symbol ptr if SYMBOL*/
char cstr[STRSIZE]={0}; /*current token value if CSTRING*/
struct symbol *dsp=0; /*declarator symbol pointer*/
/*function argument table, used to collect function parameters*/
struct farg {
struct symbol *f_sp;
int f_offset;
} fargtab[NFARGS]={0};
/*forward referenced structure prototype names*/
struct symbol *frstab[NFRSTR]={0};
int frstp=0;
/*output buffers for intermediate code and strings*/
struct io_buf obuf = {0},
sbuf = {0},
ibuf = {0},
*obp = 0;
#define stypedef(sp) (sp->s_attrib&STYPEDEF)
#define wallign(add) ((add+1)&(~1))
#define array(type) ((type&SUPTYP)==ARRAY)
#define function(type) ((type&SUPTYP)==FUNCTION)
#define pointer(type) ((type&SUPTYP)==POINTER)
#define notarray(type) ((type&SUPTYP)!=ARRAY)
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
#define notpointer(type) ((type&SUPTYP)!=POINTER)
#define btype(type) (type&TYPE)
#define suptype(type) (type&SUPTYP)
#define alltype(type) (type&(SUPTYP|TYPE))
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
#define relop(op) ((opinfo[op]&OPREL)!=0)
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
#define binop(op) ((opinfo[op]&OPBIN)!=0)
#define unaryop(op) ((opinfo[op]&OPBIN)==0)
#define leaf(op) ((opinfo[op]&OPTERM)!=0)
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
#define oppriority(op) (opinfo[op]&OPPRI)
#define makeiop(op) (op|(0254<<8))
/*functions returning pointers*/
char *expr();
char *talloc();
char *tnalloc();
char *enalloc();
char *snalloc();
char *cnalloc();
char *lcnalloc();
char *popopd();
char *cvopgen();
char *funcref();
char *arrayref();
char *install();
char *lookup();
char *sbrk();
char *balpar();
int begseq=0;
int dflag=0;
int inclflag=0;
int inittype=0;
int onepass=0;
int opdontop=0;
int pbchar=0;
int peektok=0;
struct symbol *symbols=0;
struct symbol *symtab[HSIZE] = {0};
fflush(fp)
char *fp;
{
return(myfflush(fp));
}

View File

@@ -0,0 +1,485 @@
/*
* Copies of header files used for initialization
*/
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
/*intermediate code operators*/
/*0=>EOF, special operator*/
#define EOF 0
/*1-59=>operators that generate code (entries in code gen optab)*/
#define ADD 1
#define SUB 2
#define MULT 3
#define DIV 4
#define MOD 5
#define RSH 6
#define LSH 7
#define AND 8
#define OR 9
#define XOR 10
#define NOT 11
#define UMINUS 12
#define COMPL 13
#define PREDEC 14
#define PREINC 15
#define POSTDEC 16
#define POSTINC 17
#define ASSIGN 18
#define EQADD 19
#define EQSUB 20
#define EQMULT 21
#define EQDIV 22
#define EQMOD 23
#define EQRSH 24
#define EQLSH 25
#define EQAND 26
#define EQOR 27
#define EQXOR 28
#define FJSR 29
#define EQUALS 30
#define NEQUALS 31
#define GREAT 32
#define GREATEQ 33
#define LESS 34
#define LESSEQ 35
#define INT2L 36
#define LONG2I 37
/*machine dependent operators that generate code*/
#define BTST 38
#define LOAD 39
#define LMULT 40
#define LDIV 41
#define LMOD 42
#define LEQMULT 43
#define LEQDIV 44
#define LEQMOD 45
#define EQADDR 46
#define LCGENOP 47 /*change if adding more operators...*/
/*intermediate code operators that do not generate code*/
#define ADDR 60
#define INDR 61
#define LAND 62
#define LOR 63
#define QMARK 64
#define COLON 65
#define COMMA 66
#define CINT 67
#define CLONG 68
#define SYMBOL 69
#define AUTOINC 70
#define AUTODEC 71
#define CALL 72
#define NACALL 73
#define BFIELD 74
#define IFGOTO 75
#define INIT 76
#define CFORREG 77
#define DCLONG 78
/*operators local to parser*/
#define CAST 80
#define SEMI 81
#define LCURBR 82
#define RCURBR 83
#define LBRACK 84
#define RBRACK 85
#define LPAREN 86
#define RPAREN 87
#define STRING 88
#define RESWORD 89
#define APTR 90
#define PERIOD 91
#define SIZEOF 92
#define MPARENS 93
#define STACKEND 100
/*data types*/
#define TYPELESS 0
#define CHAR 1
#define SHORT 2
#define INT 3
#define LONG 4
#define UCHAR 5
#define USHORT 6
#define UNSIGNED 7
#define ULONG 8
#define FLOAT 9
#define DOUBLE 10
/*data types local to parser*/
#define STRUCT 11
#define FRSTRUCT 12
#define LLABEL 13
/*type flags and definitions*/
#define TYPE 017
#define SUPTYP 060
#define ALLTYPE 077
#define POINTER 020
#define FUNCTION 040
#define ARRAY 060
#define SUTYPLEN 2
/* data registers*/
#define DREG2 2
#define DREG3 3
#define DREG4 4
#define DREG5 5
#define DREG6 6
#define DREG7 7
#define AREG3 11
#define AREG4 12
#define AREG5 13
/*storage classes*/
#define AUTO 1
#define REGISTER 2
#define EXTERNAL 3
#define STATIC 4
#define REGOFF 5
#define EXTOFF 6
#define STATOFF 7
#define INDEXED 8
/*exclusively code generator storage classes*/
#define CINDR 9
#define CLINDR 10
/*exclusively parser storage classes*/
#define STRPROTO 9
#define PDECLIST 10
#define PARMLIST 11
#define BFIELDCL 12
#define UNELCL 13
#define STELCL 14
/*opinfo table bits*/
#define OPPRI 077
#define OPBIN 0100
#define OPLVAL 0200
#define OPREL 0400
#define OPASSIGN 01000
#define OPLWORD 02000
#define OPRWORD 04000
#define OPCOM 010000
#define OPRAS 020000
#define OPTERM 040000
#define OPCONVS 0100000
/*68000 definitions*/
#define PTRSIZE 4
#define INTSIZE 2
#define LONGSIZE 4
#define SSIZE 8
#define TRUE 1
#define FALSE 0
#define BITSPBYTE 8
/*operator class priorities*/
#define TRMPRI 0 /*terminal nodes*/
#define RPNPRI 1 /*) and ]*/
#define CALPRI 2 /*in-stack call, ( or [*/
#define COLPRI 3 /*init or case priority for : or ,*/
#define STKPRI 4 /*priority of end of stack*/
#define COMPRI 5 /*normal priority for ,*/
#define ASGPRI 6 /*=, +=, -=, *=, /=, %=, ...*/
#define QMKPRI 7 /*?:*/
#define LORPRI 8 /*||*/
#define LNDPRI 9 /*&&*/
#define ORPRI 10 /*|, !*/
#define ANDPRI 11 /*&*/
#define EQLPRI 12 /*==, !=*/
#define RELPRI 13 /*>, <, >=, <=*/
#define SHFPRI 14 /*<<, >>*/
#define ADDPRI 15 /*+, -*/
#define MULPRI 16 /**, /, %*/
#define UNOPRI 17 /*++, --, &, *, -, ~, sizeof*/
#define LPNPRI 18 /*., ->, [, (, function call*/
#define PSTPRI 19 /*in-stack post--, post++*/
struct io_buf {
int io_fd;
int io_nc;
char *io_p;
char io_b[512];
};
struct { int hiword; int loword; };
#define EXPSIZE 1024
int exprarea[EXPSIZE]= {0}
/*symbol attribute fields*/
#define SRESWORD 001 /*is symbol a reserved word?*/
#define SGLOBAL 002 /*is symbol global?*/
#define STYPEDEF 004 /*typedef declaration?*/
#define SDEFINED 010 /*symbol defined?*/
/*reserved words*/
#define R_AUTO 1
#define R_BREAK 2
#define R_CASE 3
#define R_CHAR 4
#define R_CONTINUE 5
#define R_DO 6
#define R_DEFAULT 7
#define R_DOUBLE 8
#define R_GOTO 9
#define R_ELSE 10
#define R_EXTERNAL 11
#define R_FLOAT 12
#define R_FOR 13
#define R_IF 14
#define R_INT 15
#define R_LONG 16
#define R_REGISTER 17
#define R_RETURN 18
#define R_SHORT 19
#define R_SIZEOF 20
#define R_STATIC 21
#define R_STRUCT 22
#define R_SWITCH 23
#define R_TYPEDEF 24
#define R_UNION 25
#define R_UNSIGNED 26
#define R_WHILE 27
/*mixed-mode conversions, entries in 2-d array indexed by:*/
/*(int,unsn,long,doub,ptr)*/
#define INT_UNSN 0 /*no conversion is generated*/
#define INT_LONG 2
#define INT_DOUB 3
#define INT_PTR 4
#define UNSN_INT 0 /*no conversion is generated*/
#define UNSN_LONG 6
#define UNSN_DOUB 7
#define UNSN_PTR 8
#define LONG_INT 9
#define LONG_UNSN 10
#define LONG_DOUB 11
#define LONG_PTR 12
#define DOUB_INT 13
#define DOUB_UNSN 14
#define DOUB_LONG 15
#define PTR_INT 16
#define PTR_UNSN 17
#define PTR_LONG 18
#define PTR_PTR 19
#define BADCONV 20
#define SSIZE 8 /*chars per symbol*/
#define OPSSIZE 40 /*operator stack size*/
#define OPDSIZE 80 /*operand stack size*/
#define HSIZE 512 /*hash table size*/
#define SYMSIZE 1024 /*size to alloc for symbol structures*/
#define SWSIZE 256 /*max no. of cases in a switch*/
#define DSIZE 1000 /*dimension table size*/
#define BITSPWORD 16 /*bits per word*/
#define AREGLO 010 /*A reg flag*/
#define HICREG 2 /*highest reg # used for code generation*/
#define BITSPCHAR 8 /*bits per char*/
#define CHRSPWORD 2 /*chars per word*/
#define STRSIZE 300 /*max string length*/
#define NFARGS 40 /*max no. of args to function*/
#define NFRSTR 20 /*max no. of forward ref struct proto*/
/*symbol table node*/
struct symbol {
char s_attrib;
char s_sc;
int s_type;
int s_dp;
int s_ssp;
int s_offset;
char s_symbol[SSIZE];
struct symbol *s_next;
};
/*expression tree operator node*/
struct tnode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
struct tnode *t_left;
struct tnode *t_right;
};
/*expression tree node for symbol - only keeps location*/
struct symnode {
int t_op;
int t_type; /*data type of symbol*/
int t_dp; /*dimension pointer of symbol*/
int t_ssp; /*structure size index to dtab*/
int t_sc; /*storage class of symbol*/
int t_offset; /*offset of symbol*/
int t_label;
};
/*expression tree node for external symbol - need to keep name*/
struct extnode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
int t_sc;
int t_offset;
int t_reg;
int t_symbol[SSIZE]; /*symbol name*/
};
/*expression tree node for integer constant*/
struct conode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
int t_value; /*constant value*/
};
struct lconode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
long t_lvalue; /*constant value*/
};
struct swtch {
int sw_label;
int sw_value;
} swtab[SWSIZE] = {0};
/*operator and operand stack used by expr*/
struct ops { /*operator stack*/
int o_op; /*operator*/
int o_pri; /*priority*/
} opstack[OPSSIZE] = {0},
*opp=0;
char *opdstack[OPDSIZE]={0}; /*operand stack*/
char **opdp=0; /*operand stack pointer*/
char *opap=0; /*pointer to next available loc in exprarea*/
char *exprp; /*place to start building expression*/
int opinfo[]; /*operator info table*/
struct tnode *frp={0}; /*pointer to function return info node*/
int swp; /*current entry in switch table*/
int cswp=0; /*current low switch table index*/
int nextlabel; /*generates unique label numbers*/
int clabel=0; /*continue label*/
int blabel=0; /*break label*/
int rlabel=0; /*return label*/
int dlabel=0; /*default label*/
int lineno=0; /*current line number of input*/
int errcnt=0; /*count of errors*/
int equalstop=0; /*stop lex at '=', used for external init*/
int commastop=0; /*stop parse at comma(used for const expr)*/
int colonstop=0; /*stop parser at colon(used for case value)*/
int instruct=0; /*set when in structure declaration*/
int infunc=0; /*set when in function body*/
int smember=0; /*set when seen . or ->*/
int tdflag=0; /*declaration is a typedef proto*/
char *tdp=0; /*points to typedef prototype*/
int localsize=0; /*length of local variables*/
int naregs=0; /*keeps track of pointer registers alloc'd*/
int ndregs=0; /*keep track of data registers alloc'd*/
int loadreg=0; /*need to load registers...*/
int boffset=0; /*current bit offset in structure*/
int xflag=0; /*translate int's to long's*/
/*dimension table*/
int dtab[DSIZE]={0};
int cdp=0; /*next entry in dtab to alloc*/
/*lexical analyzer values*/
int cvalue=0; /*current token value if keyword or CINT*/
int cstrsize=0; /*current string size*/
long clvalue=0; /*current token value if long constant*/
struct symbol *csp=0; /*current token symbol ptr if SYMBOL*/
char cstr[STRSIZE]={0}; /*current token value if CSTRING*/
struct symbol *dsp=0; /*declarator symbol pointer*/
/*function argument table, used to collect function parameters*/
struct farg {
struct symbol *f_sp;
int f_offset;
} fargtab[NFARGS]={0};
/*forward referenced structure prototype names*/
struct symbol *frstab[NFRSTR]={0};
int frstp=0;
/*output buffers for intermediate code and strings*/
struct io_buf obuf = {0},
sbuf = {0},
ibuf = {0},
*obp = 0;
#define stypedef(sp) (sp->s_attrib&STYPEDEF)
#define wallign(add) ((add+1)&(~1))
#define array(type) ((type&SUPTYP)==ARRAY)
#define function(type) ((type&SUPTYP)==FUNCTION)
#define pointer(type) ((type&SUPTYP)==POINTER)
#define notarray(type) ((type&SUPTYP)!=ARRAY)
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
#define notpointer(type) ((type&SUPTYP)!=POINTER)
#define btype(type) (type&TYPE)
#define suptype(type) (type&SUPTYP)
#define alltype(type) (type&(SUPTYP|TYPE))
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
#define relop(op) ((opinfo[op]&OPREL)!=0)
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
#define binop(op) ((opinfo[op]&OPBIN)!=0)
#define unaryop(op) ((opinfo[op]&OPBIN)==0)
#define leaf(op) ((opinfo[op]&OPTERM)!=0)
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
#define oppriority(op) (opinfo[op]&OPPRI)
#define makeiop(op) (op|(0254<<8))
/*functions returning pointers*/
char *expr();
char *talloc();
char *tnalloc();
char *enalloc();
char *snalloc();
char *cnalloc();
char *lcnalloc();
char *popopd();
char *cvopgen();
char *funcref();
char *arrayref();
char *install();
char *lookup();
char *sbrk();
char *balpar();
int begseq=0;
int dflag=0;
int inclflag=0;
int inittype=0;
int onepass=0;
int opdontop=0;
int pbchar=0;
int peektok=0;
struct symbol *symbols=0;
struct symbol *symtab[HSIZE] = {0};
fflush(fp)
char *fp;
{
return(myfflush(fp));
}

View File

@@ -0,0 +1,5 @@
fflush(fp)
char *fp;
{
return(myfflush(fp));
}

View File

@@ -0,0 +1,103 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "parser.h"
int bol;
outinit(tp,type) /* returns - none*/
struct tnode *tp;
{
outexpr(tnalloc(INIT,type,0,0,tp));
}
outifgoto(tp,dir,lab)
struct tnode *tp;
int dir;
int lab;
{
outexpr(tnalloc(IFGOTO,dir,lab,0,tp));
}
outforreg(tp)
struct tnode *tp;
{
outexpr(tnalloc(CFORREG,INT,0,0,tp));
}
outexpr(tp)
struct tnode *tp;
{
if( bol == 0 )
putchar('\n');
printf(".%x\n",lineno);
outtree(tp);
}
outtree(tp)
struct tnode *tp;
{
if( tp == 0 )
return;
printf("%x.%x",tp->t_op,tp->t_type);
switch( tp->t_op ) {
case CINT:
printf(".%x\n",tp->t_value);
break;
case CLONG:
printf(".%x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
break;
case SYMBOL:
printf(".%x",tp->t_sc);
if( tp->t_sc == EXTERNAL )
printf(".%.8s\n",tp->t_symbol);
else
printf(".%x\n",tp->t_offset);
break;
case 0:
putchar('\n');
break;
case IFGOTO:
case BFIELD:
printf(".%x\n",tp->t_dp);
outtree(tp->t_left);
break;
default:
putchar('\n');
outtree(tp->t_left);
if( binop(tp->t_op) )
outtree(tp->t_right);
break;
}
}
/* snalloc - symbol node allocation*/
/* Allocates a tree symbol node and sets the info in it*/
char *snalloc(type,sc,off,dp,ssp) /* returns pointer to node alloc'ed*/
int type; /* symbol type*/
int sc; /* storage class*/
int off; /* offset*/
int dp; /* dimension pointer or other info*/
int ssp; /* structure size pointer*/
{
register struct symnode *snp;
snp = talloc(sizeof(*snp));
snp->t_op = SYMBOL;
snp->t_sc = sc;
snp->t_type = type;
snp->t_dp = dp;
snp->t_ssp = ssp;
snp->t_offset = off;
return(snp);
}

View File

@@ -0,0 +1,666 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "parser.h"
#define SOI '\01'
#define STEL HSIZE/2
/*the following are the cases within gettok, all other cases are*/
/*single character unambiguous tokens. Note that we need to take*/
/*special care not to interfere with the single character unambiguous*/
/*operators, this is why there is a gap between WHITSP and EXCLAM.*/
#define BADC 0 /*bad character*/
#define WHITSP 101 /*white space*/
#define EXCLAM 102 /*exlamation point*/
#define DQUOTE 103 /*double quote*/
#define PERCNT 104 /*percent sign*/
#define AMPER 105 /*ampersand*/
#define SQUOTE 106 /*single quote*/
#define STAR 107 /*asterisk or mult sign*/
#define PLUS 108 /*plus sign*/
#define MINUS 109 /*minus sign*/
#define SLASH 110 /*divide sign*/
#define DIGIT 111 /*0..9*/
#define LCAROT 112 /*less than sign*/
#define EQUAL 113 /*equals sign*/
#define RCAROT 114 /*greater than*/
#define ALPHA 115 /*a..z,A..Z and underbar*/
#define CAROT 116 /*^*/
#define BAR 117 /*vertical bar*/
char ctype[] {
BADC, BADC, BADC, BADC, BADC, BADC, BADC, BADC,
BADC, WHITSP, WHITSP, WHITSP, WHITSP, WHITSP, BADC, BADC,
BADC, BADC, BADC, BADC, WHITSP, BADC, BADC, BADC,
BADC, BADC, BADC, BADC, BADC, BADC, BADC, BADC,
WHITSP, EXCLAM, DQUOTE, BADC, BADC, PERCNT, AMPER, SQUOTE,
LPAREN, RPAREN, STAR, PLUS, COMMA, MINUS, PERIOD, SLASH,
DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
DIGIT, DIGIT, COLON, SEMI, LCAROT, EQUAL, RCAROT, QMARK,
BADC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, LBRACK, BADC, RBRACK, CAROT, ALPHA,
BADC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, LCURBR, BAR, RCURBR, COMPL, BADC
};
/*key word table*/
struct resword {
char *r_name;
int r_value;
} reswords[] {
"auto", R_AUTO,
"break", R_BREAK,
"case", R_CASE,
"char", R_CHAR,
"continue", R_CONTINUE,
"do", R_DO,
"default", R_DEFAULT,
"double", R_DOUBLE,
"goto", R_GOTO,
"else", R_ELSE,
"extern", R_EXTERNAL,
"float", R_FLOAT,
"for", R_FOR,
"if", R_IF,
"int", R_INT,
"long", R_LONG,
"register", R_REGISTER,
"return", R_RETURN,
"short", R_SHORT,
"sizeof", R_SIZEOF,
"static", R_STATIC,
"struct", R_STRUCT,
"switch", R_SWITCH,
"typedef", R_TYPEDEF,
"union", R_UNION,
"unsigned", R_UNSIGNED,
"while", R_WHILE,
0,
};
#define SELFMOD 0200
#define ASMASK 0177
/*this table is used to check for an operator after an equals sign.*/
/*note that =-, =* and =& may all have an ambiguous meaning if not*/
/*followed by a space, this is checked for in gettok.*/
char asmap[] {
EQUALS, /*==*/
EQADD, /*=+*/
EQSUB|SELFMOD, /*=-*/
EQMULT|SELFMOD, /*=**/
EQDIV, /*=/*/
EQOR, /*=|*/
EQAND|SELFMOD, /*=&*/
EQXOR, /*=^*/
EQMOD, /*=%*/
};
char escmap[] "\b\n\r\t";
int pbchar; /*pushed back character*/
struct symbol *symtab[HSIZE]; /*hash table*/
struct symbol *symbols; /*pointer to next avail symbol buf*/
int nsyms; /*number of symbol bufs in memory*/
int inclflag; /*in include area flag, don't*/
/*increment line numbers here*/
int peektok; /*peeked at token*/
/* getdec - get a decimal number*/
/* Uses Horner's method to get decimal number. Note that*/
/* multiplication by 10 is cleverly programmed as two shifts and two*/
/* adds. This is because long multiplies are painful on both the*/
/* PDP-11 and 68000.*/
long getdec() /* returns number*/
{
register long value;
register char c;
for( value = 0; (c=ngetch()) >= '0' && c <= '9'; ) {
value =<< 1; /*value = value*2*/
value =+ value << 2; /*value*2 + value*8 = value*10*/
value =+ (c-'0');
}
putback(c);
return(value);
}
/* gethex - get an hexidecimal number*/
/* Uses Horner's method to get hexidecimal number*/
long gethex() /* returns number*/
{
register long value;
register char c;
value = 0;
while( 1 ) {
if( (c=ngetch()) >= '0' && c <= '9' )
c =- '0';
else if( c >= 'a' && c <= 'f' )
c =- ('a'-10);
else if( c >= 'A' && c <= 'F' )
c =- ('A'-10);
else
break;
value = (value<<4) + c;
}
putback(c);
return(value);
}
/* getoct - get an octal number*/
/* Uses Horner's method to get octal number*/
long getoct(flag) /* returns number*/
int flag; /* string flag 1=>in string, else 0*/
{
register long value;
register char c;
register int count;
count = 0;
for( value = 0; (c=ngetch()) >= '0' && c <= '7'; ) {
if( flag && ++count > 3 )
break;
value = (value<<3) + (c-'0');
}
putback(c);
return(value);
}
/* gettok - get next token from input*/
/* Checks pushed-packed token buffer, supresses / * * / comments,*/
/* folds multiple character special symbols into single word token.*/
gettok() /* returns token type*/
{
register int c, nextc, i;
register char *p;
register long value;
char sym[SSIZE];
if( peektok ) {
i = peektok;
peektok = 0;
return(i);
}
while( (c=ngetch()) != EOF ) {
switch(ctype[c]) {
case BADC: /*bad character*/
error("invalid character");
break;
default:
return( ctype[c] );
case WHITSP: /*skip all white space*/
break;
case EXCLAM: /*!= or !*/
return( peekis('=') ? NEQUALS : NOT );
case DQUOTE: /*quoted string*/
getstr(cstr,STRSIZE,'"');
cvalue = nextlabel++;
return(STRING);
case PERCNT: /*%= or %*/
return( peekis('=') ? EQMOD : MOD );
case AMPER: /*&=, && or &*/
return( peekis('=') ? EQAND : peekis('&') ? LAND : AND );
case SQUOTE: /*character constant*/
getstr(cstr,STRSIZE,'\'');
if( cstrsize > CHRSPWORD+1 ) {
error("character constant too long");
cstrsize = CHRSPWORD + 1;
}
cvalue = 0;
for( p = cstr; --cstrsize > 0; ) {
cvalue =<< BITSPCHAR;
cvalue =| (*p++ & 0377);
}
return(CINT);
case STAR: /**= or **/
return( peekis('=') ? EQMULT : MULT );
case PLUS: /*+=, ++ or +*/
return( peekis('=') ? EQADD : peekis('+') ? PREINC : ADD );
case MINUS: /*-=, --, -> or -*/
return( peekis('=') ? EQSUB : peekis('-') ? PREDEC :
peekis('>') ? APTR : SUB );
case SLASH: /*/ *..* /, //..., /= or /*/
if( peekis('*') ) {
while( (c=ngetch()) != EOF )
if( c == '*' && peekis('/') )
break;
if( c == EOF ) {
error("no */ before EOF");
return(EOF);
}
continue;
}
if( peekis('/') ) {
while( (c=ngetch()) != EOF && c != '\n' )
;
continue;
}
return( peekis('=') ? EQDIV : DIV );
case DIGIT: /*number constant (long or reg)*/
i = 0; /*flags if long constant*/
if( c != '0' ) {
putback(c);
value = getdec();
if( value > 32767 || value < -32768 )
i++;
}
else if( peekis('x') || peekis('X') ) {
value = gethex();
if( value < 0 || value >= 0x10000L )
i++;
}
else {
value = getoct(0);
if( value < 0 || value >= 0x10000L )
i++;
}
if( peekis('l') || peekis('L') || i ) {
clvalue = value;
return(CLONG);
}
cvalue = value;
return(CINT);
case LCAROT: /*<=, <<, <<= or <*/
return( peekis('=') ? LESSEQ : peekis('<') ?
(peekis('=') ? EQLSH : LSH) : LESS );
case EQUAL: /*==, =<<, =>>, =+, ..., =*/
if( peekis('<') ) {
if( peekis('<') )
return(EQLSH);
}
else if( peekis('>') ) {
if( peekis('>') )
return(EQRSH);
}
else if( (i=index("=+-*/|&^%",(c=ngetch()))) >= 0 ) {
i = asmap[i];
if( i & SELFMOD ) {
if( (nextc=ngetch()) != ' ' )
error("=%c assumed",c);
putback(nextc);
}
return( i & ASMASK );
}
else
putback(c);
return(ASSIGN);
case RCAROT: /*>=, >>, >>= or >*/
return( peekis('=') ? GREATEQ : peekis('>') ?
(peekis('=') ? EQRSH : RSH) : GREAT );
case ALPHA: /*[A-Za-z][A-Za-z0-9]**/
p = &sym[0];
i = SSIZE;
for(; ctype[c] == ALPHA || ctype[c] == DIGIT; c=ngetch(),i-- )
if( i > 0 )
*p++ = c;
if( i > 0 )
*p = '\0';
putback(c);
csp = lookup(sym);
if( csp->s_attrib & SRESWORD ) {
cvalue = csp->s_offset;
return(RESWORD);
}
smember = 0;
return(SYMBOL);
case CAROT: /*^= or ^*/
return( peekis('=') ? EQXOR : XOR );
case BAR: /*|=, || or |*/
return( peekis('=') ? EQOR : peekis('|') ? LOR : OR );
}
}
return(EOF);
}
/* 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);
}
/* ngetch - get a possibly pushed back character*/
/* Checks pbchar variable, returns it if non-zero, handles counting*/
/* of new lines and whether you are in an include or not.*/
ngetch() /* returns character read or EOF*/
{
register int c;
if( pbchar ) {
c = pbchar;
pbchar = 0;
}
else if( (c=getc(&ibuf)) == '\n' ) {
if( inclflag )
inclflag = 0;
else
lineno++;
}
else if( c == SOI ) {
inclflag++;
c = ' ';
}
else if( c < 0 )
c = EOF;
return(c);
}
/* peekc - peek at the next non-whitespace character after token*/
/* This allows for the problem of having to look at two tokens*/
/* at once. The second token is always a semi-colon or colon,*/
/* so we only look at the single character, rather than going*/
/* thru gettok.*/
peekc(tc) /* returns 1 if match, 0 otherwise*/
int tc; /* character to look for*/
{
register int c;
while( (c=ngetch()) == ' ' || c == '\t' || c == '\n' )
;
if( c == tc )
return(1);
putback(c);
return(0);
}
/* putback - puts back a single character*/
/* Checks pbchar for error condition.*/
putback(c) /* returns - none*/
int c;
{
if( pbchar )
error("too many chars pushed back");
else
pbchar = c;
}
/* 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;
cstrsize = 1;
p = str;
for( i = nchars; (c=ngetch()) != endc; i-- ) {
if( c == EOF || c == '\n' ) {
error("string cannot cross line");
break;
}
if( c == '\\' ) {
if( (c=ngetch()) >= '0' && c <= '7' ) {
putback(c);
if( (c=getoct(1)) < 0 || c > 255 ) {
error("bad character constant");
continue;
}
}
else if( (j=index("bnrt",c)) >= 0 )
c = escmap[j];
else if( c == '\n' ) /*escape followed by nl->ignore*/
continue;
}
if( i > 0 ) { /*room left in string?*/
cstrsize++;
*p++ = c;
}
else if( i == 0 ) /*only say error once...*/
error("string too long");
}
if( i <= 0 ) /*string overflow?*/
p--;
*p = '\0';
}
/* syminit - initialize the symbol table, install reswords*/
/* Goes thru the resword table and installs them into the symbol*/
/* table.*/
syminit() /* returns - none*/
{
register struct resword *rp;
for( rp = &reswords[0]; rp->r_name != 0; rp++ )
install(rp->r_name,SRESWORD|SDEFINED,rp->r_value);
}
/* install - install a symbol in the symbol table*/
/* Allocates a symbol entry, copies info into it and links it*/
/* into the hash table chain.*/
char *install(sym,attrib,offset) /* returns pointer to symbol struct*/
char *sym; /* symbol to install*/
int attrib; /* attribues of symbol*/
int offset; /* symbol offset (resword value)*/
{
register struct symbol *sp;
register int i;
while( (sp=symbols) == 0 ) {
if( (sp=sbrk(SYMSIZE)) == 0 )
ferror("symbol table overflow");
for( i = SYMSIZE/(sizeof *symbols); --i >= 0; ) {
sp->s_next = symbols;
symbols = sp++;
}
}
symbols = sp->s_next;
sp->s_attrib = attrib;
sp->s_sc = 0;
sp->s_type = 0;
sp->s_dp = 0;
sp->s_ssp = 0;
sp->s_offset = offset;
symcopy(sym,sp->s_symbol); /*copy symbol to symbol struct*/
i = symhash(sym,instruct|smember); /*link into chain list*/
sp->s_next = symtab[i];
symtab[i] = sp;
return(sp);
}
/* lookup - looks up a symbol in symbol table*/
/* Hashes symbol, then goes thru chain, if not found, then*/
/* installs the symbol.*/
char *lookup(sym) /* returns pointer to symbol buffer*/
char *sym; /* pointer to symbol*/
{
register struct symbol *sp;
register char *p;
p = sym;
for( sp = symtab[symhash(p,0)]; sp != 0; sp = sp->s_next )
if((sp->s_attrib&(SRESWORD|STYPEDEF)) && symequal(p,sp->s_symbol))
return(sp);
for( sp=symtab[symhash(p,instruct|smember)]; sp != 0; sp=sp->s_next )
if( symequal(p,sp->s_symbol) )
return(sp);
return(install(p,0,0));
}
/* freesyms - frees all local symbols at end of function declaration*/
/* Searches thru symbol table, deleting all symbols marked as locals*/
freesyms() /* returns - none*/
{
register int i, tinfo;
register struct symbol *sp, *tp, *nextp, **htp;
for( htp = &symtab[0], i = HSIZE; --i >= 0; htp++ )
for( tp = 0, sp = *htp; sp != 0; sp = nextp ) {
nextp = sp->s_next;
if( (sp->s_attrib&SDEFINED) == 0 ) {
error("undefined label: %.8s",sp->s_symbol);
sp->s_attrib =| SDEFINED;
}
if( sp->s_attrib & (SGLOBAL|SRESWORD) )
tp = sp;
else {
if( tp )
tp->s_next = sp->s_next;
else
*htp = sp->s_next;
sp->s_next = symbols;
symbols = sp;
}
}
}
/* chksyms - checks symbol table for undefined symbols, etc.*/
/* Goes thru the symbol table checking for undeclared forward*/
/* referenced structures, and outputs local symbols for debugger.*/
chksyms() /* returns - none*/
{
register struct symbol **htp, *sp;
register int i, tinfo, sc;
for( htp = &symtab[0], i = HSIZE; --i >= 0; htp++ )
for( sp = *htp; sp != 0; sp = sp->s_next ) {
sc = sp->s_sc;
if( sc != 0 && btype(sp->s_type) == FRSTRUCT ) {
sp->s_ssp = frstab[sp->s_ssp]->s_ssp;
sp->s_type = (sp->s_type&~TYPE) | STRUCT;
}
if( sc == STRPROTO && dtab[sp->s_ssp] == 0 )
error("not a structure: %.8s",sp->s_symbol);
if( sc == PDECLIST ) {
error("not in parameter list: %.8s",sp->s_symbol);
sp->s_sc = AUTO;
}
if( infunc )
outlocal(sp->s_type,sp->s_sc,sp->s_symbol,sp->s_offset);
}
}
/* symhash - compute hash value for symbol*/
/* Sums the symbols characters and takes that modulus the hash table*/
/* size.*/
symhash(sym,stel) /* returns hash value for symbol*/
char *sym; /* pointer to symbol*/
int stel; /* structure element flag*/
{
register char *p;
register int hashval, i;
hashval = (stel ? STEL : 0 );
for( p = sym, i = SSIZE; *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;
for( p = sym1, q = sym2, i = SSIZE; *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; )
*q++ = ( *p ? *p++ : '\0');
}
/* index - find the index of a character in a string*/
/* This is identical to Software Tools index.*/
index(str,chr) /* returns index of c in str or -1*/
char *str; /* pointer to string to search*/
char chr; /* character to search for*/
{
register char *s;
register int i;
for( s = str, i = 0; *s != '\0'; i++ )
if( *s++ == chr )
return(i);
return(-1);
}
/* peek - peek at the next token, put back read token if not token*/
/* If token matches specified token, delete token and return*/
/* match, otherwise put token back and return failed.*/
peek(tok) /* returns 1 if matched, 0 otherwise.*/
int tok; /* token to match*/
{
register int token;
return( (peektok=gettok()) == tok );
}
/* next - if next token matches given token, skip and return success*/
/* This allows for clean parsing of declarations.*/
next(tok) /* returns 1 if matched, 0 otherwise*/
int tok;
{
register int token;
if( (token=gettok()) == tok )
return(1);
peektok = token;
return(0);
}
/* pbtok - put back the given token*/
/* This merely sets the peektok variable*/
pbtok(tok) /* returns - none*/
int tok;
{
if( peektok )
error("too many tokens pushed back");
peektok = tok;
}

View File

@@ -0,0 +1 @@
lo68 -r -s -o c068.rel startup.o decl.o expr.o icode.o interf.o lex.o main.o stmt.o tabl.o initx.o lib6.a

View File

@@ -0,0 +1,36 @@
$ num
DECL.C
DECL.lis
$ num
EXPR.C
EXPR.lis
$ num
ICODE.C
ICODE.lis
$ num
INIT.C
INIT.lis
$ num
INITX.C
INITX.lis
$ num
INTERF.C
INTERF.lis
$ num
LEX.C
LEX.lis
$ num
MAIN.C
MAIN.lis
$ num
STMT.C
STMT.lis
$ num
TABL.C
TABL.lis
$ num
ICODE.H
ICODE.lst
$ num
PARSER.H
PARSER.lst

View File

@@ -0,0 +1,143 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
/*
ALCYON C Compiler for the Motorola 68000 - Parser
Called from c68:
c068 source icode strings
source: input source code, preprocessed with comments stripped
icode: contains the intermediate code for the code generator,
for a detailed explanaion see ../doc/icode.
strings: contains all the string constants.
The basic structure of the parser is as follows:
main main driver for parser
syminit initializes symbol table
doextdef external definition syntax
getatt get type attributes
dlist declaration list for structures/unions
getatt recursive gettype call
dodecl do one declaration
declarator handle declarator syntax
dodecl do one external declaraion
initlist external initialization list
cexpr constant expressions
expr arithmetic expressions
maketree build operator tree
funcbody function body
dlist declaration list
stmt function statements
stmt recursive stmt call
expr arithmetic expressions
*/
#include "parser.h"
int nextlabel 1;
int lineno;
char *exprp &exprarea[0];
int dflag;
int lflag 0;
int onepass;
/* main - main routine for parser*/
/* Checks arguments, opens input and output files, does main loop*/
/* for external declarations and blocks.*/
main(argc,argv) /* returns - none*/
int argc; /* argument count*/
char *argv[]; /* argument pointers*/
{
register char *q;
register int i;
for( i = 4; i < argc; i++ ) {
q = argv[i];
if( *q++ != '-' )
usage();
while( 1 ) {
switch( *q++ ) {
case 'D':
dflag++;
continue;
case '1':
onepass++;
continue;
case 'L':
lflag++;
continue;
case '\0':
break;
default:
usage();
}
break;
}
}
if( argc < 4 )
usage();
if( fopen(argv[1],&ibuf,0) < 0 )
ferror("can't open %s",argv[i]);
if( fcreat(argv[2],&obuf,0) < 0 || fcreat(argv[3],&sbuf,0) < 0 )
ferror("temp creation error");
obp = &obuf;
lineno++;
syminit();
while( peek(EOF) == 0 )
doextdef();
outeof();
outdata();
copysfile(argv[3]);
exit(errcnt!=0);
}
/* usage - output usage error message and die*/
usage()
{
ferror("usage: c068 source asm str [-DL]");
}
/* error - report an error message*/
/* outputs current line number and error message*/
error(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
char *s; /* error message*/
int x1, x2, x3, x4, x5, x6; /* args for printf*/
{
register char *savep;
savep = obp;
obp = 0;
errcnt++;
if( lineno )
printf("* %d: ",lineno);
printf(s,x1,x2,x3,x4,x5,x6);
printf("\n");
obp = savep;
}
/* ferror - fatal error*/
/* Outputs error message and exits*/
ferror(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
char *s; /* error message*/
int x1, x2, x3, x4, x5, x6; /* args for printf*/
{
error(s,x1,x2,x3,x4,x5,x6);
exit(-1);
}

View File

@@ -0,0 +1,12 @@
$ set def [steve.cpm68k.c.parser]
$ set noon
$ cc68 DECL
$ cc68 EXPR
$ cc68 ICODE
$ cc68 INTERF
$ cc68 LEX
$ cc68 MAIN
$ cc68 STMT
$ cc68 TABL
$ cc68 initx
$ @relink

View File

@@ -0,0 +1,82 @@
cp68 DECL.c x.i
c068 x.i x.ic x.st
c168 x.ic DECL.s -l
as68 -l -u DECL.s
era x.i
era x.ic
era x.st
era DECL.s
cp68 EXPR.c x.i
c068 x.i x.ic x.st
c168 x.ic EXPR.s -l
as68 -l -u EXPR.s
era x.i
era x.ic
era x.st
era EXPR.s
cp68 ICODE.c x.i
c068 x.i x.ic x.st
c168 x.ic ICODE.s -l
as68 -l -u ICODE.s
era x.i
era x.ic
era x.st
era ICODE.s
cp68 INTERF.c x.i
c068 x.i x.ic x.st
c168 x.ic INTERF.s -l
as68 -l -u INTERF.s
era x.i
era x.ic
era x.st
era INTERF.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 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 STMT.c x.i
c068 x.i x.ic x.st
c168 x.ic STMT.s -l
as68 -l -u STMT.s
era x.i
era x.ic
era x.st
era STMT.s
cp68 TABL.c x.i
c068 x.i x.ic x.st
c168 x.ic TABL.s -l
as68 -l -u TABL.s
era x.i
era x.ic
era x.st
era TABL.s
cp68 initx.c x.i
c068 x.i x.ic x.st
c168 x.ic initx.s -l
as68 -l -u initx.s
era x.i
era x.ic
era x.st
era initx.s
submit link

View File

@@ -0,0 +1,260 @@
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
/*
C68 Parser - include file
*/
#include "icode.h"
/*symbol attribute fields*/
#define SRESWORD 001 /*is symbol a reserved word?*/
#define SGLOBAL 002 /*is symbol global?*/
#define STYPEDEF 004 /*typedef declaration?*/
#define SDEFINED 010 /*symbol defined?*/
/*reserved words*/
#define R_AUTO 1
#define R_BREAK 2
#define R_CASE 3
#define R_CHAR 4
#define R_CONTINUE 5
#define R_DO 6
#define R_DEFAULT 7
#define R_DOUBLE 8
#define R_GOTO 9
#define R_ELSE 10
#define R_EXTERNAL 11
#define R_FLOAT 12
#define R_FOR 13
#define R_IF 14
#define R_INT 15
#define R_LONG 16
#define R_REGISTER 17
#define R_RETURN 18
#define R_SHORT 19
#define R_SIZEOF 20
#define R_STATIC 21
#define R_STRUCT 22
#define R_SWITCH 23
#define R_TYPEDEF 24
#define R_UNION 25
#define R_UNSIGNED 26
#define R_WHILE 27
/*mixed-mode conversions, entries in 2-d array indexed by:*/
/*(int,unsn,long,doub,ptr)*/
#define INT_UNSN 0 /*no conversion is generated*/
#define INT_LONG 2
#define INT_DOUB 3
#define INT_PTR 4
#define UNSN_INT 0 /*no conversion is generated*/
#define UNSN_LONG 6
#define UNSN_DOUB 7
#define UNSN_PTR 8
#define LONG_INT 9
#define LONG_UNSN 10
#define LONG_DOUB 11
#define LONG_PTR 12
#define DOUB_INT 13
#define DOUB_UNSN 14
#define DOUB_LONG 15
#define PTR_INT 16
#define PTR_UNSN 17
#define PTR_LONG 18
#define PTR_PTR 19
#define BADCONV 20
#define SSIZE 8 /*chars per symbol*/
#define OPSSIZE 40 /*operator stack size*/
#define OPDSIZE 80 /*operand stack size*/
#define HSIZE 512 /*hash table size*/
#define SYMSIZE 1024 /*size to alloc for symbol structures*/
#define SWSIZE 256 /*max no. of cases in a switch*/
#define DSIZE 1000 /*dimension table size*/
#define BITSPWORD 16 /*bits per word*/
#define AREGLO 010 /*A reg flag*/
#define HICREG 2 /*highest reg # used for code generation*/
#define BITSPCHAR 8 /*bits per char*/
#define CHRSPWORD 2 /*chars per word*/
#define STRSIZE 300 /*max string length*/
#define NFARGS 40 /*max no. of args to function*/
#define NFRSTR 20 /*max no. of forward ref struct proto*/
/*symbol table node*/
struct symbol {
char s_attrib;
char s_sc;
int s_type;
int s_dp;
int s_ssp;
int s_offset;
char s_symbol[SSIZE];
struct symbol *s_next;
};
/*expression tree operator node*/
struct tnode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
struct tnode *t_left;
struct tnode *t_right;
};
/*expression tree node for symbol - only keeps location*/
struct symnode {
int t_op;
int t_type; /*data type of symbol*/
int t_dp; /*dimension pointer of symbol*/
int t_ssp; /*structure size index to dtab*/
int t_sc; /*storage class of symbol*/
int t_offset; /*offset of symbol*/
int t_label;
};
/*expressioon tree node for external symbol - need to keep name*/
struct extnode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
int t_sc;
int t_offset;
int t_reg;
int t_symbol[SSIZE]; /*symbol name*/
};
/*expression tree node for integer constant*/
struct conode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
int t_value; /*constant value*/
};
struct lconode {
int t_op;
int t_type;
int t_dp;
int t_ssp;
long t_lvalue; /*constant value*/
};
struct swtch {
int sw_label;
int sw_value;
} swtab[SWSIZE];
/*operator and operand stack used by expr*/
struct ops { /*operator stack*/
int o_op; /*operator*/
int o_pri; /*priority*/
} opstack[OPSSIZE], *opp;
char *opdstack[OPDSIZE]; /*operand stack*/
char **opdp; /*operand stack pointer*/
char *opap; /*pointer to next available loc in exprarea*/
char *exprp; /*place to start building expression*/
int opinfo[]; /*operator info table*/
struct tnode *frp; /*pointer to function return info node*/
int swp; /*current entry in switch table*/
int cswp; /*current low switch table index*/
int nextlabel; /*generates unique label numbers*/
int clabel; /*continue label*/
int blabel; /*break label*/
int rlabel; /*return label*/
int dlabel; /*default label*/
int lineno; /*current line number of input*/
int errcnt; /*count of errors*/
int equalstop; /*stop lex at '=', used for external init*/
int commastop; /*stop parse at comma(used for const expr)*/
int colonstop; /*stop parser at colon(used for case value)*/
int instruct; /*set when in structure declaration*/
int infunc; /*set when in function body*/
int smember; /*set when seen . or ->*/
int tdflag; /*declaration is a typedef proto*/
char *tdp; /*points to typedef prototype*/
int localsize; /*length of local variables*/
int naregs; /*keeps track of pointer registers alloc'd*/
int ndregs; /*keep track of data registers alloc'd*/
int loadreg; /*need to load registers...*/
int boffset; /*current bit offset in structure*/
int xflag; /*translate int's to long's*/
/*dimension table*/
int dtab[DSIZE];
int cdp; /*next entry in dtab to alloc*/
/*lexical analyzer values*/
int cvalue; /*current token value if keyword or CINT*/
int cstrsize; /*current string size*/
long clvalue; /*current token value if long constant*/
struct symbol *csp; /*current token symbol ptr if SYMBOL*/
char cstr[STRSIZE]; /*current token value if CSTRING*/
struct symbol *dsp; /*declarator symbol pointer*/
/*function argument table, used to collect function parameters*/
struct farg {
struct symbol *f_sp;
int f_offset;
} fargtab[NFARGS];
/*forward referenced structure prototype names*/
struct symbol *frstab[NFRSTR];
int frstp;
/*output buffers for intermediate code and strings*/
struct io_buf obuf, sbuf, ibuf, *obp;
#define stypedef(sp) (sp->s_attrib&STYPEDEF)
#define wallign(add) ((add+1)&(~1))
#define array(type) ((type&SUPTYP)==ARRAY)
#define function(type) ((type&SUPTYP)==FUNCTION)
#define pointer(type) ((type&SUPTYP)==POINTER)
#define notarray(type) ((type&SUPTYP)!=ARRAY)
#define notfunction(type) ((type&SUPTYP)!=FUNCTION)
#define notpointer(type) ((type&SUPTYP)!=POINTER)
#define btype(type) (type&TYPE)
#define suptype(type) (type&SUPTYP)
#define alltype(type) (type&(SUPTYP|TYPE))
#define asgop(op) ((opinfo[op]&OPASSIGN)!=0)
#define relop(op) ((opinfo[op]&OPREL)!=0)
#define lintegral(op) ((opinfo[op]&OPLWORD)!=0)
#define rintegral(op) ((opinfo[op]&OPRWORD)!=0)
#define rasop(op) ((opinfo[op]&OPRAS)!=0)
#define binop(op) ((opinfo[op]&OPBIN)!=0)
#define unaryop(op) ((opinfo[op]&OPBIN)==0)
#define leaf(op) ((opinfo[op]&OPTERM)!=0)
#define lvalop(op) ((opinfo[op]&OPLVAL)!=0)
#define oppriority(op) (opinfo[op]&OPPRI)
#define makeiop(op) (op|(0254<<8))
/*functions returning pointers*/
char *expr();
char *talloc();
char *tnalloc();
char *enalloc();
char *snalloc();
char *cnalloc();
char *lcnalloc();
char *popopd();
char *cvopgen();
char *funcref();
char *arrayref();
char *install();
char *lookup();
char *sbrk();
char *balpar();

View File

@@ -0,0 +1,29 @@
/*****************************************************************************
*
* P R I N T F F U N C T I O N
* -------------------------------
*
* The "printf" function is used to write data to the standard output.
*
* calling sequence:
*
* printf(format,arg1,arg2, ... argn);
*
* Where:
*
* format is a text string as described in K & R
* Arg1-argn are optional arguments to be converted and
* placed in the output
*
*****************************************************************************/
__putc(fd,c) /* WSL is backwards!! */
{ /****************************/
putchar(c); /* Output character */
} /****************************/
printf (fmt,a1) /* Declare args */
char *fmt; /* -> Format string */
int a1; /* Whatever the right size */
{ /****************************/
_printf (0,__putc,fmt,&a1); /* Invoke secret routine */
} /****************************/

View File

@@ -0,0 +1,8 @@
$ set def [steve.cpm68k.c.parser]
$ set noon
$ conv :== $bin:conv
$ lo68 -r -s -o c068.out lib:startup.o decl.o expr.o icode.o interf.o lex.o -
main.o stmt.o tabl.o initx.o lib:lib6.a
$ conv
c068.out
[--.asc]c068.asc

View File

@@ -0,0 +1,475 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "parser.h"
#define labgen(l,sl) sl=l;l=nextlabel++;
int swp -1;
/* stmt - process a single statement*/
stmt() /* returns - none*/
{
register int token, saveblab, saveclab, lab, i;
register struct tnode *tp;
register char *p;
while( 1 ) {
switch(token=gettok()) {
case LCURBR: /*handle { ... }*/
while( next(EOF) == 0 ) {
if( next(RCURBR) )
return;
stmt();
}
case EOF:
error("{ not matched by }");
case SEMI: /*null statement*/
return;
case RCURBR:
pbtok(token);
return;
case SYMBOL: /*symbol: statement*/
if( peekc(':') ) {
dolabel();
continue;
}
default: /*anything else...*/
pbtok(token);
outexpr(expr());
break;
case RESWORD:
switch(cvalue) {
case R_BREAK:
outgoto(brklabel()); /*branch to break label*/
break;
case R_CASE:
docase();
continue;
case R_CONTINUE:
outgoto(contlabel()); /*branch to continue label*/
break;
case R_DEFAULT:
dodefault();
continue;
case R_DO:
dodo();
break;
case R_FOR:
dofor();
return;
case R_GOTO:
outgoto(gotolabel());
break;
case R_IF:
doif();
return;
case R_RETURN:
doreturn();
break;
case R_SWITCH:
doswitch();
return;
case R_WHILE:
dowhile();
return;
default:
synerr("invalid keyword");
return;
}
}
if( next(SEMI) == 0 )
synerr("missing semicolon");
return;
}
}
/* balpar - handle expression within parenthesis for while and if*/
/* Merely checks for left and right parens and builds expression.*/
char *balpar() /* returns pointer to expression*/
{
register struct tnode *tp;
if( next(LPAREN) ) {
tp = expr();
if( next(RPAREN) )
return(tp);
}
synerr("parenthesized expression syntax");
return(0);
}
/* synerr - syntax error*/
/* Outputs error message and tries to resyncronize input.*/
synerr(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
char *s; /* printf format string*/
int x1, x2, x3, x4, x5, x6; /* printf arguments*/
{
register int token;
error(s,x1,x2,x3,x4,x5,x6);
while( (token=gettok()) != SEMI && token != EOF && token != LCURBR &&
token != RCURBR )
;
pbtok(token);
}
/* gotolabel - gets label id for goto*/
/* This is used for both: goto symbol and if(...)goto symbol*/
gotolabel() /* returns 0 if not, else label id*/
{
register struct symbol *sp;
if( next(SYMBOL) == 0 )
synerr("expected label");
else {
if( (sp=csp)->s_sc == 0 ) {
sp->s_type = LLABEL;
if( sp->s_offset == 0 )
sp->s_offset = nextlabel++;
}
if( (sp->s_sc == 0 || sp->s_sc == STATIC ) &&
sp->s_type == LLABEL )
return(sp->s_offset);
synerr("invalid label");
}
return(0);
}
/* dolabel - do statement label*/
/* Checks current symbol for already being defined, then sets*/
/* symbol attributes for label.*/
dolabel() /* returns - none*/
{
register struct symbol *sp;
sp = csp;
if( sp->s_sc )
error("label redeclaration: %.8s",sp->s_symbol);
else {
sp->s_attrib =| SDEFINED;
sp->s_sc = STATIC;
sp->s_type = LLABEL;
if( sp->s_offset == 0 )
sp->s_offset = nextlabel++;
outlab(sp->s_offset);
}
}
/* brklabel - generate break label*/
/* Checks if break label is undefined, and if so, generates message*/
brklabel() /* returns label number*/
{
if( blabel == 0 )
error("invalid break statement");
return(blabel);
}
/* contlabel - generate continue label*/
/* Checks if continue label is undefined, and if so, generates message*/
contlabel() /* returns label number*/
{
if( clabel == 0 )
error("invalid continue statement");
return(clabel);
}
/* docase - handles: case constant : statement*/
/* Checks for being in a switch statement, adds entry to switch table*/
docase() /* returns - none*/
{
register int value, lab;
colonstop++;
value = cexpr(); /*get case value*/
colonstop--;
if( next(COLON) == 0 ) /*check for colon*/
synerr("missing colon");
if( swp < 0 )
error("case not inside a switch block");
else if( swp >= (SWSIZE-1) )
error("too many cases in switch");
else {
addswitch(&swtab[cswp],swp-cswp,value,lab=nextlabel++);
outlab(lab);
swp++;
}
}
/* dodefault - handles: default : statement*/
/* Checks for colon and being in a switch statement*/
dodefault() /* returns - none*/
{
if( next(COLON) == 0 )
error("missing colon");
if( swp < 0 )
error("default not inside a switch block");
else {
dlabel = nextlabel++; /*allocate default label*/
outlab(dlabel); /*output default label*/
}
}
/* dodo - handles: do statement while ( expression )*/
dodo() /* returns - none*/
{
register int lab, saveblab, saveclab;
labgen(blabel,saveblab);
labgen(clabel,saveclab);
lab = nextlabel++;
outlab(lab); /*branch back to here*/
stmt(); /*do statement*/
outlab(clabel); /*continue label*/
if( nextrw(R_WHILE) == 0 ) {
error("missing while"); /*only advisory...*/
outgoto(lab);
}
else
outifgoto(balpar(),TRUE,lab); /*while expression*/
outlab(blabel); /*break label*/
blabel = saveblab; /*restore labels*/
clabel = saveclab;
}
/* dofor - handle: for ( expression ; expression ; expression ) statement*/
/* Hard part is handling re-initialization expression, which is*/
/* parsed and saved, then the statement is parsed, then the reinit*/
/* clause expression tree is output.*/
dofor() /* returns - none*/
{
register int lab, saveblab, saveclab, reinit, clineno;
register char *savep;
register struct tnode *tp;
labgen(blabel,saveblab);
labgen(clabel,saveclab);
if( next(LPAREN) == 0 ) {
forerr:
synerr("invalid for statement");
return;
}
if( next(SEMI) == 0 ) { /*do init expression*/
outexpr(expr());
if( next(SEMI) == 0 )
goto forerr;
}
outlab(clabel); /*branch back to here*/
if( next(SEMI) == 0 ) { /*do for condition*/
outifgoto(expr(),FALSE,blabel);
if( next(SEMI) == 0 )
goto forerr;
}
if( next(RPAREN) ) { /*no re-init - easy case*/
stmt(); /*output statement*/
outgoto(clabel); /*output continue label*/
}
else { /*there is a re-init clause*/
labgen(clabel,lab);
savep = exprp;
tp = expr(); /*save re-init tree until done*/
exprp = opap; /*remember until reinit is output*/
reinit = lineno;
if( next(RPAREN) == 0 )
goto forerr;
stmt(); /*do statment*/
clineno = lineno;
lineno = reinit;
outlab(clabel); /*we branch to here for reinit*/
outexpr(tp); /*output re-init clause*/
exprp = savep;
lineno = clineno;
outgoto(lab); /*branch back to top of loop*/
}
outlab(blabel); /*break to here*/
blabel = saveblab;
clabel = saveclab; /*restore labels*/
}
/* doif - handles: if ( expression ) statement [ else statement ]*/
/* Handles special cases for goto, break, continue and return.*/
doif() /* returns - none*/
{
register struct tnode *tp;
register int elselab, exitlab;
tp = balpar(); /*if( expr )...*/
exitlab = 0;
if( nextrw(R_GOTO) )
exitlab = gotolabel();
else if( nextrw(R_BREAK) )
exitlab = brklabel();
else if( nextrw(R_CONTINUE) )
exitlab = contlabel();
else if( nextrw(R_RETURN) ) {
if( peekc(';') ) {
exitlab = rlabel;
putback(';');
}
else
pbtok(RESWORD);
}
if( exitlab ) { /*easy goto, do branch if true*/
outifgoto(tp,TRUE,exitlab);
if( next(SEMI) == 0 )
synerr("missing semicolon");
if( nextrw(R_ELSE) ) /*else clause, just output it*/
stmt();
}
else { /*hard goto, branch over statement*/
elselab = nextlabel++;
outifgoto(tp,FALSE,elselab);
stmt();
if( nextrw(R_ELSE) ) {
exitlab = nextlabel++; /*branches over else clause*/
outgoto(exitlab); /*branch out of then clause*/
outlab(elselab); /*label to start else clause*/
stmt(); /*else statement*/
outlab(exitlab);
}
else
outlab(elselab); /*no else, just branch out*/
}
}
/* doreturn - handles: return [ expression ] ;*/
/* Expression is the hard part, must create an assignment expression*/
/* to assign expression to the type of the function, then get it*/
/* loaded into a specific register.*/
doreturn() /* returns - none*/
{
register int savelreg;
register struct tnode *tp;
if( peekc(';') == 0 ) { /*need to compute return?*/
opp = opstack;
opdp = opdstack;
pushopd(frp); /*push function return info node*/
pushopd(expr()); /*get return expression*/
savelreg = loadreg;
loadreg = 1;
maketree(ASSIGN); /*do assignment for conversion*/
loadreg = savelreg;
outforreg(popopd()->t_right);
opp = 0;
opdp = 0;
}
else
putback(';');
outgoto(rlabel); /*branch to the return label*/
}
/* doswitch - handles: switch ( expression ) statement*/
/* Evaluates the expression, forces the result into a known register*/
/* collects the case statements in swtab, then outputs the switch*/
/* operator and switch cases.*/
doswitch() /* returns - none*/
{
register int saveblab, swlab, savedlab, saveswp, i;
register struct tnode *tp;
labgen(blabel,saveblab);
tp = balpar();
integral(tp,-1); /*must be integral type result*/
outforreg(tp); /*compile to reg 0*/
saveswp = swp; /*remember old switch pointer*/
if( saveswp < 0 )
swp++;
i = cswp;
cswp = swp; /*remember real first entry*/
swlab = nextlabel++;
outgoto(swlab); /*branch to switch code*/
savedlab = dlabel;
dlabel = 0;
stmt(); /*do switch statement*/
outgoto(blabel); /*output branch just in case*/
outlab(swlab); /*here we now do the switch code*/
if( dlabel == 0 )
dlabel = blabel;
outswitch(swp-cswp,dlabel,&swtab[cswp]);
outlab(blabel); /*break to here*/
cswp = i;
swp = saveswp;
blabel = saveblab;
dlabel = savedlab;
}
/* dowhile - handles: while ( expression ) statement*/
/* This is fairly straight-forward.*/
dowhile() /* returns - none*/
{
register int saveclab, saveblab;
labgen(blabel,saveblab);
labgen(clabel,saveclab);
outlab(clabel); /*continue label*/
outifgoto(balpar(),FALSE,blabel); /*condition clause*/
stmt(); /*statement*/
outgoto(clabel); /*branch back to top of loop*/
outlab(blabel); /*break to here*/
blabel = saveblab;
clabel = saveclab; /*restore labels*/
}
/* nextrw - is next token the specified reserved word?*/
nextrw(rw) /* returns 1 if match, 0 otherwise*/
int rw; /* reserved word to match*/
{
register int token;
if( (token=gettok()) != RESWORD || cvalue != rw ) {
pbtok(token);
return(0);
}
return(1);
}
/* addswitch - add an entry into current switch table, bubble sorting*/
/* This makes it easier on the code generator and also checks for*/
/* duplicate labels at the "right" time.*/
addswitch(sp,ncases,nval,nlab) /* returns - none*/
struct swtch *sp; /* switch table pointer*/
int ncases; /* number of cases in switch*/
int nval; /* new value*/
int nlab; /* new label*/
{
register struct swtch *nswp, *s;
register int temp, i;
nswp = &sp[ncases];
nswp->sw_value = nval;
nswp->sw_label = nlab;
s = nswp--;
for( ; --ncases >= 0; s--, nswp-- ) {
if( s->sw_value == nswp->sw_value )
error("duplicate case value");
if( s->sw_value < nswp->sw_value ) {
temp = s->sw_value;
s->sw_value = nswp->sw_value;
nswp->sw_value = temp;
temp = s->sw_label;
s->sw_label = nswp->sw_label;
nswp->sw_label = temp;
}
}
}

View File

@@ -0,0 +1,119 @@
#
/*
Copyright 1981
Alcyon Corporation
8474 Commerce Av.
San Diego, Ca. 92121
*/
#include "parser.h"
#define ASGOP OPRAS|OPASSIGN|OPLVAL|OPBIN
/*info on operators:*/
/*000077-- OPPRI - priority*/
/*000100-- OPBIN - binary operator*/
/*000200-- OPLVAL - left operand must be lvalue*/
/*000400-- OPREL - relational operator*/
/*001000-- OPASSIGN - assignment operator*/
/*002000-- OPLWORD - int required on left*/
/*004000-- OPRWORD - int required on right*/
/*010000-- OPCOM commutative*/
/*020000-- OPRAS - right associative*/
/*040000-- OPTERM - termination node*/
/*100000 - OPCONVS - conversion operator*/
int opinfo[] {
TRMPRI, /*EOF*/
ADDPRI|OPCOM|OPBIN, /*ADD - expr + expr*/
ADDPRI|OPBIN, /*SUB - expr - expr*/
MULPRI|OPCOM|OPBIN, /*MULT - expr * expr*/
MULPRI|OPBIN, /*DIV - expr / expr*/
MULPRI|OPBIN, /*MOD - expr % expr*/
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*RSH - expr >> expr*/
SHFPRI|OPLWORD|OPRWORD|OPBIN, /*LSH - expr << expr*/
ANDPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*AND - expr & expr*/
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*OR - expr | expr*/
ORPRI|OPCOM|OPLWORD|OPRWORD|OPBIN, /*XOR - expr ^ expr*/
UNOPRI|OPRAS|OPLWORD, /*NOT - ! expr*/
UNOPRI|OPRAS, /*UMINUS - - expr*/
UNOPRI|OPRAS|OPLWORD, /*COMPL - ~ expr*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREDEC - --lvalue*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*PREINC - ++lvalue*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTDEC - lvalue--*/
UNOPRI|OPRAS|OPLVAL|OPBIN, /*POSTINC - lvalue++*/
ASGPRI|ASGOP, /*ASSIGN - lvalue = expr*/
ASGPRI|ASGOP, /*EQADD - lvalue += expr*/
ASGPRI|ASGOP, /*EQSUB - lvalue -= expr*/
ASGPRI|ASGOP, /*EQMULT - lvalue *= expr*/
ASGPRI|ASGOP, /*EQDIV - lvalue /= expr*/
ASGPRI|ASGOP, /*EQMOD - lvalue %= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQRSH - lvalue >>= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQLSH - lvalue <<= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQAND - lvalue &= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQOR - lvalue |= expr*/
ASGPRI|ASGOP|OPLWORD|OPRWORD, /*EQXOR - lvalue ^= expr*/
TRMPRI, /*FJSR - generate function jsr*/
EQLPRI|OPREL|OPBIN, /*EQUALS - expr == expr*/
EQLPRI|OPREL|OPBIN, /*NEQUALS - expr != expr*/
RELPRI|OPREL|OPBIN, /*GREAT - expr > expr*/
RELPRI|OPREL|OPBIN, /*GREATEQ - expr >= expr*/
RELPRI|OPREL|OPBIN, /*LESS - expr < expr*/
RELPRI|OPREL|OPBIN, /*LESSEQ - expr <= expr*/
TRMPRI|OPCONVS, /*INT2L*/
TRMPRI|OPCONVS, /*LONG2I*/
TRMPRI|OPBIN, /*BTST*/
TRMPRI, /*LOAD*/
TRMPRI|OPBIN, /*LMULT*/
TRMPRI|OPBIN, /*LDIV*/
TRMPRI|OPBIN, /*LMOD*/
TRMPRI|OPBIN, /*LEQMULT*/
TRMPRI|OPBIN, /*LEQDIV*/
TRMPRI|OPBIN, /*LEQMOD*/
TRMPRI|ASGOP, /*EQADDR*/
TRMPRI, /*unused - 47*/
TRMPRI, /*unused - 48*/
TRMPRI, /*unused - 49*/
TRMPRI, /*unused - 50*/
TRMPRI, /*unused - 51*/
TRMPRI, /*unused - 52*/
TRMPRI, /*unused - 53*/
TRMPRI, /*unused - 54*/
TRMPRI, /*unused - 55*/
TRMPRI, /*unused - 56*/
TRMPRI, /*unused - 57*/
TRMPRI, /*unused - 58*/
TRMPRI, /*unused - 59*/
UNOPRI|OPRAS|OPLVAL, /*ADDR - & expr*/
UNOPRI|OPRAS|OPLWORD, /*INDR - * expr*/
LNDPRI|OPBIN, /*LAND - expr && expr*/
LORPRI|OPBIN, /*LOR - expr || expr*/
QMKPRI|OPRAS|OPBIN, /*QMARK - expr ? expr : expr*/
QMKPRI|OPRAS|OPBIN, /*COLON*/
COMPRI|OPBIN, /*COMMA*/
TRMPRI|OPTERM, /*CINT*/
TRMPRI|OPTERM, /*CLONG*/
TRMPRI|OPTERM, /*SYMBOL*/
TRMPRI|OPTERM, /*AUTOINC*/
TRMPRI|OPTERM, /*AUTODEC*/
LPNPRI|OPBIN, /*CALL - call with arguments*/
LPNPRI, /*NACALL - no argument call*/
TRMPRI, /*BFIELD - field selection*/
TRMPRI, /*IFGOTO*/
TRMPRI, /*INIT*/
TRMPRI, /*CFORREG*/
TRMPRI, /*unused - 78*/
TRMPRI, /*unused - 79*/
UNOPRI|OPRAS|OPASSIGN|OPBIN, /*CAST*/
TRMPRI, /*SEMI*/
TRMPRI, /*LCURBR - {*/
TRMPRI, /*RCURBR - }*/
LPNPRI, /*LBRACK - [*/
RPNPRI, /*RBRACK - ]*/
LPNPRI, /*LPAREN - )*/
RPNPRI, /*RPAREN - )*/
TRMPRI|OPTERM, /*STRING*/
TRMPRI, /*RESWORD*/
LPNPRI|OPBIN, /*APTR - expr -> symbol*/
LPNPRI|OPBIN, /*PERIOD - expr . symbol*/
UNOPRI|OPRAS, /*SIZEOF - sizeof expr*/
LPNPRI|OPBIN, /*MPARENS - matching parens ()*/
};

View File

@@ -0,0 +1,12 @@
$ set def [steve.cpm68k.c.parser]
$ set noon
$ cx DECL
$ cx EXPR
$ cx ICODE
$ cx INTERF
$ cx LEX
$ cx MAIN
$ cx STMT
$ cx TABL
$ cx init
$ @vrelink

View File

@@ -0,0 +1,2 @@
$ set def [steve.cpm68k.c.parser]
$ clink decl,expr,icode,interf,lex,main,stmt,tabl,init,lib:k3/lib c068

View File

@@ -0,0 +1,2 @@
$ set def [steve.cpm68k.c.parser]
$ clink decl,expr,icode,interf,lex,main,stmt,tabl,init,lib:klutz/lib c068