Initial revision
This commit is contained in:
parent
bd5583311e
commit
c39c666834
20 changed files with 4338 additions and 0 deletions
20
lang/basic/src/.distr
Normal file
20
lang/basic/src/.distr
Normal file
|
@ -0,0 +1,20 @@
|
|||
Makefile
|
||||
README
|
||||
basic.g
|
||||
basic.lex
|
||||
bem.c
|
||||
bem.h
|
||||
compile.c
|
||||
eval.c
|
||||
func.c
|
||||
gencode.c
|
||||
graph.c
|
||||
graph.h
|
||||
initialize.c
|
||||
llmess.c
|
||||
maketokentab
|
||||
parsepar.c
|
||||
symbols.c
|
||||
symbols.h
|
||||
util.c
|
||||
yylexp.c
|
64
lang/basic/src/Makefile
Normal file
64
lang/basic/src/Makefile
Normal file
|
@ -0,0 +1,64 @@
|
|||
# $Header$
|
||||
|
||||
EMHOME=../../..
|
||||
h=$(EMHOME)/h
|
||||
m=$(EMHOME)/modules/h
|
||||
LIBDIR= $(EMHOME)/modules/lib
|
||||
LIBDIR2= $(EMHOME)/lib
|
||||
CFLAGS = -I$h -I$m
|
||||
|
||||
FILES= bem.o symbols.o initialize.o compile.o \
|
||||
parsepar.o gencode.o util.o graph.o \
|
||||
eval.o func.o basic.o Lpars.o
|
||||
|
||||
CSRCFILES= bem.c symbols.c initialize.c compile.c \
|
||||
parsepar.c gencode.c util.c graph.c \
|
||||
eval.c func.c
|
||||
CGENFILES= basic.c Lpars.c
|
||||
CFILES=$(CSRCFILES) $(CGENFILES)
|
||||
|
||||
LIBFILES= $(LIBDIR)/libem_mes.a $(LIBDIR)/libeme.a \
|
||||
$(LIBDIR2)/em_data.a $(LIBDIR)/libprint.a \
|
||||
$(LIBDIR)/liballoc.a \
|
||||
$(LIBDIR)/libsystem.a $(LIBDIR)/libstring.a
|
||||
|
||||
LINTLIBFILES= $(LIBDIR)/llib-lem_mes.a $(LIBDIR)/llib-leme.a \
|
||||
$(LIBDIR)/llib-lprint.a \
|
||||
$(LIBDIR)/llib-lalloc.a \
|
||||
$(LIBDIR)/llib-lsystem.a $(LIBDIR)/llib-lstring.a
|
||||
|
||||
all: dummy bem
|
||||
|
||||
dummy: basic.g
|
||||
LLgen basic.g
|
||||
touch dummy
|
||||
|
||||
install: all
|
||||
cp bem $(EMHOME)/lib/em_bem
|
||||
|
||||
cmp: all
|
||||
cmp bem $(EMHOME)/lib/em_bem
|
||||
|
||||
pr:
|
||||
@pr Makefile maketokentab bem.h symbols.h graph.h basic.g basic.lex $(CSRCFILES)
|
||||
|
||||
opr:
|
||||
make pr | opr
|
||||
|
||||
bem: $(FILES) $(LIBFILES)
|
||||
$(CC) -o bem $(FILES) $(LIBFILES)
|
||||
|
||||
basic.o : basic.c basic.lex Lpars.h llmess.c tokentab.h
|
||||
$(CC) $(CFLAGS) -c basic.c
|
||||
|
||||
$(FILES): bem.h symbols.h graph.h
|
||||
|
||||
tokentab.h: Lpars.h
|
||||
maketokentab
|
||||
|
||||
lint: $(CFILES)
|
||||
lint -b $(CFLAGS) $(CFILES) $(LINTLIBFILES)
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f basic.c Lpars.h Lpars.c dummy tokentab.h bem
|
792
lang/basic/src/basic.g
Normal file
792
lang/basic/src/basic.g
Normal file
|
@ -0,0 +1,792 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
%token ILLEGAL ;
|
||||
%token ASSYM ;
|
||||
%token BASESYM ;
|
||||
%token CALLSYM ;
|
||||
%token CLEARSYM ;
|
||||
%token CLOSESYM ;
|
||||
%token DATASYM ;
|
||||
%token DEFINTSYM ;
|
||||
%token DEFSNGSYM ;
|
||||
%token DEFDBLSYM ;
|
||||
%token DEFSTRSYM ;
|
||||
%token DEFSYM ;
|
||||
%token DIMSYM ;
|
||||
%token ELSESYM ;
|
||||
%token ERRSYM ;
|
||||
%token ERLSYM ;
|
||||
%token ERRORSYM ;
|
||||
%token FIELDSYM ;
|
||||
%token FORSYM ;
|
||||
%token FUNCTION ;
|
||||
%token FUNCTID ;
|
||||
%token INKEYSYM ;
|
||||
%token GETSYM ;
|
||||
%token GOSUBSYM ;
|
||||
%token GOTOSYM ;
|
||||
%token IFSYM ;
|
||||
%token INPUTSYM ;
|
||||
%token LETSYM ;
|
||||
%token LINESYM ;
|
||||
%token LSETSYM ;
|
||||
%token MIDSYM ;
|
||||
%token NEXTSYM ;
|
||||
%token ONSYM ;
|
||||
%token OPENSYM ;
|
||||
%token OPTIONSYM ;
|
||||
%token PRINTSYM ;
|
||||
%token POKESYM ;
|
||||
%token PUTSYM ;
|
||||
%token RANDOMIZESYM ;
|
||||
%token READSYM ;
|
||||
%token REMSYM ;
|
||||
%token RESTORESYM ;
|
||||
%token RETURNSYM ;
|
||||
%token ENDSYM ;
|
||||
%token STOPSYM ;
|
||||
%token STEPSYM ;
|
||||
%token SWAPSYM ;
|
||||
%token THENSYM ;
|
||||
%token TOSYM ;
|
||||
%token TRONOFFSYM ;
|
||||
%token USINGSYM ;
|
||||
%token USRSYM ;
|
||||
%token WHILESYM ;
|
||||
%token WENDSYM ;
|
||||
%token WRITESYM ;
|
||||
/* special tokens */
|
||||
%token EOLN ;
|
||||
%token INTVALUE ;
|
||||
%token FLTVALUE ;
|
||||
%token DBLVALUE ;
|
||||
%token STRVALUE ;
|
||||
%token UNARYSYM ;
|
||||
%token IDENTIFIER ;
|
||||
%token ANDSYM ;
|
||||
%token ORSYM ;
|
||||
%token IMPSYM ;
|
||||
%token EQVSYM ;
|
||||
%token XORSYM ;
|
||||
%token VARPTR ;
|
||||
|
||||
/* Those were originally %left */
|
||||
%token BOOLOP ;
|
||||
%token NOTSYM ;
|
||||
%token RELOP ;
|
||||
%token MODSYM ;
|
||||
|
||||
/* Some contstant declared as tokens (?) */
|
||||
%token LESYM ;
|
||||
%token GESYM ;
|
||||
%token NESYM ;
|
||||
%token UNARYMINUS ;
|
||||
|
||||
{
|
||||
#define YYDEBUG
|
||||
#include "bem.h"
|
||||
#include "llmess.c"
|
||||
|
||||
typedef union {
|
||||
int integer ;
|
||||
Symbol *Sptr ;
|
||||
char *cptr ;
|
||||
} YYSTYPE ;
|
||||
|
||||
int basicline;
|
||||
|
||||
int yydebug;
|
||||
|
||||
YYSTYPE yylval;
|
||||
|
||||
int ival;
|
||||
char *dval;
|
||||
char *sval;
|
||||
int in_data = 0; /* set if processing DATA statement */
|
||||
|
||||
char *formatstring; /* formatstring used for printing */
|
||||
Symbol *s; /* Symbol dummy */
|
||||
|
||||
#include "yylexp.c"
|
||||
#include "basic.lex"
|
||||
}
|
||||
|
||||
%lexical yylexp;
|
||||
|
||||
%start LLparse,programline ;
|
||||
|
||||
programline
|
||||
: INTVALUE
|
||||
{ basicline = ival;newblock(ival); newemblock(ival); }
|
||||
stmts EOLN
|
||||
| '#' INTVALUE STRVALUE EOLN
|
||||
| EOLN
|
||||
;
|
||||
|
||||
|
||||
stmts : singlestmt
|
||||
[ %while ( LLsymb == ':' ) ':' singlestmt ]*
|
||||
;
|
||||
|
||||
singlestmt { int d2 ; }
|
||||
: callstmt
|
||||
| clearstmt
|
||||
| CLOSESYM closestmt
|
||||
| datastmt
|
||||
| defstmt
|
||||
| defvarstmt
|
||||
| dimstmt
|
||||
| ERRORSYM expression(&d2) { errorstmt(d2); }
|
||||
| fieldstmt
|
||||
| forstmt
|
||||
| getstmt
|
||||
| gosubstmt
|
||||
| onstmt
|
||||
| ifstmt
|
||||
| illegalstmt
|
||||
| inputstmt
|
||||
| letstmt
|
||||
| lineinputstmt
|
||||
| lsetstmt
|
||||
| midstmt
|
||||
| NEXTSYM nextstmt
|
||||
| GOTOSYM INTVALUE { gotostmt(ival); }
|
||||
| openstmt
|
||||
| optionstmt
|
||||
| pokestmt
|
||||
| printstmt
|
||||
| randomizestmt
|
||||
| readstmt
|
||||
| REMSYM
|
||||
| restorestmt
|
||||
| returnstmt
|
||||
| ENDSYM { C_loc((arith) 0 );
|
||||
C_cal("_hlt");
|
||||
C_asp((arith) BEMINTSIZE);
|
||||
}
|
||||
| STOPSYM { C_cal("_stop"); }
|
||||
| swapstmt
|
||||
| TRONOFFSYM { tronoff=yylval.integer; }
|
||||
| whilestmt
|
||||
| wendstmt
|
||||
| writestmt
|
||||
| /* EMPTY STATEMENT */
|
||||
;
|
||||
|
||||
illegalstmt: ILLEGAL { illegalcmd(); }
|
||||
;
|
||||
|
||||
callstmt { Symbol *id; int i; }
|
||||
: CALLSYM
|
||||
IDENTIFIER { id = yylval.Sptr; }
|
||||
[ parmlist(&i)
|
||||
{ C_cal(id->symname);
|
||||
C_asp((arith) (i*BEMPTRSIZE));
|
||||
}
|
||||
| /* empty */
|
||||
{ C_cal(id->symname); }
|
||||
]
|
||||
;
|
||||
|
||||
parmlist(int *ip;) { int var ; }
|
||||
: '('
|
||||
variable(&var) { *ip = 1; }
|
||||
[ ',' variable(&var) { *ip = *ip + 1; } ]*
|
||||
')'
|
||||
;
|
||||
|
||||
|
||||
clearstmt { int exp; }
|
||||
: CLEARSYM [ ',' expression(&exp) ]*2
|
||||
{ warning("statement ignored"); }
|
||||
;
|
||||
|
||||
closestmt: filelist
|
||||
| /* empty */ { C_cal("_close"); }
|
||||
;
|
||||
|
||||
filelist { int intv; }
|
||||
: cross
|
||||
intvalue(&intv)
|
||||
{ C_loc((arith) ival);
|
||||
C_cal("_clochn");
|
||||
C_asp((arith) BEMINTSIZE);
|
||||
}
|
||||
[ ','
|
||||
cross
|
||||
intvalue(&intv)
|
||||
{ C_loc((arith) ival);
|
||||
C_cal("_clochn");
|
||||
C_asp((arith) BEMINTSIZE);
|
||||
}
|
||||
]* ;
|
||||
|
||||
datastmt: DATASYM { datastmt(); in_data = 1;}
|
||||
datalist { fprint(datfile,"\n"); in_data = 0; }
|
||||
;
|
||||
|
||||
dataelm : INTVALUE { fprint(datfile,"%d",ival); }
|
||||
| '-' [ INTVALUE { fprint(datfile,"%d",-ival); }
|
||||
| FLTVALUE { fprint(datfile,"-%s",dval); }
|
||||
]
|
||||
| FLTVALUE { fprint(datfile,dval); }
|
||||
| STRVALUE { fprint(datfile,"\"%s\"",sval); }
|
||||
| IDENTIFIER { fprint(datfile,"\"%s\"",sval); }
|
||||
;
|
||||
|
||||
datalist: dataelm
|
||||
[ ',' { fprint(datfile,","); }
|
||||
dataelm ]*
|
||||
;
|
||||
|
||||
defstmt : DEFSYM
|
||||
[ deffnstmt
|
||||
| defusrstmt
|
||||
]
|
||||
;
|
||||
|
||||
deffnstmt { int exp; }
|
||||
: heading '=' expression(&exp)
|
||||
{ endscope(exp); }
|
||||
;
|
||||
|
||||
heading : FUNCTID { newscope(yylval.Sptr); }
|
||||
[ '(' idlist ')' ]? { heading(); }
|
||||
;
|
||||
|
||||
idlist : IDENTIFIER { dclparm(yylval.Sptr); }
|
||||
[ ',' IDENTIFIER { dclparm(yylval.Sptr); }
|
||||
]*
|
||||
;
|
||||
|
||||
defvarstmt: DEFINTSYM { setdefaulttype( INTTYPE); }
|
||||
| DEFSNGSYM { setdefaulttype( FLOATTYPE); }
|
||||
| DEFDBLSYM { setdefaulttype( DOUBLETYPE); }
|
||||
| DEFSTRSYM { setdefaulttype( STRINGTYPE); }
|
||||
;
|
||||
|
||||
defusrstmt: USRSYM ':' { illegalcmd(); }
|
||||
;
|
||||
|
||||
dimstmt { Symbol *symp; }
|
||||
: DIMSYM arraydcl(&symp) ')' { dclarray(symp); }
|
||||
[ ',' arraydcl(&symp) ')' { dclarray(symp); }
|
||||
]*
|
||||
;
|
||||
|
||||
arraydcl(Symbol **sympp;)
|
||||
: IDENTIFIER { *sympp = s = yylval.Sptr; }
|
||||
'('
|
||||
INTVALUE
|
||||
{
|
||||
s->dimlimit[s->dimensions]=ival;
|
||||
s->dimensions++;
|
||||
}
|
||||
[ ','
|
||||
INTVALUE
|
||||
{
|
||||
if(s->dimensions<MAXDIMENSIONS) {
|
||||
s->dimlimit[s->dimensions]=ival;
|
||||
s->dimensions++;
|
||||
} else error("too many dimensions");
|
||||
}
|
||||
]* ;
|
||||
|
||||
fieldstmt { int intv; }
|
||||
: FIELDSYM cross intvalue(&intv)
|
||||
{ setchannel(ival); }
|
||||
',' fieldlist { notyetimpl(); }
|
||||
;
|
||||
|
||||
fieldlist { int intv,var; }
|
||||
: intvalue(&intv) ASSYM variable(&var)
|
||||
[ ',' intvalue(&intv) ASSYM variable(&var) ]*
|
||||
;
|
||||
|
||||
forstmt { int exp; }
|
||||
: FORSYM IDENTIFIER { forinit(yylval.Sptr); }
|
||||
'=' expression(&exp) { forexpr(exp); }
|
||||
TOSYM expression(&exp) { forlimit(exp); }
|
||||
step
|
||||
;
|
||||
|
||||
step { int exp; }
|
||||
: STEPSYM expression(&exp) { forstep(exp); }
|
||||
| /*EMPTY*/ {
|
||||
C_loc((arith) 1);
|
||||
forstep(INTTYPE);
|
||||
}
|
||||
;
|
||||
|
||||
nextstmt: [ IDENTIFIER { nextstmt(yylval.Sptr); }
|
||||
| /* empty */ { nextstmt((Symbol *)0); }
|
||||
]
|
||||
[ ',' IDENTIFIER { nextstmt(yylval.Sptr); }
|
||||
]*
|
||||
;
|
||||
|
||||
getstmt { char *cp; int intv; }
|
||||
: getput(&cp)
|
||||
[ /* empty */
|
||||
{ C_loc((arith) 0);
|
||||
C_cal(cp);
|
||||
C_asp((arith) BEMINTSIZE);
|
||||
}
|
||||
| ',' intvalue(&intv)
|
||||
{ C_loc((arith) ival);
|
||||
C_cal(cp);
|
||||
C_asp((arith) BEMINTSIZE);
|
||||
}
|
||||
]
|
||||
;
|
||||
|
||||
getput(char **cpp;) { int intv; }
|
||||
: GETSYM cross intvalue(&intv)
|
||||
{ setchannel(ival);
|
||||
*cpp = "$_getrec";
|
||||
}
|
||||
| PUTSYM cross intvalue(&intv)
|
||||
{ setchannel(ival);
|
||||
*cpp = "$_putsym";
|
||||
}
|
||||
;
|
||||
|
||||
gosubstmt: GOSUBSYM INTVALUE { gosubstmt(ival); }
|
||||
;
|
||||
|
||||
returnstmt: RETURNSYM { returnstmt(); }
|
||||
;
|
||||
|
||||
ifstmt { int exp; int d1; }
|
||||
: IFSYM expression(&exp) { d1=ifstmt(exp); }
|
||||
thenpart { d1=thenpart(d1); }
|
||||
elsepart { elsepart(d1); }
|
||||
;
|
||||
|
||||
thenpart: THENSYM [ INTVALUE { gotostmt(ival); }
|
||||
| stmts
|
||||
]
|
||||
| GOTOSYM INTVALUE { gotostmt(ival); }
|
||||
;
|
||||
|
||||
elsepart: %prefer ELSESYM
|
||||
[ INTVALUE { gotostmt(ival); }
|
||||
| stmts
|
||||
]
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
inputstmt { int intv; }
|
||||
: INPUTSYM [ semiprompt readlist
|
||||
| '#' intvalue(&intv)
|
||||
{ setchannel(ival); }
|
||||
',' readlist
|
||||
]
|
||||
;
|
||||
|
||||
semiprompt { int str; }
|
||||
: semi STRVALUE { str = yylval.integer; }
|
||||
[ ';' { loadstr(str);
|
||||
prompt(1);
|
||||
}
|
||||
| ',' { loadstr(str);
|
||||
prompt(0);
|
||||
}
|
||||
]
|
||||
| /*EMPTY*/
|
||||
{ setchannel(-1);
|
||||
C_cal("_qstmark");
|
||||
}
|
||||
;
|
||||
|
||||
semi : ';'
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
letstmt { int var,exp; }
|
||||
: LETSYM
|
||||
variable(&var) { save_address(); }
|
||||
'=' expression(&exp) { assign(var,exp); }
|
||||
|
|
||||
variable(&var) { save_address(); }
|
||||
'=' expression(&exp) { assign(var,exp); }
|
||||
;
|
||||
|
||||
lineinputstmt { int var,intv; }
|
||||
: LINESYM
|
||||
[ INPUTSYM
|
||||
semiprompt { setchannel(-1); }
|
||||
variable(&var) { linestmt(var); }
|
||||
| '#'
|
||||
intvalue(&intv) { setchannel(ival); }
|
||||
','
|
||||
variable(&var) { linestmt(var); }
|
||||
]
|
||||
;
|
||||
|
||||
readlist: readelm
|
||||
[ ',' readelm ]*
|
||||
;
|
||||
|
||||
readelm { int var; }
|
||||
: variable(&var) { readelm(var); }
|
||||
;
|
||||
|
||||
lsetstmt { int var,exp; }
|
||||
: LSETSYM variable(&var) '=' expression(&exp)
|
||||
{ notyetimpl(); }
|
||||
;
|
||||
|
||||
midstmt { int exp; }
|
||||
: MIDSYM '$' midparms '=' expression(&exp)
|
||||
{ C_cal("_midstmt");
|
||||
C_asp((arith) (2*BEMINTSIZE + 2*BEMPTRSIZE));
|
||||
}
|
||||
;
|
||||
|
||||
midparms: '(' midfirst midsec midthird ')'
|
||||
;
|
||||
|
||||
midfirst { int exp; }
|
||||
: expression(&exp) { conversion(exp,STRINGTYPE); }
|
||||
;
|
||||
|
||||
midsec { int exp; }
|
||||
: ',' expression(&exp) { conversion(exp,INTTYPE); }
|
||||
;
|
||||
|
||||
midthird { int exp; }
|
||||
: ',' expression(&exp) { conversion(exp,INTTYPE); }
|
||||
| /* empty */ { C_loc((arith) -1); }
|
||||
;
|
||||
|
||||
onstmt : ONSYM
|
||||
[ exceptionstmt
|
||||
| ongotostmt
|
||||
]
|
||||
;
|
||||
|
||||
exceptionstmt: ERRORSYM GOTOSYM INTVALUE { exceptstmt(ival); }
|
||||
;
|
||||
|
||||
ongotostmt { int exp; }
|
||||
: expression(&exp)
|
||||
[ GOSUBSYM constantlist { ongosubstmt(exp); }
|
||||
| GOTOSYM constantlist { ongotostmt(exp); }
|
||||
]
|
||||
;
|
||||
|
||||
constantlist: INTVALUE { jumpelm(ival); }
|
||||
[ ',' INTVALUE { jumpelm(ival); }
|
||||
]*
|
||||
;
|
||||
|
||||
openstmt { int exp; }
|
||||
: OPENSYM mode openchannel expression(&exp)
|
||||
{ conversion(exp,STRINGTYPE); }
|
||||
[ /* empty */ { openstmt(0); }
|
||||
| INTVALUE { openstmt(ival); }
|
||||
]
|
||||
;
|
||||
|
||||
openchannel: cross INTVALUE ',' { setchannel(ival); }
|
||||
;
|
||||
|
||||
mode { int exp; }
|
||||
: expression(&exp) ',' { conversion(exp,STRINGTYPE); }
|
||||
| ',' { C_lae_dnam("_iomode",(arith)0); }
|
||||
;
|
||||
|
||||
optionstmt { int intv; }
|
||||
: OPTIONSYM BASESYM intvalue(&intv) { optionbase(ival); }
|
||||
;
|
||||
|
||||
printstmt { int plist; }
|
||||
: PRINTSYM
|
||||
[ /* empty */ { setchannel(-1);
|
||||
C_cal("_nl");
|
||||
}
|
||||
| file format printlist(&plist)
|
||||
{ if(plist)
|
||||
C_cal("_nl");
|
||||
}
|
||||
]
|
||||
;
|
||||
|
||||
file { int intv; }
|
||||
: '#' intvalue(&intv) ',' { setchannel(ival); }
|
||||
| /* empty */ { setchannel(-1); }
|
||||
;
|
||||
|
||||
format { int var ; }
|
||||
: USINGSYM
|
||||
[ STRVALUE { loadstr(yylval.integer); } ';'
|
||||
| variable(&var) ';'
|
||||
{ if(var!=STRINGTYPE)
|
||||
error("string variable expected");
|
||||
}
|
||||
]
|
||||
| /* empty */ { formatstring=0; }
|
||||
;
|
||||
|
||||
printlist(int *ip;) { int exp; }
|
||||
: [ expression(&exp) { printstmt(exp); *ip=1; }
|
||||
| ',' { zone(1); *ip=0; }
|
||||
| ';' { zone(0); *ip=0; }
|
||||
]+
|
||||
;
|
||||
|
||||
pokestmt { int exp1,exp2 ; }
|
||||
: POKESYM
|
||||
expression(&exp1)
|
||||
','
|
||||
expression(&exp2) { pokestmt(exp1,exp2); }
|
||||
;
|
||||
|
||||
randomizestmt { int exp; }
|
||||
: RANDOMIZESYM
|
||||
[ /* empty */ { C_cal("_randomi"); }
|
||||
| expression(&exp)
|
||||
{ conversion(exp,INTTYPE);
|
||||
C_cal("_setrand");
|
||||
C_asp((arith) BEMINTSIZE);
|
||||
}
|
||||
]
|
||||
;
|
||||
|
||||
readstmt { int var; }
|
||||
: READSYM { setchannel(0); }
|
||||
variable(&var) { readelm(var); }
|
||||
[ ',' variable(&var) { readelm(var); }
|
||||
]*
|
||||
;
|
||||
|
||||
restorestmt : RESTORESYM
|
||||
[ INTVALUE { restore(ival); }
|
||||
| /* empty */ { restore(0); }
|
||||
]
|
||||
;
|
||||
|
||||
swapstmt { int var1,var2; }
|
||||
: SWAPSYM
|
||||
variable(&var1)
|
||||
','
|
||||
variable(&var2) { swapstmt(var1,var2); }
|
||||
;
|
||||
|
||||
whilestmt { int exp; }
|
||||
: WHILESYM { whilestart(); }
|
||||
expression(&exp) { whiletst(exp); }
|
||||
;
|
||||
|
||||
wendstmt : WENDSYM { wend(); }
|
||||
;
|
||||
|
||||
writestmt: WRITESYM
|
||||
[ /* empty */ { setchannel(-1);
|
||||
C_cal("_wrnl");
|
||||
}
|
||||
| file writelist { C_cal("_wrnl"); }
|
||||
]
|
||||
;
|
||||
|
||||
writelist { int exp; }
|
||||
: expression(&exp) { writestmt(exp,0); }
|
||||
[ ',' expression(&exp) { writestmt(exp,1); }
|
||||
]*
|
||||
;
|
||||
|
||||
cross: '#' | /* empty */ ;
|
||||
|
||||
intvalue(int *ip;)
|
||||
: INTVALUE { *ip = yylval.integer; }
|
||||
;
|
||||
|
||||
variable(int *ip;) { Symbol *symp; int exp; }
|
||||
: identifier(&symp)
|
||||
[ %avoid /* empty */ { *ip = loadaddr(symp); }
|
||||
| '(' { newarrayload(symp); }
|
||||
expression(&exp) { loadarray(exp); }
|
||||
[ ',' expression(&exp) { loadarray(exp); } ]*
|
||||
')' { *ip = endarrayload(); }
|
||||
]
|
||||
| ERRSYM { C_lae_dnam("_errsym",(arith) 0);
|
||||
*ip = INTTYPE;
|
||||
}
|
||||
| ERLSYM { C_lae_dnam("_erlsym",(arith) 0);
|
||||
*ip = INTTYPE;
|
||||
}
|
||||
;
|
||||
|
||||
expression(int *ip;) { int neg; } /* NIEUW */
|
||||
: expression1(&neg) { *ip = neg; }
|
||||
[
|
||||
IMPSYM
|
||||
expression(&neg) { *ip = boolop(*ip,neg,IMPSYM); }
|
||||
]?
|
||||
;
|
||||
|
||||
|
||||
expression1(int *ip;) { int neg; }
|
||||
: expression2(&neg) { *ip = neg; }
|
||||
[ EQVSYM
|
||||
expression2(&neg) { *ip = boolop(*ip,neg,EQVSYM); }
|
||||
]*
|
||||
;
|
||||
|
||||
expression2(int *ip;) { int neg; }
|
||||
: expression3(&neg) { *ip = neg; }
|
||||
[ XORSYM
|
||||
expression3(&neg) { *ip = boolop(*ip,neg,XORSYM); }
|
||||
]*
|
||||
;
|
||||
|
||||
expression3(int *ip;) { int neg; }
|
||||
: expression4(&neg) { *ip = neg; }
|
||||
[ ORSYM
|
||||
expression4(&neg) { *ip = boolop(*ip,neg,ORSYM); }
|
||||
]*
|
||||
;
|
||||
|
||||
expression4(int *ip;) { int neg; }
|
||||
: negation(&neg) { *ip = neg; }
|
||||
[ ANDSYM
|
||||
negation(&neg) { *ip = boolop(*ip,neg,ANDSYM); }
|
||||
]*
|
||||
;
|
||||
|
||||
negation(int *ip;) { int comp; }
|
||||
: NOTSYM compare(&comp) { *ip=boolop(comp,0,NOTSYM); }
|
||||
| compare(ip)
|
||||
;
|
||||
|
||||
compare(int *ip;) { int sum1,sum2,rel; }
|
||||
: sum(&sum1)
|
||||
[ /* empty */ { *ip = sum1; }
|
||||
| RELOP { rel=yylval.integer; }
|
||||
sum(&sum2) { *ip=relop(sum1,sum2,rel); }
|
||||
| '=' sum(&sum2) { *ip=relop(sum1,sum2,'='); }
|
||||
]
|
||||
;
|
||||
|
||||
sum(int *ip;) { int term1; }
|
||||
: term(&term1) { *ip = term1; }
|
||||
[ %while(1)
|
||||
'-' term(&term1) { *ip=plusmin(*ip,term1,'-'); }
|
||||
| '+' term(&term1) { *ip=plusmin(*ip,term1,'+'); }
|
||||
]*
|
||||
;
|
||||
|
||||
term(int *ip;) { int fac1; }
|
||||
: factor(&fac1) { *ip = fac1; }
|
||||
[ '*' factor(&fac1) { *ip=muldiv(*ip,fac1,'*'); }
|
||||
| '\\' factor(&fac1) { *ip=muldiv(*ip,fac1,'\\'); }
|
||||
| '/' factor(&fac1) { *ip=muldiv(*ip,fac1,'/'); }
|
||||
| MODSYM factor(&fac1) { *ip=muldiv(*ip,fac1,MODSYM); }
|
||||
]*
|
||||
;
|
||||
|
||||
factor(int *ip;)
|
||||
: '-' factor(ip) { *ip=negate(*ip); }
|
||||
| factor1(ip)
|
||||
;
|
||||
|
||||
factor1(int *ip;) { int mant,exp; }
|
||||
: factor2(&mant)
|
||||
[ /* empty */ { *ip = mant; }
|
||||
| '^' factor1(&exp) { *ip = power(mant,exp); }
|
||||
]
|
||||
;
|
||||
|
||||
factor2(int *ip;)
|
||||
{ int var,func,expl,funcc,exp,intv,funcn,inpt; int typetable[10]; }
|
||||
: INTVALUE { *ip=loadint(ival); }
|
||||
| '(' expression(&exp) ')' { *ip=exp; }
|
||||
| FLTVALUE { *ip=loaddbl(dval); }
|
||||
| STRVALUE
|
||||
{ *ip= STRINGTYPE;
|
||||
loadstr(yylval.integer);
|
||||
}
|
||||
| variable(&var)
|
||||
{ *ip=var;
|
||||
loadvar(var);
|
||||
}
|
||||
| INKEYSYM '$' { C_cal("_inkey");
|
||||
C_lfr((arith) BEMPTRSIZE);
|
||||
*ip= STRINGTYPE;
|
||||
}
|
||||
| VARPTR '(' '#' intvalue(&intv) ')'
|
||||
{ warning("Not supported");
|
||||
*ip=INTTYPE;
|
||||
}
|
||||
| FUNCTION { func=yylval.integer; }
|
||||
[ %avoid /* empty */ { *ip= callfcn(yylval.integer,0, typetable); }
|
||||
| '(' cross exprlist(&expl, typetable) ')'
|
||||
{ *ip=callfcn(func,expl, typetable); }
|
||||
]
|
||||
| funcname(&funcn)
|
||||
[ %avoid /* empty */ { *ip=fcnend(0); }
|
||||
| funccall(&funcc) ')' { *ip=fcnend(funcc); }
|
||||
]
|
||||
| MIDSYM '$' midparms
|
||||
{
|
||||
C_cal("_mid");
|
||||
C_asp((arith) (2*BEMINTSIZE+BEMPTRSIZE));
|
||||
C_lfr((arith) BEMPTRSIZE);
|
||||
*ip= STRINGTYPE;
|
||||
}
|
||||
| INPUTSYM '$' '(' expression(&exp) inputtail(&inpt)
|
||||
{ /*waar worden inpt en exp gebruikt?*/
|
||||
C_cal("_inpfcn");
|
||||
C_asp((arith) (2*BEMINTSIZE+BEMPTRSIZE));
|
||||
*ip= STRINGTYPE;
|
||||
}
|
||||
;
|
||||
|
||||
inputtail(int *ip;) { int exp; }
|
||||
: ',' cross expression(&exp) ')'
|
||||
{ conversion(exp,INTTYPE);
|
||||
*ip= INTTYPE;
|
||||
}
|
||||
| ')'
|
||||
{ C_loc((arith) -1);
|
||||
*ip= INTTYPE;
|
||||
}
|
||||
;
|
||||
|
||||
funcname(int *ip;)
|
||||
: FUNCTID { *ip=fcncall(yylval.Sptr); }
|
||||
;
|
||||
|
||||
funccall(int *ip;) { int exp; }
|
||||
: '(' expression(&exp) { callparm(0,exp);*ip=1; }
|
||||
[ ',' expression(&exp) { callparm(*ip,exp);
|
||||
*ip = *ip+1;
|
||||
}
|
||||
]*
|
||||
;
|
||||
|
||||
identifier(Symbol **ident;)
|
||||
: IDENTIFIER { dcltype(yylval.Sptr);
|
||||
*ident=yylval.Sptr;
|
||||
}
|
||||
;
|
||||
|
||||
exprlist(int *ip; int *typetable;) { int exp; }
|
||||
: expression(&exp) { typetable[0]=exp;
|
||||
*ip=1;
|
||||
}
|
||||
[ ',' expression(&exp) { typetable[*ip]=exp;
|
||||
*ip = *ip+1;
|
||||
}
|
||||
]*
|
||||
;
|
||||
|
||||
{
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Header$" ;
|
||||
#endif
|
||||
}
|
613
lang/basic/src/basic.lex
Normal file
613
lang/basic/src/basic.lex
Normal file
|
@ -0,0 +1,613 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#ifndef NORSCID
|
||||
static char rcs_lex[] = "$Header$" ;
|
||||
#endif
|
||||
|
||||
/* This file contains the new lexical analizer */
|
||||
typedef struct {
|
||||
char *name;
|
||||
int token, classvalue,length;
|
||||
} Key;
|
||||
|
||||
Key keywords [] ={
|
||||
"abs", FUNCTION, ABSSYM, 0,
|
||||
"and", ANDSYM, ANDSYM, 0,
|
||||
"asc", FUNCTION, ASCSYM, 0,
|
||||
"as", ASSYM, 0, 0,
|
||||
"atn", FUNCTION, ATNSYM, 0,
|
||||
"auto", ILLEGAL, 0, 0,
|
||||
"base", BASESYM, 0, 0,
|
||||
"call", CALLSYM, 0, 0,
|
||||
"cdbl", FUNCTION, CDBLSYM, 0,
|
||||
"chain", ILLEGAL, 0, 0,
|
||||
"chr", FUNCTION, CHRSYM, 0,
|
||||
"cint", FUNCTION, CINTSYM, 0,
|
||||
"clear", CLEARSYM, 0, 0,
|
||||
"cload", ILLEGAL, 0, 0,
|
||||
"close", CLOSESYM, 0, 0,
|
||||
"common", ILLEGAL, 0, 0,
|
||||
"cont", ILLEGAL, 0, 0,
|
||||
"cos", FUNCTION, COSSYM, 0,
|
||||
"csng", FUNCTION, CSNGSYM, 0,
|
||||
"csave", ILLEGAL, 0, 0,
|
||||
"cvi", FUNCTION, CVISYM, 0,
|
||||
"cvs", FUNCTION, CVSSYM, 0,
|
||||
"cvd", FUNCTION, CVDSYM, 0,
|
||||
"data", DATASYM, 0, 0,
|
||||
"defint", DEFINTSYM, 0, 0,
|
||||
"defsng", DEFSNGSYM, 0, 0,
|
||||
"defdbl", DEFDBLSYM, 0, 0,
|
||||
"defstr", DEFSTRSYM, 0, 0,
|
||||
"def", DEFSYM, 0, 0,
|
||||
"delete", ILLEGAL, 0, 0,
|
||||
"dim", DIMSYM, 0, 0,
|
||||
"edit", ILLEGAL, 0, 0,
|
||||
"else", ELSESYM, 0, 0,
|
||||
"end", ENDSYM, 0, 0,
|
||||
"eof", FUNCTION, EOFSYM, 0,
|
||||
"eqv", EQVSYM, EQVSYM, 0,
|
||||
"erase", ILLEGAL, 0, 0,
|
||||
"error", ERRORSYM, 0, 0,
|
||||
"err", ERRSYM, 0, 0,
|
||||
"erl", ERLSYM, 0, 0,
|
||||
"exp", FUNCTION, EXPSYM, 0,
|
||||
"field", FIELDSYM, 0, 0,
|
||||
"fix", FUNCTION, FIXSYM, 0,
|
||||
"for", FORSYM, 0, 0,
|
||||
"fre", FUNCTION, FRESYM, 0,
|
||||
"get", GETSYM, 0, 0,
|
||||
"gosub", GOSUBSYM, 0, 0,
|
||||
"goto", GOTOSYM, 0, 0,
|
||||
"hex", FUNCTION, HEXSYM, 0,
|
||||
"if", IFSYM, 0, 0,
|
||||
"imp", IMPSYM, IMPSYM, 0,
|
||||
"inkey", INKEYSYM, 0, 0,
|
||||
"input", INPUTSYM, 0, 0,
|
||||
"inp", FUNCTION, INPSYM, 0,
|
||||
"instr", FUNCTION, INSTRSYM, 0,
|
||||
"int", FUNCTION, INTSYM, 0,
|
||||
"kill", ILLEGAL, 0, 0,
|
||||
"left", FUNCTION, LEFTSYM, 0,
|
||||
"len", FUNCTION, LENSYM, 0,
|
||||
"let", LETSYM, 0, 0,
|
||||
"line", LINESYM, 0, 0,
|
||||
"list", LISTSYM, 0, 0,
|
||||
"llist", ILLEGAL, 0, 0,
|
||||
"load", LOADSYM, 0, 0,
|
||||
"loc", FUNCTION, LOCSYM, 0,
|
||||
"log", FUNCTION, LOGSYM, 0,
|
||||
"lpos", FUNCTION, LPOSSYM, 0,
|
||||
"lprint", ILLEGAL, 0, 0,
|
||||
"lset", LSETSYM, 0, 0,
|
||||
"merge", MERGESYM, 0, 0,
|
||||
"mid", MIDSYM, 0, 0,
|
||||
"mki", FUNCTION, MKISYM, 0,
|
||||
"mks", FUNCTION, MKSSYM, 0,
|
||||
"mkd", FUNCTION, MKDSYM, 0,
|
||||
"mod", MODSYM, 0, 0,
|
||||
"name", ILLEGAL, 0, 0,
|
||||
"new", ILLEGAL, 0, 0,
|
||||
"next", NEXTSYM, 0, 0,
|
||||
"not", NOTSYM, 0, 0,
|
||||
"null", ILLEGAL, 0, 0,
|
||||
"on", ONSYM, 0, 0,
|
||||
"oct", FUNCTION, OCTSYM, 0,
|
||||
"open", OPENSYM, 0, 0,
|
||||
"option", OPTIONSYM, 0, 0,
|
||||
"or", ORSYM, ORSYM, 0,
|
||||
"out", FUNCTION, OUTSYM, 0,
|
||||
"peek", PEEKSYM, 0, 0,
|
||||
"poke", POKESYM, 0, 0,
|
||||
"print", PRINTSYM, 0, 0,
|
||||
"pos", FUNCTION, POSSYM, 0,
|
||||
"put", PUTSYM, 0, 0,
|
||||
"randomize", RANDOMIZESYM, 0, 0,
|
||||
"read", READSYM, 0, 0,
|
||||
"rem", REMSYM, 0, 0,
|
||||
"renum", ILLEGAL, 0, 0,
|
||||
"ren", ILLEGAL, 0, 0,
|
||||
"restore", RESTORESYM, 0, 0,
|
||||
"resume", ILLEGAL, 0, 0,
|
||||
"return", RETURNSYM, 0, 0,
|
||||
"right", FUNCTION, RIGHTSYM, 0,
|
||||
"rnd", FUNCTION, RNDSYM, 0,
|
||||
"run", ILLEGAL, 0, 0,
|
||||
"save", ILLEGAL, 0, 0,
|
||||
"step", STEPSYM, 0, 0,
|
||||
"sgn", FUNCTION, SGNSYM, 0,
|
||||
"sin", FUNCTION, SINSYM, 0,
|
||||
"space", FUNCTION, SPACESYM, 0,
|
||||
"spc", FUNCTION, SPCSYM, 0,
|
||||
"sqr", FUNCTION, SQRSYM, 0,
|
||||
"stop", STOPSYM, 0, 0,
|
||||
"string", FUNCTION, STRINGSYM, 0,
|
||||
"str", FUNCTION, STRSYM, 0,
|
||||
"swap", SWAPSYM, 0, 0,
|
||||
"tab", FUNCTION, TABSYM, 0,
|
||||
"tan", FUNCTION, TANSYM, 0,
|
||||
"then", THENSYM, 0, 0,
|
||||
"to", TOSYM, 0, 0,
|
||||
"tron", TRONOFFSYM, TRONSYM, 0,
|
||||
"troff", TRONOFFSYM, TROFFSYM, 0,
|
||||
"using", USINGSYM, 0, 0,
|
||||
"usr", FUNCTION, USRSYM, 0,
|
||||
"val", FUNCTION, VALSYM, 0,
|
||||
"varptr", FUNCTION, VARPTRSYM, 0,
|
||||
"wait", ILLEGAL, 0, 0,
|
||||
"while", WHILESYM, 0, 0,
|
||||
"wend", WENDSYM, 0, 0,
|
||||
"width", ILLEGAL, 0, 0,
|
||||
"write", WRITESYM, 0, 0,
|
||||
"xor", XORSYM, XORSYM, 0,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* Keyword index table */
|
||||
|
||||
int kex[27];
|
||||
|
||||
/* Initialize the keyword table */
|
||||
fillkex()
|
||||
{
|
||||
Key *k;
|
||||
int i;
|
||||
for(k=keywords;k->name;k++)
|
||||
k->length= strlen(k->name);
|
||||
k=keywords;
|
||||
for(i=0;k->name && i<='z'-'a';i++)
|
||||
{
|
||||
for(;k->name && *k->name<i+'a';k++);
|
||||
if ( *k->name!=i+'a') continue;
|
||||
kex[*k->name-'a']=k-keywords;
|
||||
for(;k->name && *k->name==i+'a';k++);
|
||||
kex[*(k-1)->name-'a'+1]=k-keywords;
|
||||
}
|
||||
if (debug)
|
||||
{
|
||||
for(i=0;i<27;i++)
|
||||
print("%c:%d\n",'a'+i,kex[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
/* Get each line separately into the buffer */
|
||||
/* Lines too long are terminated and flagged illegal */
|
||||
|
||||
#define MAXLINELENGTH 1024
|
||||
|
||||
char inputline[MAXLINELENGTH]; /* current source line */
|
||||
char *cptr; /* next character to decode */
|
||||
int yylineno=0; /* source line counter */
|
||||
|
||||
#define GETSBUFSIZE 1024
|
||||
|
||||
char fgets_buf[GETSBUFSIZE];
|
||||
|
||||
|
||||
|
||||
char *our_fgets(buffer,n_char,stream)
|
||||
char *buffer;
|
||||
int n_char;
|
||||
File *stream;
|
||||
{
|
||||
/* Read one line or n_char */
|
||||
static int characters_left = 0;
|
||||
static char *internal_bufp = fgets_buf;
|
||||
char *external_bufp;
|
||||
|
||||
external_bufp = buffer; /* Moves through the external buffer */
|
||||
while ( 1 ) {
|
||||
if ( characters_left ) { /* There is still something buffered */
|
||||
if ( n_char > 1 ) { /* More characters have to be copied */
|
||||
if ( *internal_bufp == '\n' ) {
|
||||
*external_bufp++ = *internal_bufp++;
|
||||
characters_left--;
|
||||
*external_bufp = '\0';
|
||||
return(buffer); /* One line is read */
|
||||
} else {
|
||||
*external_bufp++ = *internal_bufp++;
|
||||
characters_left--;
|
||||
n_char--; /* One character is copied */
|
||||
}
|
||||
} else { /* Enough characters read */
|
||||
*external_bufp = '\0';
|
||||
return(buffer);
|
||||
}
|
||||
} else { /* Read new block */
|
||||
sys_read(stream,fgets_buf,GETSBUFSIZE,&characters_left);
|
||||
internal_bufp = fgets_buf;
|
||||
/* Move pointer back to the beginning */
|
||||
if ( characters_left == 0 ) { /* Nothing read */
|
||||
if ( external_bufp == buffer ) {
|
||||
*external_bufp = '\0';
|
||||
return(NULL); /* EOF */
|
||||
} else { /* Something was already copied */
|
||||
*external_bufp = '\0';
|
||||
return(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern char *strindex();
|
||||
|
||||
getline()
|
||||
{
|
||||
/* get next input line */
|
||||
|
||||
if ( our_fgets(inputline,MAXLINELENGTH,yyin) == NULL)
|
||||
return(FALSE);
|
||||
yylineno ++;
|
||||
if ( strindex(inputline,'\n') == 0)
|
||||
error("source line too long");
|
||||
inputline[MAXLINELENGTH-1]=0;
|
||||
if ( listing)
|
||||
fprint(STDERR, inputline);
|
||||
cptr= inputline;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typechar()
|
||||
{
|
||||
switch(*cptr)
|
||||
{
|
||||
case '$':
|
||||
cptr++; return( STRINGTYPE);
|
||||
case '%':
|
||||
cptr++; return( INTTYPE);
|
||||
case '!':
|
||||
cptr++; return( FLOATTYPE);
|
||||
case '#':
|
||||
cptr++; return( DOUBLETYPE);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* symbols in Microsoft are significant for the first 40 characters */
|
||||
#define SIGNIFICANT 40
|
||||
char name[SIGNIFICANT+1];
|
||||
|
||||
|
||||
lookup()
|
||||
{
|
||||
Key *k;
|
||||
Symbol *Sym;
|
||||
char *c;
|
||||
int i, typech;
|
||||
|
||||
sval= name;
|
||||
for(c=cptr; *c && isalnum(*c);c++)
|
||||
if ( isupper(*c) )
|
||||
*c= tolower(*c);
|
||||
for (k= keywords+kex[*cptr-'a']; k->name != 0 && *(k->name)== *cptr;k++)
|
||||
if ( strncmp(cptr,k->name,k->length)==0)
|
||||
{
|
||||
/* if ( isalnum( *(cptr+k->length) )) *//* EHB */
|
||||
if ( isalnum( *(cptr+k->length) ) && /* EHB */
|
||||
k->token == FUNCTION) /* EHB */
|
||||
continue;
|
||||
/* keywords door delimiters gescheiden */
|
||||
cptr += k->length;
|
||||
yylval.integer= k->classvalue;
|
||||
if (debug) print("lookup:%d %d\n",
|
||||
k->classvalue,k->token);
|
||||
if ( k->token == FUNCTION)
|
||||
{
|
||||
/* stripp type character */
|
||||
typech=typechar();
|
||||
}
|
||||
/* illegals + rem */
|
||||
if ( k->token == REMSYM || k->token==ILLEGAL)
|
||||
while ( *cptr && *cptr!=':' &&
|
||||
*cptr!='\n')
|
||||
cptr++;
|
||||
return( k->token);
|
||||
}
|
||||
/* Is it a function name ? */
|
||||
c=cptr;
|
||||
/* Identifier found, update the symbol table */
|
||||
i=0;
|
||||
while (( isalnum(*c) || *c == '.') && i < SIGNIFICANT)
|
||||
name[i++]= *c++;
|
||||
while (isalnum(*c) || *c == '.') c++; /* skip rest */
|
||||
name[i]=0;
|
||||
cptr=c;
|
||||
Sym= srchsymbol(name);
|
||||
yylval.Sptr = Sym;
|
||||
typech= typechar();
|
||||
if (Sym->symtype!=DEFAULTTYPE)
|
||||
{
|
||||
if (typech && typech!=Sym->symtype && wflag)
|
||||
warning("type re-declared,ignored");
|
||||
}
|
||||
if ( typech)
|
||||
Sym->symtype=typech;
|
||||
if (debug) print("lookup:%d Identifier\n",Sym);
|
||||
if ( (name[0]=='f' || name[0]=='F') &&
|
||||
(name[1]=='n' || name[1]=='N') )
|
||||
return(FUNCTID);
|
||||
return(IDENTIFIER);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Parsing unsigned numbers */
|
||||
readconstant()
|
||||
{
|
||||
/* read HEX and OCTAL numbers */
|
||||
char *c;
|
||||
cptr++;
|
||||
if ( *cptr == 'H' || *cptr=='h')
|
||||
{
|
||||
/* HEX */
|
||||
cptr++;
|
||||
c=cptr;
|
||||
while ( isdigit(*cptr) ||
|
||||
(*cptr>='a' && *cptr<='f' ) ||
|
||||
(*cptr>='A' && *cptr<='F' ) ) cptr++;
|
||||
(void) sscanf(c,"%x",&ival);
|
||||
} else
|
||||
if ( *cptr == 'O' || *cptr == 'o')
|
||||
{
|
||||
/* OCTAL */
|
||||
cptr++;
|
||||
c=cptr;
|
||||
while ( isdigit(*cptr) ) cptr++;
|
||||
(void) sscanf(c,"%o",&ival);
|
||||
} else error("H or O expected");
|
||||
return(INTVALUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef ____
|
||||
/* Computes base to the power exponent. This was not done in the old
|
||||
compiler */
|
||||
double powr(base,exp)
|
||||
double base;
|
||||
int exp;
|
||||
{
|
||||
int i;
|
||||
double result;
|
||||
int abs_exp;
|
||||
|
||||
if ( exp < 0 )
|
||||
abs_exp = -exp;
|
||||
else
|
||||
abs_exp = exp;
|
||||
|
||||
result = 1.0;
|
||||
for ( i = 1; i <= abs_exp; i++ ) {
|
||||
result = result * base;
|
||||
}
|
||||
|
||||
if ( exp < 0 )
|
||||
return ( 1.0 / result );
|
||||
else
|
||||
return ( result );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
number()
|
||||
{
|
||||
long i1;
|
||||
int overflow = 0;
|
||||
register char *c;
|
||||
static char numbuf[256];
|
||||
register char *d = numbuf;
|
||||
|
||||
dval = numbuf;
|
||||
i1=0;
|
||||
c=cptr;
|
||||
while (*c == '0') c++;
|
||||
while (isdigit(*c)){
|
||||
i1= i1*10 + *c-'0';
|
||||
if (i1 < 0) overflow = 1;
|
||||
if (d < &numbuf[255]) *d++ = *c;
|
||||
c++;
|
||||
}
|
||||
if (d == numbuf) *d++ = '0';
|
||||
cptr=c;
|
||||
if ( *c != '.' && *c != 'e' && *c != 'E'
|
||||
&& *c != 'd' && *c != 'D' ){
|
||||
if ( i1> MAXINT || i1<MININT || overflow) {
|
||||
*d = 0;
|
||||
return(FLTVALUE);
|
||||
}
|
||||
/*NOSTRICT*/ ival= i1;
|
||||
#ifdef YYDEBUG
|
||||
if (yydebug) print("number:INTVALUE %d",i1);
|
||||
#endif
|
||||
return(INTVALUE);
|
||||
}
|
||||
/* handle floats */
|
||||
if (*c == '.') {
|
||||
if (d < &numbuf[255]) *d++ = *c;
|
||||
c++;
|
||||
while ( isdigit(*c)){
|
||||
if (d < &numbuf[255]) *d++ = *c;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
/* handle exponential part */
|
||||
if ( *c == 'e' || *c == 'E' || *c == 'd' || *c == 'D' ){
|
||||
if (d < &numbuf[254]) *d++ = 'e';
|
||||
c++;
|
||||
if ( *c=='-' || *c=='+') {
|
||||
if (d < &numbuf[255]) *d++ = *c;
|
||||
c++;
|
||||
}
|
||||
while (isdigit(*c)){
|
||||
if (d < &numbuf[255]) *d++ = *c;
|
||||
c++;
|
||||
}
|
||||
if (*(d-1) == 'e') *d++ = '0';
|
||||
}
|
||||
*d = 0;
|
||||
cptr=c;
|
||||
#ifdef YYDEBUG
|
||||
if (yydebug) print("number:FLTVALUE %s",dval);
|
||||
#endif
|
||||
return(FLTVALUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Maximale grootte van een chunk; >= 4 */
|
||||
#define CHUNKSIZE 123
|
||||
|
||||
|
||||
|
||||
scanstring()
|
||||
{
|
||||
int i,length=0;
|
||||
char firstchar = *cptr;
|
||||
char buffer[CHUNKSIZE],*bufp = buffer;
|
||||
|
||||
/* generate label here */
|
||||
if (! in_data) yylval.integer= genemlabel();
|
||||
if ( *cptr== '"') cptr++;
|
||||
sval= cptr;
|
||||
while ( *cptr !='"')
|
||||
{
|
||||
switch(*cptr)
|
||||
{
|
||||
case 0:
|
||||
case '\n':
|
||||
#ifdef YYDEBUG
|
||||
if (yydebug) print("STRVALUE\n");
|
||||
#endif
|
||||
if ( firstchar == '"')
|
||||
error("non-terminated string");
|
||||
return(STRVALUE);
|
||||
/*
|
||||
case '\'':
|
||||
case '\\':
|
||||
*bufp++ = '\\';
|
||||
*bufp++ = *cptr;
|
||||
if ( bufp >= buffer + CHUNKSIZE - 4 ) {
|
||||
if (! in_data)
|
||||
C_con_scon(buffer,(arith)(bufp-buffer));
|
||||
bufp = buffer;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
*bufp++ = *cptr;
|
||||
if ( bufp >= buffer + CHUNKSIZE - 4 ) {
|
||||
if (! in_data)
|
||||
C_con_scon(buffer,(arith)(bufp-buffer));
|
||||
bufp = buffer;
|
||||
}
|
||||
}
|
||||
cptr++;
|
||||
length++;
|
||||
}
|
||||
*cptr = 0;
|
||||
*bufp++ = 0;
|
||||
cptr++;
|
||||
if (! in_data) {
|
||||
C_con_scon(buffer,(arith)(bufp-buffer));
|
||||
i=yylval.integer;
|
||||
yylval.integer= genemlabel();
|
||||
C_rom_dlb((label)i,(arith)0);
|
||||
C_rom_icon("9999",(arith)BEMINTSIZE);
|
||||
C_rom_icon(itoa(length),(arith)BEMINTSIZE);
|
||||
}
|
||||
#ifdef YYDEBUG
|
||||
if (yydebug) print("STRVALUE found\n");
|
||||
#endif
|
||||
return(STRVALUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
yylex()
|
||||
{
|
||||
char *c;
|
||||
|
||||
/* Here is the big switch */
|
||||
c= cptr;
|
||||
switch(*c){
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e':
|
||||
case 'f': case 'g': case 'h': case 'i': case 'j':
|
||||
case 'k': case 'l': case 'm': case 'n': case 'o':
|
||||
case 'p': case 'q': case 'r': case 's': case 't':
|
||||
case 'u': case 'v': case 'w': case 'x': case 'y':
|
||||
case 'z': case 'A': case 'B': case 'C': case 'D':
|
||||
case 'E': case 'F': case 'G': case 'H': case 'I':
|
||||
case 'J': case 'K': case 'L': case 'M': case 'N':
|
||||
case 'O': case 'P': case 'Q': case 'R': case 'S':
|
||||
case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z': case '_':
|
||||
return(lookup());
|
||||
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
case '.':
|
||||
return(number());
|
||||
|
||||
case '\'':
|
||||
/* comment at end of line */
|
||||
while ( *cptr != '\n' && *cptr) cptr++;
|
||||
case '\n':
|
||||
cptr++;
|
||||
return(EOLN);
|
||||
case 0:
|
||||
#ifdef YYDEBUG
|
||||
if ( yydebug) print("end of buffer");
|
||||
#endif
|
||||
return(0);
|
||||
case '"':
|
||||
return(scanstring());
|
||||
/* handle double operators */
|
||||
case ' ':
|
||||
case '\t':
|
||||
cptr++;
|
||||
return(yylex());
|
||||
case '&':
|
||||
return(readconstant());
|
||||
case '?':
|
||||
cptr++;
|
||||
return(PRINTSYM);
|
||||
case '>':
|
||||
if ( *(c+1)=='='){
|
||||
c++; c++;
|
||||
cptr=c;
|
||||
yylval.integer= GESYM;
|
||||
return(RELOP);
|
||||
}
|
||||
yylval.integer= '>';
|
||||
cptr++;
|
||||
return(RELOP);
|
||||
case '<':
|
||||
if ( *(c+1)=='='){
|
||||
c++; c++;
|
||||
cptr=c;
|
||||
yylval.integer=LESYM;
|
||||
return(RELOP);
|
||||
} else
|
||||
if ( *(c+1)=='>'){
|
||||
c++; c++;
|
||||
cptr=c;
|
||||
yylval.integer=NESYM;
|
||||
return(RELOP);
|
||||
}
|
||||
yylval.integer= '<';
|
||||
cptr++;
|
||||
return(RELOP);
|
||||
}
|
||||
return(*cptr++);
|
||||
}
|
54
lang/basic/src/bem.c
Normal file
54
lang/basic/src/bem.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#include "bem.h"
|
||||
|
||||
#ifndef NORSCID
|
||||
static char rcs_id[] = "$Header$" ;
|
||||
static char rcs_bem[] = RCS_BEM ;
|
||||
static char rcs_symb[] = RCS_SYMB ;
|
||||
static char rcs_graph[] = RCS_GRAPH ;
|
||||
#endif
|
||||
|
||||
/* Author: M.L. Kersten
|
||||
**
|
||||
** This is the main routine for the BASIC-EM frontend.
|
||||
** Program parameters are decoded, the BASIC program is parsed
|
||||
** and compiled to an executable program
|
||||
**
|
||||
** Bem expects at least three parameters. One ending with '.i' is considered
|
||||
** the input to the compiler, '.e' denotes the file to be generated,
|
||||
** and the last name denotes the name of the user supplied file name.
|
||||
** The latter is used to store the data entries.
|
||||
** Additional flags may be supplied, see parseparms.
|
||||
*/
|
||||
|
||||
char *program;
|
||||
|
||||
char datfname[MAXFILENAME] ;
|
||||
char tmpfname[MAXFILENAME] ;
|
||||
|
||||
char *inpfile, *outfile;
|
||||
int BEMINTSIZE = EMINTSIZE;
|
||||
int BEMPTRSIZE = EMPTRSIZE;
|
||||
int BEMFLTSIZE = EMFLTSIZE;
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
extern int errorcnt;
|
||||
|
||||
/* parseparams */
|
||||
parseparams(argc,argv);
|
||||
/* initialize the system */
|
||||
initialize();
|
||||
/* compile source programs */
|
||||
compileprogram();
|
||||
linewarnings();
|
||||
C_close();
|
||||
if( errorcnt) sys_stop(S_EXIT);
|
||||
/* process em object files */
|
||||
sys_stop(S_END); /* This was not done in the old compiler */
|
||||
}
|
79
lang/basic/src/bem.h
Normal file
79
lang/basic/src/bem.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <system.h>
|
||||
#include <em.h>
|
||||
#include <em_mes.h>
|
||||
|
||||
/* Author: M.L. Kersten
|
||||
** Here all the global objects are defined.
|
||||
*/
|
||||
#include "symbols.h"
|
||||
#include "graph.h"
|
||||
#include "Lpars.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
# define RCS_BEM "$Header$"
|
||||
#endif
|
||||
|
||||
#define MAXINT 32768
|
||||
#define MININT -32767
|
||||
/* #define EMINTSIZE "EM_WSIZE" */
|
||||
/* #define EMPTRSIZE "EM_PSIZE" */
|
||||
/* #define EMFLTSIZE "EM_DSIZE" */
|
||||
|
||||
#define EMINTSIZE 4
|
||||
#define EMPTRSIZE 4
|
||||
#define EMFLTSIZE 8
|
||||
|
||||
#define MAXPIECES 100
|
||||
#define MAXFILENAME 200
|
||||
|
||||
#define CHANNEL 0
|
||||
#define THRESHOLD 40 /* for splitting blocks */
|
||||
|
||||
#define void int /* Some C compilers don't know void */
|
||||
|
||||
extern int BEMINTSIZE, BEMPTRSIZE, BEMFLTSIZE;
|
||||
extern char *program; /* name of source program */
|
||||
extern char *inpfile; /* input tko compiler */
|
||||
extern char *outfile; /* output from compiler */
|
||||
|
||||
extern char datfname[MAXFILENAME]; /* data statements file */
|
||||
extern char tmpfname[MAXFILENAME]; /* temporary statements file */
|
||||
|
||||
extern File *emfile; /* EM output file */
|
||||
extern File *datfile; /* data file */
|
||||
extern File *tmp_file; /* compiler temporary */
|
||||
extern File *yyin; /* Compiler input */
|
||||
|
||||
extern int endofinput;
|
||||
extern int wflag;
|
||||
extern int hflag;
|
||||
extern int traceflag;
|
||||
extern int yydebug;
|
||||
extern int yylineno;
|
||||
extern int listing;
|
||||
extern int nolins;
|
||||
extern int threshold;
|
||||
extern int debug;
|
||||
extern int tronoff;
|
||||
extern label err_goto_label;
|
||||
|
||||
extern int dataused;
|
||||
|
||||
extern Linerecord *currline;
|
||||
|
||||
|
||||
extern char *itoa();
|
||||
extern char *salloc();
|
||||
|
||||
extern char *sprintf();
|
||||
extern char *strcpy();
|
||||
extern char *strcat();
|
||||
extern char *malloc();
|
30
lang/basic/src/compile.c
Normal file
30
lang/basic/src/compile.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#include "bem.h"
|
||||
|
||||
#ifndef NORSCID
|
||||
static char rcs_id[] = "$Header$" ;
|
||||
#endif
|
||||
|
||||
|
||||
/* compile the next program in the list */
|
||||
/* Here we should open the input file. (for the future) */
|
||||
|
||||
File *yyin;
|
||||
|
||||
compileprogram()
|
||||
{
|
||||
extern int basicline;
|
||||
|
||||
prologcode();
|
||||
prolog2(); /* Some statements are moved from prolog2 to
|
||||
epilogcode in the new version of the compiler */
|
||||
|
||||
while( basicline = 0, getline())
|
||||
(void) LLparse();
|
||||
epilogcode();
|
||||
(void) sys_close(yyin);
|
||||
}
|
536
lang/basic/src/eval.c
Normal file
536
lang/basic/src/eval.c
Normal file
|
@ -0,0 +1,536 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#include "bem.h"
|
||||
|
||||
#ifndef NORSCID
|
||||
static char rcs_id[] = "$Header$" ;
|
||||
#endif
|
||||
|
||||
|
||||
/* Here you find all routines to evaluate expressions and
|
||||
generate code for assignment statements
|
||||
*/
|
||||
|
||||
exprtype(ltype,rtype)
|
||||
int ltype,rtype;
|
||||
{
|
||||
/* determine the result type of an expression */
|
||||
if ( ltype==STRINGTYPE || rtype==STRINGTYPE)
|
||||
{
|
||||
if ( ltype!=rtype)
|
||||
error("type conflict, string expected");
|
||||
return( STRINGTYPE);
|
||||
}
|
||||
/* take maximum */
|
||||
if ( ltype<rtype) return(rtype);
|
||||
return(ltype);
|
||||
}
|
||||
|
||||
|
||||
|
||||
conversion(oldtype,newtype)
|
||||
int oldtype,newtype;
|
||||
{
|
||||
/* the value on top of the stack should be converted */
|
||||
if ( oldtype==newtype) return;
|
||||
|
||||
switch( oldtype)
|
||||
{
|
||||
case INTTYPE:
|
||||
if ( newtype==FLOATTYPE || newtype==DOUBLETYPE)
|
||||
{
|
||||
C_loc((arith)BEMINTSIZE);
|
||||
C_loc((arith)BEMFLTSIZE);
|
||||
C_cif ();
|
||||
} else {
|
||||
if (debug)
|
||||
print("type n=%d o=%d\n",newtype,oldtype);
|
||||
error("conversion error");
|
||||
}
|
||||
break;
|
||||
case FLOATTYPE:
|
||||
case DOUBLETYPE:
|
||||
if ( newtype==INTTYPE)
|
||||
{
|
||||
/* rounded ! */
|
||||
C_cal("_cint");
|
||||
C_asp((arith)BEMFLTSIZE);
|
||||
C_lfr((arith)BEMINTSIZE);
|
||||
break;
|
||||
} else if ( newtype==FLOATTYPE || newtype==DOUBLETYPE)
|
||||
break;
|
||||
default:
|
||||
if (debug)
|
||||
print("type n=%d o=%d\n",newtype,oldtype);
|
||||
error("conversion error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extraconvert(oldtype,newtype,topstack)
|
||||
int oldtype,newtype,topstack;
|
||||
{
|
||||
/* the value below the top of the stack should be converted */
|
||||
if ( oldtype==newtype ) return;
|
||||
if ( debug) print("extra convert %d %d %d\n",oldtype,newtype,topstack);
|
||||
/* save top in dummy */
|
||||
|
||||
switch( topstack)
|
||||
{
|
||||
case INTTYPE:
|
||||
C_ste_dnam("dummy1",(arith)0);
|
||||
break;
|
||||
case FLOATTYPE:
|
||||
case DOUBLETYPE:
|
||||
/* rounded ! */
|
||||
C_lae_dnam("dummy1",(arith)0);
|
||||
C_sti((arith)BEMFLTSIZE);
|
||||
break;
|
||||
default:
|
||||
error("conversion error");
|
||||
return;
|
||||
}
|
||||
/* now its on top of the stack */
|
||||
|
||||
conversion(oldtype,newtype);
|
||||
/* restore top */
|
||||
|
||||
switch( topstack)
|
||||
{
|
||||
case INTTYPE:
|
||||
C_loe_dnam("dummy1",(arith)0);
|
||||
break;
|
||||
case FLOATTYPE:
|
||||
case DOUBLETYPE:
|
||||
/* rounded ! */
|
||||
C_lae_dnam("dummy1",(arith)0);
|
||||
C_loi((arith)BEMFLTSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolop(ltype,rtype,operator)
|
||||
int ltype,rtype,operator;
|
||||
{
|
||||
if ( operator != NOTSYM)
|
||||
{
|
||||
extraconvert(ltype,INTTYPE,rtype);
|
||||
conversion(rtype,INTTYPE);
|
||||
} else conversion(ltype,INTTYPE);
|
||||
|
||||
switch( operator)
|
||||
{
|
||||
case NOTSYM:
|
||||
C_com((arith)BEMINTSIZE);
|
||||
break;
|
||||
case ANDSYM:
|
||||
C_and((arith)BEMINTSIZE);
|
||||
break;
|
||||
case ORSYM:
|
||||
C_ior((arith)BEMINTSIZE);
|
||||
break;
|
||||
case XORSYM:
|
||||
C_xor((arith)BEMINTSIZE);
|
||||
break;
|
||||
case EQVSYM:
|
||||
C_xor((arith)BEMINTSIZE);
|
||||
C_com((arith)BEMINTSIZE);
|
||||
break;
|
||||
case IMPSYM:
|
||||
/* implies */
|
||||
C_com((arith)BEMINTSIZE);
|
||||
C_and((arith)BEMINTSIZE);
|
||||
C_com((arith)BEMINTSIZE);
|
||||
break;
|
||||
default:
|
||||
error("boolop:unexpected");
|
||||
}
|
||||
|
||||
return(INTTYPE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
genbool(operator)
|
||||
int operator;
|
||||
{
|
||||
int l1,l2;
|
||||
|
||||
l1= genlabel();
|
||||
l2= genlabel();
|
||||
|
||||
switch(operator)
|
||||
{
|
||||
case '<': C_zlt((label)l1); break;
|
||||
case '>': C_zgt((label)l1); break;
|
||||
case '=': C_zeq((label)l1); break;
|
||||
case NESYM: C_zne((label)l1); break;
|
||||
case LESYM: C_zle((label)l1); break;
|
||||
case GESYM: C_zge((label)l1); break;
|
||||
default: error("relop:unexpected operator");
|
||||
}
|
||||
|
||||
C_loc((arith)0);
|
||||
C_bra((label)l2);
|
||||
C_df_ilb((label)l1);
|
||||
C_loc((arith)-1);
|
||||
C_df_ilb((label)l2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
relop( ltype,rtype,operator)
|
||||
int ltype,rtype,operator;
|
||||
{
|
||||
int result;
|
||||
|
||||
if (debug) print("relop %d %d op=%d\n",ltype,rtype,operator);
|
||||
result= exprtype(ltype,rtype);
|
||||
extraconvert(ltype,result,rtype);
|
||||
conversion(rtype,result);
|
||||
/* compare the objects */
|
||||
if ( result==INTTYPE)
|
||||
C_cmi((arith)BEMINTSIZE);
|
||||
else if ( result==FLOATTYPE || result==DOUBLETYPE)
|
||||
C_cmf((arith)BEMFLTSIZE);
|
||||
else if ( result==STRINGTYPE)
|
||||
{
|
||||
C_cal("_strcomp");
|
||||
C_asp((arith)(2*BEMPTRSIZE));
|
||||
C_lfr((arith)BEMINTSIZE);
|
||||
} else error("relop:unexpected");
|
||||
/* handle the relational operators */
|
||||
genbool(operator);
|
||||
return(INTTYPE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
plusmin(ltype,rtype,operator)
|
||||
int ltype,rtype,operator;
|
||||
{
|
||||
int result;
|
||||
|
||||
result= exprtype(ltype,rtype);
|
||||
if ( result== STRINGTYPE)
|
||||
{
|
||||
if ( operator== '+')
|
||||
{
|
||||
C_cal("_concat");
|
||||
C_asp((arith)(2*BEMPTRSIZE));
|
||||
C_lfr((arith)BEMPTRSIZE);
|
||||
} else error("illegal operator");
|
||||
} else {
|
||||
extraconvert(ltype,result,rtype);
|
||||
conversion(rtype,result);
|
||||
if ( result== INTTYPE)
|
||||
{
|
||||
if ( operator=='+')
|
||||
C_adi((arith)BEMINTSIZE);
|
||||
else C_sbi((arith)BEMINTSIZE);
|
||||
} else {
|
||||
if ( operator=='+')
|
||||
C_adf((arith)BEMFLTSIZE);
|
||||
else C_sbf((arith)BEMFLTSIZE);
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
muldiv(ltype,rtype,operator)
|
||||
int ltype,rtype,operator;
|
||||
{
|
||||
int result;
|
||||
|
||||
result=exprtype(ltype,rtype);
|
||||
if (operator==MODSYM || operator== '\\') result=INTTYPE;
|
||||
extraconvert(ltype,result,rtype);
|
||||
conversion(rtype,result);
|
||||
if ( result== INTTYPE)
|
||||
{
|
||||
if ( operator=='/')
|
||||
{
|
||||
result=DOUBLETYPE;
|
||||
extraconvert(ltype,result,rtype);
|
||||
conversion(rtype,result);
|
||||
C_dvf((arith)BEMFLTSIZE);
|
||||
} else
|
||||
if ( operator=='\\')
|
||||
C_dvi((arith)BEMINTSIZE);
|
||||
else
|
||||
if ( operator=='*')
|
||||
C_mli((arith)BEMINTSIZE);
|
||||
else
|
||||
if ( operator==MODSYM)
|
||||
C_rmi((arith)BEMINTSIZE);
|
||||
else error("illegal operator");
|
||||
} else {
|
||||
if ( operator=='/')
|
||||
C_dvf((arith)BEMFLTSIZE);
|
||||
else
|
||||
if ( operator=='*')
|
||||
C_mlf((arith)BEMFLTSIZE);
|
||||
else error("illegal operator");
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
negate(type)
|
||||
int type;
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case INTTYPE:
|
||||
C_ngi((arith)BEMINTSIZE);
|
||||
break;
|
||||
case DOUBLETYPE:
|
||||
case FLOATTYPE:
|
||||
C_ngf((arith)BEMFLTSIZE);
|
||||
break;
|
||||
default:
|
||||
error("Illegal operator");
|
||||
}
|
||||
return(type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef ___
|
||||
power(ltype,rtype)
|
||||
int ltype,rtype;
|
||||
{
|
||||
int resulttype = exprtype(ltype, rtype);
|
||||
|
||||
extraconvert(ltype,resulttype,rtype);
|
||||
conversion(rtype,resulttype);
|
||||
switch(resulttype) {
|
||||
case INTTYPE:
|
||||
C_cal("_ipower");
|
||||
break;
|
||||
case DOUBLETYPE:
|
||||
case FLOATTYPE:
|
||||
C_cal("_power");
|
||||
break;
|
||||
default:
|
||||
error("Illegal operator");
|
||||
}
|
||||
C_asp((arith)(2*typestring(resulttype)));
|
||||
C_lfr((arith)typestring(resulttype));
|
||||
return(resulttype);
|
||||
}
|
||||
#else
|
||||
power(ltype,rtype)
|
||||
int ltype,rtype;
|
||||
{
|
||||
extraconvert(ltype,DOUBLETYPE,rtype);
|
||||
conversion(rtype,DOUBLETYPE);
|
||||
C_cal("_power");
|
||||
C_asp((arith)(2*BEMFLTSIZE));
|
||||
C_lfr((arith)BEMFLTSIZE);
|
||||
return(DOUBLETYPE);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int typesize(ltype)
|
||||
int ltype;
|
||||
{
|
||||
switch( ltype)
|
||||
{
|
||||
case INTTYPE:
|
||||
return(BEMINTSIZE);
|
||||
case FLOATTYPE:
|
||||
case DOUBLETYPE:
|
||||
return(BEMFLTSIZE);
|
||||
case STRINGTYPE:
|
||||
return(BEMPTRSIZE);
|
||||
default:
|
||||
error("typesize:unexpected");
|
||||
if (debug) print("type received %d\n",ltype);
|
||||
}
|
||||
return(BEMINTSIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int typestring(type)
|
||||
int type;
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case INTTYPE:
|
||||
return(BEMINTSIZE);
|
||||
case FLOATTYPE:
|
||||
case DOUBLETYPE:
|
||||
return(BEMFLTSIZE);
|
||||
case STRINGTYPE:
|
||||
return(BEMPTRSIZE);
|
||||
default:
|
||||
error("typestring: unexpected type");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
loadvar(type)
|
||||
int type;
|
||||
{
|
||||
/* load a simple variable its address is on the stack*/
|
||||
C_loi((arith)typestring(type));
|
||||
}
|
||||
|
||||
|
||||
|
||||
loadint(value)
|
||||
int value;
|
||||
{
|
||||
C_loc((arith)value);
|
||||
return(INTTYPE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
loaddbl(value)
|
||||
char *value;
|
||||
{
|
||||
int index;
|
||||
|
||||
index=genlabel();
|
||||
C_df_dlb((label)index);
|
||||
C_bss_fcon((arith)BEMFLTSIZE,value,(arith)BEMFLTSIZE,1);
|
||||
C_lae_dlb((label)index,(arith)0);
|
||||
C_loi((arith)BEMFLTSIZE);
|
||||
return(DOUBLETYPE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
loadstr(value)
|
||||
int value;
|
||||
{
|
||||
C_lae_dlb((label)value,(arith)0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
loadaddr(s)
|
||||
Symbol *s;
|
||||
{
|
||||
extern Symbol *fcn;
|
||||
int i,j;
|
||||
arith sum;
|
||||
|
||||
if (debug) print("load %s %d\n",s->symname,s->symtype);
|
||||
if ( s->symalias>0)
|
||||
C_lae_dlb((label)s->symalias,(arith)0);
|
||||
else {
|
||||
j= -s->symalias;
|
||||
if (debug) print("load parm %d\n",j);
|
||||
/* first count the sizes. */
|
||||
sum = 0;
|
||||
for(i=fcn->dimensions;i>j;i--)
|
||||
sum += typesize(fcn->dimlimit[i-1]);
|
||||
C_lal(sum);
|
||||
}
|
||||
return(s->symtype);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This is a new routine */
|
||||
save_address()
|
||||
{
|
||||
C_lae_dnam("dummy3",(arith)0);
|
||||
C_sti((arith)BEMPTRSIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
assign(type,lt)
|
||||
int type,lt;
|
||||
{
|
||||
extern int e1,e2;
|
||||
|
||||
conversion(lt,type);
|
||||
C_lae_dnam("dummy3",(arith)0); /* Statement added by us */
|
||||
C_loi((arith)BEMPTRSIZE);
|
||||
/* address is on stack already */
|
||||
C_sti((arith)typestring(type));
|
||||
}
|
||||
|
||||
|
||||
|
||||
storevar(lab,type)
|
||||
int lab,type;
|
||||
{
|
||||
/*store value back */
|
||||
C_lae_dlb((label)lab,(arith)0);
|
||||
C_sti((arith)typestring(type));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* maintain a stack of array references */
|
||||
int dimstk[MAXDIMENSIONS], dimtop= -1;
|
||||
Symbol *arraystk[MAXDIMENSIONS];
|
||||
|
||||
|
||||
|
||||
newarrayload(s)
|
||||
Symbol *s;
|
||||
{
|
||||
if ( dimtop<MAXDIMENSIONS) dimtop++;
|
||||
if ( s->dimensions==0)
|
||||
{
|
||||
s->dimensions=1;
|
||||
defarray(s);
|
||||
}
|
||||
dimstk[dimtop]= 0;
|
||||
arraystk[dimtop]= s;
|
||||
C_lae_dlb((label)s->symalias,(arith)0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
endarrayload()
|
||||
{
|
||||
return(arraystk[dimtop--]->symtype);
|
||||
}
|
||||
|
||||
|
||||
|
||||
loadarray(type)
|
||||
int type;
|
||||
{
|
||||
int dim;
|
||||
Symbol *s;
|
||||
|
||||
if ( dimtop<0 || dimtop>=MAXDIMENSIONS)
|
||||
fatal("too many nested array references");
|
||||
/* index expression is on top of stack */
|
||||
s=arraystk[dimtop];
|
||||
dim= dimstk[dimtop];
|
||||
if ( dim>=s->dimensions)
|
||||
{
|
||||
error("too many indices");
|
||||
dimstk[dimtop]=0;
|
||||
return;
|
||||
}
|
||||
conversion(type,INTTYPE);
|
||||
C_lae_dlb((label)s->dimalias[dim],(arith)0);
|
||||
C_aar((arith)BEMINTSIZE);
|
||||
dimstk[dimtop]++;
|
||||
}
|
||||
|
||||
|
||||
|
269
lang/basic/src/func.c
Normal file
269
lang/basic/src/func.c
Normal file
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#include "bem.h"
|
||||
|
||||
#ifndef NORSCID
|
||||
static char rcs_id[] = "$Header$" ;
|
||||
#endif
|
||||
|
||||
|
||||
/* expression types for predefined functions are assembled */
|
||||
int typetable[10];
|
||||
int exprlimit;
|
||||
|
||||
/* handle all predefined functions */
|
||||
#define cv(X) conversion(type,X); pop=X
|
||||
|
||||
|
||||
|
||||
parm(cnt)
|
||||
int cnt;
|
||||
{
|
||||
if( cnt> exprlimit)
|
||||
error("Not enough arguments");
|
||||
if( cnt < exprlimit)
|
||||
error("Too many arguments");
|
||||
}
|
||||
|
||||
|
||||
|
||||
callfcn(fcnnr,cnt,typetable)
|
||||
int fcnnr,cnt;
|
||||
int *typetable;
|
||||
{
|
||||
int pop=DOUBLETYPE;
|
||||
int res=DOUBLETYPE;
|
||||
int type;
|
||||
|
||||
|
||||
type= typetable[0];
|
||||
exprlimit=cnt;
|
||||
if(debug) print("fcn=%d\n",fcnnr);
|
||||
|
||||
switch(fcnnr)
|
||||
{
|
||||
case ABSSYM: cv(DOUBLETYPE);
|
||||
C_cal("_abr");
|
||||
parm(1);
|
||||
break;
|
||||
case ASCSYM: cv(STRINGTYPE);
|
||||
C_cal("_asc");
|
||||
res=INTTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case ATNSYM: cv(DOUBLETYPE);
|
||||
C_cal("_atn");
|
||||
parm(1);
|
||||
break;
|
||||
case CDBLSYM: cv(DOUBLETYPE);
|
||||
return(DOUBLETYPE);;
|
||||
case CHRSYM: cv(INTTYPE);
|
||||
C_cal("_chr");
|
||||
res=STRINGTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case CSNGSYM: cv(DOUBLETYPE);
|
||||
return(DOUBLETYPE);
|
||||
case CINTSYM: cv(INTTYPE);
|
||||
return(INTTYPE);
|
||||
case COSSYM: cv(DOUBLETYPE);
|
||||
C_cal("_cos");
|
||||
parm(1);
|
||||
break;
|
||||
case CVISYM: cv(STRINGTYPE);
|
||||
C_cal("_cvi");
|
||||
res=INTTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case CVSSYM: cv(STRINGTYPE);
|
||||
C_cal("_cvd");
|
||||
res=DOUBLETYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case CVDSYM: cv(STRINGTYPE);
|
||||
C_cal("_cvd");
|
||||
res=DOUBLETYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case EOFSYM:
|
||||
if( cnt==0)
|
||||
{
|
||||
res= INTTYPE;
|
||||
pop= INTTYPE;
|
||||
C_loc((arith) -1);
|
||||
} else cv(INTTYPE);
|
||||
C_cal("_ioeof");
|
||||
res=INTTYPE;
|
||||
break;
|
||||
case EXPSYM: cv(DOUBLETYPE);
|
||||
C_cal("_exp");
|
||||
parm(1);
|
||||
break;
|
||||
case FIXSYM: cv(DOUBLETYPE);
|
||||
C_cal("_fix");
|
||||
res=INTTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case INPSYM:
|
||||
case LPOSSYM:
|
||||
case FRESYM: pop=0;
|
||||
warning("function not supported");
|
||||
parm(1);
|
||||
break;
|
||||
case HEXSYM: cv(INTTYPE);
|
||||
C_cal("_hex"); res=STRINGTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case OUTSYM:
|
||||
case INSTRSYM: cv(DOUBLETYPE);
|
||||
C_cal("_instr");
|
||||
res=STRINGTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case INTSYM: cv(DOUBLETYPE);
|
||||
C_cal("_fcint");
|
||||
parm(1);
|
||||
break;
|
||||
case LEFTSYM: parm(2);
|
||||
extraconvert(type, STRINGTYPE,typetable[1]);
|
||||
type= typetable[1];
|
||||
cv(INTTYPE);
|
||||
C_cal("_left");
|
||||
res=STRINGTYPE;
|
||||
C_asp((arith) BEMPTRSIZE);
|
||||
C_asp((arith) BEMINTSIZE);
|
||||
C_lfr((arith) BEMPTRSIZE);
|
||||
return(STRINGTYPE);
|
||||
case LENSYM: cv(STRINGTYPE);
|
||||
C_cal("_len");
|
||||
res=INTTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case LOCSYM: cv(INTTYPE);
|
||||
C_cal("_loc");
|
||||
res=INTTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case LOGSYM: cv(DOUBLETYPE);
|
||||
C_cal("_log");
|
||||
parm(1);
|
||||
break;
|
||||
case MKISYM: cv(INTTYPE);
|
||||
C_cal("_mki");
|
||||
res=STRINGTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case MKSSYM: cv(DOUBLETYPE);
|
||||
C_cal("_mkd");
|
||||
res=STRINGTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case MKDSYM: cv(DOUBLETYPE);
|
||||
C_cal("_mkd");
|
||||
res=STRINGTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case OCTSYM: cv(INTTYPE);
|
||||
C_cal("_oct");
|
||||
res=STRINGTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case PEEKSYM: cv(INTTYPE);
|
||||
C_cal("_peek");
|
||||
res=INTTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case POSSYM: C_asp((arith) typestring(type));
|
||||
C_exa_dnam("_pos");
|
||||
C_loe_dnam("_pos",(arith) 0);
|
||||
return(INTTYPE);
|
||||
case RIGHTSYM: parm(2);
|
||||
extraconvert(type, STRINGTYPE,typetable[1]);
|
||||
type= typetable[1];
|
||||
cv(INTTYPE);
|
||||
C_cal("_right");
|
||||
res=STRINGTYPE;
|
||||
C_asp((arith) BEMINTSIZE);
|
||||
C_asp((arith) BEMPTRSIZE);
|
||||
C_lfr((arith) BEMPTRSIZE);
|
||||
return(STRINGTYPE);
|
||||
case RNDSYM: if( cnt==1) pop=type;
|
||||
else pop=0;
|
||||
C_cal("_rnd");
|
||||
res= DOUBLETYPE;
|
||||
break;
|
||||
case SGNSYM: cv(DOUBLETYPE);
|
||||
C_cal("_sgn");
|
||||
res=INTTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case SINSYM: cv(DOUBLETYPE);
|
||||
C_cal("_sin");
|
||||
parm(1);
|
||||
break;
|
||||
case SPACESYM: cv(INTTYPE);
|
||||
C_cal("_space");
|
||||
res=STRINGTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case SPCSYM: cv(INTTYPE);
|
||||
C_cal("_spc");
|
||||
res=0;
|
||||
parm(1);
|
||||
break;
|
||||
case SQRSYM: cv(DOUBLETYPE);
|
||||
C_cal("_sqt");
|
||||
parm(1);
|
||||
break;
|
||||
case STRSYM: cv(DOUBLETYPE);
|
||||
C_cal("_nstr");
|
||||
res=STRINGTYPE; /* NEW */
|
||||
parm(1);
|
||||
break;
|
||||
case STRINGSYM:
|
||||
parm(2); /* 2 is NEW */
|
||||
if (typetable[1] == STRINGTYPE) {
|
||||
C_cal("_asc");
|
||||
C_asp((arith)BEMPTRSIZE);
|
||||
C_lfr((arith)BEMINTSIZE);
|
||||
typetable[1] = INTTYPE;
|
||||
}
|
||||
extraconvert(type,
|
||||
DOUBLETYPE,
|
||||
typetable[1]); /* NEW */
|
||||
type= typetable[1];
|
||||
cv(DOUBLETYPE); /* NEW */
|
||||
C_cal("_string");
|
||||
res=STRINGTYPE;
|
||||
C_asp((arith)typestring(DOUBLETYPE)); /*NEW*/
|
||||
break;
|
||||
case TABSYM: cv(INTTYPE);
|
||||
C_cal("_tab");
|
||||
res=0;
|
||||
parm(1);
|
||||
break;
|
||||
case TANSYM: cv(DOUBLETYPE);
|
||||
C_cal("_tan");
|
||||
parm(1);
|
||||
break;
|
||||
case VALSYM: cv(STRINGTYPE);
|
||||
C_loi((arith)BEMPTRSIZE);
|
||||
C_cal("atoi");
|
||||
res=INTTYPE;
|
||||
parm(1);
|
||||
break;
|
||||
case VARPTRSYM: cv(DOUBLETYPE);
|
||||
C_cal("_valptr");
|
||||
parm(1);
|
||||
break;
|
||||
default: error("unknown function");
|
||||
}
|
||||
|
||||
if(pop) C_asp((arith) typestring(pop));
|
||||
if(res) C_lfr((arith) typestring(res));
|
||||
return(res);
|
||||
}
|
||||
|
704
lang/basic/src/gencode.c
Normal file
704
lang/basic/src/gencode.c
Normal file
|
@ -0,0 +1,704 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#include "bem.h"
|
||||
|
||||
#ifndef NORSCID
|
||||
static char rcs_id[] = "$Header$" ;
|
||||
#endif
|
||||
|
||||
|
||||
/* Here we find all routines dealing with pure EM code generation */
|
||||
|
||||
static int emlabel=1;
|
||||
label err_goto_label;
|
||||
|
||||
|
||||
|
||||
genlabel()
|
||||
{
|
||||
return(emlabel++);
|
||||
}
|
||||
|
||||
|
||||
|
||||
genemlabel()
|
||||
{
|
||||
int l;
|
||||
|
||||
l=genlabel();
|
||||
C_df_dlb((label)l);
|
||||
return(l);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int tronoff=0;
|
||||
newemblock(nr)
|
||||
int nr;
|
||||
{
|
||||
C_df_ilb((label)currline->emlabel);
|
||||
C_lin((arith)nr);
|
||||
if ( tronoff || traceflag) {
|
||||
C_loc((arith)nr);
|
||||
C_cal("_trace");
|
||||
C_asp((arith)BEMINTSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Handle data statements */
|
||||
List *datalist=0;
|
||||
datastmt()
|
||||
{
|
||||
List *l,*l1;
|
||||
|
||||
/* NOSTRICT */ l= (List *) salloc(sizeof(List));
|
||||
l->linenr= currline->linenr;
|
||||
l->emlabel = sys_filesize(datfname);
|
||||
if ( datalist==0)
|
||||
{
|
||||
datalist=l;
|
||||
} else {
|
||||
l1= datalist;
|
||||
while (l1->nextlist) l1= l1->nextlist;
|
||||
l1->nextlist=l;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
datatable()
|
||||
{
|
||||
List *l;
|
||||
int line=0;
|
||||
|
||||
/* called at end to generate the data seek table */
|
||||
C_exa_dnam("_seektab");
|
||||
C_df_dnam("_seektab"); /* VRAAGTEKEN */
|
||||
l= datalist;
|
||||
while (l)
|
||||
{
|
||||
C_rom_cst((arith)(l->linenr));
|
||||
C_rom_cst((arith)(line++));
|
||||
l= l->nextlist;
|
||||
}
|
||||
C_rom_cst((arith)0);
|
||||
C_rom_cst((arith)0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ERROR and exception handling */
|
||||
exceptstmt(lab)
|
||||
int lab;
|
||||
{
|
||||
/* exceptions to subroutines are supported only */
|
||||
extern int gosubcnt;
|
||||
List *l;
|
||||
|
||||
C_loc((arith)gosubcnt);
|
||||
l= (List *) gosublabel();
|
||||
l->emlabel= gotolabel(lab);
|
||||
C_cal("_trpset");
|
||||
C_asp((arith)BEMINTSIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
errorstmt(exprtype)
|
||||
int exprtype;
|
||||
{
|
||||
/* convert expression to a valid error number */
|
||||
/* obtain the message and print it */
|
||||
C_cal("error");
|
||||
C_asp((arith)typesize(exprtype));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* BASIC IO */
|
||||
openstmt(recsize)
|
||||
int recsize;
|
||||
{
|
||||
C_loc((arith)recsize);
|
||||
C_cal("_opnchn");
|
||||
C_asp((arith)(2*BEMPTRSIZE+BEMINTSIZE));
|
||||
}
|
||||
|
||||
|
||||
|
||||
printstmt(exprtype)
|
||||
int exprtype;
|
||||
{
|
||||
switch(exprtype)
|
||||
{
|
||||
case INTTYPE:
|
||||
C_cal("_prinum");
|
||||
C_asp((arith)typestring(INTTYPE));
|
||||
break;
|
||||
case FLOATTYPE:
|
||||
case DOUBLETYPE:
|
||||
C_cal("_prfnum");
|
||||
C_asp((arith)typestring(DOUBLETYPE));
|
||||
break;
|
||||
case STRINGTYPE:
|
||||
C_cal("_prstr");
|
||||
C_asp((arith)BEMPTRSIZE);
|
||||
break;
|
||||
case 0: /* result of tab function etc */
|
||||
break;
|
||||
default:
|
||||
error("printstmt:unexpected");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
zone(i)
|
||||
int i;
|
||||
{
|
||||
if ( i) C_cal("_zone");
|
||||
}
|
||||
|
||||
|
||||
|
||||
writestmt(exprtype,comma)
|
||||
int exprtype,comma;
|
||||
{
|
||||
if ( comma) C_cal("_wrcomma");
|
||||
|
||||
switch(exprtype)
|
||||
{
|
||||
case INTTYPE:
|
||||
C_cal("_wrint");
|
||||
break;
|
||||
case FLOATTYPE:
|
||||
case DOUBLETYPE:
|
||||
C_cal("_wrflt");
|
||||
break;
|
||||
case STRINGTYPE:
|
||||
C_cal("_wrstr");
|
||||
break;
|
||||
default:
|
||||
error("printstmt:unexpected");
|
||||
}
|
||||
C_asp((arith)BEMPTRSIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
restore(lab)
|
||||
int lab;
|
||||
{
|
||||
/* save this information too */
|
||||
|
||||
C_loc((arith)0);
|
||||
C_cal("_setchan");
|
||||
C_asp((arith)BEMINTSIZE);
|
||||
C_loc((arith)lab);
|
||||
C_cal("_restore");
|
||||
C_asp((arith)BEMINTSIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
prompt(qst)
|
||||
int qst;
|
||||
{
|
||||
setchannel(-1);
|
||||
C_cal("_prstr");
|
||||
C_asp((arith)BEMPTRSIZE);
|
||||
if (qst) C_cal("_qstmark");
|
||||
}
|
||||
|
||||
|
||||
|
||||
linestmt(type)
|
||||
int type;
|
||||
{
|
||||
if ( type!= STRINGTYPE)
|
||||
error("String variable expected");
|
||||
C_cal("_rdline");
|
||||
C_asp((arith)BEMPTRSIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
readelm(type)
|
||||
int type;
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case INTTYPE:
|
||||
C_cal("_readint");
|
||||
break;
|
||||
case FLOATTYPE:
|
||||
case DOUBLETYPE:
|
||||
C_cal("_readflt");
|
||||
break;
|
||||
case STRINGTYPE:
|
||||
C_cal("_readstr");
|
||||
break;
|
||||
default:
|
||||
error("readelm:unexpected type");
|
||||
}
|
||||
C_asp((arith)BEMPTRSIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Swap exchanges the variable values */
|
||||
swapstmt(ltype,rtype)
|
||||
int ltype, rtype;
|
||||
{
|
||||
if ( ltype!= rtype)
|
||||
error("Type mismatch");
|
||||
else
|
||||
switch(ltype)
|
||||
{
|
||||
case INTTYPE:
|
||||
C_cal("_intswap");
|
||||
break;
|
||||
case FLOATTYPE:
|
||||
case DOUBLETYPE:
|
||||
C_cal("_fltswap");
|
||||
break;
|
||||
case STRINGTYPE:
|
||||
C_cal("_strswap");
|
||||
break;
|
||||
default:
|
||||
error("swap:unexpected");
|
||||
}
|
||||
|
||||
C_asp((arith)(2*BEMPTRSIZE));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* input/output handling */
|
||||
setchannel(val)
|
||||
int val;
|
||||
{ /* obtain file descroption */
|
||||
C_loc((arith)val);
|
||||
C_cal("_setchan");
|
||||
C_asp((arith)BEMINTSIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The if-then-else statements */
|
||||
ifstmt(type)
|
||||
int type;
|
||||
{
|
||||
/* This BASIC follows the True= -1 rule */
|
||||
int nr;
|
||||
|
||||
nr= genlabel();
|
||||
if ( type == INTTYPE)
|
||||
C_zeq((label)nr);
|
||||
else
|
||||
if ( type == FLOATTYPE || type == DOUBLETYPE )
|
||||
{
|
||||
C_lae_dnam("fltnull",(arith)0);
|
||||
C_loi((arith)BEMFLTSIZE);
|
||||
C_cmf((arith)BEMFLTSIZE);
|
||||
C_zeq((label)nr);
|
||||
}
|
||||
else error("Integer or Float expected");
|
||||
|
||||
return(nr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
thenpart( elselab)
|
||||
int elselab;
|
||||
{
|
||||
int nr;
|
||||
|
||||
nr=genlabel();
|
||||
C_bra((label)nr);
|
||||
C_df_ilb((label)elselab);
|
||||
return(nr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
elsepart(lab)int lab;
|
||||
{
|
||||
C_df_ilb((label)lab);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* generate code for the for-statement */
|
||||
#define MAXFORDEPTH 20
|
||||
|
||||
struct FORSTRUCT{
|
||||
Symbol *loopvar; /* loop variable */
|
||||
int initaddress;
|
||||
int limitaddress;
|
||||
int stepaddress;
|
||||
int fortst; /* variable limit test */
|
||||
int forinc; /* variable increment code */
|
||||
int forout; /* end of loop */
|
||||
} fortable[MAXFORDEPTH];
|
||||
|
||||
int forcnt= -1;
|
||||
|
||||
|
||||
|
||||
forinit(s)
|
||||
Symbol *s;
|
||||
{
|
||||
int type;
|
||||
struct FORSTRUCT *f;
|
||||
|
||||
dcltype(s);
|
||||
type= s->symtype;
|
||||
forcnt++;
|
||||
if ( (type!=INTTYPE && type!=FLOATTYPE && type!=DOUBLETYPE) ||
|
||||
s->dimensions)
|
||||
error("Illegal loop variable");
|
||||
if ( forcnt >=MAXFORDEPTH)
|
||||
error("too many for statements");
|
||||
else {
|
||||
f=fortable+forcnt;
|
||||
f->loopvar=s;
|
||||
f->fortst=genlabel();
|
||||
f->forinc=genlabel();
|
||||
f->forout=genlabel();
|
||||
/* generate space for temporary objects */
|
||||
f->initaddress= dclspace(type);
|
||||
f->limitaddress= dclspace(type);
|
||||
f->stepaddress= dclspace(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
forexpr(type)
|
||||
int type;
|
||||
{
|
||||
/* save start value of loop variable in a save place*/
|
||||
/* to avoid clashing with final value and step expression */
|
||||
int result;
|
||||
|
||||
result= fortable[forcnt].loopvar->symtype;
|
||||
conversion(type,result);
|
||||
storevar(fortable[forcnt].initaddress, result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
forlimit(type)
|
||||
int type;
|
||||
{
|
||||
/* save the limit value too*/
|
||||
int result;
|
||||
|
||||
result= fortable[forcnt].loopvar->symtype;
|
||||
conversion(type,result);
|
||||
storevar(fortable[forcnt].limitaddress, result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
forskipped(f)
|
||||
struct FORSTRUCT *f;
|
||||
{
|
||||
int type;
|
||||
|
||||
type= f->loopvar->symtype;
|
||||
/* evaluate lower bound times sign of step */
|
||||
C_lae_dlb((label)f->initaddress,(arith)0);
|
||||
loadvar(type);
|
||||
conversion(type,DOUBLETYPE);
|
||||
C_lae_dlb((label)f->stepaddress,(arith)0);
|
||||
loadvar(type);
|
||||
conversion(type,DOUBLETYPE);
|
||||
C_cal("_forsgn");
|
||||
C_asp((arith)BEMFLTSIZE);
|
||||
C_lfr((arith)BEMINTSIZE);
|
||||
conversion(INTTYPE,DOUBLETYPE);
|
||||
C_mlf((arith)BEMFLTSIZE);
|
||||
/* evaluate higher bound times sign of step */
|
||||
C_lae_dlb((label)f->limitaddress,(arith)0);
|
||||
loadvar(type);
|
||||
conversion(type,DOUBLETYPE);
|
||||
C_lae_dlb((label)f->stepaddress,(arith)0);
|
||||
loadvar(type);
|
||||
conversion(type,DOUBLETYPE);
|
||||
C_cal("_forsgn");
|
||||
C_asp((arith)BEMFLTSIZE);
|
||||
C_lfr((arith)BEMINTSIZE);
|
||||
conversion(INTTYPE,DOUBLETYPE);
|
||||
C_mlf((arith)BEMFLTSIZE);
|
||||
/* skip condition */
|
||||
C_cmf((arith)BEMFLTSIZE);
|
||||
C_zgt((label)f->forout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
forstep(type)
|
||||
int type;
|
||||
{
|
||||
int result;
|
||||
int varaddress;
|
||||
struct FORSTRUCT *f;
|
||||
|
||||
f= fortable+forcnt;
|
||||
result= f->loopvar->symtype;
|
||||
varaddress= f->loopvar->symalias;
|
||||
conversion(type,result);
|
||||
storevar(f->stepaddress, result);
|
||||
/* all information available, generate for-loop head */
|
||||
/* test for ingoring loop */
|
||||
forskipped(f);
|
||||
/* set initial value */
|
||||
C_lae_dlb((label)f->initaddress,(arith)0);
|
||||
loadvar(result);
|
||||
C_lae_dlb((label)varaddress,(arith)0);
|
||||
C_sti((arith)typestring(result));
|
||||
C_bra((label)f->fortst);
|
||||
/* increment loop variable */
|
||||
C_df_ilb((label)f->forinc);
|
||||
C_lae_dlb((label)varaddress,(arith)0);
|
||||
loadvar(result);
|
||||
C_lae_dlb((label)f->stepaddress,(arith)0);
|
||||
loadvar(result);
|
||||
if (result == INTTYPE)
|
||||
C_adi((arith)BEMINTSIZE);
|
||||
else C_adf((arith)BEMFLTSIZE);
|
||||
C_lae_dlb((label)varaddress,(arith)0);
|
||||
C_sti((arith)typestring(result));
|
||||
/* test boundary */
|
||||
C_df_ilb((label)f->fortst);
|
||||
C_lae_dlb((label)varaddress,(arith)0);
|
||||
loadvar(result);
|
||||
/* Start of NEW code */
|
||||
C_lae_dlb((label)f->stepaddress,(arith)0);
|
||||
loadvar(result);
|
||||
conversion(result,DOUBLETYPE);
|
||||
C_cal("_forsgn");
|
||||
C_asp((arith)BEMFLTSIZE);
|
||||
C_lfr((arith)BEMINTSIZE);
|
||||
conversion(INTTYPE,result);
|
||||
if ( result == INTTYPE )
|
||||
C_mli((arith)BEMINTSIZE);
|
||||
else C_mlf((arith)BEMFLTSIZE);
|
||||
/* End of NEW code */
|
||||
C_lae_dlb((label)f->limitaddress,(arith)0);
|
||||
loadvar(result);
|
||||
/* Start NEW code */
|
||||
C_lae_dlb((label)f->stepaddress,(arith)0);
|
||||
loadvar(result);
|
||||
conversion(result,DOUBLETYPE);
|
||||
C_cal("_forsgn");
|
||||
C_asp((arith)BEMFLTSIZE);
|
||||
C_lfr((arith)BEMINTSIZE);
|
||||
conversion(INTTYPE,result);
|
||||
if ( result == INTTYPE )
|
||||
C_mli((arith)BEMINTSIZE);
|
||||
else C_mlf((arith)BEMFLTSIZE);
|
||||
/* End NEW code */
|
||||
if (result == INTTYPE)
|
||||
C_cmi((arith)BEMINTSIZE);
|
||||
else C_cmf((arith)BEMFLTSIZE);
|
||||
C_zgt((label)f->forout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nextstmt(s)
|
||||
Symbol *s;
|
||||
{
|
||||
if (forcnt>MAXFORDEPTH || forcnt<0 ||
|
||||
(s && s!= fortable[forcnt].loopvar))
|
||||
error("NEXT without FOR");
|
||||
else {
|
||||
/* address of variable is on top of stack ! */
|
||||
C_bra((label)fortable[forcnt].forinc);
|
||||
C_df_ilb((label)fortable[forcnt].forout);
|
||||
forcnt--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
pokestmt(type1,type2)
|
||||
int type1,type2;
|
||||
{
|
||||
conversion(type1,INTTYPE);
|
||||
conversion(type2,INTTYPE);
|
||||
C_asp((arith)(2*BEMINTSIZE));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* generate code for the while statement */
|
||||
#define MAXDEPTH 20
|
||||
|
||||
int whilecnt, whilelabels[MAXDEPTH][2]; /*0=head,1=out */
|
||||
|
||||
whilestart()
|
||||
{
|
||||
whilecnt++;
|
||||
if ( whilecnt==MAXDEPTH)
|
||||
fatal("too many nestings");
|
||||
/* gendummy label in graph */
|
||||
newblock(-1);
|
||||
whilelabels[whilecnt][0]= currline->emlabel;
|
||||
whilelabels[whilecnt][1]= genlabel();
|
||||
C_df_ilb((label)whilelabels[whilecnt][0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
whiletst(exprtype)
|
||||
int exprtype;
|
||||
{
|
||||
/* test expression type */
|
||||
conversion(exprtype,INTTYPE);
|
||||
C_zeq((label)whilelabels[whilecnt][1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
wend()
|
||||
{
|
||||
if ( whilecnt<1)
|
||||
error("not part of while statement");
|
||||
else {
|
||||
C_bra((label)whilelabels[whilecnt][0]);
|
||||
C_df_ilb((label)whilelabels[whilecnt][1]);
|
||||
whilecnt--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* generate code for the final version */
|
||||
prologcode()
|
||||
{
|
||||
/* generate the EM prolog code */
|
||||
C_df_dnam("fltnull");
|
||||
C_con_cst((arith)0);
|
||||
C_con_cst((arith)0);
|
||||
C_con_cst((arith)0);
|
||||
C_con_cst((arith)0);
|
||||
C_df_dnam("dummy2");
|
||||
C_con_cst((arith)0);
|
||||
C_con_cst((arith)0);
|
||||
C_con_cst((arith)0);
|
||||
C_con_cst((arith)0);
|
||||
/* NEW variable we make */
|
||||
C_df_dnam("dummy3");
|
||||
C_bss_dnam((arith)BEMPTRSIZE,"dummy3",(arith)0,0);
|
||||
C_df_dnam("tronoff");
|
||||
C_con_cst((arith)0);
|
||||
C_df_dnam("dummy1");
|
||||
C_con_cst((arith)0);
|
||||
C_con_cst((arith)0);
|
||||
C_con_cst((arith)0);
|
||||
C_con_cst((arith)0);
|
||||
C_exa_dnam("_iomode");
|
||||
C_df_dnam("_iomode");
|
||||
C_rom_scon("O",(arith)2);
|
||||
C_exa_dnam("_errsym");
|
||||
C_df_dnam("_errsym");
|
||||
C_bss_cst((arith)BEMINTSIZE,(arith)0,1);
|
||||
C_exa_dnam("_erlsym");
|
||||
C_df_dnam("_erlsym");
|
||||
C_bss_cst((arith)BEMINTSIZE,(arith)0,1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
prolog2()
|
||||
{
|
||||
int result;
|
||||
label l = genlabel(), l2;
|
||||
|
||||
err_goto_label = genlabel();
|
||||
C_exp("main");
|
||||
C_pro("main",(arith)0);
|
||||
C_ms_par((arith)0);
|
||||
/* Trap handling */
|
||||
C_cal("_ini_trp");
|
||||
|
||||
l2 = genemlabel();
|
||||
C_rom_ilb(l);
|
||||
C_lae_dlb(l2, (arith) 0);
|
||||
C_loi((arith) BEMPTRSIZE);
|
||||
C_exa_dnam("trpbuf");
|
||||
C_lae_dnam("trpbuf",(arith)0);
|
||||
C_cal("setjmp");
|
||||
C_df_ilb(l);
|
||||
C_asp((arith)(BEMPTRSIZE+BEMPTRSIZE));
|
||||
C_lfr((arith)BEMINTSIZE);
|
||||
C_dup((arith)BEMINTSIZE);
|
||||
C_zeq((label)0);
|
||||
C_lae_dnam("returns",(arith)0);
|
||||
C_csa((arith)BEMINTSIZE);
|
||||
C_df_ilb((label)0);
|
||||
C_asp((arith)BEMINTSIZE);
|
||||
result= sys_open(datfname, OP_WRITE, &datfile);
|
||||
if ( result==0 ) fatal("improper file creation permission");
|
||||
gendata();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* NEW */
|
||||
gendata()
|
||||
{
|
||||
C_loc((arith)0);
|
||||
C_cal("_setchan");
|
||||
C_asp((arith)BEMINTSIZE);
|
||||
C_df_dnam("datfname");
|
||||
C_rom_scon(datfname,(arith)strlen(datfname) + 1); /* EHB */
|
||||
C_df_dnam("dattyp");
|
||||
C_rom_scon("i\\0",(arith)4);
|
||||
C_df_dnam("datfdes");
|
||||
C_rom_dnam("datfname",(arith)0);
|
||||
C_rom_cst((arith)1);
|
||||
C_rom_cst((arith)(itoa(strlen(datfname))));
|
||||
C_df_dnam("dattdes");
|
||||
C_rom_dnam("dattyp",(arith)0);
|
||||
C_rom_cst((arith)1);
|
||||
C_rom_cst((arith)1);
|
||||
C_lae_dnam("dattdes",(arith)0);
|
||||
C_lae_dnam("datfdes",(arith)0);
|
||||
C_loc((arith)0);
|
||||
C_cal("_opnchn");
|
||||
C_asp((arith)(2*BEMPTRSIZE+BEMINTSIZE));
|
||||
}
|
||||
|
||||
|
||||
|
||||
epilogcode()
|
||||
{
|
||||
/* finalization code */
|
||||
int nr;
|
||||
nr= genlabel();
|
||||
C_bra((label)nr);
|
||||
genreturns();
|
||||
C_df_ilb((label)nr);
|
||||
datatable(); /* NEW */
|
||||
C_loc((arith)0);
|
||||
C_cal("_hlt");
|
||||
C_df_ilb(err_goto_label);
|
||||
C_cal("_goto_err");
|
||||
C_end((arith)0);
|
||||
}
|
340
lang/basic/src/graph.c
Normal file
340
lang/basic/src/graph.c
Normal file
|
@ -0,0 +1,340 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#include "bem.h"
|
||||
|
||||
#ifndef NORSCID
|
||||
static char rcs_id[] = "$Header$" ;
|
||||
#endif
|
||||
|
||||
|
||||
List *forwardlabel=0;
|
||||
|
||||
Linerecord *firstline,
|
||||
*currline,
|
||||
*lastline;
|
||||
|
||||
|
||||
|
||||
List *newlist()
|
||||
{
|
||||
List *l;
|
||||
|
||||
/* NOSTRICT */ l = (List *) salloc(sizeof(List));
|
||||
return(l);
|
||||
}
|
||||
|
||||
|
||||
/* Line management is handled here */
|
||||
|
||||
Linerecord *srchline(nr)
|
||||
int nr;
|
||||
{
|
||||
Linerecord *l;
|
||||
|
||||
for(l=firstline;l && l->linenr<=nr;l= l->nextline)
|
||||
if ( l->linenr== nr) return(l);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
List *srchforward(nr)
|
||||
int nr;
|
||||
{
|
||||
List *l;
|
||||
|
||||
for(l=forwardlabel;l ;l=l->nextlist)
|
||||
if ( l->linenr== nr) return(l);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
linewarnings()
|
||||
{
|
||||
List *l;
|
||||
extern int errorcnt;
|
||||
|
||||
l= forwardlabel;
|
||||
while (l)
|
||||
{
|
||||
if ( !srchline(l->linenr))
|
||||
{
|
||||
fprint(STDERR, "ERROR: line %d not defined\n",l->linenr);
|
||||
errorcnt++;
|
||||
}
|
||||
l=l->nextlist;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
newblock(nr)
|
||||
int nr;
|
||||
{
|
||||
Linerecord *l;
|
||||
List *frwrd;
|
||||
|
||||
if ( debug) print("newblock at %d\n",nr);
|
||||
if ( nr>0 && currline && currline->linenr>= nr)
|
||||
{
|
||||
if ( debug) print("old line:%d\n",currline->linenr);
|
||||
error("Lines out of sequence");
|
||||
}
|
||||
|
||||
frwrd=srchforward(nr);
|
||||
if ( frwrd && debug) print("forward found %d\n",frwrd->emlabel);
|
||||
l= srchline(nr);
|
||||
if ( l)
|
||||
{
|
||||
error("Line redefined");
|
||||
nr= -genlabel();
|
||||
}
|
||||
|
||||
/* make new EM block structure */
|
||||
/* NOSTRICT */ l= (Linerecord *) salloc(sizeof(*l));
|
||||
l->emlabel= frwrd ? frwrd->emlabel : genlabel();
|
||||
l->linenr= nr;
|
||||
|
||||
/* insert this record */
|
||||
if ( firstline)
|
||||
{
|
||||
currline->nextline=l;
|
||||
l->prevline= currline;
|
||||
lastline= currline=l;
|
||||
} else
|
||||
firstline = lastline =currline=l;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gotolabel(nr)
|
||||
int nr;
|
||||
{
|
||||
/* simulate a goto statement in the line record table */
|
||||
Linerecord *l1;
|
||||
List *ll;
|
||||
|
||||
if (debug) print("goto label %d\n",nr);
|
||||
/* update currline */
|
||||
ll= newlist();
|
||||
ll-> linenr=nr;
|
||||
ll-> nextlist= currline->gotos;
|
||||
currline->gotos= ll;
|
||||
|
||||
/* try to generate code */
|
||||
l1= srchline(nr);
|
||||
if ( (ll=srchforward(nr))!=0)
|
||||
nr= ll->emlabel;
|
||||
else
|
||||
if ( l1==0)
|
||||
{
|
||||
/* declare forward label */
|
||||
if (debug) print("declare forward %d\n",nr);
|
||||
ll= newlist();
|
||||
ll->emlabel= genlabel();
|
||||
ll-> linenr=nr;
|
||||
ll->nextlist= forwardlabel;
|
||||
forwardlabel= ll;
|
||||
nr= ll->emlabel;
|
||||
} else nr= l1->emlabel;
|
||||
return(nr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
gotostmt(nr)
|
||||
int nr;
|
||||
{
|
||||
C_bra((label) gotolabel(nr));
|
||||
}
|
||||
|
||||
/* GOSUB-return, assume that proper entries are made to subroutines
|
||||
only. The return statement is triggered by a fake constant label */
|
||||
|
||||
List *gosubhead, *gotail;
|
||||
int gosubcnt=1;
|
||||
|
||||
|
||||
|
||||
List *gosublabel()
|
||||
{
|
||||
List *l;
|
||||
|
||||
l= newlist();
|
||||
l->nextlist=0;
|
||||
l->emlabel=genlabel();
|
||||
if ( gotail){
|
||||
gotail->nextlist=l;
|
||||
gotail=l;
|
||||
} else gotail= gosubhead=l;
|
||||
gosubcnt++;
|
||||
return(l);
|
||||
}
|
||||
|
||||
|
||||
|
||||
gosubstmt(lab)
|
||||
int lab;
|
||||
{
|
||||
List *l;
|
||||
int nr,n;
|
||||
|
||||
n=gosubcnt;
|
||||
l= gosublabel();
|
||||
nr=gotolabel(lab);
|
||||
/*return index */
|
||||
C_loc((arith) n);
|
||||
/* administer legal return */
|
||||
C_cal("_gosub");
|
||||
C_asp((arith) BEMINTSIZE);
|
||||
C_bra((label) nr);
|
||||
C_df_ilb((label)l->emlabel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
genreturns()
|
||||
{
|
||||
int nr;
|
||||
|
||||
nr= genlabel();
|
||||
C_df_dnam("returns");
|
||||
C_rom_ilb((label) nr);
|
||||
C_rom_cst((arith)1);
|
||||
C_rom_cst((arith) (gosubcnt-1));
|
||||
|
||||
while ( gosubhead)
|
||||
{
|
||||
C_rom_ilb((label) gosubhead->emlabel);
|
||||
gosubhead= gosubhead->nextlist;
|
||||
}
|
||||
C_df_ilb((label) nr);
|
||||
C_loc((arith) 1);
|
||||
C_cal("error");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
returnstmt()
|
||||
{
|
||||
C_cal("_retstmt");
|
||||
C_lfr((arith) BEMINTSIZE);
|
||||
C_lae_dnam("returns",(arith)0);
|
||||
C_csa((arith) BEMINTSIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* compound goto-gosub statements */
|
||||
List *jumphead,*jumptail;
|
||||
int jumpcnt;
|
||||
|
||||
|
||||
jumpelm(nr)
|
||||
int nr;
|
||||
{
|
||||
List *l;
|
||||
|
||||
l= newlist();
|
||||
l->emlabel= gotolabel(nr);
|
||||
l->nextlist=0;
|
||||
if ( jumphead==0) jumphead = jumptail = l;
|
||||
else {
|
||||
jumptail->nextlist=l;
|
||||
jumptail=l;
|
||||
}
|
||||
jumpcnt++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ongotostmt(type)
|
||||
int type;
|
||||
{
|
||||
/* generate the code itself, index in on top of the stack */
|
||||
/* blurh, store the number of entries in the descriptor */
|
||||
int firstlabel;
|
||||
int descr;
|
||||
List *l;
|
||||
|
||||
/* create descriptor first */
|
||||
descr= genlabel();
|
||||
firstlabel=genlabel();
|
||||
C_df_dlb((label)descr);
|
||||
C_rom_ilb((label)firstlabel);
|
||||
C_rom_cst((arith) 1);
|
||||
C_rom_cst((arith)(jumpcnt-1));
|
||||
l= jumphead;
|
||||
while (l)
|
||||
{
|
||||
C_rom_ilb((label)l->emlabel);
|
||||
l= l->nextlist;
|
||||
}
|
||||
jumphead= jumptail=0; jumpcnt=0;
|
||||
if (debug) print("ongotst:%d labels\n", jumpcnt);
|
||||
conversion(type,INTTYPE);
|
||||
C_dup((arith) BEMINTSIZE);
|
||||
C_zlt(err_goto_label);
|
||||
C_lae_dlb((label) descr,(arith) 0);
|
||||
C_csa((arith) BEMINTSIZE);
|
||||
C_df_ilb((label)firstlabel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ongosubstmt(type)
|
||||
int type;
|
||||
{
|
||||
List *l;
|
||||
int firstlabel;
|
||||
int descr;
|
||||
|
||||
/* create descriptor first */
|
||||
descr= genlabel();
|
||||
firstlabel=genlabel();
|
||||
C_df_dlb((label)descr);
|
||||
C_rom_ilb((label)firstlabel);
|
||||
C_rom_cst((arith)1);
|
||||
C_rom_cst((arith)(jumpcnt-1));
|
||||
l= jumphead;
|
||||
|
||||
while (l)
|
||||
{
|
||||
C_rom_ilb((label)l->emlabel);
|
||||
l= l->nextlist;
|
||||
}
|
||||
|
||||
jumphead= jumptail=0;
|
||||
jumpcnt=0;
|
||||
l= newlist();
|
||||
l->nextlist=0;
|
||||
l->emlabel=firstlabel;
|
||||
if ( gotail){
|
||||
gotail->nextlist=l;
|
||||
gotail=l;
|
||||
} else gotail=gosubhead=l;
|
||||
/* save the return point of the gosub */
|
||||
C_loc((arith) gosubcnt);
|
||||
C_cal("_gosub");
|
||||
C_asp((arith) BEMINTSIZE);
|
||||
gosubcnt++;
|
||||
/* generate gosub */
|
||||
conversion(type,INTTYPE);
|
||||
C_dup((arith) BEMINTSIZE);
|
||||
C_zlt(err_goto_label);
|
||||
C_lae_dlb((label) descr,(arith) 0);
|
||||
C_csa((arith) BEMINTSIZE);
|
||||
C_df_ilb((label)firstlabel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* REGION ANALYSIS and FINAL VERSION GENERATION */
|
||||
|
||||
|
37
lang/basic/src/graph.h
Normal file
37
lang/basic/src/graph.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#ifndef NORCSID
|
||||
# define RCS_GRAPH "$Header$"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The control graph is represented by a multi-list structure.
|
||||
** The em code is stored on the em intermediate file already
|
||||
** The offset and length is saved only.
|
||||
** Although this makes code generation mode involved, it allows
|
||||
** rather large BASIC programs to be processed.
|
||||
*/
|
||||
typedef struct LIST {
|
||||
int emlabel; /* em label used with forwards */
|
||||
int linenr; /* BASIC line number */
|
||||
struct LIST *nextlist;
|
||||
} List;
|
||||
|
||||
typedef struct LINERECORD{
|
||||
int emlabel; /* target label */
|
||||
int linenr; /* BASIC line number */
|
||||
List *callers; /* used from where ? */
|
||||
List *gotos; /* fanout labels */
|
||||
struct LINERECORD *nextline, *prevline;
|
||||
int fixed; /* fixation of block */
|
||||
} Linerecord;
|
||||
|
||||
extern Linerecord *firstline,
|
||||
*currline,
|
||||
*lastline;
|
||||
extern List *forwardlabel;
|
||||
|
||||
extern List *gosublabel();
|
52
lang/basic/src/initialize.c
Normal file
52
lang/basic/src/initialize.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#include "bem.h"
|
||||
#include <em_path.h>
|
||||
|
||||
#ifndef NORSCID
|
||||
static char rcs_id[] = "$Header$";
|
||||
#endif
|
||||
|
||||
/* generate temporary files etc */
|
||||
|
||||
File *tmp_file;
|
||||
File *datfile;
|
||||
|
||||
|
||||
|
||||
initialize()
|
||||
{
|
||||
register char *cindex, *cptr;
|
||||
int result1, result2, result3;
|
||||
|
||||
(void) sprint(tmpfname,"%s/abc%d",TMP_DIR,getpid());
|
||||
/* Find the basename */
|
||||
/* Strip leading directories */
|
||||
cindex= (char *)0;
|
||||
for ( cptr=program; *cptr; cptr++ ) if ( *cptr=='/' ) cindex=cptr;
|
||||
if ( !cindex ) cindex= program;
|
||||
else {
|
||||
cindex++;
|
||||
if ( !*cindex ) {
|
||||
warning("Null program name, assuming \"basic\"");
|
||||
cindex= "basic";
|
||||
}
|
||||
}
|
||||
cptr=datfname;
|
||||
while ( *cptr++ = *cindex++ );
|
||||
/* Strip trailing suffix */
|
||||
if ( cptr>datfname+3 && cptr[-3]=='.' ) cptr[-3]=0;
|
||||
strcat(datfname,".d");
|
||||
C_init((arith)BEMINTSIZE, (arith)BEMPTRSIZE);
|
||||
result1 = sys_open(inpfile, OP_READ, &yyin);
|
||||
result2 = C_open(outfile);
|
||||
result3 = sys_open(tmpfname,OP_WRITE, &tmp_file);
|
||||
if ( result1==0 || result2== 0 || result3== 0 )
|
||||
fatal("Improper file permissions");
|
||||
fillkex(); /* initialize symbol table */
|
||||
C_ms_emx((arith)BEMINTSIZE,(arith)BEMPTRSIZE);
|
||||
initdeftype(); /* set default symbol declarers */
|
||||
}
|
62
lang/basic/src/llmess.c
Normal file
62
lang/basic/src/llmess.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#include "tokentab.h"
|
||||
|
||||
/* Mod van gertjan */
|
||||
extern int LLsymb;
|
||||
extern int toknum;
|
||||
|
||||
|
||||
error_char(format,ch)
|
||||
char *format;
|
||||
char ch;
|
||||
{
|
||||
extern int listing,errorcnt;
|
||||
extern int basicline;
|
||||
|
||||
if ( !listing ) fprint(STDERR, "LINE %d:",basicline);
|
||||
fprint(STDERR, format,ch);
|
||||
errorcnt++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
error_string(format,str)
|
||||
char *format;
|
||||
char *str;
|
||||
{
|
||||
extern int listing,errorcnt;
|
||||
extern int basicline;
|
||||
|
||||
if ( !listing ) fprint(STDERR, "LINE %d:",basicline);
|
||||
fprint(STDERR, format,str);
|
||||
errorcnt++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LLmessage( insertedtok )
|
||||
int insertedtok;
|
||||
{
|
||||
if ( insertedtok < 0 ) {
|
||||
error("Fatal stack overflow\n");
|
||||
C_close();
|
||||
sys_stop( S_EXIT );
|
||||
}
|
||||
|
||||
if ( insertedtok == 0 )
|
||||
if ( LLsymb < 256 )
|
||||
error_char("%c deleted\n", (char)LLsymb);
|
||||
else
|
||||
error_string("%s deleted\n", tokentab[ LLsymb-256 ]);
|
||||
else {
|
||||
if ( insertedtok < 256 )
|
||||
error_char("%c inserted\n", (char)insertedtok);
|
||||
else
|
||||
error_string("%s inserted\n", tokentab[ insertedtok-256 ]);
|
||||
toknum = insertedtok;
|
||||
}
|
||||
}
|
17
lang/basic/src/maketokentab
Executable file
17
lang/basic/src/maketokentab
Executable file
|
@ -0,0 +1,17 @@
|
|||
cp Lpars.h tokentab.h
|
||||
ex tokentab.h 2>&1 > /dev/null <<+
|
||||
1d
|
||||
1,\$s/# define //
|
||||
1,\$s/ ...$//
|
||||
1,\$s/^/ "/
|
||||
1,\$-1s/\$/",/
|
||||
\$s/\$/"/
|
||||
0a
|
||||
char *tokentab[] = {
|
||||
.
|
||||
\$a
|
||||
};
|
||||
.
|
||||
w
|
||||
q
|
||||
+
|
85
lang/basic/src/parsepar.c
Normal file
85
lang/basic/src/parsepar.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#include "bem.h"
|
||||
|
||||
#ifndef NORSCID
|
||||
static char rcs_id[] = "$Header$" ;
|
||||
#endif
|
||||
|
||||
|
||||
int listing; /* -l listing required */
|
||||
int debug; /* -d compiler debugging */
|
||||
int wflag=0; /* -w no warnings */
|
||||
int traceflag=0; /* generate line tracing code */
|
||||
int nolins=0; /* generate no LIN statements */
|
||||
|
||||
|
||||
|
||||
parseparams(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int files=0 ;
|
||||
int i;
|
||||
register char *p;
|
||||
|
||||
if(argc< 4)
|
||||
{
|
||||
fprint(STDERR,"usage %s <flags> <file> <file> <source>\n",
|
||||
argv[0]);
|
||||
sys_stop(S_EXIT);
|
||||
}
|
||||
|
||||
for(i=1;i<argc;i++)
|
||||
if( argv[i][0]=='-')
|
||||
switch(argv[i][1])
|
||||
{
|
||||
case 'D': yydebug++;
|
||||
break; /* parser debugging */
|
||||
case 't': traceflag++;
|
||||
break; /* line tracing */
|
||||
case 'h': /* split EM file */
|
||||
(void) fprint(STDERR,
|
||||
"h option not implemented\n");
|
||||
break;
|
||||
case 'd': debug++;
|
||||
break;
|
||||
case 'L': nolins++;
|
||||
break; /* no EM lin statements */
|
||||
case 'E': listing++;
|
||||
break; /* generate full listing */
|
||||
case 'w': wflag++;
|
||||
break; /* no warnings */
|
||||
case 'V':
|
||||
p = &argv[i][2];
|
||||
while (*p) switch(*p++) {
|
||||
case 'w':
|
||||
BEMINTSIZE = *p++ - '0';
|
||||
break;
|
||||
case 'p':
|
||||
BEMPTRSIZE = *p++ - '0';
|
||||
break;
|
||||
case 'f':
|
||||
BEMFLTSIZE = *p++ - '0';
|
||||
break;
|
||||
default:
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* new input file */
|
||||
switch ( files++ ) {
|
||||
case 0: inpfile= argv[i]; break;
|
||||
case 1: outfile= argv[i]; break;
|
||||
case 2: /* should be the source file
|
||||
name */
|
||||
program= argv[i];
|
||||
break;
|
||||
default:fatal("Too many file arguments") ;
|
||||
}
|
||||
}
|
||||
if (files < 3) fatal("Too few file arguments");
|
||||
}
|
376
lang/basic/src/symbols.c
Normal file
376
lang/basic/src/symbols.c
Normal file
|
@ -0,0 +1,376 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#include "bem.h"
|
||||
|
||||
#ifndef NORSCID
|
||||
static char rcs_id[] = "$Header$" ;
|
||||
#endif
|
||||
|
||||
/* Symboltable management module */
|
||||
|
||||
int deftype[128]; /* default type declarer */
|
||||
/* which may be set by OPTION BASE */
|
||||
|
||||
|
||||
initdeftype()
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i='a';i<='z';i++) deftype[i]= DOUBLETYPE;
|
||||
for(i='A';i<='Z';i++) deftype[i]= DOUBLETYPE;
|
||||
}
|
||||
|
||||
|
||||
int indexbase=0; /* start of array subscripting */
|
||||
|
||||
Symbol *firstsym = NIL;
|
||||
Symbol *alternate = NIL;
|
||||
|
||||
|
||||
|
||||
Symbol *srchsymbol(str)
|
||||
char *str;
|
||||
{
|
||||
Symbol *s;
|
||||
|
||||
/* search symbol table entry or create it */
|
||||
if (debug) print("srchsymbol %s\n",str);
|
||||
s=firstsym;
|
||||
|
||||
while (s)
|
||||
{
|
||||
if ( strcmp(s->symname,str)==0) return(s);
|
||||
s= s->nextsym;
|
||||
}
|
||||
|
||||
/* search alternate list */
|
||||
s=alternate;
|
||||
|
||||
while (s)
|
||||
{
|
||||
if ( strcmp(s->symname,str)==0) return(s);
|
||||
s= s->nextsym;
|
||||
}
|
||||
|
||||
/* not found, create an empty slot */
|
||||
s = (Symbol *) salloc(sizeof(Symbol));
|
||||
s->symtype= DEFAULTTYPE;
|
||||
s->nextsym= firstsym;
|
||||
s->symname= (char *) salloc((unsigned) strlen(str)+1);
|
||||
strcpy(s->symname,str);
|
||||
firstsym= s;
|
||||
if (debug) print("%s allocated\n",str);
|
||||
return(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
dcltype(s)
|
||||
Symbol *s;
|
||||
{
|
||||
/* type declarer */
|
||||
int type;
|
||||
|
||||
if ( s->isparam) return;
|
||||
type=s->symtype;
|
||||
if (type==DEFAULTTYPE)
|
||||
/* use the default rule */
|
||||
type= deftype[*s->symname];
|
||||
/* generate the emlabel too */
|
||||
if ( s->symalias==0)
|
||||
s->symalias= dclspace(type);
|
||||
s->symtype= type;
|
||||
if (debug) print("symbol set to %d\n",type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
dclarray(s)
|
||||
Symbol *s;
|
||||
{
|
||||
int i; int size;
|
||||
|
||||
if ( s->symtype==DEFAULTTYPE) s->symtype= DOUBLETYPE;
|
||||
if (debug) print("generate space and descriptors for %d\n",s->symtype);
|
||||
if (debug) print("dim %d\n",s->dimensions);
|
||||
s->symalias= genlabel();
|
||||
/* generate descriptors */
|
||||
size=1;
|
||||
|
||||
for(i=0;i<s->dimensions;i++) {
|
||||
s->dimalias[i]= genlabel();
|
||||
}
|
||||
|
||||
for(i=s->dimensions-1;i>=0;i--)
|
||||
{
|
||||
C_df_dlb((label)(s->dimalias[i]));
|
||||
C_rom_cst((arith)indexbase);
|
||||
C_rom_cst((arith)(s->dimlimit[i]-indexbase));
|
||||
C_rom_cst((arith)(size*typesize(s->symtype)));
|
||||
size = size* (s->dimlimit[i]+1-indexbase);
|
||||
}
|
||||
|
||||
if (debug) print("size=%d\n",size);
|
||||
/* size of stuff */
|
||||
C_df_dlb((label)s->symalias);
|
||||
get_space(s->symtype,size); /* Van ons. */
|
||||
}
|
||||
|
||||
|
||||
|
||||
get_space(type,size)
|
||||
int type,size;
|
||||
{
|
||||
|
||||
switch ( type ) {
|
||||
case INTTYPE:
|
||||
C_bss_cst((arith)BEMINTSIZE*size,
|
||||
(arith)0,
|
||||
1);
|
||||
break;
|
||||
case FLOATTYPE:
|
||||
case DOUBLETYPE:
|
||||
C_bss_fcon((arith)BEMFLTSIZE*size,
|
||||
"0.0",
|
||||
(arith)BEMFLTSIZE,
|
||||
1);
|
||||
break;
|
||||
case STRINGTYPE: /* Note: this is ugly. Gertjan */
|
||||
C_bss_icon((arith)BEMPTRSIZE*size,
|
||||
"0",
|
||||
(arith)BEMPTRSIZE,
|
||||
1);
|
||||
break;
|
||||
default:
|
||||
error("Space allocated for unknown type. Coredump.");
|
||||
abort(); /* For debugging purposes */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
defarray(s)
|
||||
Symbol *s;
|
||||
{
|
||||
/* array is used without dim statement, set default limits */
|
||||
int i;
|
||||
for(i=0;i<s->dimensions;i++) s->dimlimit[i]=10;
|
||||
dclarray(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
dclspace(type)
|
||||
{
|
||||
int nr;
|
||||
|
||||
nr= genemlabel();
|
||||
|
||||
switch( type)
|
||||
{
|
||||
case STRINGTYPE:
|
||||
C_bss_icon((arith)BEMPTRSIZE,"0",(arith)BEMPTRSIZE,1);
|
||||
break;
|
||||
case INTTYPE:
|
||||
C_bss_cst((arith)BEMINTSIZE,(arith)0,1);
|
||||
break;
|
||||
case FLOATTYPE:
|
||||
case DOUBLETYPE:
|
||||
C_bss_fcon((arith)BEMFLTSIZE,"0.0",(arith)BEMFLTSIZE,1);
|
||||
break;
|
||||
}
|
||||
return(nr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* SOME COMPILE TIME OPTIONS */
|
||||
optionbase(ival)
|
||||
int ival;
|
||||
{
|
||||
if ( ival<0 || ival>1)
|
||||
error("illegal option base value");
|
||||
else indexbase=ival;
|
||||
}
|
||||
|
||||
|
||||
|
||||
setdefaulttype(type)
|
||||
int type;
|
||||
{
|
||||
extern char *cptr;
|
||||
char first,last,i;
|
||||
|
||||
/* handcrafted parser for letter ranges */
|
||||
if (debug) print("deftype:%s\n",cptr);
|
||||
while ( isspace(*cptr)) cptr++;
|
||||
if ( !isalpha(*cptr))
|
||||
error("letter expected");
|
||||
first= *cptr++;
|
||||
if (*cptr=='-')
|
||||
{
|
||||
/* letter range */
|
||||
cptr++;
|
||||
last= *cptr;
|
||||
if ( !isalpha(last))
|
||||
error("letter expected");
|
||||
else for(i=first;i<=last;i++) deftype[i]= type;
|
||||
cptr++;
|
||||
} else deftype[first]=type;
|
||||
if ( *cptr== ',')
|
||||
{
|
||||
cptr++;
|
||||
setdefaulttype(type); /* try again */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Symbol *fcn;
|
||||
|
||||
|
||||
|
||||
newscope(s)
|
||||
Symbol *s;
|
||||
{
|
||||
if (debug) print("new scope for %s\n",s->symname);
|
||||
alternate= firstsym;
|
||||
firstsym = NIL;
|
||||
fcn=s;
|
||||
s->isfunction=1;
|
||||
if ( fcn->dimensions)
|
||||
error("Array redeclared");
|
||||
if ( fcn->symtype== DEFAULTTYPE)
|
||||
fcn->symtype=DOUBLETYPE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* User defined functions */
|
||||
|
||||
|
||||
|
||||
heading( )
|
||||
{
|
||||
char procname[50];
|
||||
|
||||
sprint(procname,"_%s",fcn->symname);
|
||||
C_pro_narg(procname);
|
||||
if ( fcn->symtype== DEFAULTTYPE)
|
||||
fcn->symtype= DOUBLETYPE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int fcnsize()
|
||||
{
|
||||
/* generate portable function size */
|
||||
int i,sum; /* sum is NEW */
|
||||
|
||||
sum = 0;
|
||||
for(i=0;i<fcn->dimensions;i++)
|
||||
sum += typesize(fcn->dimlimit[i]);
|
||||
return(sum);
|
||||
}
|
||||
|
||||
|
||||
|
||||
endscope(type)
|
||||
int type;
|
||||
{
|
||||
Symbol *s;
|
||||
|
||||
if ( debug) print("endscope");
|
||||
conversion(type,fcn->symtype);
|
||||
C_ret((arith) typestring(fcn->symtype));
|
||||
/* generate portable EM code */
|
||||
C_end( (arith)fcnsize() );
|
||||
s= firstsym;
|
||||
|
||||
while (s)
|
||||
{
|
||||
firstsym = s->nextsym;
|
||||
(void) free((char *)s);
|
||||
s= firstsym;
|
||||
}
|
||||
|
||||
firstsym= alternate;
|
||||
alternate = NIL;
|
||||
fcn=NIL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
dclparm(s)
|
||||
Symbol *s;
|
||||
{
|
||||
int size=0;
|
||||
|
||||
if ( s->symtype== DEFAULTTYPE)
|
||||
s->symtype= DOUBLETYPE;
|
||||
s->isparam=1;
|
||||
fcn->dimlimit[fcn->dimensions]= s->symtype;
|
||||
fcn->dimensions++;
|
||||
s->symalias= -fcn->dimensions;
|
||||
if ( debug) print("parameter %d offset %d\n",fcn->dimensions-1,-size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* unfortunately function calls have to be stacked as well */
|
||||
#define MAXNESTING 50
|
||||
Symbol *fcntable[MAXNESTING];
|
||||
int fcnindex= -1;
|
||||
|
||||
|
||||
|
||||
fcncall(s)
|
||||
Symbol *s;
|
||||
{
|
||||
if ( !s->isfunction)
|
||||
error("Function not declared");
|
||||
else{
|
||||
fcn= s;
|
||||
fcnindex++;
|
||||
fcntable[fcnindex]=s;
|
||||
}
|
||||
return(s->symtype);
|
||||
}
|
||||
|
||||
|
||||
|
||||
fcnend(parmcount)
|
||||
int parmcount;
|
||||
{
|
||||
int type;
|
||||
static char concatbuf[50]; /* NEW */
|
||||
|
||||
/* check number of arguments */
|
||||
if ( parmcount <fcn->dimensions)
|
||||
error("not enough parameters");
|
||||
if ( parmcount >fcn->dimensions)
|
||||
error("too many parameters");
|
||||
(void) sprint(concatbuf,"_%s",fcn->symname);
|
||||
C_cal(concatbuf);
|
||||
C_asp((arith)fcnsize());
|
||||
C_lfr((arith) typestring(fcn->symtype));
|
||||
type= fcn->symtype;
|
||||
fcnindex--;
|
||||
if ( fcnindex>=0)
|
||||
fcn= fcntable[fcnindex];
|
||||
return(type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
callparm(ind,type)
|
||||
int ind,type;
|
||||
{
|
||||
if ( fcnindex<0) error("unexpected parameter");
|
||||
if ( ind >= fcn->dimensions)
|
||||
error("too many parameters");
|
||||
else
|
||||
conversion(type,fcn->dimlimit[ind]);
|
||||
}
|
88
lang/basic/src/symbols.h
Normal file
88
lang/basic/src/symbols.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#ifndef NORCSID
|
||||
# define RCS_SYMB "$Header$"
|
||||
#endif
|
||||
|
||||
#define NIL 0
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define DEFAULTTYPE 500
|
||||
#define INTTYPE 501
|
||||
#define FLOATTYPE 502
|
||||
#define DOUBLETYPE 503
|
||||
#define STRINGTYPE 504
|
||||
|
||||
#define ABSSYM 520
|
||||
#define ASCSYM 521
|
||||
#define ATNSYM 522
|
||||
#define CDBLSYM 524
|
||||
#define CHRSYM 525
|
||||
#define CINTSYM 526
|
||||
#define COSSYM 527
|
||||
#define CSNGSYM 528
|
||||
#define CVISYM 529
|
||||
#define CVSSYM 530
|
||||
#define CVDSYM 531
|
||||
#define EOFSYM 532
|
||||
#define EXPSYM 533
|
||||
#define FIXSYM 534
|
||||
#define FRESYM 535
|
||||
#define HEXSYM 536
|
||||
#define INPSYM 538
|
||||
#define INSTRSYM 539
|
||||
#define LEFTSYM 540
|
||||
#define LENSYM 541
|
||||
#define LOCSYM 542
|
||||
#define LOGSYM 543
|
||||
#define LPOSSYM 544
|
||||
#define MKISYM 546
|
||||
#define MKSSYM 547
|
||||
#define MKDSYM 548
|
||||
#define OCTSYM 549
|
||||
#define PEEKSYM 550
|
||||
#define POSSYM 551
|
||||
#define RIGHTSYM 552
|
||||
#define RNDSYM 553
|
||||
#define SGNSYM 554
|
||||
#define SINSYM 555
|
||||
#define SPACESYM 556
|
||||
#define SPCSYM 557
|
||||
#define SQRSYM 558
|
||||
#define STRSYM 559
|
||||
#define STRINGSYM 560
|
||||
#define TABSYM 561
|
||||
#define TANSYM 562
|
||||
#define VALSYM 564
|
||||
#define VARPTRSYM 565
|
||||
/* some stuff forgotten */
|
||||
#define INTSYM 567
|
||||
#define AUTOSYM 568
|
||||
#define LISTSYM 569
|
||||
#define LOADSYM 570
|
||||
#define MERGESYM 571
|
||||
#define TRONSYM 572
|
||||
#define TROFFSYM 0 /* NIEUW : was 573, werkte als TRON */
|
||||
/* IMPSYM, EQVSYM en XORSYM zijn tokens geworden */
|
||||
#define OUTSYM 577
|
||||
|
||||
#define MAXDIMENSIONS 10
|
||||
|
||||
typedef struct SYMBOL{
|
||||
char *symname;
|
||||
int symalias;
|
||||
int symtype;
|
||||
int dimensions; /* dimension array/function */
|
||||
int dimlimit[MAXDIMENSIONS]; /* type of parameter */
|
||||
int dimalias[MAXDIMENSIONS];
|
||||
struct SYMBOL *nextsym;
|
||||
int isfunction;
|
||||
int parmsize;
|
||||
int isparam;
|
||||
} Symbol;
|
||||
|
||||
extern Symbol *srchsymbol();
|
98
lang/basic/src/util.c
Normal file
98
lang/basic/src/util.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
#include "bem.h"
|
||||
|
||||
#ifndef NORSCID
|
||||
static char rcs_id[] = "$Header$" ;
|
||||
#endif
|
||||
|
||||
#define abs(X) (X>=0?X:-X)
|
||||
/* Miscelaneous routines can be found here */
|
||||
|
||||
int errorcnt;
|
||||
|
||||
|
||||
|
||||
warning(str)
|
||||
char *str;
|
||||
{
|
||||
if (wflag) return;
|
||||
Xerror("WARNING", str);
|
||||
}
|
||||
|
||||
|
||||
error(str)
|
||||
char *str;
|
||||
{
|
||||
Xerror("ERROR", str);
|
||||
errorcnt++;
|
||||
}
|
||||
|
||||
Xerror(type, str)
|
||||
char *str;
|
||||
char *type;
|
||||
{
|
||||
extern int listing;
|
||||
extern int basicline;
|
||||
|
||||
if( !listing) fprint(STDERR, "LINE %d:",basicline);
|
||||
fprint(STDERR, "%s:%s\n",type, str);
|
||||
}
|
||||
|
||||
|
||||
|
||||
fatal(str)
|
||||
char *str;
|
||||
{
|
||||
Xerror("FATAL",str);
|
||||
C_close();
|
||||
sys_stop(S_EXIT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
notyetimpl()
|
||||
{
|
||||
warning("not yet implemented");
|
||||
}
|
||||
|
||||
|
||||
|
||||
illegalcmd()
|
||||
{
|
||||
warning("illegal command");
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *itoa(i)
|
||||
int i;
|
||||
{
|
||||
static char buf[30];
|
||||
|
||||
(void) sprint(buf,"%d",i);
|
||||
return(buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
char *salloc(length)
|
||||
unsigned length;
|
||||
{
|
||||
char *s,*c;
|
||||
extern char *malloc() ;
|
||||
|
||||
s=c=malloc(length);
|
||||
if ( !s ) fatal("Out of memory") ;
|
||||
while(length--)*c++ =0;
|
||||
return(s);
|
||||
}
|
||||
|
||||
|
||||
|
22
lang/basic/src/yylexp.c
Normal file
22
lang/basic/src/yylexp.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
int toknum;
|
||||
|
||||
yylexp()
|
||||
{
|
||||
/* als toknum != 0 dan bevat toknum een door LLmessage back-ge-pushed token */
|
||||
|
||||
int t;
|
||||
|
||||
if ( toknum == 0 )
|
||||
return(yylex());
|
||||
else {
|
||||
t = toknum;
|
||||
toknum = 0;
|
||||
return(t);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue