/**************************************************************/ /* Small C Compiler 1.0 */ /**************************************************************/ /* Author: Lucio Zambon (after a tutorial of J. Crenshaw) Date: 1998 Topics: described with BNF
::= [
|
]*
::=
';'
::= INT | SHORT | CHAR
::=
[','
]*
::=
| '*'
|
'['
']'
::=
[
|
]*
::=
['*']
'('
')'
::= VOID |
::=
[','
]* | null
::= '{' [
]
'}'
::= [
]*
::=
|
|
| null
::= '{'
'}'
::=
|
|
|
|
::= IF '('
')'
[ELSE
]
::= WHILE '('
')'
::= DO
WHILE '('
')'
::= FOR '('
';'
';'
')'
::=
::=
::= [['*']
'=']
::=
['?'
]
::=
['||'
]*
::=
['&&'
]*
::=
[
]*
::=
['&'
]*
::= ['!']
::=
[
]
::=
[
]
::=
[
]*
::=
[
factor]*
::= [
]
::=
|
|
| '('
')'
::=
'('
')'
::=
[','
]* | null
::= [
]
|
[
|
]
::= '['
']'
::= '++' | '--'
::= '|' | '~'
::= '==' | '<' | '<=' | '!=' | '>' | '>='
::= '<<' | '>>'
::= '+' | '-'
::= '*' | '/' | '%'
::= '*' | '&'
::= [
]* */ #define DOS 1 #if DOS #include
#include
#else #include
#endif #ifndef TRUE #define TRUE 1 #define FALSE 0 #define X 1 /* file execution flag */ #define W 2 /* file write flag */ #define R 4 /* file read flag */ #define O_APPEND 8 /* append to file */ #define O_CREAT 16 /* create new file */ #define O_TRUNC 32 /* truncate file */ #define O_EXCL 64 /* exclusive open */ #endif #define TAB 9 #define CR 13 #if DOS #define LF 10 #else #define LF 11 #endif #define MAXENTRY 100 #define NKW 25 #define NKW1 26 #define SYMBOLSIZE 9 #define MaxParam 10 #define OPCOM '\255' /* Open Comment */ #define Pointer 0x4000 /* Pointer to */ #define Vector 0x2000 /* Vector of */ #define Function 0x1000 #define VOID 1 #define CHAR 2 #define SHORT 3 #define INT 4 #define B 1 #define W 2 #define L 4 #define ISPOINTER(typ) (typ & Pointer) #define ISVECTOR(typ) (typ & Vector) #define ISFUN(typ) (typ & Function) /*--------------------------------------------------------------*/ /* Type Declarations */ typedef char symbol[SYMBOLSIZE]; typedef symbol symtab[1000]; typedef symtab *tabptr; typedef char boolean; struct typetable { int type, len; }; struct TinyIMP { int lcount; /* Label Counter */ int nentry; /* Number of Entries */ char look; /* Lookahead Character */ char tempchar; /* Temporary Character */ char token; /* Encoded Token */ int funtyp; /* Function Type */ char isassign; /* Is Assignment */ char *breakaddr; /* Address for Break */ char value[17]; /* Unencoded Token */ char MessageString[50]; /* Long Buffer */ char bufchar[2]; /* Short Buffer */ symbol st[MAXENTRY]; /* Symbol Table */ int stype[MAXENTRY+1]; /* Symbol Type */ int slen[MAXENTRY+1]; /* Symbol Vector Length */ symbol kwlist[NKW]; /* Keywords List */ char kwcode[NKW1+1]; /* Keywords Shortcut */ symbol params[MaxParam]; /* Parameter Table */ int paramtyp[MaxParam]; /* Parameters Type */ int paramlen[MaxParam]; /* Parameters Vector */ int parampos[MaxParam]; /* Parameters Offset */ int numparams,base,lastparam; /* Counters */ boolean mul32set, div32set, mod32set; #if DOS FILE *fdin, *fdout; /* I/O file descriptors */ #else int fdin, fdout; /* I/O file descriptors */ #endif }; typedef struct TinyIMP TIMP; int topencl(); int topen(); int treadcl(); int tread(); int twritecl(); int twrite(); char readch(); void Getchar(); void error(); void nabort(); void expected(); void undefined(); void duplicate(); void emit(); void emitln(); char typ2char(); int typsize(); void tmove(); void tmoveq(); void titoa(); char * String_Of(); void checkident(); boolean istalpha(); boolean istdigit(); boolean istalnum(); boolean isindop(); boolean isaddop(); boolean ismulop(); boolean isorop(); boolean isdiseqop(); boolean isrelop(); boolean isvarext(); boolean isvartype(); boolean iswhite(); void skipwhite(); void skipcomment(); void getname(); void getnum(); void getop(); void next(); void matchstring(); void readstr(); void postlabel(); void clear(); void negate(); void notit(); void loadconst(); void globalinc(); void globaldec(); int loadglobal(); void push(); void genadd(); void gensub(); void genmult(); void genlongmult(); void mul32bit(); void gendiv(); void genmod(); void genlongdiv(); void genlongmod(); void div32bit(); void mod32bit(); void convert(); void pop(); void pop2(); void popand(); void popor(); void popxor(); void popcompare(); void setequal(); void setnequal(); void setgreater(); void setless(); void setlessorequal(); void setgreaterorequal(); void setshright(); void setshleft(); void storevar(); void tbranch(); void branchfalse(); void branchfalse2(); void branchtrue(); void branchtrue2(); void readit(); void execit(); void mallocit(); void freeit(); void createit(); void mutexit(); void exitit(); void swriteit(); void iwriteit(); void header(); void epilog(); void allocvar(); void allocvector(); void call(); void funprolog(); void funepilog(); void cleanstack(); void localinc(); void localdec(); int loadlocal(); void storeparam(); char *newlabel(); int tlookup(); int locate(); boolean intable(); void checktable(); void checkdup(); int scantype(); void addentry(); void scan(); int indop(); int unop(); void shiftleftn(); int popaddtyp(); int popadd(); int popsub(); int popmul(); int popdiv(); int popmod(); void clearparams(); int paramnumber(); boolean isparam(); int evalpos(); void addparam(); void locdecl(); int locdecls(); void formalparam(); void renumparams(); void formallist(); void dofun(); void param(); int paramlist(); int callfun(); int promote(); int sametype(); int typeof(); int vartype(); int loadnum(); void loadindex(); int loadvar(); void assignment(); int factor(); int multiply(); int divide(); int module(); int term(); int add(); int subtract(); int expression(); void shiftleft(); void shiftright(); int shift(); int compareexpression(); int nextexpression(); int equal(); int lessorequal(); int notequal(); int less(); int greater(); int relation(); int notfactor(); int boolterm(); int boolor(); int boolxor(); int logicfactor(); int logicterm(); int logicexpression(); int extendedexpression(); void doreturn(); void dobreak(); void doif(); void doswitch(); void dowhile(); void dodo(); void dofor(); void readvar(); void doread(); void doexec(); void writetoken(); void dowrite(); void domalloc(); void dofree(); void docreate(); void doself(); void domutexcreate(); void domutexdestroy(); void dolock(); void dounlock(); void doexit(); void dokill(); void semi(); void store(); void statement(); void block(); void beginblock(); void talloc(); void dovar(); void topdecls(); void init(); /*--------------------------------------------------------------*/ /* Main Program */ #if DOS void main (argc,argv) #else void tiny (argc,argv) #endif int argc; char **argv; { TIMP e; init(&e,argc,argv); header(&e); topdecls(&e); if (!ISFUN(typeof(&e, "main"))) { strcpy(e.MessageString,"main"); expected(&e, e.MessageString); } epilog(&e); } /* --------------------------------------------------------------- */ /* input output error */ /* --------------------------------------------------------------- */ int topencl(a,b) char *a; int b; { #if !DOS @ trap #2 #endif } int topen(path,flag,mode) char *path; int flag,mode; { return topencl(path,flag+(mode%256)*256); } int treadcl(a,b) int a; char *b; { #if !DOS @ trap #0 #endif } int tread(fd,buf,nbyte) int fd; char *buf; int nbyte; { return treadcl(fd+nbyte*256,buf); } int twritecl(a,b) int a; char *b; { #if !DOS @ trap #1 #endif } int twrite(fd,buf,nbyte) #if DOS FILE *fd; #else int fd; #endif char *buf; int nbyte; { #if DOS for (nbyte=0; buf[nbyte]; nbyte++) if (buf[nbyte]==11) buf[nbyte] = 0; if (fd != NULL) fprintf(fd, "%s", buf); else printf("%s",buf); return 1; #else return twritecl(fd+nbyte*256,buf); #endif } /*--------------------------------------------------------------*/ /* Read New Character From Input Stream */ char readch (e) TIMP *e; { char c; #if DOS if (e->fdin) c = getc(e->fdin); else { c = getch(); printf("%c", c); if (c == CR) printf("%c",LF); } #else e->bufchar[0] = '\0'; while (!tread(e->fdin,e->bufchar,1) || !e->bufchar[0]) if (e->fdin) break; c = e->bufchar[0]; if (!e->fdin) { twrite(1,e->bufchar); if (e->look == CR) twrite(1,"\v"); } #endif return c; } /*--------------------------------------------------------------*/ /* Read New Character From Input Stream */ void GetcharX (e) TIMP *e; { e->look = readch(e); } void Getchar(e) TIMP *e; { if (e->tempchar != ' ') { e->look = e->tempchar; e->tempchar = ' '; } else { GetcharX(e); if (e->look == '/') { e->tempchar = readch(e); if (e->tempchar == '*') { e->look = OPCOM; e->tempchar = ' '; } } } } /*--------------------------------------------------------------*/ /* Report an Error */ void error (e,s) TIMP *e; char s[]; { twrite(e->fdout,"\n\v Error: ",12); twrite(e->fdout,s,strlen(s)); twrite(e->fdout,".\n\v",3); } /*--------------------------------------------------------------*/ /* Report Error and Halt */ void nabort (e,s) TIMP *e; char s[]; { error(e,s); #if DOS exit(); #else @ trap #6 // back to OS #endif } /*--------------------------------------------------------------*/ /* Report What Was Expected */ void expected (e,s) TIMP *e; char s[]; { nabort(e,strcat(s," Expected")); } /*--------------------------------------------------------------*/ /* Report an Undefined Identifier */ void undefined (e,n) TIMP *e; char n[]; { strcpy(e->MessageString,"Undefined Identifier "); strcat(e->MessageString,n); nabort(e,e->MessageString); } /*--------------------------------------------------------------*/ /* Report a Duplicate Identifier */ void duplicate (e,n) TIMP *e; char n[]; { strcpy(e->MessageString,"Duplicate Identifier "); strcat(e->MessageString,n); nabort(e,e->MessageString); } /*--------------------------------------------------------------*/ /* Output a String with Tab */ void emit (e,s) TIMP *e; char s[]; { twrite(e->fdout,"\t",1); twrite(e->fdout,s,strlen(s)); } /*--------------------------------------------------------------*/ /* Output a String with Tab and CRLF */ void emitln (e,s) TIMP *e; char s[]; { emit(e,s); twrite(e->fdout,"\n\v",2); } /*--------------------------------------------------------------*/ /* Convert Type to Char */ char typ2char(e, typ) TIMP *e; int typ; { if (ISPOINTER(typ) || (typ == 4)) return 'L'; if (typ == 3) return 'W'; if (typ == 2) return 'B'; expected(e, "Scalar Type"); } /*--------------------------------------------------------------*/ /* Match Types' Size */ int typsize(e, typ) TIMP *e; int typ; { switch (typ%Function) { case 4: return 4; case 3: return 2; case 2: return 1; default: nabort(e, " Uncorrect Type "); } } /*---------------------------------------------------------------*/ /* Generate a Move Instruction */ void tmove (e, typ, source, dest) TIMP *e; int typ; char source[]; char dest[]; { char s[50]; strcpy(s, "MOVE. "); s[5] = typ2char(e, typ); strcat(s, source); strcat(s, ","); strcat(s, dest); emitln(e, s); } /*---------------------------------------------------------------*/ /* Generate a Move Instruction */ void tmoveq (e,source,dest) TIMP *e; char source; char dest[]; { char s[10]; int i; i=0; emit(e, "MOVEQ.L #"); titoa(s, source, &i); twrite(e->fdout,s,strlen(s)); twrite(e->fdout,",",1); twrite(e->fdout,dest,strlen(dest)); twrite(e->fdout,"\n\v",2); } /* --------------------------------------------------------------- */ /* scanner */ /* --------------------------------------------------------------- */ void titoa(st,i,k) char *st; int i; int *k; { if (i/10) titoa(st,i/10,k); st[(*k)++] = '0'+i%10; st[*k] = '\0'; } char *String_Of(e,look) TIMP *e; char look; { e->bufchar[0] = look; return e->bufchar; } /*--------------------------------------------------------------*/ /* Check to Make Sure the Current Token is an Identifier */ void checkident (e) TIMP *e; { if (e->token != 'x') expected(e,"Identifier "); } /*--------------------------------------------------------------*/ /* Recognize an Alpha Character */ boolean istalpha (c) char c; { return ((c>='A') && (c<='Z')) || ((c>='a') && (c<='z')); } /*--------------------------------------------------------------*/ /* Recognize a Decimal Digit */ boolean istdigit (c) char c; { return (c>='0') && (c<='9'); } /*--------------------------------------------------------------*/ /* Recognize an AlphaNumeric Character */ boolean istalnum (c) char c; { return (istalpha(c) || istdigit(c)); } /*--------------------------------------------------------------*/ /* Recognize an Indop */ boolean isindop (c) char c; { return((c=='&') || (c=='*')); } /*--------------------------------------------------------------*/ /* Recognize an Addop */ boolean isaddop (c) char c; { return((c=='+') || (c=='-')); } /*--------------------------------------------------------------*/ /* Recognize a Mulop */ boolean ismulop (c) char c; { return((c=='*') || (c=='/') || (c=='%')); } /*--------------------------------------------------------------*/ /* Recognize a Boolean Orop */ boolean isorop (c) char c; { return((c=='|') || (c=='^')); } /*--------------------------------------------------------------*/ /* Recognize a Diseqop */ boolean isdiseqop (c) char c; { return((c=='<') || (c=='>')); } /*--------------------------------------------------------------*/ /* Recognize a Relop */ boolean isrelop (c) char c; { return((c=='=') || (c=='!') || (c=='<') || (c=='>')); } /*--------------------------------------------------------------*/ /* Recognize a Legal Variable Extension */ boolean isvarext (c) char c; { return ((c=='B') || (c=='W') || (c=='L')); } /*--------------------------------------------------------------*/ /* Recognize a Legal Variable Type */ boolean isvartype (c) char c; { if (c >= 'a') c -= 32; return ((c=='C') || (c=='S') || (c=='N') || (c=='P')); } /*--------------------------------------------------------------*/ /* Recognize White Space */ boolean iswhite (c) char c; { return((c==' ') || (c==TAB) || (c==CR) || (c==LF) || (c==OPCOM) ); } /*--------------------------------------------------------------*/ /* Skip Over Leading White Space */ void skipwhite (e) TIMP *e; { while (iswhite(e->look)) if (e->look==OPCOM) skipcomment(e); else Getchar(e); } /*--------------------------------------------------------------*/ /* Skip A Comment Field */ void skipcomment (e) TIMP *e; { do { do GetcharX(e); while (e->look != '*'); GetcharX(e); } while (e->look != '/'); GetcharX(e); } /*--------------------------------------------------------------*/ /* Get an Identifier */ void getname (e) TIMP *e; { short i; skipwhite(e); if ( ! istalpha(e->look)) expected(e,"Identifier"); e->token = 'x'; for (i=0; istalnum(e->look); i++) { e->value[i] = e->look; Getchar(e); } e->value[i] = '\0'; } /*--------------------------------------------------------------*/ /* Get a Number */ void getnum (e) TIMP *e; { short i; skipwhite(e); if ( ! istdigit(e->look)) expected(e,"Number"); e->token = '#'; for (i=0; istdigit(e->look); i++) { e->value[i] = e->look; Getchar(e); } e->value[i] = '\0'; } /*--------------------------------------------------------------*/ /* Get an Operator */ void getop (e) TIMP *e; { skipwhite(e); e->token = e->look; strcpy (e->value,String_Of(e,e->look)); Getchar(e); } /*--------------------------------------------------------------*/ /* Get the Next Input Token */ void next (e) TIMP *e; { skipwhite(e); if (istalpha(e->look)) getname(e); else if (istdigit(e->look)) getnum(e); else getop(e); } /*--------------------------------------------------------------*/ /* Match a Specific Input String */ void matchstring (e,x) TIMP *e; char x[]; { if (strcmp(e->value,x)) { strcpy(e->MessageString,"\'"); strcat(e->MessageString,x); strcat(e->MessageString,"\'"); expected(e, e->MessageString); } next(e); } /*--------------------------------------------------------------*/ /* Process a Constant String */ void readstr (e) TIMP *e; { int i; i=0; while (e->look != '\"') { if ((e->MessageString[i++] = e->look) == '\\') { GetcharX(e); strcpy(&e->MessageString[i-1], "',"); e->MessageString[i++] = ','; switch (e->look) { case 't': strcat(e->MessageString, "8"); break; case 'n': strcat(e->MessageString, "13"); break; case 'v': strcat(e->MessageString, "10"); } strcat(e->MessageString, ",\'"); i = strlen(e->MessageString); } e->MessageString[i] = '\0'; GetcharX(e); } next(e); matchstring(e,"\""); } /* --------------------------------------------------------------- */ /* code generation */ /* --------------------------------------------------------------- */ /*--------------------------------------------------------------*/ /* Post a Label To Output */ void postlabel (e,l) TIMP *e; char l[]; { twrite(e->fdout,l,strlen(l)); twrite(e->fdout,": \n\v",4); } /*---------------------------------------------------------------*/ /* Clear the Primary Register */ void clear (e) TIMP *e; { emitln(e,"CLR D0"); } /*---------------------------------------------------------------*/ /* Negate the Primary Register */ void negate (e) TIMP *e; { emitln(e,"NEG D0"); } /*---------------------------------------------------------------*/ /* Complement the Primary Register */ void notit (e) TIMP *e; { emitln(e,"NOT D0"); } /*---------------------------------------------------------------*/ /* Load a Constant to the Primary Register */ void loadconst(e, n, typ) TIMP *e; int n; int typ; { char temp[15]; int i; i=0; temp[0] = '#'; titoa(&temp[1],n,&i); tmove(e, typ, temp, "D0"); } /* ------------------------------------------------------------ */ /* Emit Parameter Post Increment */ void globalinc(e, typ, loc) TIMP *e; int typ; char *loc; { int i,t; char add[20]; strcpy(add, "LEA "); strcat(add, loc); strcat(add, ",A0"); emitln(e, add); if (ISPOINTER(typ) && ((t=typsize(e, typ))>1)) { int i=0; strcpy(add, "MOVEQ.L #"); titoa(&add[9], t, &i); strcat(add, ",D7"); emitln(e, add); strcpy(add, "ADD.L D7,(A0)"); emitln(e, add); } else { strcpy(add, "ADDQ. #1,(A0)"); add[5] = typ2char(e, typ); emitln(e, add); } } /* ------------------------------------------------------------ */ /* Emit Parameter Post Decrement */ void globaldec(e, typ, loc) TIMP *e; int typ; char *loc; { int i,t; char add[20]; strcpy(add, "LEA "); strcat(add, loc); strcat(add, ",A0"); emitln(e, add); if (ISPOINTER(typ) && ((t=typsize(e, typ))>1)) { int i=0; strcpy(add, "MOVEQ.L #"); titoa(&add[9], t, &i); strcat(add, ",D7"); emitln(e, add); strcpy(add, "SUB.L D7,(A0)"); emitln(e, add); } else { strcpy(add, "SUBQ. #1,(A0)"); add[5] = typ2char(e, typ); emitln(e, add); } } /*---------------------------------------------------------------*/ /* Load a Variable to Primary Register */ int loadglobal (e, postop, vect, name) TIMP *e; char postop; char vect; char name[]; { int typ, t; char loc[20], add[20]; if ( ! intable(e,name)) undefined(e,name); typ = vartype(e, name); strcpy(loc, name); strcat(loc, "(PC"); if (vect) { int j,i=0; if (j = typ%Vector-2) { strcpy(add, "ASL.L #"); titoa(&add[7], j, &i); strcat(add, ",D0"); emitln(e, add); } strcat(loc, ",D0"); } strcat(loc, ")"); tmove(e, typ, loc, "D0"); switch (postop) { case '+': globalinc(e, typ, loc); break; case '-': globaldec(e, typ, loc); break; } return typ; } /*---------------------------------------------------------------*/ /* Push Primary onto Stack */ void push(e, size) TIMP *e; int size; { tmove(e, size, "D0", "-(SP)"); } /*---------------------------------------------------------------*/ /* Add Top of Stack to Primary */ void genadd(e, size) TIMP *e; char size; { char st[12]; strcpy(st,"ADD. D7,D0"); st[4] = typ2char(e, size); emitln(e, st); } /*---------------------------------------------------------------*/ /* Subtract Primary from Top of Stack */ void gensub(e, size) TIMP *e; char size; { char st[12]; strcpy(st,"SUB. D7,D0"); st[4] = typ2char(e, size); emitln(e, st); strcpy(st,"NEG. D0"); st[4] = typ2char(e, size); emitln(e, st); } /*---------------------------------------------------------------*/ /* Multiply Top of Stack by Primary (Word) */ void genmult(e) TIMP *e; { emitln(e, "MULS D7,D0"); } /*---------------------------------------------------------------*/ /* Multiply Top of Stack by Primary (Long) */ void genlongmult(e) TIMP *e; { emitln(e,"BSR MUL32"); } /*--------------------------------------------------------------*/ /* Generate Code for 32 bits Multipication */ void mul32bit(e) TIMP *e; { twrite(e->fdout, "MUL32:\n\v", 8); emitln(e, "MOVE.L D7,D2"); emitln(e, "MULU D0,D7"); emitln(e, "MOVE.L D0,D1"); emitln(e, "SWAP D0"); emitln(e, "MULU D2,D0"); emitln(e, "SWAP D2"); emitln(e, "MULU D2,D1"); emitln(e, "ADD.W D1,D0"); emitln(e, "SWAP D0"); emitln(e, "CLR.W D0"); emitln(e, "ADD.L D7,D0"); emitln(e, "RTS"); } /*---------------------------------------------------------------*/ /* Divide Top of Stack by Primary (Word) */ void gendiv(e) TIMP *e; { emitln(e, "DIVS D0,D7"); tmove(e, SHORT, "D7", "D0"); } /*---------------------------------------------------------------*/ /* Divide Top of Stack by Primary (Word) */ void genmod(e) TIMP *e; { emitln(e, "DIVS D0,D7"); emitln(e, "SWAP D7"); tmove(e, SHORT, "D7", "D0"); } /*---------------------------------------------------------------*/ /* Divide Top of Stack by Primary (Long) */ void genlongdiv(e) TIMP *e; { emitln(e, "JSR DIV32"); } /*---------------------------------------------------------------*/ /* Divide Top of Stack by Primary (Long) */ void genlongmod(e) TIMP *e; { emitln(e, "JSR MOD32"); } /*--------------------------------------------------------------*/ /* Generate Code for 32 bits Division */ void div32bit(e) TIMP *e; { twrite(e->fdout, "DIV32:\n\v", 8); emitln(e, "MOVE.L D7,D1"); emitln(e, "BEQ DIV0"); emitln(e, "BGT DIV1"); emitln(e, "NEG.L D1"); twrite(e->fdout, "DIV1:\tCMPI.L #$00010000,D1\n\v", 28); emitln(e, "BGT DIV0"); emitln(e, "MOVE.L D0,D1"); emitln(e, "MOVE.L D7,D2"); emitln(e, "MOVEQ.L #16,D3"); emitln(e, "ASR.L D3,D1"); emitln(e, "DIVS D1,D2"); emitln(e, "MOVE.L D2,D1"); emitln(e, "AND.L #$FFFF0000,D1"); emitln(e, "ASL.L D3,D2"); emitln(e, "AND.L #$FFFF,D0"); emitln(e, "ADD.L D1,D0"); emitln(e, "DIVS D0,D7"); emitln(e, "ADD.W D7,D2"); emitln(e, "MOVE.L D2,D0"); emitln(e, "RTS"); twrite(e->fdout, "DIVERR:\tDC.B 'Runtime Error: Division By Zero or Divisor Too Long',0\n\v", 70); twrite(e->fdout, "DIV0:\tLEA DIVERR(PC),A0\n\v", 25); emitln(e,"MOVE.L A0,D1"); emitln(e,"MOVEQ.L #1,D0"); emitln(e,"TRAP #1"); emitln(e, "RTS"); } /*--------------------------------------------------------------*/ /* Generate Code for 32 bits Modulus */ void mod32bit(e) TIMP *e; { twrite(e->fdout, "MOD32:\n\v", 8); emitln(e, "MOVE.L D7,D1"); emitln(e, "BEQ MOD0"); emitln(e, "BGT MOD1"); emitln(e, "NEG.L D1"); twrite(e->fdout, "MOD1:\tCMPI.L #$00010000,D1\n\v", 28); emitln(e, "BGT MOD0"); emitln(e, "DIVS D0,D7"); emitln(e, "SWAP D7"); emitln(e, "CLR.L D0"); emitln(e, "MOVE.W D7,D0"); emitln(e, "RTS"); twrite(e->fdout, "MODERR:\tDC.B 'Runtime Error: Division By Zero or Divisor Too Long',0\n\v", 70); twrite(e->fdout, "MOD0:\tLEA MODERR(PC),A0\n\v", 25); emitln(e,"MOVE.L A0,D1"); emitln(e,"MOVEQ.L #1,D0"); emitln(e,"TRAP #1"); emitln(e, "RTS"); } /*---------------------------------------------------------------*/ /* Convert a Data Item from One Type to Another */ void convert(e, source, dest, reg) TIMP *e; int source, dest; char *reg; { char st[15]; if (source != dest) { if (source == 2) { strcpy(st, "AND.W #$FF,"); strcat(st,reg); emitln(e,st); } if (dest == 4) { strcpy(st, "EXT.L "); strcat(st,reg); emitln(e,st); } } } /*---------------------------------------------------------------*/ /* Pop Stack into Secondary Register */ void pop(e, size) TIMP *e; int size; { tmove(e, size, "(SP)+", "D7"); } /*---------------------------------------------------------------*/ /* Move Stack into Secondary Register */ void pop2(e, size) TIMP *e; int size; { tmove(e, size, "(SP)", "D7"); } /*---------------------------------------------------------------*/ /* AND Top of Stack with Primary */ void popand (e, typ) TIMP *e; int typ; { char s[15]; strcpy(s, "AND. D7,D0"); s[4] = typ2char(e, typ); emitln(e, s); } /*---------------------------------------------------------------*/ /* OR Top of Stack with Primary */ void popor (e, typ) TIMP *e; int typ; { char s[15]; strcpy(s, "OR. D7,D0"); s[3] = typ2char(e, typ); emitln(e, s); } /*---------------------------------------------------------------*/ /* XOR Top of Stack with Primary */ void popxor (e, typ) TIMP *e; int typ; { char s[15]; strcpy(s, "EOR. D7,D0"); s[4] = typ2char(e, typ); emitln(e, s); } /*---------------------------------------------------------------*/ /* Compare Top of Stack with Primary */ void popcompare (e, typ) TIMP *e; int typ; { char s[15]; strcpy(s, "CMP. D7,D0"); s[4] = typ2char(e, typ); emitln(e, s); } /*---------------------------------------------------------------*/ /* Set D0 If Compare was = */ void setequal (e) TIMP *e; { emitln(e,"SEQ D0"); emitln(e,"EXT.W D0"); } /*---------------------------------------------------------------*/ /* Set D0 If Compare was != */ void setnequal (e) TIMP *e; { emitln(e,"SNE D0"); emitln(e,"EXT.W D0"); } /*---------------------------------------------------------------*/ /* Set D0 If Compare was > */ void setgreater (e) TIMP *e; { emitln(e,"SLT D0"); emitln(e,"EXT.W D0"); } /*---------------------------------------------------------------*/ /* Set D0 If Compare was < */ void setless (e) TIMP *e; { emitln(e,"SGT D0"); emitln(e,"EXT.W D0"); } /*---------------------------------------------------------------*/ /* Set D0 If Compare was <= */ void setlessorequal (e) TIMP *e; { emitln(e,"SGE D0"); emitln(e,"EXT.W D0"); } /*---------------------------------------------------------------*/ /* Set D0 If Compare was >= */ void setgreaterorequal (e) TIMP *e; { emitln(e,"SLE D0"); emitln(e,"EXT.W D0"); } /*---------------------------------------------------------------*/ /* Set D0 If Shift was >> */ void setshright (e, typ) TIMP *e; int typ; { char c; strcpy(e->MessageString, "ASR. D0,D7"); c = e->MessageString[4] = typ2char(e, typ); emitln(e, e->MessageString); strcpy(e->MessageString, "MOVE. D7,D0"); e->MessageString[5] = c; emitln(e, e->MessageString); } /*---------------------------------------------------------------*/ /* Set D0 If Shift was << */ void setshleft (e, typ) TIMP *e; int typ; { char c; strcpy(e->MessageString, "ASL. D0,D7"); c = e->MessageString[4] = typ2char(e, typ); emitln(e, e->MessageString); strcpy(e->MessageString, "MOVE. D7,D0"); e->MessageString[5] = c; emitln(e, e->MessageString); } /*---------------------------------------------------------------*/ /* Store Primary to Variable */ void storevar (e, name, typ, ind, vect) TIMP *e; char *name; int typ; boolean ind; char vect; { char s[50]; strcpy(s,"LEA "); strcat(s,name); strcat(s,"(PC),A0"); emitln(e, s); if (ind) { emitln(e, "MOVEA.L (A0),A0"); typ -= Pointer; } strcpy(s, "(A0"); if (vect) { pop(e, INT); strcat(s, ",D7"); } strcat(s, ")"); tmove(e, typ, "D0", s); } /*---------------------------------------------------------------*/ /* Branch Unconditional */ void tbranch (e,l) TIMP *e; char l[]; { strcpy(e->MessageString,"BRA "); strcat(e->MessageString,l); emitln(e,e->MessageString); } /*---------------------------------------------------------------*/ /* Branch False */ void branchfalse (e, l, typ) TIMP *e; char l[]; int typ; { strcpy(e->MessageString, "TST. D0"); e->MessageString[4] = typ2char(e, typ); emitln(e, e->MessageString); strcpy(e->MessageString,"BEQ "); strcat(e->MessageString,l); emitln(e,e->MessageString); } /*---------------------------------------------------------------*/ /* Branch False Short */ void branchfalse2 (e, l) TIMP *e; char l[]; { strcpy(e->MessageString,"BEQ "); strcat(e->MessageString,l); emitln(e,e->MessageString); } /*---------------------------------------------------------------*/ /* Branch True */ void branchtrue (e, l, typ) TIMP *e; char l[]; int typ; { strcpy(e->MessageString, "TST. D0"); e->MessageString[4] = typ2char(e, typ); emitln(e, e->MessageString); strcpy(e->MessageString,"BNE "); strcat(e->MessageString,l); emitln(e,e->MessageString); } /*---------------------------------------------------------------*/ /* Branch True Short */ void branchtrue2 (e, l) TIMP *e; char l[]; { strcpy(e->MessageString,"BNE "); strcat(e->MessageString,l); emitln(e,e->MessageString); } /*---------------------------------------------------------------*/ /* Read Variable to Primary Register */ void readit (e) TIMP *e; { emitln(e, "CLR.L D0"); emitln(e, "CLR.L D1"); emitln(e, "TRAP #0"); } /*---------------------------------------------------------------*/ /* Write a String from Primary Register */ void execit (e,s) TIMP *e; char *s; { char l1[10],l2[10],s1[50]; int l; strcpy(s1,s); strcpy(l1,newlabel(e)); strcpy(l2,newlabel(e)); emit(e,"BRA "); twrite(e->fdout,l2,strlen(l2)); twrite(e->fdout," \n\v",3); twrite(e->fdout,l1,strlen(l1)); twrite(e->fdout,":\tDC.B \'",8); twrite(e->fdout,s1,l = strlen(s1)); twrite(e->fdout,"\'",1); if (!(l%2)) twrite(e->fdout,",0",2); twrite(e->fdout,",0 \n\v",5); postlabel(e,l2); emit(e,"LEA "); twrite(e->fdout,l1,strlen(l1)); twrite(e->fdout,"(PC),A0\n\v",9); emitln(e,"MOVE.L A0,D1"); emitln(e,"MOVEQ.L #2,D0"); emitln(e,"TRAP #4"); } /*---------------------------------------------------------------*/ /* Call Malloc Trap */ void mallocit (e) TIMP *e; { emitln(e, "TRAP #8"); } /*---------------------------------------------------------------*/ /* Call Free Trap */ void freeit (e) TIMP *e; { emitln(e, "TRAP #9"); } /*---------------------------------------------------------------*/ /* Call Trap for Thread Create */ void createit (e,name) TIMP *e; char name[]; { char buf[25]; if (name) { strcpy(buf, "LEA "); strcat(buf, name); strcat(buf, "(PC),A0"); emitln(e, buf); tmove(e, 'L', "A0", "D0"); } else emitln(e, "CLR.L D0"); emitln(e, "TRAP #11"); } /*---------------------------------------------------------------*/ /* Call Thread Mutex Trap */ void mutexit (e, c) TIMP *e; char c; { if (c) tmoveq(e, c, "D1"); else emitln(e, "CLR.L D1"); emitln(e, "TRAP #12"); } /*---------------------------------------------------------------*/ /* Call Thread Exit Trap */ void exitit (e, c) TIMP *e; char c; { if (c) tmoveq(e, c, "D1"); else emitln(e, "CLR.L D1"); emitln(e, "TRAP #13"); } /*---------------------------------------------------------------*/ /* Write a Constant String */ void swriteit (e,s) TIMP *e; char *s; { char l1[10],l2[10],s1[50]; int l; strcpy(s1,s); strcpy(l1,newlabel(e)); strcpy(l2,newlabel(e)); emit(e,"BRA "); twrite(e->fdout,l2,strlen(l2)); twrite(e->fdout," \n\v",3); twrite(e->fdout,l1,strlen(l1)); twrite(e->fdout,":\tDC.B \'",8); twrite(e->fdout,s1,l = strlen(s1)); twrite(e->fdout,"\'",1); if (!(l%2)) twrite(e->fdout,",0",2); twrite(e->fdout,",0 \n\v",5); postlabel(e,l2); emit(e,"LEA "); twrite(e->fdout,l1,strlen(l1)); twrite(e->fdout,"(PC),A0\n\v",9); emitln(e,"MOVE.L A0,D1"); emitln(e,"MOVEQ.L #1,D0"); emitln(e,"TRAP #1"); } /*---------------------------------------------------------------*/ /* Write an Integer from Primary Register */ void iwriteit (e) TIMP *e; { emitln(e,"ASL.L #8,D0"); emitln(e,"ADDQ.L #1,D0"); emitln(e,"CLR.L D1"); emitln(e,"TRAP #1"); } /*--------------------------------------------------------------*/ /* Write Header Info */ void header (e) TIMP *e; { twrite(e->fdout,"\tBRA MAIN \n\v",12); } /*--------------------------------------------------------------*/ /* Write the Epilog */ void epilog (e) TIMP *e; { if (e->mul32set) mul32bit(e); if (e->div32set) div32bit(e); if (e->mod32set) mod32bit(e); emitln(e,"END MAIN "); } /*--------------------------------------------------------------*/ /* Generate Code for Allocation of a Variable */ void allocvar (e, n, t) TIMP *e; char *n, t; { char s[22]; strcpy(s, n); strcat(s, ":\tDC. 0"); if((s[strlen(s)-3] = t) == 'B') strcat(s, ",0\n\v"); else strcat(s, "\n\v"); twrite(e->fdout, s, strlen(s)); } /*--------------------------------------------------------------*/ /* Generate Code for Allocation of a Vector */ void allocvector (e, n, l, t) TIMP *e; char *n, *l, t; { char s[22]; strcpy(s, n); strcat(s, ":\tDS. "); s[strlen(s)-2] = t; strcat(s, l); strcat(s, "\n\v"); twrite(e->fdout, s, strlen(s)); } /*--------------------------------------------------------------*/ /* Call a Procedure */ void call(e,n) TIMP *e; char *n; { char st[50]; strcpy(st,"BSR "); strcat(st,n); emitln(e,st); } /* ------------------------------------------------------------ */ /* Write the Prolog for a Void */ void funprolog(e, n, k) TIMP *e; char *n; int k; { int i; i=0; postlabel(e, n); titoa(n,-k-(k%2),&i); emit(e, "LINK A5,#-"); twrite(e->fdout, n, strlen(n)); twrite(e->fdout,"\n\v",2); } /* ------------------------------------------------------------ */ /* Write the Epilog for a Void */ void funepilog(e) TIMP *e; { emitln(e, "UNLK A5"); emitln(e, "RTS"); } /* ------------------------------------------------------------ */ /* Adjust the Stack Pointer Upwards by N Bytes */ void cleanstack(e, n) TIMP *e; int n; { char st[10]; int i; i=0; if (n > 0) { emit(e, "ADD #"); titoa(st,n,&i); twrite(e->fdout, st, strlen(st)); twrite(e->fdout, ",SP\n\v", 5); } } /* ------------------------------------------------------------ */ /* Emit Parameter Post Increment */ void localinc(e, typ, offset) TIMP *e; int typ; char *offset; { int i,j; char add[20]; if (ISPOINTER(typ) && ((j=typsize(e, typ)) > 1)) { strcpy(add, "MOVEQ.L #"); i=0; titoa(&add[9], j, &i); strcat(add, ",D7"); emitln(e, add); strcpy(add, "ADD.L D7,"); strcat(add, offset); emitln(e, add); } else { strcpy(add, "ADDQ. #1,"); add[5] = typ2char(e, typ); strcat(add, offset); emitln(e, add); } } /* ------------------------------------------------------------ */ /* Emit Parameter Post Decrement */ void localdec(e, typ, offset) TIMP *e; int typ; char *offset; { int i,j; char add[20]; if (ISPOINTER(typ) && ((j=typsize(e, typ)) > 1)) { strcpy(add, "MOVEQ.L #"); i=0; titoa(&add[9], j, &i); strcat(add, ",D7"); emitln(e, add); strcpy(add, "SUB.L D7,"); strcat(add, offset); emitln(e, add); } else { strcpy(add, "SUBQ. #1,"); add[5] = typ2char(e, typ); strcat(add, offset); emitln(e, add); } } /* ------------------------------------------------------------ */ /* Load a Parameter to the Primary Register */ int loadlocal(e, postop, vect, n) TIMP *e; char postop; char vect; int n; { int typ; char offset[30], add[20]; int i,j; i=0; offset[0]='-'; typ = e->paramtyp[n-1]; j = e->parampos[n-1]; titoa(&offset[j<0], abs(j), &i); strcat(offset,"(A5"); if (vect) { int j,i=0; if (!ISVECTOR(typ)) expected(e, "Vector not"); typ -= Vector+Pointer; if (j = typ-2) { strcpy(add, "ASL.L #"); titoa(&add[7], j, &i); strcat(add, ",D0"); emitln(e, add); } strcat(offset, ",D0"); } else if (ISVECTOR(typ)) typ -= Vector; strcat(offset,")"); tmove(e, typ, offset, "D0"); switch (postop) { case '+': localinc(e, typ, offset); break; case '-': localdec(e, typ, offset); break; } return typ; } /* ------------------------------------------------------------ */ /* Store a Parameter from the Primary Register */ void storeparam(e, n, typ, ind, vect) TIMP *e; int n; boolean ind; char vect; { char offset[20]; int i,j; i=0; offset[0]='-'; j = e->parampos[n-1]; titoa(&offset[j<0], abs(j), &i); strcat(offset,"(A5"); if (vect) { pop(e, INT); strcat(offset, ",D7"); } strcat(offset, ")"); if (ind) { tmove(e, L, offset, "A0"); strcpy(offset, "(A0)"); typ -= Pointer; } tmove(e, typ, "D0", offset); } /* --------------------------------------------------------------- */ /* parser */ /* --------------------------------------------------------------- */ /*--------------------------------------------------------------*/ /* Generate a Unique Label */ char *newlabel (e) TIMP *e; { int i = 0; strcpy(e->MessageString,"L"); titoa(&e->MessageString[1],e->lcount++,&i); return e->MessageString; } /*--------------------------------------------------------------*/ /* Table Lookup */ int tlookup (t,s,n) tabptr t; char s[]; int n; { int i; boolean found; int function; found = FALSE; i = n; while ((i >= 0) && ! found) if (!strcmp(s,&(*(*t))[SYMBOLSIZE*i])) found = TRUE; else i--; return i+1; } /*--------------------------------------------------------------*/ /* Locate a Symbol in Table */ /* Returns the index of the entry. Zero if not present. */ int locate (e,n) TIMP *e; symbol n; { return tlookup((tabptr) e->st,n,e->nentry); } /*--------------------------------------------------------------*/ /* Look for Symbol in Table */ boolean intable (e,n) TIMP *e; symbol n; { return tlookup(e->st,n,e->nentry); } /*--------------------------------------------------------------*/ /* Check to See if an Identifier is in the Symbol Table */ /* Report an error if it's not. */ void checktable (e,n) TIMP *e; symbol n; { if ( ! intable(e,n)) undefined(e,n); } /*--------------------------------------------------------------*/ /* Check the Symbol Table for a Duplicate Identifier */ /* Report an error if identifier is already in table. */ void checkdup (e,n) TIMP *e; symbol n; { if (intable(e,n)) duplicate(e,n); } /*--------------------------------------------------------------*/ /* Recognize a type */ int scantype (name) char *name; { if (!strcmp(name,"void")) return 1; if (!strcmp(name,"char")) return 2; if (!strcmp(name,"short")) return 3; if (!strcmp(name,"int")) return 4; return 0; } /*--------------------------------------------------------------*/ /* Add a New Entry to Symbol Table */ void addentry (e, n, typ) TIMP *e; symbol n; int typ; { checkdup(e,n); if (e->nentry == MAXENTRY) nabort(e,"Symbol Table Full"); strcpy (e->st[e->nentry],n); e->stype[e->nentry++] = typ; } /*--------------------------------------------------------------*/ /* Scan the Current Identifier for Keywords */ void scan (e) TIMP *e; { if (e->token == 'x') e->token = e->kwcode[tlookup(e->kwlist,e->value,NKW-1)]; } /*---------------------------------------------------------------*/ /* Process a Term with Leading Indirection Operator */ int indop(e, op) TIMP *e; char op; { char s[30]; int typ; int i,j; i=0; next(e); typ = typeof(e, e->value); if (op == '&') { typ &= Pointer; if (isparam(e, e->value)) { j = paramnumber(e, e->value); tmove(e, 4, "A5", "D0"); strcpy(s, "ADD.L #-"); j = e->parampos[j-1]; titoa(&s[7+(j<0)], abs(j), &i); strcat(s, ",D0"); emitln(e, s); } else { strcpy(s, "LEA "); strcat(s, e->value); strcat(s, "(PC),A0"); emitln(e, s); tmove(e, 4, "A0", "D0"); } } else { if (!ISPOINTER(typ)) expected(e, "Pointer"); typ -= Pointer; if (isparam(e, e->value)) { j = paramnumber(e, e->value); j = e->parampos[j-1]; strcpy(s, "MOVEA.L -"); titoa(&s[8+(j<0)], abs(j), &i); strcat(s, "(A5),A0"); emitln(e, s); tmove(e, typ, "(A0)", "D0"); } else { strcpy(s, "LEA "); strcat(s, e->value); strcat(s, "(PC),A0"); emitln(e, s); emitln(e, "MOVEA.L (A0),A0"); tmove(e, typ, "(A0)", "D0"); } } next(e); return typ; } /*---------------------------------------------------------------*/ /* Process a Term with Leading Unary Operator */ int unop(e) TIMP *e; { clear(e); return 'W'; } /*---------------------------------------------------------------*/ /* Shift Left */ void shiftleftn(e, i, reg) TIMP *e; int i; char reg[]; { char st[15]; int j=0; promote(e, i, INT, reg); if (!i) return; strcpy(st, "ASL.L #"); titoa(&st[7], i, &j); strcat(st, ","); strcat(st, reg); emitln(e, st); } /*---------------------------------------------------------------*/ /* Generate Code to Add/Sub Primary to the Stack */ int popaddtyp(e, t1, t2) TIMP *e; int t1,t2; { if (ISPOINTER(t1)) { if (ISPOINTER(t2)) if (t1!=t2) nabort(e, "Pointer Mismatch"); shiftleftn(e, t1%Function-2, "D0"); t2 = t1; } else if (ISPOINTER(t2)) shiftleftn(e, t2%Function-2, "D7"); else t2 = sametype(e, t1, t2); return t2; } /*---------------------------------------------------------------*/ /* Generate Code to Add Primary to the Stack */ int popadd(e, t1, t2) TIMP *e; int t1,t2; { pop(e, t1); t2 = popaddtyp(e, t1, t2); genadd(e, t2); return t2; } /*---------------------------------------------------------------*/ /* Generate Code to Subtract Primary from the Stack */ int popsub(e, t1, t2) TIMP *e; int t1,t2; { pop(e, t1); if (ISPOINTER(t2)) nabort(e, "Illegal Pointer Subtraction"); if (ISPOINTER(t1)) { shiftleftn(e, t1%Function-2, "D0"); t2 = t1; } else t2 = sametype(e, t1, t2); gensub(e, t2); return t2; } /*---------------------------------------------------------------*/ /* Generate Code to Multiply Primary by Stack */ int popmul(e, t1, t2) TIMP *e; int t1, t2; { int typ; if (ISPOINTER(t1) || ISPOINTER(t2)) nabort(e, "Pointer Multiplication not Allowed"); pop(e, t1); typ = sametype(e, t1, t2); convert(e, typ, W, "D7"); convert(e, typ, W, "D0"); if (typ == L) { e->mul32set = 1; genlongmult(e); } else genmult(e); return (typ == B)? W: L; } /*---------------------------------------------------------------*/ /* Generate Code to Divide Stack by the Primary */ int popdiv(e, t1, t2) TIMP *e; int t1, t2; { if (ISPOINTER(t1) || ISPOINTER(t2)) nabort(e, "Pointer Division not Allowed"); pop(e, t1); convert(e, t1, L, "D7"); if ((t1 == L) || (t2 == L)) { convert(e, t2, L, "D0"); e->div32set = 1; genlongdiv(e); return L; } else { convert(e, t2, W, "D0"); gendiv(e); return t1; } } /*---------------------------------------------------------------*/ /* Generate Code to Module Stack by the Primary */ int popmod(e, t1, t2) TIMP *e; int t1, t2; { if (ISPOINTER(t1) || ISPOINTER(t2)) nabort(e, "Pointer Module not Allowed"); pop(e, t1); convert(e, t1, L, "D7"); if ((t1 == L) || (t2 == L)) { convert(e, t2, L, "D0"); e->mod32set = 1; genlongmod(e); return L; } else { convert(e, t2, W, "D0"); genmod(e); return t1; } } /* ------------------------------------------------------------ */ /* Initialize Parameter Table to Null */ void clearparams(e) TIMP *e; { int i; for (i=0; i
params[i][0] = e->paramtyp[i] = '\0'; e->numparams = e->lastparam = 0; } /* ------------------------------------------------------------ */ /* Find the Parameter Number */ int paramnumber(e, n) TIMP *e; char *n; { return tlookup(e->params, n, e->numparams); } /* ------------------------------------------------------------ */ /* See if an Identifier is a Parameter */ boolean isparam(e, n) TIMP *e; char *n; { return tlookup(e->params, n, e->numparams) != 0; } /* ------------------------------------------------------------ */ /* See if an Identifier is a Parameter */ int evalpos(e, typ, dim) TIMP *e; int typ; int dim; { int i; switch (typ) { case 2: i=1; break; case 3: i=2; break; case 4: i=4; break; default: if (ISPOINTER(typ)) i=4; } if (e->lastparam%2 && !(i%2)) e->lastparam--; if (dim) i *= dim; e->lastparam -= i; return e->lastparam; } /* ------------------------------------------------------------ */ /* Add a New Parameter to Table */ void addparam(e, name, typ, dim) TIMP *e; char *name; int typ; int dim; { if (isparam(e, name)) duplicate(e, name); e->parampos[e->numparams] = evalpos(e, typ, dim); if (dim) typ |= Pointer+Vector; e->paramtyp[e->numparams] = typ; strcpy(e->params[e->numparams++],name); } /*--------------------------------------------------------------*/ /* Parse and Translate a Local Data Declaration */ void locdecl(e, typ) TIMP *e; int typ; { symbol name; int dim=0; next(e); if (e->token=='*') { typ |= Pointer; next(e); } strcpy(name, e->value); next(e); if (e->token=='[') { getnum(e); dim = atoi(e->value); next(e); matchstring(e, "]"); } addparam(e, name, typ, dim); skipwhite(e); } /*--------------------------------------------------------------*/ /* Parse and Translate Local Declarations */ int locdecls(e) TIMP *e; { int typ; int n; n = 0; scan(e); while (typ = scantype(e->value)) { locdecl(e, typ); n++; while (!strcmp(e->value,",")) { locdecl(e, typ); n++; } semi(e); scan(e); } return e->lastparam; } /* ------------------------------------------------------------ */ /* Process a Formal Parameter */ void formalparam(e) TIMP *e; { int typ; scan(e); if (typ = scantype(e->value)) { next(e); if (e->token == '*') { typ |= Pointer; next(e); } addparam(e, e->value, typ, 0); next(e); } } /* ------------------------------------------------------------ */ /* Process a Formal Parameter */ void renumparams(e) TIMP *e; { int i; e->base = e->numparams; for (i=0; i< e->base; i++) e->parampos[i] = (e->base-i)*4+4; e->lastparam = 0; } /* ------------------------------------------------------------ */ /* Process the Formal Parameter List of a Void */ void formallist(e) TIMP *e; { matchstring(e, "("); if (strcmp(e->value, ")")) { formalparam(e); while (!strcmp(e->value, ",")) { matchstring(e, ","); formalparam(e); } } matchstring(e, ")"); skipwhite(e); renumparams(e); } /* ------------------------------------------------------------ */ /* Parse and Translate a Void Declaration */ void dofun(e, typ, pnt, name) TIMP *e; int typ; char pnt; char *name; { int k; checkdup(e, name); typ += pnt*Pointer+Function; addentry(e, name, typ); formallist(e); matchstring(e, "{"); skipwhite(e); k = locdecls(e); funprolog(e, name, k); e->funtyp = typ; block(e); matchstring(e, "}"); skipwhite(e); funepilog(e); clearparams(e); scan(e); } /* ------------------------------------------------------------ */ /* Process an Actual Parameter */ void param(e) TIMP *e; { int typ; typ = extendedexpression(e); convert(e, typ2char(e, typ), 'L', "D0"); push(e, L); } /* ------------------------------------------------------------ */ /* Process the Parameter List for a Procedure Call */ int paramlist(e) TIMP *e; { int n; n = 0; matchstring(e, "("); if (strcmp(e->value, ")")) { param(e); n++; while (!strcmp(e->value, ",")) { matchstring(e, ","); param(e); n++; } } matchstring(e, ")"); return 4 * n; } /* ------------------------------------------------------------ */ /* Process a Void Call */ int callfun(e, typ, n) TIMP *e; int typ; char *n; { int i; symbol name; strcpy(name, n); i = paramlist(e); call(e, name); cleanstack(e, i); return typ-Function; } /*---------------------------------------------------------------*/ /* Promote the Size of a Register Value */ int promote(e, t1, t2, reg) TIMP *e; int t1, t2; char *reg; { int typ; typ = t1; if (t1 != t2) if ((t1 == CHAR) || ((t1 == SHORT) && (t2 == INT))) { convert(e, t1, t2, reg); typ = t2; } return typ; } /*---------------------------------------------------------------*/ /* Force both Arguments to Same Type */ int sametype(e, t1, t2) TIMP *e; int t1, t2; { t1 = promote(e, t1, t2, "D7"); return promote(e, t2, t1, "D0"); } /* ------------------------------------------------------------ */ /* Get Type of Symbol */ int typeof(e, n) TIMP *e; char *n; { return isparam(e, n)? e->paramtyp[paramnumber(e, n)-1] : e->stype[locate(e, n)-1]; } /*--------------------------------------------------------------*/ /* Get a Variable Type from the Symbol Table */ int vartype (e, name) TIMP *e; char *name; { int typ; typ = typeof(e, name); if ( ISFUN(typ)) { char s[50]; strcpy(s,"Identifier "); strcat(s,name); strcat(s," is not a variable"); nabort(e, s); } return typ; } /*--------------------------------------------------------------*/ /* Load a Constant to the Primary Register */ int loadnum(e, n) TIMP *e; int n; { int typ; if (abs(n) <= 127) typ = 2; else if (abs(n) <= 32767) typ = 3; else typ = 4; loadconst(e, n, typ); return typ; } /* ------------------------------------------------------------ */ /* Parse and Translate an Assignment Statement */ void assignment(e, name, vect) TIMP *e; char *name; char vect; { int typ; boolean ind; next(e); typ = typeof(e, name); if (ind = !strcmp(name, "*")) { strcpy(name, e->value); if (!ISPOINTER(typ)) expected(e, "Pointer"); next(e); matchstring(e, "="); } if (vect) { char mul[20]; int j,i=0; if (j = typ%Vector-2) { strcpy(mul, "ASL.L #"); titoa(&mul[7], j, &i); strcat(mul, ",D0"); emitln(e, mul); } push(e, INT); } typ = extendedexpression(e); store(e, name, typ, ind, vect); } /*---------------------------------------------------------------*/ /* Load a Vector Index */ void loadindex (e) TIMP *e; { int typ; char assign; next(e); assign = e->isassign; typ = extendedexpression(e); e->isassign = assign; if (ISPOINTER(typ)) expected(e, "Scalar Value"); promote(e, typ, INT, "D0"); matchstring(e, "]"); } /*---------------------------------------------------------------*/ /* Load a Variable */ int loadvar (e, name, vect) TIMP *e; char *name; char vect; { char postop=0; if ((e->token=='+' && (postop = e->look)=='+') || (e->token=='-' && (postop = e->look)=='-')) {next(e); next(e);} if (isparam(e, name)) return loadlocal(e, postop, vect, paramnumber(e, name)); else return loadglobal(e, postop, vect, name); } /*---------------------------------------------------------------*/ /* Parse and Translate a Math Factor */ int factor (e) TIMP *e; { int typ; char token; symbol name; char vect=0; if (e->token == '(') { next(e); typ = extendedexpression(e); matchstring(e,")"); } else { strcpy(name, e->value); token = e->token; next(e); typ = typeof(e, name); if (vect = e->token=='[') { loadindex(e); } if (e->isassign && e->token=='=' && e->look!='=') assignment(e, name, vect); else if (token == 'x') if (ISFUN(typ)) typ = callfun(e, typ, name); else typ = loadvar(e, name, vect); else if (token == '#') typ = loadnum(e, atoi(name)); else expected(e,"Math Factor"); } e->isassign = 0; return typ; } /*--------------------------------------------------------------*/ /* Recognize and Translate a Multiply */ int multiply (e, typ) TIMP *e; int typ; { next(e); return popmul(e, typ, factor(e)); } /*-------------------------------------------------------------*/ /* Recognize and Translate a Divide */ int divide (e, typ) TIMP *e; int typ; { next(e); return popdiv(e, typ, factor(e)); } /*-------------------------------------------------------------*/ /* Recognize and Translate a Module */ int module (e, typ) TIMP *e; int typ; { next(e); return popmod(e, typ, factor(e)); } /*---------------------------------------------------------------*/ /* Parse and Translate a Math Term */ int term (e) TIMP *e; { int typ; if (isindop(e->token)) typ = indop(e, e->token); else typ = factor(e); while (ismulop(e->token)) { push(e, typ); switch (e->token) { case '*': typ = multiply(e, typ); break; case '/': typ = divide(e, typ); break; case '%': typ = module(e, typ); break; } } return typ; } /*--------------------------------------------------------------*/ /* Recognize and Translate an Add */ int add(e, typ) TIMP *e; int typ; { next(e); return popadd(e, typ, term(e)); } /*-------------------------------------------------------------*/ /* Recognize and Translate a Subtract */ int subtract(e, typ) TIMP *e; int typ; { next(e); return popsub(e, typ, term(e)); } /*---------------------------------------------------------------*/ /* Parse and Translate an Expression */ int expression (e) TIMP *e; { int typ; if (isaddop(e->token)) typ = unop(e); else typ = term(e); while (isaddop(e->token)) { push(e, typ); switch (e->token) { case '+': typ = add(e, typ); break; case '-': typ = subtract(e, typ); break; } } return typ; } /*---------------------------------------------------------------*/ /* Recognize and Translate a Left Shift */ void shiftleft (e, typ) TIMP *e; int typ; { int t; next(e); matchstring(e, "<"); t = expression(e); pop(e, typ); setshleft(e, typ); } /*---------------------------------------------------------------*/ /* Recognize and Translate a Right Shift */ void shiftright (e, typ) TIMP *e; int typ; { int t; next(e); matchstring(e, ">"); t = expression(e); pop(e, typ); setshright(e, typ); } /*---------------------------------------------------------------*/ /* Parse and Translate a Shift */ int shift (e) TIMP *e; { int typ; typ = expression(e); if (isdiseqop(e->token) && isdiseqop(e->look)) { push(e, typ); switch (e->token) { case '<': shiftleft(e, typ); break; case '>': shiftright(e, typ); break; } } return typ; } /*---------------------------------------------------------------*/ /* Get Another Expression and Compare */ int compareexpression (e, typ) TIMP *e; int typ; { int t; t = shift(e); pop(e, typ); if (ISPOINTER(typ) || ISPOINTER(t)) { if ((typ|Vector) != (t|Vector)) nabort(e, "Nonportable Pointer Conversion"); } else t = sametype(e, typ, t); popcompare(e, t); return t; } /*---------------------------------------------------------------*/ /* Get The Next Expression and Compare */ int nextexpression (e, typ) TIMP *e; int typ; { next(e); return compareexpression(e, typ); } /*---------------------------------------------------------------*/ /* Recognize and Translate a Relational "Equals" */ int equal (e, typ) TIMP *e; int typ; { next(e); if (e->token == '=') { typ = nextexpression(e, typ); setequal(e); } else expected(e, "=="); return SHORT; } /*---------------------------------------------------------------*/ /* Recognize and Translate a Relational "Less Than or Equal" */ int lessorequal (e, typ) TIMP *e; int typ; { typ = nextexpression(e, typ); setlessorequal(e); return typ; } /*---------------------------------------------------------------*/ /* Recognize and Translate a Relational "Not Equals" */ int notequal (e, typ) TIMP *e; int typ; { next(e); if (e->token == '=') { typ = nextexpression(e, typ); setnequal(e); } else expected(e, "!="); return SHORT; } /*---------------------------------------------------------------*/ /* Recognize and Translate a Relational "Less Than" */ int less (e, typ) TIMP *e; int typ; { next(e); switch (e->token) { case '=': typ = lessorequal(e, typ); break; default: typ = compareexpression(e, typ); setless(e); break; } return SHORT; } /*---------------------------------------------------------------*/ /* Recognize and Translate a Relational "Greater Than" */ int greater (e, typ) TIMP *e; int typ; { next(e); if (e->token == '=') { typ = nextexpression(e, typ); setgreaterorequal(e); } else { typ = compareexpression(e, typ); setgreater(e); } return SHORT; } /*---------------------------------------------------------------*/ /* Parse and Translate a Relation */ int relation (e) TIMP *e; { int typ; typ = shift(e); if (isrelop(e->token) && !isdiseqop(e->look)) { push(e, typ); switch (e->token) { case '=': typ = equal(e, typ); break; case '!': typ = notequal(e, typ); break; case '<': typ = less(e, typ); break; case '>': typ = greater(e, typ); break; } } return typ; } /*---------------------------------------------------------------*/ /* Parse and Translate a Boolean Factor with Leading NOT */ int notfactor (e) TIMP *e; { int typ; if (e->token == '!') { next(e); relation(e); notit(e); } else typ = relation(e); return typ; } /*---------------------------------------------------------------*/ /* Parse and Translate a Boolean Term */ int boolterm (e) TIMP *e; { int typ; typ = notfactor(e); while (e->token == '&' && e->look!='&') { char t; push(e, typ); next(e); t = notfactor(e); pop(e, typ); typ = sametype(e, typ, t); popand(e, typ); } return typ; } /*--------------------------------------------------------------*/ /* Recognize and Translate a Boolean OR */ int boolor (e, typ) TIMP *e; int typ; { int t; next(e); t = boolterm(e); pop(e, typ); t = sametype(e, typ, t); popor(e, t); return t; } /*--------------------------------------------------------------*/ /* Recognize and Translate an Exclusive Or */ int boolxor (e, typ) TIMP *e; int typ; { int t; next(e); t = boolterm(e); pop(e, typ); t = sametype(e, typ, t); popxor(e, t); return t; } /*---------------------------------------------------------------*/ /* Parse and Translate a Logic Factor */ int logicfactor (e) TIMP *e; { int typ; typ = boolterm(e); while (isorop(e->token) && e->look!='|') { push(e, typ); switch (e->token) { case '|': typ = boolor(e, typ); break; case '^': typ = boolxor(e, typ); break; } } return typ; } /*---------------------------------------------------------------*/ /* Parse and Translate a Logic Term */ int logicterm (e) TIMP *e; { int typ; char l[10]; *l = 0; typ = logicfactor(e); while (e->token=='&') { next(e); next(e); if (!(*l)) { strcpy (l,newlabel(e)); if (typ!=SHORT) setnequal(e); } branchfalse2(e, l); typ = logicfactor(e); if (typ!=SHORT) setnequal(e); } if (*l) { postlabel(e, l); typ = SHORT; } return typ; } /*---------------------------------------------------------------*/ /* Parse and Translate a Logic Expression */ int logicexpression (e) TIMP *e; { int typ; char l[10]; *l = 0; typ = logicterm(e); while (e->token=='|') { next(e); next(e); if (!(*l)) { strcpy (l,newlabel(e)); if (typ!=SHORT) setnequal(e); } branchtrue2(e, l); typ = logicterm(e); if (typ!=SHORT) setnequal(e); } if (*l) { postlabel(e, l); typ = SHORT; } return typ; } /*---------------------------------------------------------------*/ /* Parse and Translate an Extended Expression */ int extendedexpression (e) TIMP *e; { int typ; char l1[10], l2[10]; e->isassign = 1; typ = logicexpression(e); if (e->token=='?') { next(e); strcpy (l1, newlabel(e)); branchfalse(e, l1, typ); typ = extendedexpression(e); scan(e); matchstring(e, ":"); strcpy (l2, newlabel(e)); tbranch(e, l2); postlabel(e,l1); typ = extendedexpression(e); postlabel(e,l2); } return typ; } /*---------------------------------------------------------------*/ /* Recognize and Translate a RETURN Instruction */ void doreturn (e) TIMP *e; { int funtyp,typ=0; funtyp = e->funtyp-Function; if (e->look != ';') { next(e); typ = extendedexpression(e); } if (funtyp>1 && typ) { if (ISPOINTER(funtyp) || ISPOINTER(typ)) { if (funtyp!=typ) nabort(e, "Type mismatch"); } else promote(e, typ, funtyp, "D0"); } else if (funtyp>1 && !typ) expected(e, "return Expression"); else if (funtyp==1 && typ) nabort(e, "Unexpected Expression after 'return'"); funepilog(e); next(e); } /*---------------------------------------------------------------*/ /* Recognize and Translate a BREAK Instruction */ void dobreak (e) TIMP *e; { if (!e->breakaddr) expected(e, "break not"); tbranch(e, e->breakaddr); next(e); } /*---------------------------------------------------------------*/ /* Recognize and Translate an IF Construct */ void doif (e) TIMP *e; { char l1[10], l2[10]; int typ; next(e); matchstring(e, "("); typ = extendedexpression(e); matchstring(e, ")"); strcpy (l1,newlabel(e)); strcpy (l2,l1); branchfalse(e, l1, typ); statement(e); scan(e); if (e->token == 'l') { next(e); strcpy (l2,newlabel(e)); tbranch(e,l2); postlabel(e,l1); statement(e); } postlabel(e,l2); } /*---------------------------------------------------------------*/ /* Recognize and Translate a SWITCH CASE Construct */ void doswitch (e) TIMP *e; { char l1[10], l2[10], l3[10]; int t1, t2; char *backbreak; next(e); matchstring(e, "("); t1 = extendedexpression(e); push(e,t1); matchstring(e, ")"); matchstring(e, "{"); strcpy (l1,newlabel(e)); backbreak = e->breakaddr; e->breakaddr = l1; *l2 = *l3 = 0; scan(e); while (e->token=='a') { if (*l2) postlabel(e, l2); next(e); t2 = extendedexpression(e); matchstring(e, ":"); pop2(e, t1); t2 = sametype(e, t1, t2); popcompare(e, t2); strcpy (l2,newlabel(e)); branchfalse(e, l2, t2); if (*l3) postlabel(e, l3); block(e); strcpy (l3,newlabel(e)); tbranch(e, l3); } matchstring(e, "}"); postlabel(e,l1); postlabel(e,l2); postlabel(e,l3); pop(e, t1); e->breakaddr = backbreak; } /*--------------------------------------------------------------*/ /* Parse and Translate a WHILE Statement */ void dowhile (e) TIMP *e; { char l1[10], l2[10]; int typ; char *backbreak; next(e); strcpy (l1,newlabel(e)); strcpy (l2,newlabel(e)); backbreak = e->breakaddr; e->breakaddr = l2; postlabel(e,l1); matchstring(e, "("); typ = extendedexpression(e); matchstring(e, ")"); branchfalse(e, l2, typ); statement(e); tbranch(e,l1); postlabel(e,l2); e->breakaddr = backbreak; } /*--------------------------------------------------------------*/ /* Parse and Translate a DO WHILE Statement */ void dodo (e) TIMP *e; { char l1[10], l2[10]; int typ; char *backbreak; next(e); strcpy (l1,newlabel(e)); strcpy (l2,newlabel(e)); backbreak = e->breakaddr; e->breakaddr = l2; postlabel(e,l1); statement(e); matchstring(e, "WHILE"); matchstring(e, "("); typ = extendedexpression(e); matchstring(e, ")"); branchtrue(e, l1, typ); postlabel(e,l2); e->breakaddr = backbreak; } /*--------------------------------------------------------------*/ /* Parse and Translate a FOR Statement */ void dofor (e) TIMP *e; { int typ; char *backbreak; symbol l1, l2, l3, l4; next(e); strcpy (l1,newlabel(e)); strcpy (l2,newlabel(e)); strcpy (l3,newlabel(e)); strcpy (l4,newlabel(e)); backbreak = e->breakaddr; e->breakaddr = l4; matchstring(e, "("); extendedexpression(e); semi(e); postlabel(e,l1); typ = extendedexpression(e); semi(e); branchfalse(e, l4, typ); tbranch(e,l3); postlabel(e,l2); extendedexpression(e); matchstring(e, ")"); tbranch(e,l1); postlabel(e,l3); statement(e); tbranch(e,l2); postlabel(e,l4); e->breakaddr = backbreak; } /*--------------------------------------------------------------*/ /* Read a Single Variable */ void readvar (e) TIMP *e; { symbol name; boolean ind, vect; int typ; if (ind = !strcmp(e->value, "*")) { next(e); strcpy(name, e->value); if (!ISPOINTER(typ=vartype(e, e->value))) expected(e, "Pointer"); next(e); } else { strcpy(name, e->value); typ = vartype(e, name); next(e); if (vect = !strcmp(e->value, "[")) { char mul[20]; int t,j,i=0; next(e); t = extendedexpression(e); promote(e, t, L, "D0"); matchstring(e, "]"); if (j = typ%Vector-2) { strcpy(mul, "ASL.L #"); titoa(&mul[7], j, &i); strcat(mul, ",D0"); emitln(e, mul); } push(e, INT); } } readit(e); storevar(e, name, typ, ind, vect); } /*--------------------------------------------------------------*/ /* Process a Read Statement */ void doread (e) TIMP *e; { next(e); matchstring(e,"("); readvar(e); while (e->token == ',') { next(e); readvar(e); } matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Process a Write Parameter */ void writetoken (e) TIMP *e; { if (e->token == '"') { readstr(e); swriteit(e,e->MessageString); } else { char typ; typ = extendedexpression(e); convert(e, typ, 'L', "D0"); iwriteit(e); } } /*--------------------------------------------------------------*/ /* Process a Write Statement */ void dowrite (e) TIMP *e; { next(e); matchstring(e,"("); writetoken(e); while (e->token == ',') { next(e); writetoken(e); } matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Process an Exec Statement */ void doexec (e) TIMP *e; { next(e); matchstring(e,"("); if (e->token == '"') { readstr(e); execit(e,e->MessageString); } else expected(e, "Command String"); matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Process a Malloc Statement */ void domalloc (e) TIMP *e; { char pnt[9], typ; next(e); matchstring(e, "("); strcpy(pnt, e->value); next(e); matchstring(e, ","); typ = extendedexpression(e); convert(e, typ, 'L', "D0"); mallocit(e); if (vartype(e, pnt) == 'L') store(e, pnt, 'L'); else expected(e, "Integer Variable"); matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Process a Free Statement */ void dofree (e) TIMP *e; { next(e); matchstring(e,"("); if (extendedexpression(e) != 'L') expected(e, " Integer Variable "); freeit(e); matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Process a Thread Create Statement */ void docreate (e) TIMP *e; { symbol tid; char typ; next(e); matchstring(e, "("); strcpy(tid, e->value); next(e); matchstring(e, ","); typ = typeof(e, e->value); if ((typ=='p') || isvartype(typ)) { createit(e, e->value); } else expected(e, "Procedure Descriptor"); store(e, tid, vartype(e, tid)); next(e); matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Process a Thread Me Statement */ void doself (e) TIMP *e; { char tid[9]; next(e); matchstring(e, "("); strcpy(tid, e->value); createit(e, (char *)0); store(e, tid, vartype(e, tid)); next(e); matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Process a Thread Me Statement */ void domutexcreate (e) TIMP *e; { char tid[9]; next(e); matchstring(e, "("); strcpy(tid, e->value); mutexit(e, 0); store(e, tid, vartype(e, tid)); next(e); matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Process a Thread Me Statement */ void domutexdestroy (e) TIMP *e; { next(e); matchstring(e, "("); mutexit(e, 3); next(e); matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Process a Thread Mutex Lock Statement */ void dolock (e) TIMP *e; { next(e); matchstring(e, "("); extendedexpression(e); mutexit(e, 1); matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Process a Thread Mutex Unlock Statement */ void dounlock (e) TIMP *e; { next(e); matchstring(e, "("); extendedexpression(e); mutexit(e, 2); matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Process a Thread Exit Statement */ void doexit (e) TIMP *e; { next(e); matchstring(e, "("); exitit(e, 0); matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Process a Thread Kill Statement */ void dokill (e) TIMP *e; { next(e); matchstring(e, "("); extendedexpression(e); exitit(e, 1); matchstring(e,")"); } /*--------------------------------------------------------------*/ /* Match a Semicolon */ void semi (e) TIMP *e; { if (e->token == ';') next(e); } /*--------------------------------------------------------------*/ /* Store a Variable from the Primary Register */ void store(e, name, t1, ind, vect) TIMP *e; char *name; int t1; boolean ind; char vect; { int t2; t2 = typeof(e, name)-vect*(Pointer+Vector); if (ISPOINTER(t1)) { if (t1!=t2) expected(e, "pointer conversion"); } else { if (ind || !ISPOINTER(t2)) convert(e, t1, t2, "D0"); else expected(e, "pointer conversion"); } if (isparam(e, name)) storeparam(e, paramnumber(e, name), t2, ind, vect); else storevar(e, name, t2, ind, vect); } /*--------------------------------------------------------------*/ /* Parse and Translate a Single Statement */ void statement(e) TIMP *e; { scan(e); switch (e->token) { case 'x': extendedexpression(e); break; case '{': beginblock(e); break; case 'i': doif(e); break; case 'w': dowhile(e); break; case 'd': dodo(e); break; case 'f': dofor(e); break; case 'r': doreturn(e); break; case 'R': doread(e); break; case 'W': dowrite(e); break; case 'b': dobreak(e); break; case 't': doswitch(e); break; case 'X': doexec(e); break; case 'A': domalloc(e); break; case 'F': dofree(e); break; case 'C': docreate(e); break; case 'S': doself(e); break; case 'L': dolock(e); break; case 'U': dounlock(e); break; case 'M': domutexcreate(e); break; case 'D': domutexdestroy(e); break; case 'E': doexit(e); break; case 'K': dokill(e); break; case '*': { symbol name; strcpy(name, e->value); assignment(e, name); break; } } semi(e); } /*--------------------------------------------------------------*/ /* Parse and Translate a Block of Statements */ void block(e) TIMP *e; { scan(e); while ((e->token != '}') && (e->token != 'a')) { statement(e); scan(e); } } /*--------------------------------------------------------------*/ /* Parse and Translate a BeginBlock */ void beginblock(e) TIMP *e; { matchstring(e, "{"); skipwhite(e); block(e); matchstring(e, "}"); skipwhite(e); } /*--------------------------------------------------------------*/ /* Allocate Storage for a Variable */ void talloc(e, typ, pnt, name) TIMP *e; int typ; char pnt; char *name; { char num[10]; if (e->token == '[') { getnum(e); strcpy(num, e->value); next(e); matchstring(e, "]"); allocvector(e, name, num, typ2char(e, typ)); typ |= Pointer + Vector; } else { typ |= pnt*Pointer; allocvar(e, name, typ2char(e, typ)); } addentry(e, name, typ); } /*--------------------------------------------------------------*/ /* Parse and Translate Global Variable Declarations */ void dovar(e, typ, pnt, name) TIMP *e; int typ; char pnt; char *name; { talloc(e, typ, pnt, name); while (e->token == ',') { next(e); if (pnt = (e->token == '*')) next(e); if (e->token != 'x') expected(e, "Variable Name"); strcpy(name, e->value); next(e); talloc(e, typ, pnt, name); } semi(e); scan(e); } /*--------------------------------------------------------------*/ /* Parse and Translate Global Declarations */ void topdecls(e) TIMP *e; { int typ; char pnt; symbol name; scan(e); while (typ = scantype(e->value)) { next(e); if (pnt = (e->token == '*')) next(e); strcpy(name, e->value); next(e); if (e->token != '(') dovar(e, typ, pnt, name); else dofun(e, typ, pnt, name); } } /*--------------------------------------------------------------*/ /* Initialize */ void init (e,argc,argv) TIMP *e; int argc; char **argv; { int i; #if DOS e->fdin = e->fdout = NULL; if (argc>1) e->fdin = fopen(argv[1], "r"); if (argc>2) if ((e->fdout = fopen(argv[2], "w")) == NULL) nabort(e," Impossible to open output file "); #else e->fdin = 0; e->fdout = 1; if (argc>1) e->fdin = topen(argv[1],R); if (argc>2) if ((e->fdout = topen(argv[2],W+O_CREAT,(R+W)*9)) == -1) nabort(e," Impossible to open output file "); #endif /* Definition of Keywords and Token Types */ strcpy(e->kwlist[0],"if"); strcpy(e->kwlist[1],"else"); strcpy(e->kwlist[2],"while"); strcpy(e->kwlist[3],"do"); strcpy(e->kwlist[4],"for"); strcpy(e->kwlist[5],"read"); strcpy(e->kwlist[6],"write"); strcpy(e->kwlist[7],"break"); strcpy(e->kwlist[8],"void"); strcpy(e->kwlist[9],"int"); strcpy(e->kwlist[10],"short"); strcpy(e->kwlist[11],"char"); strcpy(e->kwlist[12],"return"); strcpy(e->kwlist[13],"switch"); strcpy(e->kwlist[14],"case"); strcpy(e->kwlist[15],"exec"); strcpy(e->kwlist[16],"malloc"); strcpy(e->kwlist[17],"free"); strcpy(e->kwlist[18],"thcreate"); strcpy(e->kwlist[19],"thself"); strcpy(e->kwlist[20],"thlock"); strcpy(e->kwlist[21],"thunlock"); strcpy(e->kwlist[22],"thmutexi"); strcpy(e->kwlist[23],"thmutexd"); strcpy(e->kwlist[24],"thexit"); strcpy(e->kwlist[25],"thkill"); strcpy(e->kwcode,"xilwdfRWbpnscrtaXAFCSLUMDEK"); e->lcount = e->nentry = 0; for (i=0; i
st[i][0] ='\0'; e->bufchar[1] = '\0'; e->mul32set = e->div32set = e->mod32set = 0; e->tempchar = ' '; e->breakaddr = 0; clearparams(e); Getchar(e); next(e); }