The version of basic copied from Martin Kerstens directory.

This commit is contained in:
em 1984-11-27 22:11:59 +00:00
parent 502a7a86af
commit 4301dfb7bf
16 changed files with 3076 additions and 0 deletions

View file

@ -0,0 +1,14 @@
CFLAGS = -c
FILES= bem.o y.tab.o symbols.o initialize.o compile.o \
parseparams.o yywrap.o gencode.o util.o graph.o \
eval.o func.o split.o
../bem: $(FILES)
cc -o ../bem $(FILES)
y.tab.o : y.tab.c lex.c
cc $(CFLAGS) y.tab.c
y.tab.c : basic.yacc
yacc -d basic.yacc

View file

@ -0,0 +1,464 @@
/* This file contains the new lexical analizer */
typedef struct {
char *name;
int token, classvalue,length;
} Key;
Key keywords [] ={
"abs", FUNCTION, ABSSYM, 0,
"and", BOOLOP, 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", ILLEGAL, 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,
"erase", ILLEGAL, 0, 0,
"error", ERRORSYM, 0, 0,
"err", ERRSYM, 0, 0,
"erl", ERLSYM, 0, 0,
"else", ELSESYM, 0, 0,
"eqv", BOOLOP, EQVSYM, 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", BOOLOP, 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", BOOLOP, 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", BOOLOP, 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++)
printf("%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 */
getline()
{
/* get next input line */
if( fgets(inputline,MAXLINELENGTH,yyin) == NULL)
return(FALSE);
yylineno ++;
if( index(inputline,'\n') == 0)
error("source line too long");
inputline[MAXLINELENGTH-1]=0;
if( listing)
fputs(inputline,stdout);
cptr= inputline;
return(TRUE);
}
yyerror(str)
char *str;
{
error("Syntax error");
}
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 *s;
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)== *cptr;k++)
if( strncmp(cptr,k->name,k->length)==0)
{
/* check functions first*/
if( isalnum( *(cptr+k->length) ) &&
k->token==FUNCTION) continue;
cptr += k->length;
yylval= k->classvalue;
if(debug) printf("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 == '.')
if( i<SIGNIFICANT) name[i++]= *c++;
name[i]=0;
cptr=c;
s= (Symbol *) srchsymbol(name);
yylval = (YYSTYPE) s;
typech= typechar();
if(s->symtype!=DEFAULTTYPE)
{
if(typech && typech!=s->symtype && wflag)
warning("type re-declared,ignored");
}
if( typech)
s->symtype=typech;
if(debug) printf("lookup:%d Identifier\n",s);
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++;
sscanf(c,"%x",&ival);
} else
if( *cptr == 'O' || *cptr == 'o')
{
/* OCTAL */
cptr++;
c=cptr;
while( isdigit(*cptr) ) cptr++;
sscanf(c,"%o",&ival);
} else
error("H or O expected");
return(INTVALUE);
}
number()
{
long i1;
double f,dec;
int minflag;
register char *c;
i1=0;
c=cptr;
while(isdigit(*c)){
i1= i1*10 + *c-'0';
c++;
}
cptr=c;
if( *c != '.'){
if( i1> MAXINT || i1<MININT) {
dval= i1;
return(FLTVALUE);
}
ival= i1;
#ifdef YYDEBUG
if(yydebug) printf("number:INTVALUE %d",i1);
#endif
return(INTVALUE);
}
/* handle floats */
f= i1; dec=0.1;
c++;
while( isdigit(*c)){
f= f + dec * (*c - '0');
dec /= 10.0;
c++;
}
/* handle exponential part */
if( *c =='e' || *c == 'E'){
c++;
minflag= (*c== '-')? -1: 1;
if( *c=='-' || *c=='+') c++;
while(isdigit(*c)){
f *= 10.0;
c++;
}
if(minflag== -1) f= 1.0/f;
}
dval= f;
cptr=c;
#ifdef YYDEBUG
if(yydebug) printf("number:FLTVALUE %f",f);
#endif
return(FLTVALUE);
}
scanstring()
{
int i,length;
char firstchar;
/* skip this string value, you might as well copy it to
the EM file as well, because it is not used internally
*/
/* generate label here */
yylval= genrom();
length=0;
if( fputc('"',emfile) == EOF) fatal("scanstring");
sval= cptr;
firstchar = *cptr;
if( *cptr== '"') cptr++;
while( *cptr !='"')
{
switch(*cptr)
{
case 0:
case '\n':
#ifdef YYDEBUG
if(yydebug) printf("STRVALUE\n");
#endif
if( firstchar == '"')
error("non-terminated string");
return(STRVALUE);
default:
fputc(*cptr,emfile);
}
cptr++;
length++;
}
*cptr=0;
cptr++;
fprintf(emfile,"\\000\"\n");
i=yylval;
yylval= genrom();
fprintf(emfile,"l%d,1,%d\n",i,length);
#ifdef YYDEBUG
if(yydebug) printf("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) printf("end of buffer");
#endif
return(0);
case '"':
return(scanstring());
/* handle double operators */
case ' ':
case '\t':
cptr++;
return(yylex());
case '&':
return(readconstant());
case '?': return(PRINTSYM);
case '>':
if( *(c+1)=='='){
c++;c++;cptr=c; yylval= GESYM;return(RELOP);
}
yylval= '>';
cptr++;
return(RELOP);
break;
case '<':
if( *(c+1)=='='){
c++; c++; cptr=c; yylval=LESYM; return(RELOP);
} else
if( *(c+1)=='>'){
c++; c++; cptr=c; yylval=NESYM; return(RELOP);
}
yylval= '<';
cptr++;
return(RELOP);
}
return(*cptr++);
}

View file

@ -0,0 +1,461 @@
%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 ELSESYM
%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 VARPTR
%left BOOLOP
%left NOTSYM
%left RELOP '=' '<' '>' LESYM GESYM NESYM
%left '+' '-'
%left '*' '/' '\\' MODSYM
%left '^'
%left UNARYMINUS
%{
#define YYDEBUG
#include "bem.h"
int ival; /* parser temporary values */
double dval;
char *sval;
int e1,e2;
int chann; /* input/output channel */
int deftype; /* predefined type declarer */
char *formatstring; /* formatstring used for printing */
Symbol *s; /* Symbol dummy */
%}
%%
programline : INTVALUE {newblock(ival); newemblock(ival);} stmts EOLN
| '#' INTVALUE STRVALUE EOLN
| EOLN
;
stmts : singlestmt
| stmts ':' singlestmt
;
singlestmt : callstmt
| clearstmt
| closestmt
| datastmt
| deffnstmt
| defvarstmt
| defusrstmt
| dimstmt
| ERRORSYM expression {errorstmt($2);}
| fieldstmt
| forstmt
| getstmt
| gosubstmt
| ongotostmt
| ifstmt
| illegalstmt
| inputstmt
| letstmt
| lineinputstmt
| lsetstmt
| midstmt
| exceptionstmt
| nextstmt
| GOTOSYM INTVALUE {gotostmt(ival);}
| openstmt
| optionstmt
| pokestmt
| printstmt
| randomizestmt
| readstmt
| REMSYM
| restorestmt
| returnstmt
| ENDSYM { emcode("loc","0");
emcode("cal","$_hlt");
emcode("asp",EMINTSIZE);}
| STOPSYM { emcode("cal","$_stop");}
| swapstmt
| TRONOFFSYM { tronoff=$1;}
| whilestmt
| wendstmt
| writestmt
| /* EMPTY STATEMENT */
;
illegalstmt: ILLEGAL {illegalcmd();}
callstmt: CALLSYM IDENTIFIER parmlist ')'
{
emcode("cal",proclabel(((Symbol *) $2)->symname));
while($3 -- >0) emcode("asp",EMPTRSIZE);
}
| CALLSYM IDENTIFIER
{ emcode("cal",proclabel(((Symbol *) $2)->symname));}
parmlist: '(' variable { $$=1;}
| parmlist ',' variable { $$= $1+1;}
clearstmt: CLEARSYM {warning("statement ignored");}
| CLEARSYM ',' expression {warning("statement ignored");}
| CLEARSYM ',' expression ',' expression {warning("statement ignored");}
closestmt: CLOSESYM filelist
| CLOSESYM {emcode("cal","$_close");}
filelist: cross intvalue { emcode("loc",$2);
emcode("cal","$_clochn");
emcode("asp",EMINTSIZE);}
| filelist ',' cross intvalue { emcode("loc",$4);
emcode("cal","$_clochn");
emcode("asp",EMINTSIZE);}
datastmt: DATASYM {datastmt();} datalist {fprintf(datfile,"\n");}
dataelm : INTVALUE {fprintf(datfile,"%d",ival);}
| '-' INTVALUE {fprintf(datfile,"%d",-ival);}
| FLTVALUE {fprintf(datfile,"%f",dval);}
| '-' FLTVALUE {fprintf(datfile,"%f",-dval);}
| STRVALUE {fprintf(datfile,"\"%s\"",sval);}
| IDENTIFIER {fprintf(datfile,"\"%s\"",sval);}
;
datalist: dataelm
| datalist ',' {fputc(',',datfile);} dataelm
;
deffnstmt: DEFSYM heading '=' expression {endscope($4);}
heading : FUNCTID { newscope($1); heading();}
| FUNCTID {newscope($1);} '(' idlist ')' { heading();}
idlist : IDENTIFIER { dclparm($1);}
| idlist ',' IDENTIFIER { dclparm($3);}
;
defvarstmt: DEFINTSYM { setdefaulttype( INTTYPE);}
| DEFSNGSYM { setdefaulttype( FLOATTYPE);}
| DEFDBLSYM { setdefaulttype( DOUBLETYPE);}
| DEFSTRSYM { setdefaulttype( STRINGTYPE);}
defusrstmt: DEFSYM USRSYM error ':' {illegalcmd();}
dimstmt: DIMSYM arraydcl ')' {dclarray($2);}
| dimstmt ',' arraydcl ')' {dclarray($3);}
;
arraydcl : IDENTIFIER '(' INTVALUE {$$=$1; s= (Symbol *) $1;
s->dimlimit[s->dimensions]=ival;
s->dimensions++;
}
| arraydcl ',' INTVALUE {$$=$1; s=(Symbol *) $1;
if(s->dimensions<MAXDIMENSIONS)
{
s->dimlimit[s->dimensions]=ival;
s->dimensions++;
} else
error("too many dimensions");
}
fieldstmt: FIELDSYM cross intvalue {setchannel(ival);} ',' fieldlist {notyetimpl();}
fieldlist: intvalue ASSYM variable
| fieldlist ',' intvalue ASSYM variable
;
forstmt: FORSYM IDENTIFIER {forinit($2);} '=' expression {forexpr($5);}
TOSYM expression {forlimit($8);} step
;
step : STEPSYM expression {forstep($2);}
| /*EMPTY*/ {emcode("loc","1"); forstep(INTTYPE);}
;
nextstmt: NEXTSYM IDENTIFIER {nextstmt($2);}
| NEXTSYM { nextstmt(0);}
| nextstmt ',' IDENTIFIER { nextstmt($3);}
getstmt: getput {emcode("loc",itoa(0));
emcode("cal",$1);
emcode("asp",EMINTSIZE);}
| getput ',' intvalue
{ /* position seek pointer first*/
emcode("loc",itoa(ival));
emcode("cal",$1);
emcode("asp",EMINTSIZE);
}
getput: GETSYM cross intvalue { setchannel(ival); $$= (YYSTYPE)"$_getrec";}
| PUTSYM cross intvalue { setchannel(ival); $$= (YYSTYPE)"$_putsym";}
gosubstmt: GOSUBSYM INTVALUE {gosubstmt(ival);}
returnstmt: RETURNSYM {returnstmt();}
ifstmt: IFSYM expression {$1=ifstmt($2);} thenpart
{$1=thenpart($1);} elsepart {elsepart($1);}
;
thenpart: THENSYM INTVALUE {gotostmt(ival);}
| THENSYM stmts
| GOTOSYM INTVALUE {gotostmt(ival);}
;
elsepart: ELSESYM INTVALUE {gotostmt(ival);}
| ELSESYM stmts
| /* empty */
;
inputstmt: INPUTSYM semiprompt readlist
| INPUTSYM '#' intvalue {setchannel(ival);}',' readlist
;
semiprompt : semi STRVALUE ';' { loadstr($2); prompt(1);}
| semi STRVALUE ',' { loadstr($2); prompt(0);}
| /*EMPTY*/ { setchannel(-1);
emcode("cal","$_qstmark");}
semi : ';' | /* empty */ ;
letstmt: LETSYM {e1=where();} variable {e2=where();}
'=' expression {assign($3,$6);}
| {e1=where();} variable {e2=where();}
'=' expression {assign($2,$5);}
lineinputstmt: LINESYM INPUTSYM semiprompt {setchannel(-1);} variable {linestmt($5);}
| LINESYM '#' intvalue {setchannel(ival);} ',' variable {linestmt($6);}
;
readlist: readelm
| readlist ',' readelm
;
readelm: variable {readelm($1);}
lsetstmt: LSETSYM variable '=' expression {notyetimpl();}
midstmt: MIDSYM '$' midparms '=' expression
{ emcode("cal","$_midstmt");
emcode("asp",EMINTSIZE);
emcode("asp",EMINTSIZE);
emcode("asp",EMPTRSIZE);
emcode("asp",EMPTRSIZE);}
midparms: '(' midfirst midsec midthird ')'
midfirst: expression { conversion($1,STRINGTYPE); }
midsec: ',' expression { conversion($2,INTTYPE); }
midthird: ',' expression { conversion($2,INTTYPE); }
| /* empty */ { emcode("loc","-1");}
exceptionstmt: ONSYM ERRORSYM GOTOSYM INTVALUE {exceptstmt(ival);}
ongotostmt: ONSYM expression
GOSUBSYM constantlist {ongosubstmt($2);}
| ONSYM expression
GOTOSYM constantlist {ongotostmt($2);}
constantlist: INTVALUE {jumpelm(ival);}
| constantlist ',' INTVALUE { jumpelm(ival);}
openstmt: OPENSYM mode openchannel expression
{ conversion($4,STRINGTYPE); openstmt(0);}
| OPENSYM mode openchannel
expression {conversion($4,STRINGTYPE);}
INTVALUE { openstmt(ival);}
openchannel: cross INTVALUE ',' { setchannel(ival);}
mode : expression ',' {conversion($1,STRINGTYPE);}
| ',' { emcode("lae","_iomode");}
;
optionstmt: OPTIONSYM BASESYM intvalue { optionbase($3);}
printstmt: PRINTSYM {setchannel(-1);emcode("cal","$_nl");}
| PRINTSYM file format printlist
{ if( $4) emcode("cal","$_nl");}
file : '#' intvalue ',' {setchannel(ival);}
| /* empty */ {setchannel(-1);}
;
format : USINGSYM STRVALUE ';' { loadstr($2);}
| USINGSYM variable ';' {
if($2!=STRINGTYPE) error("string variable expected");}
| /* empty */ {formatstring=0;}
printlist: expression { printstmt($1); $$=1;}
| ',' { zone(0); $$=0;}
| ';' { zone(1); $$=0;}
| printlist expression { printstmt($2); $$=1;}
| printlist ',' { zone(1);$$=0;}
| printlist ';' { zone(0);$$=0;}
;
pokestmt: POKESYM expression ',' expression {pokestmt($2,$4);}
;
randomizestmt: RANDOMIZESYM
{ emcode("cal","$_randomize");}
| RANDOMIZESYM expression
{ conversion($2,INTTYPE);
emcode("cal","$_setrandom");
emcode("asp",EMINTSIZE);}
readstmt: READSYM {setchannel(0);} variable { readelm($3);}
| readstmt ',' variable { readelm($3);}
restorestmt: RESTORESYM INTVALUE { restore(ival);}
| RESTORESYM { restore(0);}
swapstmt: SWAPSYM variable ',' variable { swapstmt($2,$4);}
whilestmt: WHILESYM {whilestart();} expression {whiletst($3);}
;
wendstmt : WENDSYM {wend();}
writestmt: WRITESYM {setchannel(-1);emcode("cal","$_wrnl");}
| WRITESYM file writelist {emcode("cal","$_wrnl");}
;
writelist: expression {writestmt($1,0);}
| writelist ',' expression {writestmt($3,1);}
;
cross: '#' | /* empty */
intvalue: INTVALUE
;
variable: identifier { $$=loadaddr($1);}
| indexed ')' {$$=endarrayload();}
| ERRSYM {emcode("lae","_errsym"); $$= INTTYPE;}
| ERLSYM {emcode("lae","_erlsym"); $$= INTTYPE;}
;
indexed : identifier '(' {newarrayload($1);}
expression {loadarray($4); $$=$1;}
| indexed ',' expression {loadarray($3); $$=$1;}
;
expression: negation
| negation BOOLOP expression {$$=boolop($1,$3,$2);}
negation: NOTSYM compare {$$=boolop($2,0,NOTSYM);}
| compare
;
compare : sum
| sum RELOP sum {$$=relop($1,$3,$2);}
| sum '=' sum {$$=relop($1,$3,'=');}
sum : term
| term '-' sum {$$=plusmin($1,$3,'-');}
| term '+' sum {$$=plusmin($1,$3,'+');}
term : factor
| factor '^' factor {$$=power($1,$3);}
| factor '*' term {$$=muldiv($1,$3,'*');}
| factor '\\' term {$$=muldiv($1,$3,'\\');}
| factor '/' term {$$=muldiv($1,$3,'/');}
| factor MODSYM term {$$=muldiv($1,$3,MODSYM);}
factor : INTVALUE {$$=loadint(ival);}
| '(' expression ')' {$$=$2;}
| '-' factor { $$=negate($2);}
| FLTVALUE {$$=loaddbl(dval);}
| STRVALUE {$$=loadstr($1);}
| variable {$$=loadvar($1);}
| INKEYSYM '$' { emcode("cal","$_inkey");
emcode("lfr",EMPTRSIZE);
$$= STRINGTYPE;
}
| VARPTR '(' '#' intvalue ')' { warning("Not supported"); $$=INTTYPE;}
| FUNCTION {$$= callfcn($1,0);}
| FUNCTION '(' cross exprlist')' {$$=callfcn($1,$4);}
| funcname { $$=fcnend($1);}
| funcname funccall ')' { $$=fcnend($1,$2);}
| MIDSYM '$' midparms
{ emcode("cal","$_mid");
emcode("asp",itoa($3));
emcode("lfr",EMPTRSIZE);
$$= STRINGTYPE;
}
| INPUTSYM '$' '(' expression inputtail
{
emcode("cal","$_inpfcn");
emcode("asp",EMINTSIZE);
emcode("asp",EMINTSIZE);
emcode("asp",EMPTRSIZE);
$$= STRINGTYPE;
}
inputtail: ',' expression ')' { conversion($2,INTTYPE); $$= INTTYPE;}
| ',' '#' expression ')' { conversion($3,INTTYPE); $$= INTTYPE;}
| ')' { emcode("loc","-1"); $$= INTTYPE;}
funcname: FUNCTID {$$=fcncall($1);}
funccall: '(' expression { callparm(0,$2); $$=1;}
| funccall ',' expression { callparm($1,$3); $$=$1+1;}
identifier: IDENTIFIER { dcltype($1); $$=$1;}
exprlist: expression { typetable[0]= $1; $$=1;}
| exprlist ',' expression { typetable[$1]=$3;$$=$1+1;}
%%
#include "lex.c"

38
lang/basic/src.old/bem.c Normal file
View file

@ -0,0 +1,38 @@
#include "bem.h"
/* 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;
main(argc,argv)
int argc;
char **argv;
{
extern int errorcnt;
/* parseparams */
parseparams(argc,argv);
/* initialize the system */
initialize();
/* compile source programs */
compileprogram(program);
linewarnings();
if( errorcnt) exit(-1);
/* process em object files */
simpleprogram();
}

59
lang/basic/src.old/bem.h Normal file
View file

@ -0,0 +1,59 @@
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
/* Author: M.L. Kersten
** Here all the global objects are defined.
*/
#include "symbols.h"
#include "graph.h"
#include "y.tab.h"
#define POINTERSIZE 4
#define MAXINT 32768
#define MININT -32767
#define EMINTSIZE "EM_WSIZE"
#define EMPTRSIZE "EM_PSIZE"
#define EMFLTSIZE "EM_DSIZE"
#define MAXPIECES 100
#define MAXFILENAME 200
#define CHANNEL 0
#define THRESHOLD 40 /* for splitting blocks */
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 *tmpfile; /* 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 int emlinecount; /* counts lines on tmpfile */
extern int dataused;
extern int typetable[10]; /* parameters to standard functions */
extern Linerecord *currline;
extern char *itoa();
extern char *datalabel();
extern char *instrlabel();
extern char *typesize();

View file

@ -0,0 +1,13 @@
#include "bem.h"
/* compile the next program in the list */
FILE *yyin;
compileprogram()
{
while( getline())
yyparse();
fclose(yyin);
}

437
lang/basic/src.old/eval.c Normal file
View file

@ -0,0 +1,437 @@
#include "bem.h"
/* 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)
{
emcode("loc",EMINTSIZE);
emcode("loc",EMFLTSIZE);
emcode("cif","");
}else{
if(debug)
printf("type n=%d o=%d\n",newtype,oldtype);
error("conversion error");
}
break;
case FLOATTYPE:
case DOUBLETYPE:
if( newtype==INTTYPE)
{
/* rounded ! */
emcode("cal","$_cint");
emcode("asp",EMFLTSIZE);
emcode("lfr",EMINTSIZE);
break;
}else
if( newtype== FLOATTYPE || newtype==DOUBLETYPE)
break;
default:
if(debug)
printf("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) printf("extra convert %d %d %d\n",oldtype,newtype,topstack);
/* save top in dummy */
switch( topstack)
{
case INTTYPE:
emcode("ste","dummy1");
break;
case FLOATTYPE:
case DOUBLETYPE:
/* rounded ! */
emcode("lae","dummy1");
emcode("sti",EMFLTSIZE);
break;
default:
error("conversion error");
return;
}
/* now its on top of the stack */
conversion(oldtype,newtype);
/* restore top */
switch( topstack)
{
case INTTYPE:
emcode("loe","dummy1");
break;
case FLOATTYPE:
case DOUBLETYPE:
/* rounded ! */
emcode("lae","dummy1");
emcode("loi",EMFLTSIZE);
}
}
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: emcode("com",EMINTSIZE); break;
case ANDSYM: emcode("and",EMINTSIZE); break;
case ORSYM: emcode("ior",EMINTSIZE); break;
case XORSYM: emcode("xor",EMINTSIZE); break;
case EQVSYM:
emcode("xor",EMINTSIZE);
emcode("com",EMINTSIZE);
break;
case IMPSYM:
/* implies */
emcode("com",EMINTSIZE);
emcode("and",EMINTSIZE);
emcode("com",EMINTSIZE);
break;
default: error("boolop:unexpected");
}
return(INTTYPE);
}
genbool(opcode)
char *opcode;
{
int l1,l2;
l1= genlabel();
l2= genlabel();
emcode(opcode,instrlabel(l1));
emcode("loc",itoa(0));
emcode("bra",instrlabel(l2));
fprintf(tmpfile,"%d\n",l1); emlinecount++;
emcode("loc",itoa(-1));
fprintf(tmpfile,"%d\n",l2); emlinecount++;
}
relop( ltype,rtype,operator)
int ltype,rtype,operator;
{
int result;
if(debug) printf("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)
emcode("cmi", EMINTSIZE);
else
if( result==FLOATTYPE || result==DOUBLETYPE)
emcode("cmf",EMFLTSIZE);
else
if( result==STRINGTYPE)
{
emcode("cal","$_strcompare");
emcode("asp",EMPTRSIZE);
emcode("asp",EMPTRSIZE);
emcode("lfr",EMINTSIZE);
} else error("relop:unexpected");
/* handle the relational operators */
switch(operator)
{
case '<': genbool("zlt"); break;
case '>': genbool("zgt"); break;
case '=': genbool("zeq"); break;
case NESYM: genbool("zne"); break;
case LESYM: genbool("zle"); break;
case GESYM: genbool("zge"); break;
default: error("relop:unexpected operator");
}
return(INTTYPE);
}
plusmin(ltype,rtype,operator)
int ltype,rtype,operator;
{
int result;
result= exprtype(ltype,rtype);
if( result== STRINGTYPE)
{
if( operator== '+')
{
emcode("cal","$_concat");
emcode("asp",EMPTRSIZE);
emcode("asp",EMPTRSIZE);
emcode("lfr",EMPTRSIZE);
} else error("illegal operator");
} else {
extraconvert(ltype,result,rtype);
conversion(rtype,result);
if( result== INTTYPE)
{
if( operator=='+')
emcode("adi",EMINTSIZE);
else emcode("sbi",EMINTSIZE);
} else{
if( operator=='+')
emcode("adf",EMFLTSIZE);
else emcode("sbf",EMFLTSIZE);
}
}
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);
emcode("dvf",EMFLTSIZE);
} else
if( operator=='\\')
emcode("dvi",EMINTSIZE);
else
if( operator=='*')
emcode("mli",EMINTSIZE);
else
if( operator==MODSYM)
emcode("rmi",EMINTSIZE);
else error("illegal operator");
} else{
if( operator=='/')
emcode("dvf",EMFLTSIZE);
else
if( operator=='*')
emcode("mlf",EMFLTSIZE);
else error("illegal operator");
}
return(result);
}
negate(type)
int type;
{
switch(type)
{
case INTTYPE:
emcode("ngi",EMINTSIZE); break;
case DOUBLETYPE:
case FLOATTYPE:
emcode("ngf",EMFLTSIZE); break;
default:
error("Illegal operator");
}
return(type);
}
power(ltype,rtype)
int ltype,rtype;
{
extraconvert(ltype,DOUBLETYPE,rtype);
conversion(rtype,DOUBLETYPE);
emcode("cal","$_power");
emcode("asp",EMFLTSIZE);
emcode("asp",EMFLTSIZE);
emcode("lfr",EMFLTSIZE);
return(DOUBLETYPE);
}
char *typesize(ltype)
int ltype;
{
switch( ltype)
{
case INTTYPE:
return(EMINTSIZE);
case FLOATTYPE:
case DOUBLETYPE:
return(EMFLTSIZE);
case STRINGTYPE:
return(EMPTRSIZE);
default:
error("typesize:unexpected");
if(debug) printf("type received %d\n",ltype);
}
return(EMINTSIZE);
}
/*
loadptr(s)
Symbol *s;
{
if( POINTERSIZE==WORDSIZE)
fprintf(tmpfile," loe l%d\n",s->symalias);
else
if( POINTERSIZE== 2*WORDSIZE)
fprintf(tmpfile," lde l%d\n",s->symalias);
else error("loadptr:unexpected pointersize");
}
*/
char *typestring(type)
int type;
{
switch(type)
{
case INTTYPE:
return(EMINTSIZE);
case FLOATTYPE:
case DOUBLETYPE:
return(EMFLTSIZE);
case STRINGTYPE:
return(EMPTRSIZE);
default:
error("typestring: unexpected type");
}
return("0");
}
loadvar(type)
int type;
{
/* load a simple variable its address is on the stack*/
emcode("loi",typestring(type));
return(type);
}
loadint(value)
int value;
{
emcode("loc",itoa(value));
return(INTTYPE);
}
loaddbl(value)
double value;
{
int index;
index= genlabel();
fprintf(emfile,"l%d\n bss 8,%fF8,1\n",index,value);
emcode("lae",datalabel(index));
emcode("loi",EMFLTSIZE);
return(DOUBLETYPE);
}
loadstr(value)
int value;
{
emcode("lae",datalabel(value));
return(STRINGTYPE);
}
loadaddr(s)
Symbol *s;
{
extern Symbol *fcn;
int i,j;
if(debug) printf("load %s %d\n",s->symname,s->symtype);
if( s->symalias>0)
emcode("lae",datalabel(s->symalias));
else{
j= -s->symalias;
if(debug) printf("load parm %d\n",j);
fprintf(tmpfile," lal ");
for(i=fcn->dimensions;i>j;i--)
fprintf(tmpfile,"%s+",typesize(fcn->dimlimit[i-1]));
fprintf(tmpfile,"0\n");
emlinecount++;
/*
emcode("lal",datalabel(fcn->dimalias[-s->symalias]));
*/
}
return(s->symtype);
}
assign(type,lt)
int type,lt;
{
extern int e1,e2;
conversion(lt,type);
exchange(e1,e2);
/* address is on stack already */
emcode("sti",typestring(type) );
}
storevar(lab,type)
int lab,type;
{
/*store value back */
emcode("lae",datalabel(lab));
emcode("sti",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]= s->dimensions;
arraystk[dimtop]= s;
emcode("lae",datalabel(s->symalias));
}
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==0)
{
error("too many indices");
dimstk[dim--]=0;
return;
}
conversion(type,INTTYPE);
dim--;
/* first check index range */
fprintf(tmpfile," lae r%d\n",s->dimalias[dim]);
emlinecount++;
emcode("rck",EMINTSIZE);
emcode("lae",datalabel(s->dimalias[dim]));
emcode("aar",EMINTSIZE);
dimstk[dimtop]--;
}
storearray(type)
{
/* used only in let statement */
extern int e1,e2;
exchange(e1,e2);
emcode("sti",typestring(type));
}

214
lang/basic/src.old/func.c Normal file
View file

@ -0,0 +1,214 @@
#include "bem.h"
/* expression types for predefined functions are assembled */
int typetable[10];
int exprlimit;
/* handle all predefined functions */
#define cv(X) conversion(type,X); pop=X
#define cl(X) emcode("cal",X);
parm(cnt)
int cnt;
{
if( cnt> exprlimit)
error("Not enough arguments");
if( cnt < exprlimit)
error("Too many arguments");
}
callfcn(fcnnr,cnt)
int fcnnr,cnt;
{
int pop=DOUBLETYPE;
int res=DOUBLETYPE;
int type;
type= typetable[0];
exprlimit=cnt;
if(debug) printf("fcn=%d\n",fcnnr);
switch(fcnnr)
{
case ABSSYM: cv(DOUBLETYPE);
cl("$_abr");
parm(1);
break;
case ASCSYM: cv(STRINGTYPE);
cl("$_asc"); res=INTTYPE;
parm(1);
break;
case ATNSYM: cv(DOUBLETYPE);
cl("$_atn");
parm(1);
break;
case CDBLSYM: cv(DOUBLETYPE); return(DOUBLETYPE);;
case CHRSYM: cv(INTTYPE);
cl("$_chr"); res=STRINGTYPE;
parm(1);
break;
case CSNGSYM:
cv(DOUBLETYPE); return(DOUBLETYPE);
case CINTSYM: cv(INTTYPE); return(INTTYPE);
case COSSYM: cv(DOUBLETYPE);
cl("$_cos");
parm(1);
break;
case CVISYM: cv(STRINGTYPE);
cl("$_cvi"); res=INTTYPE;
parm(1);
break;
case CVSSYM: cv(STRINGTYPE);
cl("$_cvd"); res=DOUBLETYPE;
parm(1);
break;
case CVDSYM: cv(STRINGTYPE);
cl("$_cvd"); res=DOUBLETYPE;
parm(1);
break;
case EOFSYM:
if( cnt==0)
{
res= INTTYPE;
pop= INTTYPE;
emcode("loc","-1");
} else cv(INTTYPE);
cl("$_ioeof"); res=INTTYPE;
break;
case EXPSYM: cv(DOUBLETYPE);
cl("$_exp");
parm(1);
break;
case FIXSYM: cv(DOUBLETYPE);
cl("$_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);
cl("$_hex"); res=STRINGTYPE;
parm(1);
break;
case OUTSYM:
case INSTRSYM: cv(DOUBLETYPE);
cl("$_instr"); res=STRINGTYPE;
parm(1);
break;
case INTSYM: cv(DOUBLETYPE);
cl("$_fcint");
parm(1);
break;
case LEFTSYM: parm(2);
extraconvert(type, STRINGTYPE,typetable[1]);
type= typetable[1];
cv(INTTYPE);
cl("$_left"); res=STRINGTYPE;
emcode("asp",EMPTRSIZE);
emcode("asp",EMINTSIZE);
emcode("lfr",EMPTRSIZE);
return(STRINGTYPE);
case LENSYM: cv(STRINGTYPE);
cl("$_len"); res=INTTYPE;
parm(1);
break;
case LOCSYM: cv(INTTYPE);
cl("$_loc"); res=INTTYPE;
parm(1);
break;
case LOGSYM: cv(DOUBLETYPE);
cl("$_log");
parm(1);
break;
case MKISYM: cv(INTTYPE);
cl("$_mki"); res=STRINGTYPE;
parm(1);
break;
case MKSSYM: cv(DOUBLETYPE);
cl("$_mkd"); res=STRINGTYPE;
parm(1);
break;
case MKDSYM: cv(DOUBLETYPE);
cl("$_mkd"); res=STRINGTYPE;
parm(1);
break;
case OCTSYM: cv(INTTYPE);
cl("$_oct"); res=STRINGTYPE;
parm(1);
break;
case PEEKSYM: cv(INTTYPE);
cl("$_peek"); res=INTTYPE;
parm(1);
break;
case POSSYM: emcode("asp",typestring(type));
emcode("exa","_pos");
emcode("loe","_pos");
return(INTTYPE);
case RIGHTSYM: parm(2);
extraconvert(type, STRINGTYPE,typetable[1]);
type= typetable[1];
cv(INTTYPE);
cl("$_right"); res=STRINGTYPE;
emcode("asp",EMINTSIZE);
emcode("asp",EMPTRSIZE);
emcode("lfr",EMPTRSIZE);
return(STRINGTYPE);
case RNDSYM: if( cnt==1) pop=type; else pop=0;
cl("$_rnd"); res= DOUBLETYPE;
break;
case SGNSYM: cv(DOUBLETYPE);
cl("$_sgn"); res=INTTYPE;
parm(1);
break;
case SINSYM: cv(DOUBLETYPE);
cl("$_sin");
parm(1);
break;
case SPACESYM: cv(INTTYPE);
cl("$_space"); res=STRINGTYPE;
parm(1);
break;
case SPCSYM: cv(INTTYPE);
cl("$_spc"); res=0;
parm(1);
break;
case SQRSYM: cv(DOUBLETYPE);
cl("$_sqt");
parm(1);
break;
case STRSYM: cv(DOUBLETYPE);
cl("$_str");
parm(1);
break;
case STRINGSYM: cv(STRINGTYPE);
cl("$_string"); res=STRINGTYPE;
parm(1);
break;
case TABSYM: cv(INTTYPE);
cl("$_tab"); res=0;
parm(1);
break;
case TANSYM: cv(DOUBLETYPE);
cl("$_tan");
parm(1);
break;
case VALSYM: cv(STRINGTYPE);
cl("$atol"); res=INTTYPE;
parm(1);
break;
case VARPTRSYM: cv(DOUBLETYPE);
cl("$_valptr");
parm(1);
break;
default: error("unknown function");
}
if(pop)
emcode("asp",typestring(pop));
if(res)
emcode("lfr",typestring(res));
return(res);
}

View file

@ -0,0 +1,561 @@
#include "bem.h"
/* Here we find all routines dealing with pure EM code generation */
static int emlabel=1;
genlabel() { return(emlabel++);}
genemlabel()
{
int l;
l=genlabel();
fprintf( emfile,"l%d\n",l);
return(l);
}
genrom()
{
int l;
l= genemlabel();
fprintf(emfile," rom ");
return(l);
}
where()
{
return(emlinecount);
}
exchange(blk1,blk2)
int blk1,blk2;
{
/* exchange assembler blocks */
if(debug) printf("exchange %d %d %d\n",blk1,blk2,emlinecount);
fprintf(tmpfile," exc %d,%d\n",blk2-blk1,emlinecount-blk2);
emlinecount++;
}
/* routines to manipulate the tmpfile */
int emlinecount; /* count number of lines generated */
/* this value can be used to generate EXC */
int tronoff=0;
newemblock(nr)
int nr;
{
/* save location on tmpfile */
currline->offset= ftell(tmpfile);
fprintf(tmpfile,"%d\n",currline->emlabel);
fprintf(tmpfile," lin %d\n",nr);
emlinecount += 2;
if( tronoff || traceflag) emcode("cal","$_trace");
}
emcode(operation,params)
char *operation,*params;
{
fprintf(tmpfile," %s %s\n",operation,params);
emlinecount++;
}
/* Handle data statements */
int dataused=0;
List *datalist=0;
datastmt()
{
List *l,*l1;
l= (List *) salloc(sizeof(List));
l->linenr= currline->linenr;
l->emlabel= (long) ftell(datfile);
if( datalist==0)
{
datalist=l;
datfile= fopen(datfname,"w");
if( datfile==NULL) fatal("improper file creation permission");
}else{
l1= datalist;
while(l1->nextlist) l1= l1->nextlist;
l1->nextlist=l;
}
dataused=1;
}
datatable()
{
List *l;
int line=0;
/* called at end to generate the data seek table */
fprintf(emfile," exa _seektable\n");
fprintf(emfile,"_seektable\n");
l= datalist;
while(l)
{
fprintf(emfile," rom %d,%d\n", l->linenr,line++);
l= l->nextlist;
}
fprintf(emfile," rom 0,0\n");
}
/* ERROR and exception handling */
exceptstmt(lab)
int lab;
{
/* exceptions to subroutines are supported only */
extern int gosubcnt;
List *l;
emcode("loc",itoa(gosubcnt));
l= (List *) gosublabel();
l->emlabel= gotolabel(lab);
emcode("cal","$_trpset");
emcode("asp",EMINTSIZE);
}
errorstmt(exprtype)
int exprtype;
{
/* convert expression to a valid error number */
/* obtain the message and print it */
emcode("cal","$error");
emcode("asp",typesize(exprtype));
}
/* BASIC IO */
openstmt(recsize)
int recsize;
{
emcode("loc",itoa(recsize));
emcode("cal","$_opnchn");
emcode("asp",EMPTRSIZE);
emcode("asp",EMPTRSIZE);
emcode("asp",EMINTSIZE);
}
printstmt(exprtype)
int exprtype;
{
switch(exprtype)
{
case INTTYPE:
emcode("cal","$_prinum");
emcode("asp",typestring(INTTYPE));
break;
case FLOATTYPE:
case DOUBLETYPE:
emcode("cal","$_prfnum");
emcode("asp",typestring(DOUBLETYPE));
break;
case STRINGTYPE:
emcode("cal","$_prstr");
emcode("asp",EMPTRSIZE);
break;
case 0: /* result of tab function etc */
break;
default:
error("printstmt:unexpected");
}
}
zone(i)
int i;
{
if( i)emcode("cal","$_zone");
}
writestmt(exprtype,comma)
int exprtype,comma;
{
if( comma) emcode("cal","$_wrcomma");
switch(exprtype)
{
case INTTYPE:
emcode("cal","$_wrint");
break;
case FLOATTYPE:
case DOUBLETYPE:
emcode("cal","$_wrint");
break;
case STRINGTYPE:
emcode("cal","$_wrstr");
break;
default:
error("printstmt:unexpected");
}
emcode("asp",EMPTRSIZE);
}
restore(lab)
int lab;
{
/* save this information too */
emcode("loc",itoa(0));
emcode("cal","$_setchannel");
emcode("asp",EMINTSIZE);
emcode("loc",itoa(lab));
emcode("cal","$_restore");
emcode("asp",EMINTSIZE);
}
prompt(qst)
int qst;
{
setchannel(-1);
emcode("cal","$_prstr");
emcode("asp",EMPTRSIZE);
if(qst) emcode("cal","$_qstmark");
}
linestmt(type)
int type;
{
if( type!= STRINGTYPE)
error("String variable expected");
emcode("cal","$_rdline");
emcode("asp",EMPTRSIZE);
}
readelm(type)
int type;
{
switch(type)
{
case INTTYPE:
emcode("cal","$_readint");
break;
case FLOATTYPE:
case DOUBLETYPE:
emcode("cal","$_readflt");
break;
case STRINGTYPE:
emcode("cal","$_readstr");
break;
default:
error("readelm:unexpected type");
}
emcode("asp",EMPTRSIZE);
}
/* Swap exchanges the variable values */
swapstmt(ltype,rtype)
int ltype, rtype;
{
if( ltype!= rtype)
error("Type mismatch");
else
switch(ltype)
{
case INTTYPE:
emcode("cal","$_intswap");
break;
case FLOATTYPE:
case DOUBLETYPE:
emcode("cal","$_fltswap");
break;
case STRINGTYPE:
emcode("cal","$_strswap");
break;
default:
error("swap:unexpected");
}
emcode("asp",EMPTRSIZE);
emcode("asp",EMPTRSIZE);
}
/* input/output handling */
setchannel(val)
int val;
{ /* obtain file descroption */
emcode("loc",itoa(val));
emcode("cal","$_setchannel");
emcode("asp",EMINTSIZE);
}
/* The if-then-else statements */
ifstmt(type)
int type;
{
/* This BASIC follows the True= -1 rule */
int nr;
nr= genlabel();
if( type == INTTYPE)
emcode("zeq",instrlabel(nr));
else
if( type == FLOATTYPE)
{
emcode("lae","fltnull");
emcode("loi",EMFLTSIZE);
emcode("cmf",EMFLTSIZE);
emcode("zeq",instrlabel(nr));
}
else error("Integer or Float expected");
return(nr);
}
thenpart( elselab)
int elselab;
{
int nr;
nr=genlabel();
emcode("bra",instrlabel(nr));
fprintf(tmpfile,"%d\n",elselab);
emlinecount++;
return(nr);
}
elsepart(lab)int lab;
{
fprintf(tmpfile,"%d\n",lab); emlinecount++;
}
/* 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 */
emcode("lae",datalabel(f->initaddress));
loadvar(type);
conversion(type,DOUBLETYPE);
emcode("lae",datalabel(f->stepaddress));
loadvar(type);
conversion(type,DOUBLETYPE);
emcode("cal","$_sgn");
emcode("asp",EMFLTSIZE);
emcode("lfr",EMINTSIZE);
conversion(INTTYPE,DOUBLETYPE);
emcode("mlf",EMFLTSIZE);
/* evaluate higher bound times sign of step */
emcode("lae",datalabel(f->limitaddress));
loadvar(type);
conversion(type,DOUBLETYPE);
emcode("lae",datalabel(f->stepaddress));
loadvar(type);
conversion(type,DOUBLETYPE);
emcode("cal","$_sgn");
emcode("asp",EMFLTSIZE);
emcode("lfr",EMINTSIZE);
conversion(INTTYPE,DOUBLETYPE);
emcode("mlf",EMFLTSIZE);
/* skip condition */
emcode("cmf",EMFLTSIZE);
emcode("zgt",instrlabel(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 */
emcode("lae",datalabel(f->initaddress));
loadvar(result);
emcode("lae",datalabel(varaddress));
emcode("sti",typestring(result));
emcode("bra",instrlabel(f->fortst));
/* increment loop variable */
fprintf(tmpfile,"%d\n",f->forinc);
emlinecount++;
emcode("lae",datalabel(varaddress));
loadvar(result);
emcode("lae",datalabel(f->stepaddress));
loadvar(result);
if(result == INTTYPE)
emcode("adi",EMINTSIZE);
else emcode("adf",EMFLTSIZE);
emcode("lae",datalabel(varaddress));
emcode("sti",typestring(result));
/* test boundary */
fprintf(tmpfile,"%d\n",f->fortst);
emlinecount++;
emcode("lae",datalabel(varaddress));
loadvar(result);
emcode("lae",datalabel(f->limitaddress));
loadvar(result);
if(result == INTTYPE)
emcode("cmi",EMINTSIZE);
else emcode("cmf",EMFLTSIZE);
emcode("zgt",instrlabel(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 ! */
emcode("bra",instrlabel(fortable[forcnt].forinc));
fprintf(tmpfile,"%d\n",fortable[forcnt].forout);
forcnt--;
}
}
pokestmt(type1,type2)
int type1,type2;
{
conversion(type1,INTTYPE);
conversion(type2,INTTYPE);
emcode("cal","$_poke");
emcode("asp",EMINTSIZE);
emcode("asp",EMINTSIZE);
}
/* 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();
fprintf(tmpfile,"%d\n", whilelabels[whilecnt][0]);
emlinecount++;
}
whiletst(exprtype)
int exprtype;
{
/* test expression type */
conversion(exprtype,INTTYPE);
fprintf(tmpfile," zeq *%d\n",whilelabels[whilecnt][1]);
emlinecount++;
}
wend()
{
if( whilecnt<1)
error("not part of while statement");
else{
fprintf(tmpfile," bra *%d\n",whilelabels[whilecnt][0]);
fprintf(tmpfile,"%d\n",whilelabels[whilecnt][1]);
emlinecount++;
emlinecount++;
whilecnt--;
}
}
/* generate code for the final version */
prologcode()
{
/* generate the EM prolog code */
fprintf(emfile,"fltnull\n con 0,0,0,0\n");
fprintf(emfile,"dummy2\n con 0,0,0,0\n");
fprintf(emfile,"tronoff\n con 0\n");
fprintf(emfile,"dummy1\n con 0,0,0,0\n");
fprintf(emfile," exa _iomode\n_iomode\n rom \"O\"\n");
fprintf(emfile," exa _errsym\n");
fprintf(emfile,"_errsym\n bss 2,0,1\n");
fprintf(emfile," exa _erlsym\n");
fprintf(emfile,"_erlsym\n bss 2,0,1\n");
}
prolog2()
{
fprintf(emfile," exp $main\n");
fprintf(emfile," pro $main,0\n");
fprintf(emfile," mes 3\n");
fprintf(emfile," mes 9,0\n");
/* Trap handling */
fprintf(emfile," cal $_ini_trp\n");
fprintf(emfile," exa trpbuf\n");
fprintf(emfile," lae trpbuf\n");
fprintf(emfile," cal $setjmp\n");
fprintf(emfile," asp 4\n");
fprintf(emfile," lfr %s\n",EMINTSIZE);
fprintf(emfile," dup %s\n",EMINTSIZE);
fprintf(emfile," zeq *0\n");
fprintf(emfile," lae returns\n");
fprintf(emfile," csa %s\n",EMINTSIZE);
fprintf(emfile,"0\n");
fprintf(emfile," asp EM_WSIZE\n");
/* when data lists are used open its file */
if( dataused)
{
fprintf(emfile," loc 0\n");
fprintf(emfile," cal $_setchannel\n");
fprintf(emfile," asp EM_WSIZE\n");
fprintf(emfile,"datfname\n rom \"%s\"\n", datfname);
fprintf(emfile," lae datfname\n");
fprintf(emfile," cal $_opnchn\n");
fprintf(emfile," asp EM_PSIZE\n");
}
datatable();
}
epilogcode()
{
/* finalization code */
int nr;
nr= genlabel();
fprintf(emfile," bra *%d\n",nr);
genreturns();
fprintf(emfile,"%d\n",nr);
fprintf(emfile," loc 0\n");
fprintf(emfile," cal $_hlt\n");
fprintf(emfile," end 0\n");
fprintf(emfile," mes 4,4\n");
}

279
lang/basic/src.old/graph.c Normal file
View file

@ -0,0 +1,279 @@
#include "bem.h"
List *forwardlabel=0;
/* 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))
{
printf("ERROR: line %d not defined\n",l->linenr);
errorcnt++;
}
l=l->nextlist;
}
}
newblock(nr)
int nr;
{
Linerecord *l;
List *frwrd;
if( debug) printf("newblock at %d\n",nr);
if( nr>0 && currline && currline->linenr>= nr)
{
if( debug) printf("old line:%d\n",currline->linenr);
error("Lines out of sequence");
}
frwrd=srchforward(nr);
if( frwrd && debug) printf("forward found %d\n",frwrd->emlabel);
l= srchline(nr);
if( l)
{
error("Line redefined");
nr= -genlabel();
}
/* make new EM block structure */
l= (Linerecord *) salloc(sizeof(*l));
l->emlabel= frwrd? frwrd->emlabel: genlabel();
l->linenr= nr;
/* save offset into tmpfile too */
l->offset = (long) ftell(tmpfile);
l->codelines= emlinecount;
/* 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) printf("goto label %d\n",nr);
/* update currline */
ll= (List *) salloc( sizeof(*ll));
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) printf("declare forward %d\n",nr);
ll= (List *) salloc( sizeof(*ll));
ll->emlabel= genlabel();
ll-> linenr=nr;
ll->nextlist= forwardlabel;
forwardlabel= ll;
nr= ll->emlabel;
} else
nr= l1->emlabel;
return(nr);
}
gotostmt(nr)
int nr;
{
emcode("bra",instrlabel(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;
int n;
l= (List *) salloc(sizeof(List));
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);
emcode("loc",itoa(n)); /*return index */
emcode("cal","$_gosub"); /* administer legal return */
emcode("asp",EMINTSIZE);
emcode("bra",instrlabel(nr));
fprintf(tmpfile,"%d\n",l->emlabel);
emlinecount++;
}
genreturns()
{
int nr;
nr= genlabel();
fprintf(emfile,"returns\n");
fprintf(emfile," rom *%d,1,%d\n",nr,gosubcnt-1);
while( gosubhead)
{
fprintf(emfile," rom *%d\n",gosubhead->emlabel);
gosubhead= gosubhead->nextlist;
}
fprintf(emfile,"%d\n",nr);
fprintf(emfile," loc 1\n");
fprintf(emfile," cal $error\n");
}
returnstmt()
{
emcode("cal","$_retstmt"); /* ensure legal return*/
emcode("lfr",EMINTSIZE);
fprintf(tmpfile," lae returns\n");
emlinecount++;
emcode("csa",EMINTSIZE);
}
/* compound goto-gosub statements */
List *jumphead,*jumptail;
int jumpcnt;
jumpelm(nr)
int nr;
{
List *l;
l= (List *) salloc(sizeof(List));
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();
fprintf(tmpfile,"l%d\n",descr); emlinecount++;
fprintf(tmpfile," rom *%d,1,%d\n",firstlabel,jumpcnt); emlinecount++;
l= jumphead;
while( l)
{
fprintf(tmpfile," rom *%d\n",l->emlabel); emlinecount++;
l= l->nextlist;
}
jumphead= jumptail=0; jumpcnt=0;
if(debug) printf("ongotst:%d labels\n", jumpcnt);
conversion(type,INTTYPE);
emcode("lae",datalabel(descr));
emcode("csa",EMINTSIZE);
fprintf(tmpfile,"%d\n",firstlabel); emlinecount++;
}
ongosubstmt(type)
int type;
{
List *l;
int firstlabel;
int descr;
/* create descriptor first */
descr= genlabel();
firstlabel=genlabel();
fprintf(tmpfile,"l%d\n",descr); emlinecount++;
fprintf(tmpfile," rom *%d,1,%d\n",firstlabel,jumpcnt); emlinecount++;
l= jumphead;
while( l)
{
fprintf(tmpfile," rom *%d\n",l->emlabel); emlinecount++;
l= l->nextlist;
}
jumphead= jumptail=0; jumpcnt=0;
l= (List *) salloc(sizeof(List));
l->nextlist=0;
l->emlabel=firstlabel;
if( gotail){
gotail->nextlist=l;
gotail=l;
} else gotail= gosubhead=l;
/* save the return point of the gosub */
emcode("loc",itoa(gosubcnt));
emcode("cal","$_gosub");
emcode("asp",EMINTSIZE);
gosubcnt++;
/* generate gosub */
conversion(type,INTTYPE);
emcode("lae",datalabel(descr));
emcode("csa",EMINTSIZE);
fprintf(tmpfile,"%d\n",firstlabel);
emlinecount++;
}
/* REGION ANALYSIS and FINAL VERSION GENERATION */
simpleprogram()
{
char buf[512];
int length;
/* a small EM programs has been found */
prologcode();
prolog2();
fclose(tmpfile);
tmpfile= fopen(tmpfname,"r");
if( tmpfile==NULL)
fatal("tmp file disappeared");
while( (length=fread(buf,1,512,tmpfile)) != 0)
fwrite(buf,1,length,emfile);
epilogcode();
unlink(tmpfname);
}

View file

@ -0,0 +1,23 @@
#include "bem.h"
/* generate temporary files etc */
FILE *emfile;
FILE *tmpfile;
FILE *datfile;
initialize()
{
sprintf(tmpfname,"/tmp/abc%d",getpid());
strcpy(datfname,program);
strcat(datfname,".d");
yyin= fopen(inpfile,"r");
emfile= fopen(outfile,"w");
tmpfile= fopen(tmpfname,"w");
if( yyin==NULL || emfile== NULL || tmpfile== NULL )
fatal("Improper file permissions");
fillkex(); /* initialize symbol table */
fprintf(emfile,"#\n");
fprintf(emfile," mes 2,EM_WSIZE,EM_PSIZE\n");
initdeftype(); /* set default symbol declarers */
}

View file

@ -0,0 +1,51 @@
#include "bem.h"
int listing; /* -l listing required */
int debug; /* -d compiler debugging */
int wflag=1; /* -w no warnings */
int hflag=0; /* -h<number> to split EM program */
int traceflag=0; /* generate line tracing code */
int nolins=0; /* generate no LIN statements */
parseparams(argc,argv)
int argc;
char **argv;
{
int i,j,k;
char *ext;
j=k=0;
if(argc< 4)
{
fprintf(stderr,"usage %s <flags> <file>.i <file>.e <source>\n", argv[0]);
exit(-1);
}
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 */
hflag=0;
threshold= (long) atol(argv[i][2]);
if( threshold==0)
threshold= THRESHOLD;
break;
case 'd': debug++; break;
case 'l': nolins++; break; /* no EM lin statements */
case 'E': listing++; break; /* generate full listing */
} else {
/* new input file */
ext= argv[i]+strlen(argv[i])-1;
if( *(ext-1) != '.')
/* should be the source file name */
program= argv[i];
else
if( *ext == 'i')
inpfile= argv[i];
else
if( *ext == 'e')
outfile= argv[i];
}
}

