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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
$ diff DECL.c drb0:[steve.cpm68k.c.fparser]DECL.c
$ diff EXPR.c drb0:[steve.cpm68k.c.fparser]EXPR.c
$ diff ICODE.c drb0:[steve.cpm68k.c.fparser]ICODE.c
$ diff INIT.c drb0:[steve.cpm68k.c.fparser]INIT.c
$ diff INTERF.c drb0:[steve.cpm68k.c.fparser]INTERF.c
$ diff LEX.c drb0:[steve.cpm68k.c.fparser]LEX.c
$ diff MAIN.c drb0:[steve.cpm68k.c.fparser]MAIN.c
$ diff STMT.c drb0:[steve.cpm68k.c.fparser]STMT.c
$ diff TABL.c drb0:[steve.cpm68k.c.fparser]TABL.c
$ diff VERSION.c drb0:[steve.cpm68k.c.fparser]VERSION.c

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,311 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
int bol 1;
int inittype;
int begseq;
/* 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 ");
}
/* 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");
}
/* outfpdata - set up for floating point data output*/
outfpdata() /*[vlh] 3.4 returns - none*/
{
inittype = FLOAT;
printf("\t.data\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 && !nas ) /* 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 )
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();
}
}
outeof()
{
register int c;
v6flush(&sbuf);
v6flush(&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 ) /* 3rd arg for versados */
ferror("can't copy %s",fname);
while( (c=getc(&sbuf)) > 0 )
putc(c,&obuf);
v6flush(&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();
}
/* outfp - output floating point data*/
outfp(l) /*[vlh] 3.4 returns - none*/
long l; /* floating point data to output*/
{
outwdata();
outword(l.hiword);
outword(l.loword);
outendseq();
}
outendseq() /* returns - none*/
{
begseq = 0;
putchar('\n');
}
/*
* 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 )
write(1,&c,1);
else if( c == '\t' ) {
if( bol ) /* not used && !onepass ) */
putc('(',obp); /*for code generator*/
}
else {
bol = (c == '\n');
putc(c,obp);
}
}

View File

@@ -0,0 +1,251 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "machine.h"
/*
* 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 EQNOT 47
#define EQNEG 48
#define DOCAST 49
#define STASSIGN 50 /*[vlh]*/
#define LONG2F 51 /*[vlh] 3.4*/
#define FLOAT2L 52 /*[vlh] 3.4*/
#define INT2F 53 /*[vlh] 3.4*/
#define FLOAT2I 54 /*[vlh] 3.4*/
#define LCGENOP 55 /*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
#define CFLOAT 79 /*[vlh] 3.4*/
/*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 FRETURN 94
#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 DREG0 0
#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
#define CFINDR 11 /* [vlh] 3.4 */
/*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 /* chars per symbol */
#define TRUE 1
#define FALSE 0
#define TABC '\t' /* tab character */
#define EOLC '\n' /* end of line character */
#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];
};
#ifdef PDP11
struct { short hiword; short loword; };
#endif
#ifdef MC68000
struct { short hiword; short loword; };
#endif
#ifdef VAX
struct { short loword; short hiword; };
#endif
#define EXPSIZE 1024
int exprarea[EXPSIZE];
/* v6io buffer declaration */
#define BLEN 512
struct iobuf{
int fildes;
int nunused;
char *xfree;
char buff[BLEN];
};

View File

