add LCC - a better C-Compiler for WEGA
This commit is contained in:
parent
30ca515d0f
commit
d16dd1e868
|
|
@ -0,0 +1,296 @@
|
|||
# ifndef EXIT
|
||||
# define EXIT exit
|
||||
# endif
|
||||
|
||||
int nerrors = 0; /* number of errors */
|
||||
|
||||
NODE *lastfree; /* pointer to last free node; (for allocator) */
|
||||
|
||||
# ifndef MYWHERE
|
||||
where(c)
|
||||
{
|
||||
/* print location of error. c is either 'u', 'c', or 'w' */
|
||||
fprintf( stderr, "%s, line %d: ", ftitle, lineno );
|
||||
}
|
||||
# endif
|
||||
|
||||
/* VARARGS1 */
|
||||
uerror( s, a )
|
||||
char *s;
|
||||
{
|
||||
/* nonfatal error message
|
||||
** the routine where is different for pass 1 and pass 2;
|
||||
** it tells where the error took place
|
||||
*/
|
||||
++nerrors;
|
||||
where('u');
|
||||
fprintf( stderr, s, a );
|
||||
fprintf( stderr, "\n" );
|
||||
if( nerrors > 30 ) cerror( "too many errors");
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
lerror( s, a )
|
||||
char *s, *a;
|
||||
{
|
||||
/* nonfatal error message
|
||||
** the routine where is different for pass 1 and pass 2;
|
||||
** it tells where the error took place
|
||||
*/
|
||||
++nerrors;
|
||||
where('u');
|
||||
fprintf( stderr, s, a );
|
||||
fprintf( stderr, "\n" );
|
||||
if( nerrors > 30 ) cerror( "too many errors");
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
cerror( s, a, b, c )
|
||||
char *s;
|
||||
{
|
||||
/* compiler error: die */
|
||||
where('c');
|
||||
if( nerrors && nerrors <= 30 )
|
||||
{
|
||||
/* give the compiler the benefit of the doubt */
|
||||
fprintf( stderr,
|
||||
"cannot recover from earlier errors: goodbye!\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, "compiler error: " );
|
||||
fprintf( stderr, s, a, b, c );
|
||||
fprintf( stderr, "\n" );
|
||||
fflush( stdout );
|
||||
}
|
||||
EXIT(1);
|
||||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
werror( s, a, b )
|
||||
char *s;
|
||||
{
|
||||
/* warning */
|
||||
where('w');
|
||||
fprintf( stderr, "warning: " );
|
||||
fprintf( stderr, s, a, b );
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
|
||||
tinit()
|
||||
{
|
||||
/* initialize expression tree search */
|
||||
register NODE *p;
|
||||
|
||||
for( p=node; p<= &node[TREESZ-1]; ++p ) p->in.op = FREE;
|
||||
lastfree = node;
|
||||
}
|
||||
|
||||
# define TNEXT(p) (p== &node[TREESZ-1]?node:p+1)
|
||||
|
||||
NODE *
|
||||
talloc()
|
||||
{
|
||||
register NODE *p, *q;
|
||||
|
||||
q = lastfree;
|
||||
for( p = TNEXT(q); p!=q; p= TNEXT(p))
|
||||
if( p->in.op ==FREE ) return(lastfree=p);
|
||||
|
||||
cerror( "out of tree space; simplify expression");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
tcheck()
|
||||
{
|
||||
/* ensure that all nodes have been freed */
|
||||
register NODE *p;
|
||||
|
||||
if( !nerrors )
|
||||
for( p=node; p<= &node[TREESZ-1]; ++p )
|
||||
{
|
||||
if( p->in.op != FREE )
|
||||
{
|
||||
cerror( "wasted space: %d", p-node );
|
||||
}
|
||||
}
|
||||
else
|
||||
tinit();
|
||||
freestr();
|
||||
}
|
||||
|
||||
tfree(p)
|
||||
register NODE *p;
|
||||
{
|
||||
/* allow tree fragments to be freed, also */
|
||||
if( !p ) return;
|
||||
switch( optype( p->tn.op ) )
|
||||
{
|
||||
case BITYPE:
|
||||
tfree( p->in.right );
|
||||
case UTYPE:
|
||||
tfree( p->in.left );
|
||||
}
|
||||
p->in.op = FREE;
|
||||
}
|
||||
|
||||
|
||||
int dope[ DSIZE ];
|
||||
char *opst[DSIZE];
|
||||
NODE node[TREESZ];
|
||||
|
||||
char ftitle[100] = "\"\""; /* title of the file */
|
||||
extern int lineno; /* line number of the input file */
|
||||
|
||||
struct dopest
|
||||
{
|
||||
int dopeop;
|
||||
char opst[8];
|
||||
int dopeval;
|
||||
} indope[] =
|
||||
{
|
||||
NAME, "NAME", LTYPE,
|
||||
STRING, "STRING", LTYPE,
|
||||
REG, "REG", LTYPE,
|
||||
TEMP, "TEMP", LTYPE,
|
||||
VAUTO, "AUTO", LTYPE,
|
||||
VPARAM, "PARAM", LTYPE,
|
||||
ICON, "ICON", LTYPE,
|
||||
FCON, "FCON", LTYPE,
|
||||
CCODES, "CCODES", LTYPE,
|
||||
UNARY MINUS, "U-", UTYPE,
|
||||
UNARY MUL, "STAR", UTYPE,
|
||||
UNARY AND, "U&", UTYPE,
|
||||
UNARY CALL, "UCALL", UTYPE|CALLFLG,
|
||||
UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG,
|
||||
NOT, "!", UTYPE|LOGFLG,
|
||||
COMPL, "~", UTYPE,
|
||||
INIT, "INIT", UTYPE,
|
||||
CONV, "CONV", UTYPE,
|
||||
PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG,
|
||||
ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG,
|
||||
MINUS, "-", BITYPE|FLOFLG|SIMPFLG,
|
||||
ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG,
|
||||
MUL, "*", BITYPE|FLOFLG|MULFLG,
|
||||
ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG,
|
||||
AND, "&", BITYPE|SIMPFLG|COMMFLG,
|
||||
ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG,
|
||||
QUEST, "?", BITYPE,
|
||||
COLON, ":", BITYPE,
|
||||
ANDAND, "&&", BITYPE|LOGFLG,
|
||||
OROR, "||", BITYPE|LOGFLG,
|
||||
CM, ",", BITYPE,
|
||||
COMOP, ",OP", BITYPE,
|
||||
FREE, "FREE!?!", LTYPE,
|
||||
ASSIGN, "=", BITYPE|ASGFLG,
|
||||
DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG,
|
||||
ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG,
|
||||
MOD, "%", BITYPE|DIVFLG,
|
||||
ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG,
|
||||
LS, "<<", BITYPE|SHFFLG,
|
||||
ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
|
||||
RS, ">>", BITYPE|SHFFLG,
|
||||
ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
|
||||
OR, "|", BITYPE|COMMFLG|SIMPFLG,
|
||||
ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
|
||||
ER, "^", BITYPE|COMMFLG|SIMPFLG,
|
||||
ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
|
||||
INCR, "++", BITYPE|ASGFLG,
|
||||
DECR, "--", BITYPE|ASGFLG,
|
||||
STREF, "->", BITYPE,
|
||||
CALL, "CALL", BITYPE|CALLFLG,
|
||||
FORTCALL, "FCALL", BITYPE|CALLFLG,
|
||||
EQ, "==", BITYPE|LOGFLG,
|
||||
NE, "!=", BITYPE|LOGFLG,
|
||||
LE, "<=", BITYPE|LOGFLG,
|
||||
LT, "<", BITYPE|LOGFLG,
|
||||
GE, ">", BITYPE|LOGFLG,
|
||||
GT, ">", BITYPE|LOGFLG,
|
||||
UGT, "UGT", BITYPE|LOGFLG,
|
||||
UGE, "UGE", BITYPE|LOGFLG,
|
||||
ULT, "ULT", BITYPE|LOGFLG,
|
||||
ULE, "ULE", BITYPE|LOGFLG,
|
||||
ARS, "A>>", BITYPE,
|
||||
TYPE, "TYPE", LTYPE,
|
||||
LB, "[", BITYPE,
|
||||
CBRANCH, "CBRANCH", BITYPE,
|
||||
GENLAB, "GENLAB", UTYPE,
|
||||
GENUBR, "GENUBR", UTYPE,
|
||||
GENBR, "GENBR", UTYPE,
|
||||
CMP, "CMP", BITYPE,
|
||||
FLD, "FLD", UTYPE,
|
||||
PMUL, "P*", BITYPE,
|
||||
PDIV, "P/", BITYPE,
|
||||
RETURN, "RETURN", BITYPE|ASGFLG,
|
||||
CAST, "CAST", BITYPE|ASGFLG,
|
||||
GOTO, "GOTO", UTYPE,
|
||||
STASG, "STASG", BITYPE,
|
||||
STARG, "STARG", UTYPE,
|
||||
STCALL, "STCALL", BITYPE|CALLFLG,
|
||||
UNARY STCALL, "USTCALL", UTYPE|CALLFLG,
|
||||
RNODE, "RNODE", LTYPE,
|
||||
SNODE, "SNODE", LTYPE,
|
||||
QNODE, "QNODE", LTYPE,
|
||||
MANY, "MANY", BITYPE,
|
||||
FUNARG, "ARG", UTYPE,
|
||||
UOP0, "UOP0", UTYPE|SPFLG,
|
||||
UOP1, "UOP1", UTYPE|SPFLG,
|
||||
UOP2, "UOP2", UTYPE|SPFLG,
|
||||
UOP3, "UOP3", UTYPE|SPFLG,
|
||||
UOP4, "UOP4", UTYPE|SPFLG,
|
||||
UOP5, "UOP5", UTYPE|SPFLG,
|
||||
UOP6, "UOP6", UTYPE|SPFLG,
|
||||
UOP7, "UOP7", UTYPE|SPFLG,
|
||||
UOP8, "UOP8", UTYPE|SPFLG,
|
||||
UOP9, "UOP9", UTYPE|SPFLG,
|
||||
|
||||
-1, 0
|
||||
};
|
||||
|
||||
mkdope()
|
||||
{
|
||||
register struct dopest *q;
|
||||
|
||||
for( q = indope; q->dopeop >= 0; ++q )
|
||||
{
|
||||
dope[q->dopeop] = q->dopeval;
|
||||
opst[q->dopeop] = q->opst;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define NTSTRBUF 40
|
||||
#define TSTRSZ 2048
|
||||
char itstrbuf[TSTRSZ];
|
||||
char *tstrbuf[NTSTRBUF] = { itstrbuf };
|
||||
char **curtstr = tstrbuf;
|
||||
int tstrused;
|
||||
|
||||
char *
|
||||
tstr( cp ) /* place copy of string into temp storage */
|
||||
register char *cp; /* strings longer than TSTRSZ will break tstr */
|
||||
{
|
||||
register int i = strlen( cp );
|
||||
register char *dp;
|
||||
extern char * malloc();
|
||||
extern char * strcpy();
|
||||
|
||||
if ( tstrused + i >= TSTRSZ )
|
||||
{
|
||||
if ( ++curtstr >= &tstrbuf[NTSTRBUF] )
|
||||
cerror( "out of temporary string space" );
|
||||
tstrused = 0;
|
||||
if ( *curtstr == 0 )
|
||||
{
|
||||
if ( ( dp = (char *) malloc( TSTRSZ ) ) == 0 )
|
||||
cerror( "out of memory [tstr()]" );
|
||||
*curtstr = dp;
|
||||
}
|
||||
}
|
||||
strcpy( dp = *curtstr + tstrused, cp );
|
||||
tstrused += i + 1;
|
||||
return ( dp );
|
||||
}
|
||||
Loading…
Reference in New Issue