View file

@ -0,0 +1,86 @@
#include "bem.h"
/* Split the intermediate code into procedures.
This is necessary to make the EM code fit on
smaller machines. (for the Peephole optimizer!)
*/
/* Heuristic is to collect all basic blocks of more then THRESHOLD
em instructions into a procedure
*/
int procnum;
int threshold; /* can be set by the user */
fix(lnr)
int lnr;
{
/* this block may not be moved to a procedure */
Linerecord *lr;
if(debug) printf("fixate %d\n",lnr);
for(lr= firstline;lr; lr=lr->nextline)
if( lr->linenr == lnr)
lr->fixed=1;
}
fixblock(l)
List *l;
{
while(l)
{
fix(l->linenr);
l=l->nextlist;
}
}
phase1()
{
/* copy all offloaded blocks */
Linerecord *lr, *lf,*lr2;
int blksize;
lf= lr= firstline;
blksize= lr->codelines;
while( lr)
{
if( lr->fixed){
if( !lf->fixed && blksize>threshold)
{
/*move block */
if(debug) printf("%d %d->%d moved\n",
blksize,lf->linenr, lr->linenr);
}
lf= lr;
blksize= lr->codelines;
}
lr= lr->nextline;
}
}
phase2()
{
/* copy main procedure */
prolog2();
epilogcode();
}
split()
{
/* selectively copy the intermediate code to procedures */
Linerecord *lr;
if( debug) printf("split EM code using %d\n",threshold);
/* First consolidate the goto's and caller's */
lr= firstline;
while(lr)
{
fixblock(lr->callers);
fixblock(lr->gotos);
lr= lr->nextline;
}
/* Copy the temporary file piecewise */
prologcode();
phase1();
phase2();
}