@@ -0,0 +1,323 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
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_CHAR 1
#define UNSN_CHAR 1
#define LONG_CHAR 1
#define DOUB_CHAR 1
#define PTR_CHAR 1
#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
/* miscellaneous constants */
#define OPSSIZE 40 /*operator stack size*/
#define OPDSIZE 80 /*operand stack size*/
#define HSIZE 517 /*hash table size, 3.4 made prime */
#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; /* defined, resword, global, typedef */
char s_sc; /* auto, static, external, register */
int s_type; /* 4bits specified, 2 bit fields for ptr... */
int s_dp; /* index into dimension table */
int s_ssp; /* dimension table/function arg table */
int s_offset; /* offset inside of structure */
char s_symbol[SSIZE]; /* symbol identifier, to SSIZE chars */
struct symbol *s_struc; /* if struct, ptr to parent (sys III) */
struct symbol *s_next; /* next symbol table entry */
};
/*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]=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; /*ptr to next available loc in exprarea*/
struct tnode *frp=0; /*pointer to function return info node*/
int cswp=0; /*current low switch table index*/
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 inclflag=0; /*in include file, don't incr line #'s*/
int inclline=0; /*[vlh]line# in incl file for err rpting*/
char inclfile[13]=0; /*[vlh]include filename for err rpting*/
int equalstop=0; /*stop lex at '=', used for external init*/
int commastop=0; /*stop parse @ comma(used for const expr)*/
int colonstop=0; /*stop parse @ colon(used for case value)*/
int instruct=0; /*set when in structure declaration*/
int smember=0; /*set when seen . or ->*/
int infunc=0; /*set when in function body*/
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 ptr 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 eflag=0; /*[vlh] 3.4 IEEE floats */
int fflag=0; /*[vlh] 3.4 FFP floats */
int xflag=0; /*translate int's to long's*/
int wflag=0; /*[vlh] don't generate warning mesgs*/
int reducep=0; /*[vlh] if(procid); reduction*/
int peektok=0; /*peeked at token*/
/*dimension table*/
long dtab[DSIZE]=0; /* [vlh] 3.4 int => long */
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*/
/* -1 -> not instruct, 0 -> unnamed struct */
struct symbol *strucptr[10]=0; /*[vlh] ptrs to struc symbols*/
/*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 walign(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))
/* checks for symbol with structure element storage class */
#define isstel(tp) (tp->t_op==SYMBOL && (sesc(tp)))
#define sesc(t) (t->t_sc==STELCL||t->t_sc==UNELCL||t->t_sc==BFIELDCL)
/* peek at next token, if not read token put back, else delete */
/* 1 if matched, 0 otherwise */
#define peek(tok) ( (peektok=gettok()) == tok )
#define outcommon(sym,size) printf("\t.comm _%.8s,%ld\n",sym,size)
#define outgoto(lab) if( lab > 0 ) printf("\tbra L%d\n",lab)
/* change to text segment */
#define outtext() printf("\t.text\n")
/* change segment to bss */
#define outbss() printf("\t.bss\n")
/* output global symbol references */
#define outextdef(sym) printf("\t.globl _%.8s\n",sym)
/* outputs reserved memory [vlh] 3.4 %d => %ld */
#define outresmem(size) printf("\t.ds.b %ld\n",size)
/* output padding for word alignments */
#define outpad() printf("\t.even\n")
/* output long constant to assembler */
#define outlcon(val) printf("\t.dc.l %d\n",val)
/* output label constant */
#define outclab(lab) printf("\t.dc.l L%d\n",lab)
/* output a label */
#define outlab(lab) printf("\tL%d:",lab)
/* output function label */
#define outflab(sym) printf("\t_%.8s:\n\t~~%.8s:\n",sym,sym)
/* output data label */
#define outdlab(sym) printf("\t_%.8s:\n",sym)
/*functions returning pointers*/
char *expr();
char *talloc();
char *tnalloc();
char *enalloc();
char *snalloc();
char *cnalloc();
char *lcnalloc();
char *fpcnalloc();
char *popopd();
char *cvopgen();
char *arrayref();
char *funcref();
char *install();
char *lookup();
char *balpar();
char *sbrk();
long initlist();
long dsize();
long psize();
long dodecl();
long dlist();
long getdec();
long gethex();
long getoct();
long getfp();
long toieee();
long toffp();
int inittype=0;
int strassign=0;
int begseq=0;
#define EXPSIZE 1024
int exprarea[EXPSIZE]=0;
int opdontop=0;
int pbchar=0;
struct symbol *symbols=0;
struct symbol *symtab[HSIZE]=0;

