mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
Upload
Digital Research
This commit is contained in:
1033
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/decl.c
Normal file
1033
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/decl.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
@@ -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.
|
948
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/expr.c
Normal file
948
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/expr.c
Normal 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);
|
||||
}
|
372
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/icode.c
Normal file
372
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/icode.c
Normal 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);
|
||||
}
|
||||
}
|
215
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/icode.h
Normal file
215
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/icode.h
Normal 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];
|
485
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/init.c
Normal file
485
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/init.c
Normal 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));
|
||||
}
|
@@ -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));
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
fflush(fp)
|
||||
char *fp;
|
||||
{
|
||||
return(myfflush(fp));
|
||||
}
|
@@ -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);
|
||||
}
|
666
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/lex.c
Normal file
666
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/lex.c
Normal 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;
|
||||
}
|
@@ -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
|
@@ -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
|
143
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/main.c
Normal file
143
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/main.c
Normal 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);
|
||||
}
|
@@ -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
|
@@ -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
|
@@ -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();
|
@@ -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 */
|
||||
} /****************************/
|
||||
|
@@ -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
|
475
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/stmt.c
Normal file
475
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/stmt.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
119
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/tabl.c
Normal file
119
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/c/parser/tabl.c
Normal 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 ()*/
|
||||
};
|
@@ -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
|
@@ -0,0 +1,2 @@
|
||||
$ set def [steve.cpm68k.c.parser]
|
||||
$ clink decl,expr,icode,interf,lex,main,stmt,tabl,init,lib:k3/lib c068
|
@@ -0,0 +1,2 @@
|
||||
$ set def [steve.cpm68k.c.parser]
|
||||
$ clink decl,expr,icode,interf,lex,main,stmt,tabl,init,lib:klutz/lib c068
|
Reference in New Issue
Block a user