View file

@ -0,0 +1,285 @@
#include "bem.h"
/* 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) printf("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 emty slot */
s= (Symbol *) salloc(sizeof(Symbol));
s->symtype= DEFAULTTYPE;
s->nextsym= firstsym;
s->symname= (char *) salloc(strlen(str)+1);
strcpy(s->symname,str);
firstsym= s;
if(debug) printf("%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) printf("symbol set to %d\n",type);
}
dclarray(s)
Symbol *s;
{
int i; int size;
if( s->symtype==DEFAULTTYPE) s->symtype= DOUBLETYPE;
if(debug) printf("generate space and descriptors for %d\n",s->symtype);
if(debug) printf("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--)
{
fprintf(emfile,"l%d\n rom %d,%d,%d*%s\n",
s->dimalias[i],
indexbase,
s->dimlimit[i]-indexbase,
size, typesize(s->symtype));
size = size* (s->dimlimit[i]+1-indexbase);
}
if(debug) printf("size=%d\n",size);
/* size of stuff */
fprintf(emfile,"l%d\n bss %d*%s,0,1\n",
s->symalias,size,typesize(s->symtype));
/* Generate the range check descriptors */
for( i= 0; i<s->dimensions;i++)
fprintf(emfile,"r%d\n rom %d,%d\n",
s->dimalias[i],
indexbase,
s->dimlimit[i]);
}
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:
fprintf(emfile," bss %s,0,1\n",EMPTRSIZE);
break;
case INTTYPE:
fprintf(emfile," bss %s,0,1\n",EMINTSIZE);
break;
case FLOATTYPE:
case DOUBLETYPE:
fprintf(emfile," bss 8,0.0F %s,1\n",EMFLTSIZE);
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) printf("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) printf("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];
sprintf(procname,"$_%s",fcn->symname);
emcode("pro",procname);
if( fcn->symtype== DEFAULTTYPE)
fcn->symtype= DOUBLETYPE;
}
fcnsize(s)
Symbol *s;
{
/* generate portable function size */
int i;
for(i=0;i<fcn->dimensions;i++)
fprintf(tmpfile,"%s+",typesize(fcn->dimlimit[i]));
fprintf(tmpfile,"0\n"); emlinecount++;
}
endscope(type)
int type;
{
Symbol *s;
if( debug) printf("endscope");
conversion(type,fcn->symtype);
emcode("ret", typestring(fcn->symtype));
/* generate portable EM code */
fprintf(tmpfile," end ");
fcnsize(fcn);
s= firstsym;
while(s)
{
firstsym = s->nextsym;
free(s);
s= firstsym;
}
firstsym= alternate;
alternate = NIL;
fcn=NIL;
}
dclparm(s)
Symbol *s;
{
int i,size=0;
if( s->symtype== DEFAULTTYPE)
s->symtype= DOUBLETYPE;
s->isparam=1;
fcn->dimlimit[fcn->dimensions]= s->symtype;
fcn->dimensions++;
/*
OLD STUFF
for(i=fcn->dimensions;i>0;i--)
fcn->dimalias[i]= fcn->dimalias[i-1];
*/
/*fcn->parmsize += typesize(s->symtype);*/
/* fcn->dimalias[0]= -typesize(s->symtype)-fcn->dimalias[1];*/
s->symalias= -fcn->dimensions;
if( debug) printf("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;
}
}
fcnend(fcntype, parmcount)
int fcntype, parmcount;
{
int type;
/* check number of arguments */
if( parmcount <fcn->dimensions)
error("not enough parameters");
if( parmcount >fcn->dimensions)
error("too many parameters");
fprintf(tmpfile," cal $_%s\n",fcn->symname);
emlinecount++;
fprintf(tmpfile," asp ");
fcnsize(fcn);
emcode("lfr",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]);
}