View File

@@ -0,0 +1,106 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "parser.h"
int bol;
outinit(tp,type) /* returns - none*/
struct tnode *tp;
{
outexpr(tnalloc(INIT,type,0,0,tp));
}
outcforreg(tp)
struct tnode *tp;
{
outexpr(tnalloc(CFORREG,tp->t_type,0,0,tp));
}
outifgoto(tp,dir,lab)
struct tnode *tp;
int dir;
int lab;
{
outexpr(tnalloc(IFGOTO,dir,lab,0,tp));
}
outexpr(tp)
struct tnode *tp;
{
if( !bol )
putchar('\n');
printf(".%x\n",lineno);
outtree(tp);
}
outtree(tp)
struct tnode *tp;
{
if( !tp )
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 CFLOAT: /*[vlh] 3.4*/
printf(".%x.%x\n",tp->t_lvalue.hiword,tp->t_lvalue.loword);
break;
case SYMBOL:
printf(".%x",tp->t_sc);
if( tp->t_sc == EXTERNAL )
printf(".%.8s\n",tp->t_symbol);
else
printf(".%x\n",tp->t_offset);
break;
case 0:
putchar('\n');
break;
case IFGOTO:
case BFIELD:
printf(".%x\n",tp->t_dp);
outtree(tp->t_left);
break;
default:
putchar('\n');
outtree(tp->t_left);
if( binop(tp->t_op) )
outtree(tp->t_right);
break;
}
}
/* snalloc - symbol node allocation*/
/* Allocates a tree symbol node and sets the info in it*/
char *snalloc(type,sc,off,dp,ssp) /* returns pointer to node alloc'ed*/
int type; /* symbol type*/
int sc; /* storage class*/
int off; /* offset*/
int dp; /* dimension pointer or other info*/
int ssp; /* structure size pointer*/
{
register struct symnode *snp;
snp = talloc(sizeof(*snp));
snp->t_op = SYMBOL;
snp->t_sc = sc;
snp->t_type = type;
snp->t_dp = dp;
snp->t_ssp = ssp;
snp->t_offset = off;
return(snp);
}

View File

