Initial revision
This commit is contained in:
parent
25eef41c3a
commit
91ad12242c
36
util/misc/Makefile
Normal file
36
util/misc/Makefile
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
d=../..
|
||||||
|
h=$d/h
|
||||||
|
l=$d/lib
|
||||||
|
|
||||||
|
DEC_PATH=decode
|
||||||
|
ENC_PATH=encode
|
||||||
|
DATA_PATH=$l/em_data.a
|
||||||
|
|
||||||
|
CFLAGS=-O -I$h
|
||||||
|
|
||||||
|
all: $(DEC_PATH) $(ENC_PATH)
|
||||||
|
|
||||||
|
$(DEC_PATH): decode.o $(DATA_PATH)
|
||||||
|
cc -n -o $(DEC_PATH) decode.o $(DATA_PATH)
|
||||||
|
|
||||||
|
$(ENC_PATH): encode.o $(DATA_PATH)
|
||||||
|
cc -n -o $(ENC_PATH) encode.o $(DATA_PATH)
|
||||||
|
|
||||||
|
encode.o: $h/em_spec.h $h/em_pseu.h $h/em_flag.h $h/em_ptyp.h $h/em_mes.h
|
||||||
|
|
||||||
|
decode.o: $h/em_spec.h $h/em_pseu.h $h/em_flag.h $h/em_ptyp.h $h/em_mes.h
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(DEC_PATH) $(ENC_PATH) *.o *.old
|
||||||
|
install : all
|
||||||
|
cp $(DEC_PATH) $l/em_$(DEC_PATH)
|
||||||
|
cp $(ENC_PATH) $l/em_$(ENC_PATH)
|
||||||
|
|
||||||
|
cmp : all
|
||||||
|
cmp $(DEC_PATH) $l/$(DEC_PATH)
|
||||||
|
cmp $(ENC_PATH) $l/$(ENC_PATH)
|
||||||
|
|
||||||
|
opr:
|
||||||
|
make pr ^ opr
|
||||||
|
pr:
|
||||||
|
@pr -n Makefile decode.c encode.c
|
495
util/misc/decode.c
Normal file
495
util/misc/decode.c
Normal file
|
@ -0,0 +1,495 @@
|
||||||
|
/*
|
||||||
|
* (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
*
|
||||||
|
* This product is part of the Amsterdam Compiler Kit.
|
||||||
|
*
|
||||||
|
* Permission to use, sell, duplicate or disclose this software must be
|
||||||
|
* obtained in writing. Requests for such permissions may be sent to
|
||||||
|
*
|
||||||
|
* Dr. Andrew S. Tanenbaum
|
||||||
|
* Wiskundig Seminarium
|
||||||
|
* Vrije Universiteit
|
||||||
|
* Postbox 7161
|
||||||
|
* 1007 MC Amsterdam
|
||||||
|
* The Netherlands
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode compact EM assembly language
|
||||||
|
*
|
||||||
|
* Author: Johan Stevenson, Vrije Universiteit, Amsterdam
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <em_spec.h>
|
||||||
|
#include <em_pseu.h>
|
||||||
|
#include <em_flag.h>
|
||||||
|
#include <em_ptyp.h>
|
||||||
|
#include <em_mes.h>
|
||||||
|
|
||||||
|
#define get8() ((unsigned)getchar())
|
||||||
|
|
||||||
|
#define check(x) if (!(x)) fail_check()
|
||||||
|
|
||||||
|
#define MAXSTR 256
|
||||||
|
|
||||||
|
/*
|
||||||
|
* global variables
|
||||||
|
*/
|
||||||
|
|
||||||
|
int opcode;
|
||||||
|
int offtyp;
|
||||||
|
long argval;
|
||||||
|
int dlbval;
|
||||||
|
char string[MAXSTR];
|
||||||
|
int strsiz;
|
||||||
|
|
||||||
|
int wsize;
|
||||||
|
int psize;
|
||||||
|
int lineno;
|
||||||
|
int argnum;
|
||||||
|
int errors;
|
||||||
|
char *progname;
|
||||||
|
char *filename;
|
||||||
|
|
||||||
|
long wordmask[] = { /* allowed bits in a word */
|
||||||
|
0x00000000,
|
||||||
|
0x000000FF,
|
||||||
|
0x0000FFFF,
|
||||||
|
0x00000000,
|
||||||
|
0xFFFFFFFF
|
||||||
|
};
|
||||||
|
|
||||||
|
long sizemask[] = { /* allowed bits in multiples of 'wsize' */
|
||||||
|
0x00000000,
|
||||||
|
0x7FFFFFFF,
|
||||||
|
0x7FFFFFFE,
|
||||||
|
0x00000000,
|
||||||
|
0x7FFFFFFC
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* external tables
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern char em_flag[];
|
||||||
|
extern short em_ptyp[];
|
||||||
|
extern char em_mnem[][4];
|
||||||
|
extern char em_pseu[][4];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* routines
|
||||||
|
*/
|
||||||
|
|
||||||
|
int get16();
|
||||||
|
long get32();
|
||||||
|
|
||||||
|
main(argc,argv) char **argv; {
|
||||||
|
|
||||||
|
progname = argv[0];
|
||||||
|
if (argc >= 2) {
|
||||||
|
filename = argv[1];
|
||||||
|
if (freopen(argv[1],"r",stdin) == NULL)
|
||||||
|
fatal("can't open %s",argv[1]);
|
||||||
|
}
|
||||||
|
if (argc >= 3)
|
||||||
|
if (freopen(argv[2],"w",stdout) == NULL)
|
||||||
|
fatal("can't create %s",argv[2]);
|
||||||
|
if (get16() != sp_magic)
|
||||||
|
fatal("bad magic word");
|
||||||
|
/* In System III the array is called _ctype[] without the trailing '_' */
|
||||||
|
(_ctype_+1)['_'] = (_ctype_+1)['a'];
|
||||||
|
while (nextline())
|
||||||
|
;
|
||||||
|
return(errors ? -1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----- copy ----- */
|
||||||
|
|
||||||
|
int nextline() {
|
||||||
|
register t;
|
||||||
|
|
||||||
|
lineno++;
|
||||||
|
argnum = 1;
|
||||||
|
switch (t = table1()) {
|
||||||
|
case EOF:
|
||||||
|
return(0);
|
||||||
|
case sp_fmnem:
|
||||||
|
instr();
|
||||||
|
break;
|
||||||
|
case sp_fpseu:
|
||||||
|
pseudo();
|
||||||
|
break;
|
||||||
|
case sp_ilb1:
|
||||||
|
case sp_ilb2:
|
||||||
|
argnum = 0;
|
||||||
|
putarg(sp_cst2);
|
||||||
|
break;
|
||||||
|
case sp_dlb1:
|
||||||
|
case sp_dlb2:
|
||||||
|
case sp_dnam:
|
||||||
|
argnum = 0;
|
||||||
|
putarg(t);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("unknown opcode %d",t);
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
instr() {
|
||||||
|
register i,j,t;
|
||||||
|
register long l;
|
||||||
|
|
||||||
|
i = opcode - sp_fmnem;
|
||||||
|
printf(" %s",em_mnem[i]);
|
||||||
|
j = em_flag[i] & EM_PAR;
|
||||||
|
if (j == PAR_NO)
|
||||||
|
return;
|
||||||
|
t = em_ptyp[j];
|
||||||
|
t = getarg(t);
|
||||||
|
/*
|
||||||
|
* range checking
|
||||||
|
*/
|
||||||
|
switch (j) {
|
||||||
|
case PAR_N:
|
||||||
|
check(argval >= 0);
|
||||||
|
break;
|
||||||
|
case PAR_G:
|
||||||
|
if (t != sp_cst2 && t != sp_cst4)
|
||||||
|
break;
|
||||||
|
check(argval >= 0);
|
||||||
|
/* fall through */
|
||||||
|
case PAR_L:
|
||||||
|
l = argval >= 0 ? argval : -argval;
|
||||||
|
check((l & ~wordmask[psize]) == 0);
|
||||||
|
break;
|
||||||
|
case PAR_W:
|
||||||
|
if (t == sp_cend)
|
||||||
|
break;
|
||||||
|
check((argval & ~wordmask[wsize]) == 0);
|
||||||
|
/* fall through */
|
||||||
|
case PAR_S:
|
||||||
|
check(argval != 0);
|
||||||
|
/* fall through */
|
||||||
|
case PAR_Z:
|
||||||
|
check((argval & ~sizemask[wsize]) == 0);
|
||||||
|
break;
|
||||||
|
case PAR_O:
|
||||||
|
check(argval != 0);
|
||||||
|
check((argval & ~sizemask[wsize])==0 || (wsize % argval)==0);
|
||||||
|
break;
|
||||||
|
case PAR_B:
|
||||||
|
t = sp_ilb2;
|
||||||
|
break;
|
||||||
|
case PAR_R:
|
||||||
|
check(argval >= 0 && argval <= 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
putarg(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
pseudo() {
|
||||||
|
register i,t;
|
||||||
|
|
||||||
|
i = opcode;
|
||||||
|
printf(" %s",em_pseu[i - sp_fpseu]);
|
||||||
|
switch (i) {
|
||||||
|
case ps_bss:
|
||||||
|
case ps_hol:
|
||||||
|
putarg(getarg(cst_ptyp));
|
||||||
|
putarg(getarg(val_ptyp));
|
||||||
|
putarg(getarg(ptyp(sp_cst2)));
|
||||||
|
check(argval==0 || argval==1);
|
||||||
|
break;
|
||||||
|
case ps_rom:
|
||||||
|
case ps_con:
|
||||||
|
putarg(getarg(val_ptyp));
|
||||||
|
while ((t = getarg(any_ptyp)) != sp_cend)
|
||||||
|
putarg(t);
|
||||||
|
break;
|
||||||
|
case ps_mes:
|
||||||
|
putarg(getarg(ptyp(sp_cst2)));
|
||||||
|
if (argval == ms_emx) {
|
||||||
|
putarg(getarg(ptyp(sp_cst2)));
|
||||||
|
check(argval > 0 && argval <= 4);
|
||||||
|
wsize = (int) argval;
|
||||||
|
putarg(getarg(ptyp(sp_cst2)));
|
||||||
|
check(argval > 0 && argval <= 4);
|
||||||
|
psize = (int) argval;
|
||||||
|
}
|
||||||
|
while ((t = getarg(any_ptyp)) != sp_cend)
|
||||||
|
putarg(t);
|
||||||
|
break;
|
||||||
|
case ps_exa:
|
||||||
|
case ps_ina:
|
||||||
|
putarg(getarg(sym_ptyp));
|
||||||
|
break;
|
||||||
|
case ps_exp:
|
||||||
|
case ps_inp:
|
||||||
|
putarg(getarg(ptyp(sp_pnam)));
|
||||||
|
break;
|
||||||
|
case ps_exc:
|
||||||
|
putarg(getarg(ptyp(sp_cst2)));
|
||||||
|
putarg(getarg(ptyp(sp_cst2)));
|
||||||
|
break;
|
||||||
|
case ps_pro:
|
||||||
|
putarg(getarg(ptyp(sp_pnam)));
|
||||||
|
putarg(getarg(cst_ptyp|ptyp(sp_cend)));
|
||||||
|
break;
|
||||||
|
case ps_end:
|
||||||
|
putarg(getarg(cst_ptyp|ptyp(sp_cend)));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("bad pseudo %d",i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----- input ----- */
|
||||||
|
|
||||||
|
int getarg(typset) {
|
||||||
|
register t,argtyp;
|
||||||
|
|
||||||
|
argtyp = t = table2();
|
||||||
|
if (t == EOF)
|
||||||
|
fatal("unexpected EOF");
|
||||||
|
t -= sp_fspec;
|
||||||
|
assert(t >= 0 && t < 16);
|
||||||
|
t = 1 << t;
|
||||||
|
if ((typset & t) == 0)
|
||||||
|
error("bad argument type %d",argtyp);
|
||||||
|
return(argtyp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int table1() {
|
||||||
|
register i;
|
||||||
|
|
||||||
|
i = get8();
|
||||||
|
if (i < sp_fmnem+sp_nmnem && i >= sp_fmnem) {
|
||||||
|
opcode = i;
|
||||||
|
return(sp_fmnem);
|
||||||
|
}
|
||||||
|
if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) {
|
||||||
|
opcode = i;
|
||||||
|
return(sp_fpseu);
|
||||||
|
}
|
||||||
|
if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) {
|
||||||
|
argval = i - sp_filb0;
|
||||||
|
return(sp_ilb2);
|
||||||
|
}
|
||||||
|
return(table3(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
int table2() {
|
||||||
|
register i;
|
||||||
|
|
||||||
|
i = get8();
|
||||||
|
if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) {
|
||||||
|
argval = i - sp_zcst0;
|
||||||
|
return(sp_cst2);
|
||||||
|
}
|
||||||
|
return(table3(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
int table3(i) {
|
||||||
|
long consiz;
|
||||||
|
|
||||||
|
switch(i) {
|
||||||
|
case sp_ilb1:
|
||||||
|
argval = get8();
|
||||||
|
break;
|
||||||
|
case sp_dlb1:
|
||||||
|
dlbval = get8();
|
||||||
|
break;
|
||||||
|
case sp_dlb2:
|
||||||
|
dlbval = get16();
|
||||||
|
if ( dlbval<0 ) {
|
||||||
|
error("illegal data label .%d",dlbval);
|
||||||
|
dlbval=0 ;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case sp_cst2:
|
||||||
|
argval = get16();
|
||||||
|
break;
|
||||||
|
case sp_ilb2:
|
||||||
|
argval = get16();
|
||||||
|
if ( argval<0 ) {
|
||||||
|
error("illegal instruction label %D",argval);
|
||||||
|
argval=0 ;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case sp_cst4:
|
||||||
|
argval = get32();
|
||||||
|
break;
|
||||||
|
case sp_dnam:
|
||||||
|
case sp_pnam:
|
||||||
|
getstring(1);
|
||||||
|
break;
|
||||||
|
case sp_scon:
|
||||||
|
getstring(0);
|
||||||
|
break;
|
||||||
|
case sp_doff:
|
||||||
|
offtyp = getarg(sym_ptyp);
|
||||||
|
getarg(cst_ptyp);
|
||||||
|
break;
|
||||||
|
case sp_icon:
|
||||||
|
case sp_ucon:
|
||||||
|
case sp_fcon:
|
||||||
|
getarg(cst_ptyp);
|
||||||
|
consiz = (long) argval;
|
||||||
|
getstring(0);
|
||||||
|
argval = consiz;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
int get16() {
|
||||||
|
register int l_byte, h_byte;
|
||||||
|
|
||||||
|
l_byte = get8();
|
||||||
|
h_byte = get8();
|
||||||
|
if ( h_byte>=128 ) h_byte -= 256 ;
|
||||||
|
return l_byte | (h_byte*256) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
long get32() {
|
||||||
|
register long l;
|
||||||
|
register int h_byte;
|
||||||
|
|
||||||
|
l = get8(); l |= (unsigned)get8()*256 ; l |= get8()*256L*256L ;
|
||||||
|
h_byte = get8() ;
|
||||||
|
if ( h_byte>=128 ) h_byte -= 256 ;
|
||||||
|
return l | (h_byte*256L*256*256L) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
getstring(ident) {
|
||||||
|
register char *p;
|
||||||
|
register n;
|
||||||
|
|
||||||
|
getarg(cst_ptyp);
|
||||||
|
if (argval < 0 || argval > MAXSTR)
|
||||||
|
fatal("string/identifier too long");
|
||||||
|
strsiz = n = argval;
|
||||||
|
p = string;
|
||||||
|
while (--n >= 0)
|
||||||
|
*p++ = get8();
|
||||||
|
if (ident) {
|
||||||
|
if (!isascii(string[0]) || !isalpha(string[0])) {
|
||||||
|
identerror();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (n=strsiz,p=string+1;--n>0;p++)
|
||||||
|
if (!isascii(*p) || !isalnum(*p)) {
|
||||||
|
identerror();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----- output ----- */
|
||||||
|
|
||||||
|
putarg(t) {
|
||||||
|
|
||||||
|
if (argnum != 0)
|
||||||
|
putchar(argnum == 1 ? ' ' : ',');
|
||||||
|
argnum++;
|
||||||
|
puttyp(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
puttyp(t) {
|
||||||
|
|
||||||
|
switch (t) {
|
||||||
|
case sp_ilb1:
|
||||||
|
case sp_ilb2:
|
||||||
|
printf("*%d",(int) argval);
|
||||||
|
break;
|
||||||
|
case sp_dlb1:
|
||||||
|
case sp_dlb2:
|
||||||
|
printf(".%d",dlbval);
|
||||||
|
break;
|
||||||
|
case sp_dnam:
|
||||||
|
putstr(0,0);
|
||||||
|
break;
|
||||||
|
case sp_cst2:
|
||||||
|
case sp_cst4:
|
||||||
|
printf("%D",argval);
|
||||||
|
break;
|
||||||
|
case sp_doff:
|
||||||
|
puttyp(offtyp);
|
||||||
|
if (argval >= 0) putchar('+');
|
||||||
|
printf("%D",argval);
|
||||||
|
break;
|
||||||
|
case sp_pnam:
|
||||||
|
putstr('$',0);
|
||||||
|
break;
|
||||||
|
case sp_scon:
|
||||||
|
putstr('\'','\'');
|
||||||
|
break;
|
||||||
|
case sp_icon:
|
||||||
|
putstr(0,'I');
|
||||||
|
printf("%D",argval);
|
||||||
|
break;
|
||||||
|
case sp_ucon:
|
||||||
|
putstr(0,'U');
|
||||||
|
printf("%D",argval);
|
||||||
|
break;
|
||||||
|
case sp_fcon:
|
||||||
|
putstr(0,'F');
|
||||||
|
printf("%D",argval);
|
||||||
|
break;
|
||||||
|
case sp_cend:
|
||||||
|
putchar('?');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
putstr(c,c2) register c; {
|
||||||
|
register char *p;
|
||||||
|
|
||||||
|
if (c)
|
||||||
|
putchar(c);
|
||||||
|
p = string;
|
||||||
|
while (--strsiz >= 0) {
|
||||||
|
c = *p++ & 0377;
|
||||||
|
if (c >= 040 && c < 0177) {
|
||||||
|
if (c == '\'' || c == '\\')
|
||||||
|
putchar('\\');
|
||||||
|
putchar(c);
|
||||||
|
} else
|
||||||
|
printf("\\%03o",c);
|
||||||
|
}
|
||||||
|
if (c2)
|
||||||
|
putchar(c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----- error handling ----- */
|
||||||
|
|
||||||
|
fail_check() {
|
||||||
|
error("argument range error");
|
||||||
|
}
|
||||||
|
|
||||||
|
identerror() {
|
||||||
|
error("'%s' is not a correct identifier",string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VARARGS */
|
||||||
|
error(s,a1,a2,a3,a4) char *s; {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: line %d: ",
|
||||||
|
filename ? filename : progname,
|
||||||
|
lineno);
|
||||||
|
fprintf(stderr,s,a1,a2,a3,a4);
|
||||||
|
fprintf(stderr,"\n");
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VARARGS */
|
||||||
|
fatal(s,a1,a2,a3,a4) char *s; {
|
||||||
|
error(s,a1,a2,a3,a4);
|
||||||
|
exit(-1);
|
||||||
|
}
|
757
util/misc/encode.c
Normal file
757
util/misc/encode.c
Normal file
|
@ -0,0 +1,757 @@
|
||||||
|
/*
|
||||||
|
* (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
*
|
||||||
|
* This product is part of the Amsterdam Compiler Kit.
|
||||||
|
*
|
||||||
|
* Permission to use, sell, duplicate or disclose this software must be
|
||||||
|
* obtained in writing. Requests for such permissions may be sent to
|
||||||
|
*
|
||||||
|
* Dr. Andrew S. Tanenbaum
|
||||||
|
* Wiskundig Seminarium
|
||||||
|
* Vrije Universiteit
|
||||||
|
* Postbox 7161
|
||||||
|
* 1007 MC Amsterdam
|
||||||
|
* The Netherlands
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode to compact EM assembly language
|
||||||
|
*
|
||||||
|
* Author: Johan Stevenson, Vrije Universiteit, Amsterdam
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <em_spec.h>
|
||||||
|
#include <em_pseu.h>
|
||||||
|
#include <em_flag.h>
|
||||||
|
#include <em_ptyp.h>
|
||||||
|
#include <em_mes.h>
|
||||||
|
|
||||||
|
#define put8(x) putchar(x)
|
||||||
|
|
||||||
|
#define check(x) if (!(x)) fail_check()
|
||||||
|
|
||||||
|
#define fit16i(x) ((x) >= 0xFFFF8000 && (x) <= 0x00007FFF)
|
||||||
|
#define fit8u(x) ((x) >= 0 && (x) <= 0xFF)
|
||||||
|
|
||||||
|
#define MAXSTR 256
|
||||||
|
#define HSIZE 256
|
||||||
|
#define EMPTY (EOF-1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* global variables
|
||||||
|
*/
|
||||||
|
|
||||||
|
int opcode;
|
||||||
|
int offtyp;
|
||||||
|
long argval;
|
||||||
|
int dlbval;
|
||||||
|
char string[MAXSTR];
|
||||||
|
int strsiz;
|
||||||
|
|
||||||
|
int wsize;
|
||||||
|
int psize;
|
||||||
|
int lineno;
|
||||||
|
int argnum;
|
||||||
|
int errors;
|
||||||
|
char *progname;
|
||||||
|
char *filename = "INPUT";
|
||||||
|
|
||||||
|
long wordmask[] = { /* allowed bits in a word */
|
||||||
|
0x00000000,
|
||||||
|
0x000000FF,
|
||||||
|
0x0000FFFF,
|
||||||
|
0x00000000,
|
||||||
|
0xFFFFFFFF
|
||||||
|
};
|
||||||
|
|
||||||
|
long sizemask[] = { /* allowed bits in multiples of 'wsize' */
|
||||||
|
0x00000000,
|
||||||
|
0x7FFFFFFF,
|
||||||
|
0x7FFFFFFE,
|
||||||
|
0x00000000,
|
||||||
|
0x7FFFFFFC
|
||||||
|
};
|
||||||
|
|
||||||
|
int peekc = EMPTY;
|
||||||
|
int hashtab[HSIZE];
|
||||||
|
jmp_buf recover;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* external tables
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern char em_flag[];
|
||||||
|
extern short em_ptyp[];
|
||||||
|
extern char em_mnem[][4];
|
||||||
|
extern char em_pseu[][4];
|
||||||
|
|
||||||
|
int main(argc,argv) char **argv; {
|
||||||
|
|
||||||
|
progname = argv[0];
|
||||||
|
if (argc >= 2) {
|
||||||
|
filename = argv[1];
|
||||||
|
if (freopen(filename,"r",stdin) == NULL)
|
||||||
|
fatal("can't open %s",filename);
|
||||||
|
}
|
||||||
|
if (argc >= 3)
|
||||||
|
if (freopen(argv[2],"w",stdout) == NULL)
|
||||||
|
fatal("can't create %s",argv[2]);
|
||||||
|
init();
|
||||||
|
put16(sp_magic);
|
||||||
|
setjmp(recover);
|
||||||
|
while (nextline())
|
||||||
|
;
|
||||||
|
return(errors ? -1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----- copy ----- */
|
||||||
|
|
||||||
|
int nextline() {
|
||||||
|
register c,i;
|
||||||
|
|
||||||
|
lineno++;
|
||||||
|
argnum = 1;
|
||||||
|
c = nextchar();
|
||||||
|
if (c == EOF)
|
||||||
|
return(0);
|
||||||
|
if (isspace(c) && c != '\n') {
|
||||||
|
c = nospace();
|
||||||
|
if (isalpha(c)) {
|
||||||
|
inmnem(c);
|
||||||
|
if (opcode <= sp_lmnem)
|
||||||
|
instr();
|
||||||
|
else
|
||||||
|
pseudo();
|
||||||
|
} else
|
||||||
|
peekc = c;
|
||||||
|
} else if (c == '#') {
|
||||||
|
line_line();
|
||||||
|
} else {
|
||||||
|
peekc = c;
|
||||||
|
i = gettyp(sym_ptyp | ptyp(sp_cst2) | ptyp(sp_cend));
|
||||||
|
switch (i) {
|
||||||
|
case sp_cst2:
|
||||||
|
i = (int) argval;
|
||||||
|
if (i >= 0 && i < sp_nilb0)
|
||||||
|
put8(i + sp_filb0);
|
||||||
|
else
|
||||||
|
putarg(sp_ilb2);
|
||||||
|
break;
|
||||||
|
case sp_dlb2:
|
||||||
|
case sp_dnam:
|
||||||
|
putarg(i);
|
||||||
|
break;
|
||||||
|
case sp_cend:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nospace() != '\n')
|
||||||
|
syntax("end of line expected");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
instr() {
|
||||||
|
register i,j,t;
|
||||||
|
register long l;
|
||||||
|
|
||||||
|
i = opcode;
|
||||||
|
put8(i);
|
||||||
|
i -= sp_fmnem;
|
||||||
|
j = em_flag[i] & EM_PAR;
|
||||||
|
if (j == PAR_NO)
|
||||||
|
return;
|
||||||
|
t = em_ptyp[j];
|
||||||
|
if (j == PAR_B)
|
||||||
|
t = ptyp(sp_ilb2);
|
||||||
|
t = getarg(t);
|
||||||
|
/*
|
||||||
|
* range checking
|
||||||
|
*/
|
||||||
|
switch (j) {
|
||||||
|
case PAR_N:
|
||||||
|
check(argval >= 0);
|
||||||
|
break;
|
||||||
|
case PAR_G:
|
||||||
|
if (t != sp_cst2 && t != sp_cst4)
|
||||||
|
break;
|
||||||
|
check(argval >= 0);
|
||||||
|
/* fall through */
|
||||||
|
case PAR_L:
|
||||||
|
l = argval >= 0 ? argval : -argval;
|
||||||
|
check((l & ~wordmask[psize]) == 0);
|
||||||
|
break;
|
||||||
|
case PAR_W:
|
||||||
|
if (t == sp_cend)
|
||||||
|
break;
|
||||||
|
check((argval & ~wordmask[wsize]) == 0);
|
||||||
|
/* fall through */
|
||||||
|
case PAR_S:
|
||||||
|
check(argval != 0);
|
||||||
|
/* fall through */
|
||||||
|
case PAR_Z:
|
||||||
|
check((argval & ~sizemask[wsize]) == 0);
|
||||||
|
break;
|
||||||
|
case PAR_O:
|
||||||
|
check(argval != 0);
|
||||||
|
check((argval & ~sizemask[wsize])==0 || (wsize % argval)==0);
|
||||||
|
break;
|
||||||
|
case PAR_B:
|
||||||
|
t = sp_cst2;
|
||||||
|
break;
|
||||||
|
case PAR_R:
|
||||||
|
check(argval >= 0 && argval <= 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
putarg(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
pseudo() {
|
||||||
|
register i,t;
|
||||||
|
|
||||||
|
i = opcode;
|
||||||
|
put8(i);
|
||||||
|
switch (i) {
|
||||||
|
case ps_bss:
|
||||||
|
case ps_hol:
|
||||||
|
putarg(getarg(cst_ptyp));
|
||||||
|
putarg(getarg(val_ptyp));
|
||||||
|
putarg(getarg(ptyp(sp_cst2)));
|
||||||
|
check(argval==0 || argval==1);
|
||||||
|
break;
|
||||||
|
case ps_rom:
|
||||||
|
case ps_con:
|
||||||
|
putarg(getarg(val_ptyp));
|
||||||
|
do
|
||||||
|
putarg(t = getarg(any_ptyp));
|
||||||
|
while (t != sp_cend);
|
||||||
|
break;
|
||||||
|
case ps_mes:
|
||||||
|
putarg(getarg(ptyp(sp_cst2)));
|
||||||
|
if (argval == ms_emx) {
|
||||||
|
putarg(getarg(ptyp(sp_cst2)));
|
||||||
|
check(argval > 0 && argval <= 4);
|
||||||
|
wsize = (int) argval;
|
||||||
|
putarg(getarg(ptyp(sp_cst2)));
|
||||||
|
check(argval > 0 && argval <= 4);
|
||||||
|
psize = (int) argval;
|
||||||
|
}
|
||||||
|
do
|
||||||
|
putarg(t = getarg(any_ptyp));
|
||||||
|
while (t != sp_cend);
|
||||||
|
break;
|
||||||
|
case ps_exa:
|
||||||
|
case ps_ina:
|
||||||
|
putarg(getarg(sym_ptyp));
|
||||||
|
break;
|
||||||
|
case ps_exp:
|
||||||
|
case ps_inp:
|
||||||
|
putarg(getarg(ptyp(sp_pnam)));
|
||||||
|
break;
|
||||||
|
case ps_exc:
|
||||||
|
putarg(getarg(ptyp(sp_cst2)));
|
||||||
|
putarg(getarg(ptyp(sp_cst2)));
|
||||||
|
break;
|
||||||
|
case ps_pro:
|
||||||
|
putarg(getarg(ptyp(sp_pnam)));
|
||||||
|
putarg(getarg(cst_ptyp|ptyp(sp_cend)));
|
||||||
|
break;
|
||||||
|
case ps_end:
|
||||||
|
putarg(getarg(cst_ptyp|ptyp(sp_cend)));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
syntax("bad pseudo %d",i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----- input ----- */
|
||||||
|
|
||||||
|
int getarg(typset) {
|
||||||
|
register c;
|
||||||
|
|
||||||
|
if (argnum != 1) {
|
||||||
|
c = nospace();
|
||||||
|
if (c != ',') {
|
||||||
|
if (c != '\n')
|
||||||
|
syntax("comma expected");
|
||||||
|
peekc = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argnum++;
|
||||||
|
return(gettyp(typset));
|
||||||
|
}
|
||||||
|
|
||||||
|
int gettyp(typset) {
|
||||||
|
register c,t,sp;
|
||||||
|
|
||||||
|
c = nospace();
|
||||||
|
if (c == '\n') {
|
||||||
|
peekc = c;
|
||||||
|
sp = sp_cend;
|
||||||
|
} else if (isdigit(c) || c == '+' || c == '-' || c == '(') {
|
||||||
|
sp = inexpr1(c);
|
||||||
|
if (sp == sp_cst4 && fit16i(argval))
|
||||||
|
sp = sp_cst2;
|
||||||
|
} else if (isalpha(c)) {
|
||||||
|
inname(c);
|
||||||
|
sp = offsetted(sp_dnam);
|
||||||
|
} else if (c == '.') {
|
||||||
|
in15u();
|
||||||
|
dlbval = (int) argval;
|
||||||
|
sp = offsetted(sp_dlb2);
|
||||||
|
} else if (c == '*') {
|
||||||
|
in15u();
|
||||||
|
sp = sp_ilb2;
|
||||||
|
} else if (c == '$') {
|
||||||
|
inname(nextchar());
|
||||||
|
sp = sp_pnam;
|
||||||
|
} else if (c == '"' || c == '\'') {
|
||||||
|
sp = instring(c);
|
||||||
|
} else if (c == '?') {
|
||||||
|
sp = sp_cend;
|
||||||
|
} else
|
||||||
|
syntax("operand expected");
|
||||||
|
t = sp - sp_fspec;
|
||||||
|
assert(t >= 0 && t < 16);
|
||||||
|
t = 1 << t;
|
||||||
|
if ((typset & t) == 0)
|
||||||
|
error("bad argument type %d",sp);
|
||||||
|
return(sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int offsetted(sp) {
|
||||||
|
register c;
|
||||||
|
|
||||||
|
c = nospace();
|
||||||
|
if (c == '+' || c == '-') {
|
||||||
|
gettyp(cst_ptyp);
|
||||||
|
if (c == '-')
|
||||||
|
argval = -argval;
|
||||||
|
offtyp = sp;
|
||||||
|
return(sp_doff);
|
||||||
|
}
|
||||||
|
peekc = c;
|
||||||
|
return(sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
inname(c) register c; {
|
||||||
|
register char *p;
|
||||||
|
|
||||||
|
if (isalpha(c) == 0)
|
||||||
|
syntax("letter expected");
|
||||||
|
p = string;
|
||||||
|
do {
|
||||||
|
if (p < &string[MAXSTR-1])
|
||||||
|
*p++ = c;
|
||||||
|
c = nextchar();
|
||||||
|
} while (isalnum(c));
|
||||||
|
peekc = c;
|
||||||
|
*p = '\0';
|
||||||
|
strsiz = p - string;
|
||||||
|
}
|
||||||
|
|
||||||
|
int inmnem(c) register c; {
|
||||||
|
register unsigned h;
|
||||||
|
register i;
|
||||||
|
|
||||||
|
inname(c);
|
||||||
|
h = hash(string);
|
||||||
|
for (;;) {
|
||||||
|
h++;
|
||||||
|
h %= HSIZE;
|
||||||
|
i = hashtab[h];
|
||||||
|
if (i == 0)
|
||||||
|
syntax("bad mnemonic");
|
||||||
|
if (i <= sp_lmnem) {
|
||||||
|
assert(i >= sp_fmnem);
|
||||||
|
if (strcmp(string,em_mnem[i - sp_fmnem]) != 0)
|
||||||
|
continue;
|
||||||
|
return(opcode = i);
|
||||||
|
}
|
||||||
|
assert(i <= sp_lpseu && i >= sp_fpseu);
|
||||||
|
if (strcmp(string,em_pseu[i - sp_fpseu]) != 0)
|
||||||
|
continue;
|
||||||
|
return(opcode = i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int inexpr1(c) register c; {
|
||||||
|
long left;
|
||||||
|
|
||||||
|
if ((c = inexpr2(c)) != sp_cst4)
|
||||||
|
return(c);
|
||||||
|
for (;;) {
|
||||||
|
c = nospace();
|
||||||
|
if (c != '+' && c != '-') {
|
||||||
|
peekc = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
left = argval;
|
||||||
|
if (inexpr2(nospace()) != sp_cst4)
|
||||||
|
syntax("term expected");
|
||||||
|
if (c == '+')
|
||||||
|
argval += left;
|
||||||
|
else
|
||||||
|
argval = left - argval;
|
||||||
|
}
|
||||||
|
return(sp_cst4);
|
||||||
|
}
|
||||||
|
|
||||||
|
int inexpr2(c) register c; {
|
||||||
|
long left;
|
||||||
|
|
||||||
|
if ((c = inexpr3(c)) != sp_cst4)
|
||||||
|
return(c);
|
||||||
|
for (;;) {
|
||||||
|
c = nospace();
|
||||||
|
if (c != '*' && c != '/' && c != '%') {
|
||||||
|
peekc = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
left = argval;
|
||||||
|
if (inexpr3(nospace()) != sp_cst4)
|
||||||
|
syntax("factor expected");
|
||||||
|
if (c == '*')
|
||||||
|
argval *= left;
|
||||||
|
else if (c == '/')
|
||||||
|
argval = left / argval;
|
||||||
|
else
|
||||||
|
argval = left % argval;
|
||||||
|
}
|
||||||
|
return(sp_cst4);
|
||||||
|
}
|
||||||
|
|
||||||
|
inexpr3(c) register c; {
|
||||||
|
|
||||||
|
if (c == '(') {
|
||||||
|
if (inexpr1(nospace()) != sp_cst4)
|
||||||
|
syntax("expression expected");
|
||||||
|
if (nospace() != ')')
|
||||||
|
syntax("')' expected");
|
||||||
|
return(sp_cst4);
|
||||||
|
}
|
||||||
|
return(innumber(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
int innumber(c) register c; {
|
||||||
|
register char *p;
|
||||||
|
register n;
|
||||||
|
int expsign;
|
||||||
|
static char numstr[MAXSTR];
|
||||||
|
long atol();
|
||||||
|
|
||||||
|
p = numstr;
|
||||||
|
expsign = 0;
|
||||||
|
if (c == '+' || c == '-') {
|
||||||
|
if (c == '-')
|
||||||
|
*p++ = c;
|
||||||
|
c = nextchar();
|
||||||
|
}
|
||||||
|
if (isdigit(c) == 0)
|
||||||
|
syntax("digit expected");
|
||||||
|
n = sp_cst4;
|
||||||
|
for (;;) {
|
||||||
|
if (p >= &numstr[MAXSTR-1])
|
||||||
|
fatal("number too long");
|
||||||
|
*p++ = c;
|
||||||
|
c = nextchar();
|
||||||
|
if (c == '.' || c == 'e' || c == 'E') {
|
||||||
|
expsign = c != '.';
|
||||||
|
n = sp_fcon;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (expsign) {
|
||||||
|
expsign = 0;
|
||||||
|
if (c == '+' || c == '-')
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (isdigit(c) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
peekc = c;
|
||||||
|
*p = '\0';
|
||||||
|
c = nospace();
|
||||||
|
if (n == sp_fcon && c != 'F')
|
||||||
|
syntax("'F' expected");
|
||||||
|
if (c == 'I' || c == 'U' || c == 'F')
|
||||||
|
return(incon(numstr,c));
|
||||||
|
peekc = c;
|
||||||
|
argval = atol(numstr);
|
||||||
|
return(sp_cst4);
|
||||||
|
}
|
||||||
|
|
||||||
|
in15u() {
|
||||||
|
|
||||||
|
if (innumber(nextchar()) != sp_cst4)
|
||||||
|
syntax("integer expected");
|
||||||
|
check((argval & ~077777) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int incon(p,c) register char *p; {
|
||||||
|
register char *q;
|
||||||
|
|
||||||
|
q = string;
|
||||||
|
while (*q++ = *p++)
|
||||||
|
;
|
||||||
|
strsiz = q - string - 1;
|
||||||
|
gettyp(cst_ptyp);
|
||||||
|
return(c == 'I' ? sp_icon : (c == 'U' ? sp_ucon : sp_fcon));
|
||||||
|
}
|
||||||
|
|
||||||
|
int instring(termc) {
|
||||||
|
register char *p;
|
||||||
|
register c;
|
||||||
|
|
||||||
|
p = string;
|
||||||
|
for (;;) {
|
||||||
|
c = nextchar();
|
||||||
|
if (c == '\n' || c == EOF) {
|
||||||
|
peekc = c;
|
||||||
|
syntax("non-terminated string");
|
||||||
|
}
|
||||||
|
if (c == termc) {
|
||||||
|
if (termc == '"')
|
||||||
|
*p++ = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c == '\\')
|
||||||
|
c = inescape();
|
||||||
|
if (p >= &string[MAXSTR-1])
|
||||||
|
fatal("string too long");
|
||||||
|
*p++ = c;
|
||||||
|
}
|
||||||
|
strsiz = p - string;
|
||||||
|
return(sp_scon);
|
||||||
|
}
|
||||||
|
|
||||||
|
int inescape() {
|
||||||
|
register c,j,r;
|
||||||
|
|
||||||
|
c = nextchar();
|
||||||
|
if (c >= '0' && c <= '7') {
|
||||||
|
r = c - '0';
|
||||||
|
for (j = 0; j < 2; j++) {
|
||||||
|
c = nextchar();
|
||||||
|
if (c < '0' || c > '7') {
|
||||||
|
peekc = c;
|
||||||
|
return(r);
|
||||||
|
}
|
||||||
|
r <<= 3;
|
||||||
|
r += (c - '0');
|
||||||
|
}
|
||||||
|
return(r);
|
||||||
|
}
|
||||||
|
switch (c) {
|
||||||
|
case 'b': return('\b');
|
||||||
|
case 'f': return('\f');
|
||||||
|
case 'n': return('\n');
|
||||||
|
case 'r': return('\r');
|
||||||
|
case 't': return('\t');
|
||||||
|
}
|
||||||
|
return(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nospace() {
|
||||||
|
register c;
|
||||||
|
|
||||||
|
do
|
||||||
|
c = nextchar();
|
||||||
|
while (isspace(c) && c != '\n');
|
||||||
|
if (c == ';')
|
||||||
|
do
|
||||||
|
c = nextchar();
|
||||||
|
while (c != '\n' && c != EOF);
|
||||||
|
return(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nextchar() {
|
||||||
|
register c;
|
||||||
|
|
||||||
|
if (peekc != EMPTY) {
|
||||||
|
c = peekc;
|
||||||
|
peekc = EMPTY;
|
||||||
|
return(c);
|
||||||
|
}
|
||||||
|
c = getchar();
|
||||||
|
if (isascii(c) == 0 && c != EOF)
|
||||||
|
fatal("non-ascii char");
|
||||||
|
return(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
line_line() {
|
||||||
|
register char *p,*q;
|
||||||
|
static char filebuff[MAXSTR+1];
|
||||||
|
|
||||||
|
gettyp(ptyp(sp_cst2));
|
||||||
|
lineno = (int) (argval-1);
|
||||||
|
gettyp(ptyp(sp_scon));
|
||||||
|
p = string;
|
||||||
|
q = filebuff;
|
||||||
|
while (--strsiz >= 0)
|
||||||
|
*q++ = *p++;
|
||||||
|
*q = '\0';
|
||||||
|
filename = filebuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
register i;
|
||||||
|
|
||||||
|
for (i = sp_fmnem; i <= sp_lmnem; i++)
|
||||||
|
pre_hash(i,em_mnem[i - sp_fmnem]);
|
||||||
|
for (i = sp_fpseu; i <= sp_lpseu; i++)
|
||||||
|
pre_hash(i,em_pseu[i - sp_fpseu]);
|
||||||
|
/* treat '_' as letter */
|
||||||
|
/* In System III the array is called _ctype[] without the trailing '_' */
|
||||||
|
(_ctype_+1)['_'] = (_ctype_+1)['a'];
|
||||||
|
}
|
||||||
|
|
||||||
|
pre_hash(i,s) char *s; {
|
||||||
|
register unsigned h;
|
||||||
|
|
||||||
|
assert(i != 0);
|
||||||
|
h = hash(s);
|
||||||
|
for (;;) {
|
||||||
|
h++;
|
||||||
|
h %= HSIZE;
|
||||||
|
if (hashtab[h] == 0) {
|
||||||
|
hashtab[h] = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int hash(s) register char *s; {
|
||||||
|
register h;
|
||||||
|
|
||||||
|
h = 0;
|
||||||
|
while (*s) {
|
||||||
|
h <<= 1;
|
||||||
|
h += *s++;
|
||||||
|
}
|
||||||
|
return(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----- output ----- */
|
||||||
|
|
||||||
|
putarg(sp) register sp; {
|
||||||
|
register i;
|
||||||
|
|
||||||
|
switch (sp) {
|
||||||
|
case sp_ilb2:
|
||||||
|
i = (int) argval;
|
||||||
|
if (fit8u(i)) {
|
||||||
|
put8(sp_ilb1);
|
||||||
|
put8(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
put8(sp);
|
||||||
|
put16(i);
|
||||||
|
break;
|
||||||
|
case sp_dlb2:
|
||||||
|
i = dlbval;
|
||||||
|
if (fit8u(i)) {
|
||||||
|
put8(sp_dlb1);
|
||||||
|
put8(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
put8(sp);
|
||||||
|
put16(i);
|
||||||
|
break;
|
||||||
|
case sp_cst2:
|
||||||
|
case sp_cst4:
|
||||||
|
if (fit16i(argval) == 0) {
|
||||||
|
put8(sp_cst4);
|
||||||
|
put32(argval);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i = (int) argval;
|
||||||
|
if (i >= -sp_zcst0 && i < sp_ncst0 - sp_zcst0) {
|
||||||
|
put8(i + sp_zcst0 + sp_fcst0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
put8(sp_cst2);
|
||||||
|
put16(i);
|
||||||
|
break;
|
||||||
|
case sp_doff:
|
||||||
|
put8(sp);
|
||||||
|
putarg(offtyp);
|
||||||
|
putarg(sp_cst4);
|
||||||
|
break;
|
||||||
|
case sp_dnam:
|
||||||
|
case sp_pnam:
|
||||||
|
case sp_scon:
|
||||||
|
put8(sp);
|
||||||
|
putstr();
|
||||||
|
break;
|
||||||
|
case sp_icon:
|
||||||
|
case sp_ucon:
|
||||||
|
case sp_fcon:
|
||||||
|
put8(sp);
|
||||||
|
putarg(sp_cst4);
|
||||||
|
putstr();
|
||||||
|
break;
|
||||||
|
case sp_cend:
|
||||||
|
put8(sp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
putstr() {
|
||||||
|
register char *p;
|
||||||
|
long consiz;
|
||||||
|
|
||||||
|
consiz = argval;
|
||||||
|
argval = strsiz;
|
||||||
|
putarg(sp_cst4);
|
||||||
|
argval = consiz;
|
||||||
|
p = string;
|
||||||
|
while (--strsiz >= 0)
|
||||||
|
put8(*p++);
|
||||||
|
}
|
||||||
|
|
||||||
|
put16(w) int w; {
|
||||||
|
|
||||||
|
put8(w);
|
||||||
|
put8(w >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
put32(f) long f; {
|
||||||
|
|
||||||
|
put16((int) f);
|
||||||
|
put16((int)(f >> 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----- error handling ----- */
|
||||||
|
|
||||||
|
fail_check() {
|
||||||
|
error("argument range error");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VARARGS */
|
||||||
|
error(s,a1,a2,a3,a4) char *s; {
|
||||||
|
fprintf(stderr,"%s: line %d: ", filename, lineno);
|
||||||
|
fprintf(stderr,s,a1,a2,a3,a4);
|
||||||
|
fprintf(stderr,"\n");
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VARARGS */
|
||||||
|
fatal(s,a1,a2,a3,a4) char *s; {
|
||||||
|
error(s,a1,a2,a3,a4);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VARARGS */
|
||||||
|
syntax(s,a1,a2,a3,a4) char *s; {
|
||||||
|
register c;
|
||||||
|
|
||||||
|
error(s,a1,a2,a3,a4);
|
||||||
|
do
|
||||||
|
c = nextchar();
|
||||||
|
while (c != '\n' && c != EOF);
|
||||||
|
longjmp(recover);
|
||||||
|
}
|
Loading…
Reference in a new issue