74
lang/basic/src.old/util.c Normal file
View file

@ -0,0 +1,74 @@
#include "bem.h"
#define abs(X) (X>=0?X:-X)
/* Miscelaneous routines can be found here */
int errorcnt;
warning(str)
char *str;
{
printf("WARNING:%s\n",str);
}
error(str)
char *str;
{
extern int listing,yylineno;
if( !listing) printf("LINE %d:",yylineno);
printf("ERROR:%s\n",str);
errorcnt++;
}
fatal(str)
char *str;
{
printf("FATAL:%s\n",str);
exit(-1);
}
notyetimpl()
{
printf("WARNING: not yet implemented\n");
}
illegalcmd()
{
printf("WARNING: illegal command\n");
}
char *itoa(i)
int i;
{
static char buf[30];
sprintf(buf,"%d",i);
return(buf);
}
char *instrlabel(i)
int i;
{
static char buf[30];
sprintf(buf,"*%d",i);
return(buf);
}
char *datalabel(i)
int i;
{
static char buf[30];
if( i>0)
sprintf(buf,"l%d",i);
else sprintf(buf,"%d",-i);
return(buf);
}
char *salloc(length)
int length;
{
char *s,*c;
s=c= (char *) malloc(length);
while(length-->0)*c++ =0;
return(s);
}
char * proclabel(str)
char *str;
{
static char buf[50];
sprintf(buf,"$%s",str);
return(buf);
}

View file

@ -0,0 +1,17 @@
#include "bem.h"
/* Author: M.L. Kersten
** yywrap is called upon encountering endoffile on yyin.
** when more input files are present, it moves to the next
** otherwise -1 is returned and simultaneous endofinput is set
*/
int endofinput =0;
yywrap()
{
if( fclose(yyin) == EOF)
fatal("fclose problems ");
/* check for next input file */
return(-1);
}