@@ -0,0 +1,827 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
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*/
/*
* 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);
}
#define BIAS 127L
#define EXPSIZ 4
#define FRACSIZ 20
long toieee();
long toffp();
float power10();
/*
* getfp - get a floating point constant
* we've already gotten the significant digits, now build a
* floating point number with possible decimal digits and an
* exponent, yields an ieee formated floating point number,
* unless the fflag is on, then a ffp constant is generated.
*/
long
getfp(significant)
long significant;
{
register char c;
register long places; /* decimal places */
int esign;
float exp, fraction, fp;
places = 0L; esign = 0; fraction = significant; exp = 0.0;
if ((c = ngetch()) == '.') /* get decimal places */
for( ; (c=ngetch()) >= '0' && c <= '9';) {
fraction = fraction * 10.0;
fraction = fraction + (c - '0');
places++;
}
if (c=='e' || c=='E') { /* exponent exists */
esign = (peekis('-')) ? 1 : (peekis('+')) ? 0 : 0;
for( ; (c=ngetch()) >= '0' && c <= '9'; ) {
exp = exp * 10.0;
exp = exp + (c - '0');
}
}
putback(c);
if (esign)
exp = -exp;
places = exp - places;
fp = fraction * power10(places);
if (fflag)
return( toffp(fp) );
else
return ( toieee(fp) );
}
float
power10(pwr) /* used by getfp, 10^pwr */
long pwr;
{
float f;
if (pwr < 0L) /* negative power */
for (f = 1.0; pwr < 0L; pwr++)
f = f / 10.0;
else /* positive power */
for (f = 1.0; pwr > 0L; pwr--)
f = f * 10.0;
return(f);
}
long
toffp(f) /* converts current machine float to ffp rep */
float f;
{
register long exp;
register int sign, count;
long l;
if (f == 0.0)
return(0L);
if (f < 0.0) {
sign = 1;
f = -f;
}
else
sign = 0;
exp = 0L;
for( ; f >= 1.0; f = f / 2.0)
exp++;
for( ; f < 0.5; f = f * 2.0)
exp--;
f = f * 16777216.0; /* 2 ^ 24 */
l = f;
l =<< 8;
if (sign)
l =| 0x80;
exp =+ 0x40;
l =| (exp & 0x7f);
return(l);
}
long
toieee(f) /* converts current machine float to ieee rep */
float f;
{
register long exp;
register int sign, count;
long l;
if (f == 0.0)
return(0L);
if (f < 0.0) {
sign = 1;
f = -f;
}
else
sign = 0;
exp = 0L;
for( ; f >= 2.0; f = f / 2.0)
exp++;
for( ; f < 1.0; f = f * 2.0)
exp--;
f = f - 1.0;
f = f * 8388608.0; /* 2 ^ 23 */
l = f;
if (sign)
l =| 0x80000000;
exp = (exp + BIAS)<<23;
l =| (exp & 0x7f800000);
return(l);
}
#define toupper(c) ((c) & ~32)
/* gethex - get an hexidecimal number*/
/* Uses Horner's method to get hexidecimal number*/
long gethex() /* returns number*/
{
register long value;
register char c, ch;
value = 0;
while( 1 ) {
if( (c=ngetch()) >= '0' && c <= '9' )
c =- '0';
else if((ch=toupper(c)) >= 'A' && ch <= 'F' ) /* [vlh] */
c = ch - ('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;
case SEMI:
cvalue = 0; /* [vlh] not reserved word... */
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 != EOLC )
;
continue;
}
return( peekis('=') ? EQDIV : DIV );
case DIGIT: /*number constant (long or reg)*/
i = 0; /*flags if long constant*/
if( c != '0' ) {
putback(c);
dofp:
value = getdec();
if ((c=ngetch())=='.' || c=='e' || c=='E') { /*[vlh] 3.4 */
putback(c);
clvalue = getfp(value);
return(CFLOAT);
}
putback(c);
if( value > 32767 || value < -32768 )
i++;
}
else if( peekis('x') || peekis('X') ) {
value = gethex();
if( value < 0 || value >= 0x10000L )
i++;
}
else {
if (peekis('.')) {
putback('.');
goto dofp;
}
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()) != ' ' )
if (!wflag) /*[vlh] old fashion initialization*/
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;
register char *ifile;
if( pbchar ) {
c = pbchar;
pbchar = 0;
}
else if( (c=getc(&ibuf)) == EOLC ) {
if( inclflag )
inclflag = 0;
else
lineno++;
}
else if( c == SOI) { /*[vlh]add incl filename & line # */
inclflag++;
ifile = &inclfile;
while ((c=getc(&ibuf)) != SOI)
*ifile++ = c&0377;
*ifile = 0;
inclline = getdec() & 077777;
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( ctype[(c=ngetch())] == WHITSP) ;
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 == EOLC ) {
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 == EOLC ) /*escape followed by nl->ignore*/
continue;
}
if( i > 0 ) { /*room left in string?*/
cstrsize++;
*p++ = c;
}
else if( !i ) /*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) ) {
if( !(sp=sbrk(SYMSIZE)) )
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;
sp->s_struc = (instruct) ? strucptr[smember+instruct] : 0;
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, *hold;
register char *p;
int exact; /* same name, diff type or offset */
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);
if (!(smember|instruct)) { /*[vlh]*/
for( sp=symtab[symhash(p,0)]; sp!=0; sp=sp->s_next )
if( symequal(p,sp->s_symbol) ) return(sp);
}
else { /* doing a declaration or an expression */
hold = 0; exact = 0;
for( sp=symtab[symhash(p,instruct|smember)]; sp!=0; sp=sp->s_next )
if( symequal(p,sp->s_symbol) )
if (symsame(sp,hold,&exact)) return(sp);
else if (!hold && !exact) hold = sp;
if (hold && !exact) return(hold);
}
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) ) {
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, 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 && sp->s_ssp>=0 && (btype(sp->s_type))==FRSTRUCT) {
sp->s_ssp = frstab[sp->s_ssp]->s_ssp; /* 3.4 ssp>0 */
sp->s_type = (sp->s_type&~TYPE) | STRUCT;
}
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);
}
/* symsame - symbol member same as declared */
symsame(sp,hold,exact) /* [vlh] */
struct symbol *sp, *hold;
int *exact;
{
if (strucptr[smember+instruct])
if (strucptr[smember+instruct]==sp->s_struc) return(1);
if (hold)
if (sp->s_type != hold->s_type || sp->s_offset != hold->s_offset)
*exact = 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);
}
/* next - if next token matches given token, skip and return success*/
/* This allows for clean parsing of declarations.*/
next(tok) /* returns 1 if matched, 0 otherwise*/
int tok;
{
register int token;
if( (token=gettok()) == tok )
return(1);
peektok = token;
return(0);
}
/* pbtok - put back the given token*/
/* This merely sets the peektok variable*/
pbtok(tok) /* returns - none*/
int tok;
{
if( peektok )
error("too many tokens pushed back");
peektok = tok;
}

View File

@@ -0,0 +1,6 @@
$1lo68 -r -f $1 -unofloat 0$1s.o DECL.o EXPR.o ICODE.o INTERF.o LEX.o MAIN.o STMT.o TABL.o 0$1lib6.a 0$1libF.a 0$1clib
era *.o
era c068.rel
ren c068.rel=c.out
user 13!make $1

View File

@@ -0,0 +1,39 @@
$ num
DECL.C
DECL.lis
$ num
EXPR.C
EXPR.lis
$ num
ICODE.C
ICODE.lis
$ num
INIT.C
INIT.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
VERSION.C
VERSION.lis
$ num
ICODE.H
ICODE.lst
$ num
MACHINE.H
MACHINE.lst
$ num
PARSER.H
PARSER.lst

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
#define PDP11 1 /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
#define UNIX 1 /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
#define MC68000 1 /* 68000 version */
/*#define VAX 1*/ /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
#define CPM 1 /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
/*#define VMS 1*/ /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
#define VAX 1 /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
#define VMS 1 /* VMS Operating System*/

View File

@@ -0,0 +1,10 @@
/*
* Use this file to determine what kind of machine you want the
* Alcyon stuff to run on ....
*/
/*#define MC68000 1*/ /* 68000 version */
#define VAX 1 /* VAX Version */
/*#define PDP11 1*/ /* PDP-11 Version*/
/*#define CPM 1*/ /* CP/M Operating System*/
/*#define UNIX 1*/ /* UNIX Operating System*/
#define VMS 1 /* VMS Operating System*/

View File

@@ -0,0 +1,173 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *version "@(#) c068 parser 4.0 - Feb 11, 1983";
/*
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];
/*
* 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 'F':
case 'f':
fflag++;
continue;
case 'E':
case 'e':
eflag++;
continue;
case 'W':
case 'w':
wflag++;
continue;
case '\0':
break;
default:
usage();
}
break;
}
}
if( argc < 4 )
usage();
if( fopen(argv[1],&ibuf,0) < 0 ) /* 3rd arg for versados */
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++;
frstp = -1; /* [vlh] 3.4 - initialize only once */
syminit();
while( !peek(EOF) )
doextdef();
outeof();
outdata();
copysfile(argv[3]);
exit(errcnt!=0);
}
/* usage - output usage error message and die*/
usage()
{
ferror("usage: c068 source icode str [-e] [-f] [-w]");
}
/* 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 (!inclflag) {
if( lineno )
printf("* %d: ",lineno);
}
else /*[vlh] generate filename and approp line #*/
printf("%s: * %d: ",inclfile,inclline);
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);
}
v6flush(v6buf)
struct iobuf *v6buf;
{
register i;
i = BLEN - v6buf->nunused;
v6buf->nunused = BLEN;
v6buf->xfree = &(v6buf->buff[0]);
if(write(v6buf->fildes,v6buf->xfree,i) != i)
return(-1);
return(0);
}
printf(string,a,b,c,d,e,f,g)
char *string;
int a,b,c,d,e,f,g;
{
char area[256];
register char *p;
sprintf(area,string,a,b,c,d,e,f,g);
for(p = &area[0]; *p; p++)
putchar(*p);
}

View File

@@ -0,0 +1,86 @@
$1stat machine.h=rw
$1pip machine.h=machine.68k
$1cp68 -i 0$1 DECL.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic DECL.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u DECL.s
era DECL.s
$1cp68 -i 0$1 EXPR.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic EXPR.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u EXPR.s
era EXPR.s
$1cp68 -i 0$1 ICODE.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic ICODE.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u ICODE.s
era ICODE.s
$1cp68 -i 0$1 INTERF.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic INTERF.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u INTERF.s
era INTERF.s
$1cp68 -i 0$1 LEX.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic LEX.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u LEX.s
era LEX.s
$1cp68 -i 0$1 MAIN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic MAIN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u MAIN.s
era MAIN.s
$1cp68 -i 0$1 STMT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic STMT.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u STMT.s
era STMT.s
$1cp68 -i 0$1 TABL.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic TABL.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u TABL.s
era TABL.s
$1cp68 -i 0$1 VERSION.c $1x.i
$1c068 $1x.i $1x.ic $1x.st -f
$1c168 $1x.ic VERSION.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -s 0$1 -f $1 -l -u VERSION.s
era VERSION.s
link $1

View File

@@ -0,0 +1,320 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
/*
C68 Parser - include file
*/
#include <stdio.h>
#include <klib.h>
#undef putchar
#define putchar xputchar
#undef ferror
#define printf xprintf
#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_CHAR 1
#define UNSN_CHAR 1
#define LONG_CHAR 1
#define DOUB_CHAR 1
#define PTR_CHAR 1
#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
/* miscellaneous constants */
#define OPSSIZE 40 /*operator stack size*/
#define OPDSIZE 80 /*operand stack size*/
#define HSIZE 517 /*hash table size, 3.4 made prime */
#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; /* defined, resword, global, typedef */
char s_sc; /* auto, static, external, register */
int s_type; /* 4bits specified, 2 bit fields for ptr... */
int s_dp; /* index into dimension table */
int s_ssp; /* dimension table/function arg table */
int s_offset; /* offset inside of structure */
char s_symbol[SSIZE]; /* symbol identifier, to SSIZE chars */
struct symbol *s_struc; /* if struct, ptr to parent (sys III) */
struct symbol *s_next; /* next symbol table entry */
};
/*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; /*ptr 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 inclflag; /*in include file, don't incr line #'s*/
int inclline; /*[vlh]line# in incl file for err rpting*/
char inclfile[13]; /*[vlh]include filename for err rpting*/
int equalstop; /*stop lex at '=', used for external init*/
int commastop; /*stop parse @ comma(used for const expr)*/
int colonstop; /*stop parse @ colon(used for case value)*/
int instruct; /*set when in structure declaration*/
int smember; /*set when seen . or ->*/
int infunc; /*set when in function body*/
int tdflag; /*declaration is a typedef proto*/
char *tdp; /*points to typedef prototype*/
int localsize; /*length of local variables*/
int naregs; /*keeps track of ptr 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 eflag; /*[vlh] 3.4 IEEE floats */
int fflag; /*[vlh] 3.4 FFP floats */
int xflag; /*translate int's to long's*/
int wflag; /*[vlh] don't generate warning mesgs*/
int reducep; /*[vlh] if(procid); reduction*/
int peektok; /*peeked at token*/
/*dimension table*/
long dtab[DSIZE]; /* [vlh] 3.4 int => long */
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*/
/* -1 -> not instruct, 0 -> unnamed struct */
struct symbol *strucptr[10]; /*[vlh] ptrs to struc symbols*/
/*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 walign(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))
/* checks for symbol with structure element storage class */
#define isstel(tp) (tp->t_op==SYMBOL && (sesc(tp)))
#define sesc(t) (t->t_sc==STELCL||t->t_sc==UNELCL||t->t_sc==BFIELDCL)
/* peek at next token, if not read token put back, else delete */
/* 1 if matched, 0 otherwise */
#define peek(tok) ( (peektok=gettok()) == tok )
#define outcommon(sym,size) printf("\t.comm _%.8s,%ld\n",sym,size)
#define outgoto(lab) if( lab > 0 ) printf("\tbra L%d\n",lab)
/* change to text segment */
#define outtext() printf("\t.text\n")
/* change segment to bss */
#define outbss() printf("\t.bss\n")
/* output global symbol references */
#define outextdef(sym) printf("\t.globl _%.8s\n",sym)
/* outputs reserved memory [vlh] 3.4 %d => %ld */
#define outresmem(size) printf("\t.ds.b %ld\n",size)
/* output padding for word alignments */
#define outpad() printf("\t.even\n")
/* output long constant to assembler */
#define outlcon(val) printf("\t.dc.l %d\n",val)
/* output label constant */
#define outclab(lab) printf("\t.dc.l L%d\n",lab)
/* output a label */
#define outlab(lab) printf("\tL%d:",lab)
/* output function label */
#define outflab(sym) printf("\t_%.8s:\n\t~~%.8s:\n",sym,sym)
/* output data label */
#define outdlab(sym) printf("\t_%.8s:\n",sym)
/*functions returning pointers*/
char *expr();
char *talloc();
char *tnalloc();
char *enalloc();
char *snalloc();
char *cnalloc();
char *lcnalloc();
char *fpcnalloc();
char *popopd();
char *cvopgen();
char *arrayref();
char *funcref();
char *install();
char *lookup();
char *balpar();
char *sbrk();
long initlist();
long dsize();
long psize();
long dodecl();
long dlist();
long getdec();
long gethex();
long getoct();
long getfp();
long toieee();
long toffp();

View File

@@ -0,0 +1,16 @@
e:send DECL.C
e:send EXPR.C
e:send ICODE.C
e:send INTERF.C
e:send LEX.C
e:send MAIN.C
e:send STMT.C
e:send TABL.C
e:send VERSION.C
e:send ICODE.H
e:send PARSER.H
e:send MACHINE.68K
e:send LINK.SUB
e:send MAKE.SUB
e:send MACHINE.H
e:send SEND12.SU

View File

@@ -0,0 +1,507 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
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, lab, i;
register struct tnode *tp;
register char *p;
while( 1 ) {
switch(token=gettok()) {
case LCURBR: /*handle { ... }*/
while( !next(EOF) ) {
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:
lab = brklabel();
outgoto(lab); /*branch to break label*/
break;
case R_CASE:
docase();
continue;
case R_CONTINUE:
lab = contlabel(); /*branch to continue label*/
outgoto(lab);
break;
case R_DEFAULT:
dodefault();
continue;
case R_DO:
dodo();
break;
case R_FOR:
dofor();
return;
case R_GOTO:
lab = gotolabel();
outgoto(lab);
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) )
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) ) {
reducep = 1;
tp = expr();
reducep = 0;
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) )
synerr("expected label");
else {
sp = csp;
if( !(sp->s_sc) ) {
sp->s_type = LLABEL;
if( !sp->s_offset )
sp->s_offset = nextlabel++;
}
if( (!sp->s_sc || 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 )
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 )
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 )
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) ) /*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) )
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) ) {
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) ) {
forerr:
synerr("invalid for statement");
return;
}
if( !next(SEMI) ) { /*do init expression*/
outexpr(expr());
if( !next(SEMI) )
goto forerr;
}
outlab(clabel); /*branch back to here*/
if( !next(SEMI) ) { /*do for condition*/
outifgoto(expr(),FALSE,blabel);
if( !next(SEMI) )
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) )
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) )
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 struct tnode *tp;
if( !peekc(';') ) /*need to compute return?*/
outforreg(FRETURN,frp,expr());
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(ASSIGN,snalloc(INT,AUTO,0,0,0),tp);
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 )
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;
}
}
}
/* outforreg - generate assignment for switch and return*/
outforreg(op,ltp,rtp) /*returns - none*/
int op; /*operator for build tree*/
struct tnode *ltp; /*left expression tree*/
struct tnode *rtp; /*right expression tree*/
{
register struct tnode *tp;
opp = opstack;
opdp = opdstack;
pushopd(ltp);
pushopd(rtp);
maketree(op);
if( tp = popopd() )
outcforreg(tp->t_right);
opp = opdp = 0;
}
/* outassign - generate assignment for function args*/
outassign(ltp,rtp) /*returns - none*/
struct tnode *ltp; /*left expression tree*/
struct tnode *rtp; /*right expression tree*/
{
opp = opstack;
opdp = opdstack;
pushopd(ltp);
pushopd(rtp);
maketree(ASSIGN);
outexpr(popopd());
opp = opdp = 0;
}

View File

@@ -0,0 +1,119 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
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, /*EQNOT*/
TRMPRI, /*EQNEG*/
TRMPRI|OPBIN, /*DOCAST*/
ASGPRI|ASGOP, /*STASSIGN [vlh]*/
TRMPRI|OPCONVS, /*LONG2F [vlh] 3.4*/
TRMPRI|OPCONVS, /*FLOAT2L [vlh] 3.4*/
TRMPRI|OPCONVS, /*INT2F [vlh] 3.4*/
TRMPRI|OPCONVS, /*FLOAT2F [vlh] 3.4*/
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|OPTERM, /*CFLOAT [vlh] 3.4*/
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 ()*/
UNOPRI|OPRAS|OPASSIGN|OPBIN, /*FRETURN*/
};

View File

@@ -0,0 +1,16 @@
e:vax DECL.C s
e:vax EXPR.C s
e:vax ICODE.C s
e:vax INTERF.C s
e:vax LEX.C s
e:vax MAIN.C s
e:vax STMT.C s
e:vax TABL.C s
e:vax VERSION.C s
e:vax ICODE.H s
e:vax PARSER.H s
e:vax MACHINE.68K s
e:vax LINK.SUB s
e:vax MAKE.SUB s
e:vax MACHINE.H s
e:vax SEND12.SUB s

View File

@@ -0,0 +1 @@
char *compiled "@(#) parser - Thu Feb 10 13:02 1983";

View File

@@ -0,0 +1,18 @@
$ parser
$ set noon
$ !
$ ! C068 make file for VMS
$ !
$ copy machine.vax machine.h
$ pur machine.h
$ cx DECL
$ cx EXPR
$ cx ICODE
$ cx INIT
$ cx INTERF
$ cx LEX
$ cx MAIN
$ cx STMT
$ cx TABL
$ cx VERSION
$ clink DECL,EXPR,ICODE,INTERF,LEX,MAIN,STMT,TABL,init,version,lib:klib/lib c068