commit
e2625813c9
|
@ -90,6 +90,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "bem.h"
|
#include "bem.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "gencode.h"
|
||||||
|
#include "eval.h"
|
||||||
|
#include "func.h"
|
||||||
#include "llmess.h"
|
#include "llmess.h"
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef NORSCID
|
|
||||||
|
#ifndef NORCSID
|
||||||
static char rcs_lex[] = "$Id$" ;
|
static char rcs_lex[] = "$Id$" ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -151,7 +152,7 @@ Key keywords [] ={
|
||||||
int kex[27];
|
int kex[27];
|
||||||
|
|
||||||
/* Initialize the keyword table */
|
/* Initialize the keyword table */
|
||||||
fillkex()
|
void fillkex(void)
|
||||||
{
|
{
|
||||||
Key *k;
|
Key *k;
|
||||||
int i;
|
int i;
|
||||||
|
@ -235,7 +236,7 @@ File *stream;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getinputline()
|
int getinputline(void)
|
||||||
{
|
{
|
||||||
/* get next input line */
|
/* get next input line */
|
||||||
|
|
||||||
|
@ -255,7 +256,7 @@ getinputline()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typechar()
|
int typechar(void)
|
||||||
{
|
{
|
||||||
switch(*cptr)
|
switch(*cptr)
|
||||||
{
|
{
|
||||||
|
@ -277,7 +278,7 @@ typechar()
|
||||||
char name[SIGNIFICANT+1];
|
char name[SIGNIFICANT+1];
|
||||||
|
|
||||||
|
|
||||||
lookup()
|
int lookup(void)
|
||||||
{
|
{
|
||||||
Key *k;
|
Key *k;
|
||||||
Symbol *Sym;
|
Symbol *Sym;
|
||||||
|
@ -341,7 +342,7 @@ lookup()
|
||||||
|
|
||||||
|
|
||||||
/* Parsing unsigned numbers */
|
/* Parsing unsigned numbers */
|
||||||
readconstant()
|
int readconstant(void)
|
||||||
{
|
{
|
||||||
/* read HEX and OCTAL numbers */
|
/* read HEX and OCTAL numbers */
|
||||||
char *c;
|
char *c;
|
||||||
|
@ -372,9 +373,7 @@ readconstant()
|
||||||
#ifdef ____
|
#ifdef ____
|
||||||
/* Computes base to the power exponent. This was not done in the old
|
/* Computes base to the power exponent. This was not done in the old
|
||||||
compiler */
|
compiler */
|
||||||
double powr(base,exp)
|
double powr(double base,int exp)
|
||||||
double base;
|
|
||||||
int exp;
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
double result;
|
double result;
|
||||||
|
@ -398,7 +397,7 @@ int exp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
number()
|
int number(void)
|
||||||
{
|
{
|
||||||
long i1;
|
long i1;
|
||||||
int overflow = 0;
|
int overflow = 0;
|
||||||
|
@ -468,7 +467,7 @@ number()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
scanstring()
|
int scanstring(void)
|
||||||
{
|
{
|
||||||
int i,length=0;
|
int i,length=0;
|
||||||
char firstchar = *cptr;
|
char firstchar = *cptr;
|
||||||
|
@ -532,7 +531,7 @@ scanstring()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
yylex()
|
int yylex(void)
|
||||||
{
|
{
|
||||||
char *c;
|
char *c;
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "bem.h"
|
#include "bem.h"
|
||||||
|
#include "parsepar.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "graph.h"
|
||||||
|
|
||||||
#ifndef NORSCID
|
|
||||||
|
#ifndef NORCSID
|
||||||
static char rcs_id[] = "$Id$" ;
|
static char rcs_id[] = "$Id$" ;
|
||||||
static char rcs_bem[] = RCS_BEM ;
|
static char rcs_bem[] = RCS_BEM ;
|
||||||
static char rcs_symb[] = RCS_SYMB ;
|
static char rcs_symb[] = RCS_SYMB ;
|
||||||
|
@ -33,9 +37,11 @@ char *inpfile, *outfile;
|
||||||
int BEMINTSIZE = EMINTSIZE;
|
int BEMINTSIZE = EMINTSIZE;
|
||||||
int BEMPTRSIZE = EMPTRSIZE;
|
int BEMPTRSIZE = EMPTRSIZE;
|
||||||
int BEMFLTSIZE = EMFLTSIZE;
|
int BEMFLTSIZE = EMFLTSIZE;
|
||||||
main(argc,argv)
|
|
||||||
int argc;
|
extern void initialize(void);
|
||||||
char **argv;
|
extern void compileprogram(void);
|
||||||
|
|
||||||
|
int main(int argc,char **argv)
|
||||||
{
|
{
|
||||||
extern int errorcnt;
|
extern int errorcnt;
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <system.h>
|
#include "system.h"
|
||||||
#include <print.h>
|
#include "print.h"
|
||||||
#include <em.h>
|
#include "em.h"
|
||||||
#include <em_mes.h>
|
#include "em_mes.h"
|
||||||
|
|
||||||
/* Author: M.L. Kersten
|
/* Author: M.L. Kersten
|
||||||
** Here all the global objects are defined.
|
** Here all the global objects are defined.
|
||||||
|
|
|
@ -3,19 +3,25 @@
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*#include "bem.h"*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "system.h"
|
||||||
|
#include "gencode.h"
|
||||||
#include "bem.h"
|
#include "bem.h"
|
||||||
|
|
||||||
#ifndef NORSCID
|
#ifndef NORCSID
|
||||||
static char rcs_id[] = "$Id$" ;
|
static char rcs_id[] = "$Id$" ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern int getinputline(void);
|
||||||
|
extern void LLparse(void);
|
||||||
|
|
||||||
/* compile the next program in the list */
|
/* compile the next program in the list */
|
||||||
/* Here we should open the input file. (for the future) */
|
/* Here we should open the input file. (for the future) */
|
||||||
|
|
||||||
File *yyin;
|
File *yyin;
|
||||||
|
|
||||||
compileprogram()
|
void compileprogram(void)
|
||||||
{
|
{
|
||||||
extern int basicline;
|
extern int basicline;
|
||||||
|
|
||||||
|
@ -24,7 +30,9 @@ compileprogram()
|
||||||
epilogcode in the new version of the compiler */
|
epilogcode in the new version of the compiler */
|
||||||
|
|
||||||
while( basicline = 0, getinputline())
|
while( basicline = 0, getinputline())
|
||||||
(void) LLparse();
|
{
|
||||||
|
LLparse();
|
||||||
|
}
|
||||||
epilogcode();
|
epilogcode();
|
||||||
sys_close(yyin);
|
sys_close(yyin);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "bem.h"
|
#include "bem.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "gencode.h"
|
||||||
|
|
||||||
#ifndef NORSCID
|
#ifndef NORCSID
|
||||||
static char rcs_id[] = "$Id$" ;
|
static char rcs_id[] = "$Id$" ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -14,8 +16,7 @@ static char rcs_id[] = "$Id$" ;
|
||||||
generate code for assignment statements
|
generate code for assignment statements
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exprtype(ltype,rtype)
|
static int exprtype(int ltype,int rtype)
|
||||||
int ltype,rtype;
|
|
||||||
{
|
{
|
||||||
/* determine the result type of an expression */
|
/* determine the result type of an expression */
|
||||||
if ( ltype==STRINGTYPE || rtype==STRINGTYPE)
|
if ( ltype==STRINGTYPE || rtype==STRINGTYPE)
|
||||||
|
@ -31,9 +32,7 @@ int ltype,rtype;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void conversion(int oldtype,int newtype)
|
||||||
conversion(oldtype,newtype)
|
|
||||||
int oldtype,newtype;
|
|
||||||
{
|
{
|
||||||
/* the value on top of the stack should be converted */
|
/* the value on top of the stack should be converted */
|
||||||
if ( oldtype==newtype) return;
|
if ( oldtype==newtype) return;
|
||||||
|
@ -62,7 +61,10 @@ int oldtype,newtype;
|
||||||
C_lfr((arith)BEMINTSIZE);
|
C_lfr((arith)BEMINTSIZE);
|
||||||
break;
|
break;
|
||||||
} else if ( newtype==FLOATTYPE || newtype==DOUBLETYPE)
|
} else if ( newtype==FLOATTYPE || newtype==DOUBLETYPE)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (debug)
|
if (debug)
|
||||||
print("type n=%d o=%d\n",newtype,oldtype);
|
print("type n=%d o=%d\n",newtype,oldtype);
|
||||||
|
@ -72,9 +74,7 @@ int oldtype,newtype;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void extraconvert(int oldtype,int newtype,int topstack)
|
||||||
extraconvert(oldtype,newtype,topstack)
|
|
||||||
int oldtype,newtype,topstack;
|
|
||||||
{
|
{
|
||||||
/* the value below the top of the stack should be converted */
|
/* the value below the top of the stack should be converted */
|
||||||
if ( oldtype==newtype ) return;
|
if ( oldtype==newtype ) return;
|
||||||
|
@ -116,8 +116,7 @@ int oldtype,newtype,topstack;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
boolop(ltype,rtype,operator)
|
int boolop(int ltype,int rtype,int operator)
|
||||||
int ltype,rtype,operator;
|
|
||||||
{
|
{
|
||||||
if ( operator != NOTSYM)
|
if ( operator != NOTSYM)
|
||||||
{
|
{
|
||||||
|
@ -158,8 +157,7 @@ int ltype,rtype,operator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
genbool(operator)
|
void genbool(int operator)
|
||||||
int operator;
|
|
||||||
{
|
{
|
||||||
int l1,l2;
|
int l1,l2;
|
||||||
|
|
||||||
|
@ -186,8 +184,7 @@ int operator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
relop( ltype,rtype,operator)
|
int relop(int ltype,int rtype,int operator)
|
||||||
int ltype,rtype,operator;
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
@ -213,8 +210,7 @@ int ltype,rtype,operator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
plusmin(ltype,rtype,operator)
|
int plusmin(int ltype,int rtype,int operator)
|
||||||
int ltype,rtype,operator;
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
@ -246,8 +242,7 @@ int ltype,rtype,operator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
muldiv(ltype,rtype,operator)
|
int muldiv(int ltype,int rtype,int operator)
|
||||||
int ltype,rtype,operator;
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
@ -286,8 +281,7 @@ int ltype,rtype,operator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
negate(type)
|
int negate(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
|
@ -307,8 +301,7 @@ int type;
|
||||||
|
|
||||||
|
|
||||||
#ifdef ___
|
#ifdef ___
|
||||||
power(ltype,rtype)
|
int power(int ltype,int rtype)
|
||||||
int ltype,rtype;
|
|
||||||
{
|
{
|
||||||
int resulttype = exprtype(ltype, rtype);
|
int resulttype = exprtype(ltype, rtype);
|
||||||
|
|
||||||
|
@ -330,8 +323,7 @@ int ltype,rtype;
|
||||||
return(resulttype);
|
return(resulttype);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
power(ltype,rtype)
|
int power(int ltype,int rtype)
|
||||||
int ltype,rtype;
|
|
||||||
{
|
{
|
||||||
extraconvert(ltype,DOUBLETYPE,rtype);
|
extraconvert(ltype,DOUBLETYPE,rtype);
|
||||||
conversion(rtype,DOUBLETYPE);
|
conversion(rtype,DOUBLETYPE);
|
||||||
|
@ -343,8 +335,7 @@ int ltype,rtype;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int typesize(ltype)
|
int typesize(int ltype)
|
||||||
int ltype;
|
|
||||||
{
|
{
|
||||||
switch( ltype)
|
switch( ltype)
|
||||||
{
|
{
|
||||||
|
@ -364,8 +355,7 @@ int ltype;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int typestring(type)
|
int typestring(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
|
@ -384,8 +374,7 @@ int type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loadvar(type)
|
void loadvar(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
/* load a simple variable its address is on the stack*/
|
/* load a simple variable its address is on the stack*/
|
||||||
C_loi((arith)typestring(type));
|
C_loi((arith)typestring(type));
|
||||||
|
@ -393,8 +382,7 @@ int type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loadint(value)
|
int loadint(int value)
|
||||||
int value;
|
|
||||||
{
|
{
|
||||||
C_loc((arith)value);
|
C_loc((arith)value);
|
||||||
return(INTTYPE);
|
return(INTTYPE);
|
||||||
|
@ -402,8 +390,7 @@ int value;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loaddbl(value)
|
int loaddbl(char* value)
|
||||||
char *value;
|
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
|
@ -417,16 +404,14 @@ char *value;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loadstr(value)
|
void loadstr(int value)
|
||||||
int value;
|
|
||||||
{
|
{
|
||||||
C_lae_dlb((label)value,(arith)0);
|
C_lae_dlb((label)value,(arith)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loadaddr(s)
|
int loadaddr(Symbol *s)
|
||||||
Symbol *s;
|
|
||||||
{
|
{
|
||||||
extern Symbol *fcn;
|
extern Symbol *fcn;
|
||||||
int i,j;
|
int i,j;
|
||||||
|
@ -450,7 +435,7 @@ Symbol *s;
|
||||||
|
|
||||||
|
|
||||||
/* This is a new routine */
|
/* This is a new routine */
|
||||||
save_address()
|
void save_address(void)
|
||||||
{
|
{
|
||||||
C_lae_dnam("dummy3",(arith)0);
|
C_lae_dnam("dummy3",(arith)0);
|
||||||
C_sti((arith)BEMPTRSIZE);
|
C_sti((arith)BEMPTRSIZE);
|
||||||
|
@ -458,8 +443,7 @@ save_address()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
assign(type,lt)
|
void assign(int type,int lt)
|
||||||
int type,lt;
|
|
||||||
{
|
{
|
||||||
extern int e1,e2;
|
extern int e1,e2;
|
||||||
|
|
||||||
|
@ -472,8 +456,7 @@ int type,lt;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
storevar(lab,type)
|
void storevar(int lab,int type)
|
||||||
int lab,type;
|
|
||||||
{
|
{
|
||||||
/*store value back */
|
/*store value back */
|
||||||
C_lae_dlb((label)lab,(arith)0);
|
C_lae_dlb((label)lab,(arith)0);
|
||||||
|
@ -488,8 +471,7 @@ Symbol *arraystk[MAXDIMENSIONS];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
newarrayload(s)
|
void newarrayload(Symbol *s)
|
||||||
Symbol *s;
|
|
||||||
{
|
{
|
||||||
if ( dimtop<MAXDIMENSIONS) dimtop++;
|
if ( dimtop<MAXDIMENSIONS) dimtop++;
|
||||||
if ( s->dimensions==0)
|
if ( s->dimensions==0)
|
||||||
|
@ -504,16 +486,14 @@ Symbol *s;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endarrayload()
|
int endarrayload(void)
|
||||||
{
|
{
|
||||||
return(arraystk[dimtop--]->symtype);
|
return(arraystk[dimtop--]->symtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void loadarray(int type)
|
||||||
loadarray(type)
|
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
int dim;
|
int dim;
|
||||||
Symbol *s;
|
Symbol *s;
|
||||||
|
|
54
lang/basic/src/eval.h
Normal file
54
lang/basic/src/eval.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __EVAL_H_INCLUDED__
|
||||||
|
#define __EVAL_H_INCLUDED__
|
||||||
|
|
||||||
|
#include "symbols.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------- Utilities -----------------------*/
|
||||||
|
|
||||||
|
/** From an internal type definition return the size in bytes of the data.
|
||||||
|
* If not a known data type return an integer size. */
|
||||||
|
extern int typesize(int ltype);
|
||||||
|
/** From an internal type definition return the size in bytes of the data. If not a
|
||||||
|
* known data type return a 0 size. */
|
||||||
|
extern int typestring(int type);
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------- Code generation ---------------------*/
|
||||||
|
|
||||||
|
/** Emit code to convert from the old internal type to the new internal type definition.
|
||||||
|
* Generates an error if the type conversion is not allowed. */
|
||||||
|
extern void conversion(int oldtype,int newtype);
|
||||||
|
/** Emit code to store a value of the specified type from the top of stack
|
||||||
|
* into the specified variable pointed to by label.
|
||||||
|
*/
|
||||||
|
extern void storevar(int lab,int type);
|
||||||
|
|
||||||
|
/** Emit code to load a simple variable value on the stack. On input the address of the variable
|
||||||
|
* is on the stack. */
|
||||||
|
extern void loadvar(int type);
|
||||||
|
|
||||||
|
extern void extraconvert(int oldtype,int newtype,int topstack);
|
||||||
|
|
||||||
|
extern void loadstr(int value);
|
||||||
|
extern int endarrayload(void);
|
||||||
|
extern void loadarray(int type);
|
||||||
|
extern void save_address(void);
|
||||||
|
extern void assign(int type,int lt);
|
||||||
|
extern int boolop(int ltype,int rtype,int operator);
|
||||||
|
extern int relop(int ltype,int rtype,int operator);
|
||||||
|
extern int plusmin(int ltype,int rtype,int operator);
|
||||||
|
extern int muldiv(int ltype,int rtype,int operator);
|
||||||
|
extern int negate(int type);
|
||||||
|
extern int power(int ltype,int rtype);
|
||||||
|
extern int loadint(int value);
|
||||||
|
extern int loaddbl(char* value);
|
||||||
|
extern int loadaddr(Symbol *s);
|
||||||
|
extern void newarrayload(Symbol *s);
|
||||||
|
|
||||||
|
#endif /* __EVAL_H_INCLUDED */
|
|
@ -4,8 +4,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "bem.h"
|
#include "bem.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "eval.h"
|
||||||
|
|
||||||
#ifndef NORSCID
|
#ifndef NORCSID
|
||||||
static char rcs_id[] = "$Id$" ;
|
static char rcs_id[] = "$Id$" ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -19,8 +21,7 @@ int exprlimit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
parm(cnt)
|
void parm(int cnt)
|
||||||
int cnt;
|
|
||||||
{
|
{
|
||||||
if( cnt> exprlimit)
|
if( cnt> exprlimit)
|
||||||
error("Not enough arguments");
|
error("Not enough arguments");
|
||||||
|
@ -30,9 +31,7 @@ int cnt;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
callfcn(fcnnr,cnt,typetable)
|
int callfcn(int fcnnr,int cnt,int *typetable)
|
||||||
int fcnnr,cnt;
|
|
||||||
int *typetable;
|
|
||||||
{
|
{
|
||||||
int pop=DOUBLETYPE;
|
int pop=DOUBLETYPE;
|
||||||
int res=DOUBLETYPE;
|
int res=DOUBLETYPE;
|
||||||
|
|
13
lang/basic/src/func.h
Normal file
13
lang/basic/src/func.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __FUNC_H_INCLUDED__
|
||||||
|
#define __FUNC_H_INCLUDED__
|
||||||
|
|
||||||
|
|
||||||
|
extern int callfcn(int fcnnr,int cnt,int *typetable);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __FUNC_H_INCLUDED__ */
|
|
@ -4,9 +4,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "bem.h"
|
#include "bem.h"
|
||||||
#include "system.h"
|
#include "graph.h"
|
||||||
|
#include "eval.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "gencode.h"
|
||||||
|
|
||||||
#ifndef NORSCID
|
#ifndef NORCSID
|
||||||
static char rcs_id[] = "$Id$" ;
|
static char rcs_id[] = "$Id$" ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -18,14 +21,14 @@ label err_goto_label;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
genlabel()
|
int genlabel(void)
|
||||||
{
|
{
|
||||||
return(emlabel++);
|
return(emlabel++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
genemlabel()
|
int genemlabel(void)
|
||||||
{
|
{
|
||||||
int l;
|
int l;
|
||||||
|
|
||||||
|
@ -39,8 +42,7 @@ genemlabel()
|
||||||
|
|
||||||
|
|
||||||
int tronoff=0;
|
int tronoff=0;
|
||||||
newemblock(nr)
|
void newemblock(int nr)
|
||||||
int nr;
|
|
||||||
{
|
{
|
||||||
C_df_ilb((label)currline->emlabel);
|
C_df_ilb((label)currline->emlabel);
|
||||||
C_lin((arith)nr);
|
C_lin((arith)nr);
|
||||||
|
@ -57,7 +59,7 @@ int nr;
|
||||||
|
|
||||||
/* Handle data statements */
|
/* Handle data statements */
|
||||||
List *datalist=0;
|
List *datalist=0;
|
||||||
datastmt()
|
void datastmt(void)
|
||||||
{
|
{
|
||||||
List *l,*l1;
|
List *l,*l1;
|
||||||
|
|
||||||
|
@ -78,7 +80,7 @@ datastmt()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
datatable()
|
void datatable(void)
|
||||||
{
|
{
|
||||||
List *l;
|
List *l;
|
||||||
int line=0;
|
int line=0;
|
||||||
|
@ -100,8 +102,7 @@ datatable()
|
||||||
|
|
||||||
|
|
||||||
/* ERROR and exception handling */
|
/* ERROR and exception handling */
|
||||||
exceptstmt(lab)
|
void exceptstmt(int lab)
|
||||||
int lab;
|
|
||||||
{
|
{
|
||||||
/* exceptions to subroutines are supported only */
|
/* exceptions to subroutines are supported only */
|
||||||
extern int gosubcnt;
|
extern int gosubcnt;
|
||||||
|
@ -116,8 +117,7 @@ int lab;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
errorstmt(exprtype)
|
void errorstmt(int exprtype)
|
||||||
int exprtype;
|
|
||||||
{
|
{
|
||||||
/* convert expression to a valid error number */
|
/* convert expression to a valid error number */
|
||||||
/* obtain the message and print it */
|
/* obtain the message and print it */
|
||||||
|
@ -128,8 +128,7 @@ int exprtype;
|
||||||
|
|
||||||
|
|
||||||
/* BASIC IO */
|
/* BASIC IO */
|
||||||
openstmt(recsize)
|
void openstmt(int recsize)
|
||||||
int recsize;
|
|
||||||
{
|
{
|
||||||
C_loc((arith)recsize);
|
C_loc((arith)recsize);
|
||||||
C_cal("_opnchn");
|
C_cal("_opnchn");
|
||||||
|
@ -138,8 +137,7 @@ int recsize;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
printstmt(exprtype)
|
void printstmt(int exprtype)
|
||||||
int exprtype;
|
|
||||||
{
|
{
|
||||||
switch(exprtype)
|
switch(exprtype)
|
||||||
{
|
{
|
||||||
|
@ -165,16 +163,14 @@ int exprtype;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
zone(i)
|
void zone(int i)
|
||||||
int i;
|
|
||||||
{
|
{
|
||||||
if ( i) C_cal("_zone");
|
if ( i) C_cal("_zone");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
writestmt(exprtype,comma)
|
void writestmt(int exprtype, int comma)
|
||||||
int exprtype,comma;
|
|
||||||
{
|
{
|
||||||
if ( comma) C_cal("_wrcomma");
|
if ( comma) C_cal("_wrcomma");
|
||||||
|
|
||||||
|
@ -198,8 +194,7 @@ int exprtype,comma;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
restore(lab)
|
void restore(int lab)
|
||||||
int lab;
|
|
||||||
{
|
{
|
||||||
/* save this information too */
|
/* save this information too */
|
||||||
|
|
||||||
|
@ -213,8 +208,7 @@ int lab;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
prompt(qst)
|
void prompt(int qst)
|
||||||
int qst;
|
|
||||||
{
|
{
|
||||||
setchannel(-1);
|
setchannel(-1);
|
||||||
C_cal("_prstr");
|
C_cal("_prstr");
|
||||||
|
@ -224,8 +218,7 @@ int qst;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
linestmt(type)
|
void linestmt(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
if ( type!= STRINGTYPE)
|
if ( type!= STRINGTYPE)
|
||||||
error("String variable expected");
|
error("String variable expected");
|
||||||
|
@ -235,8 +228,7 @@ int type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
readelm(type)
|
void readelm(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
|
@ -259,8 +251,7 @@ int type;
|
||||||
|
|
||||||
|
|
||||||
/* Swap exchanges the variable values */
|
/* Swap exchanges the variable values */
|
||||||
swapstmt(ltype,rtype)
|
void swapstmt(int ltype,int rtype)
|
||||||
int ltype, rtype;
|
|
||||||
{
|
{
|
||||||
if ( ltype!= rtype)
|
if ( ltype!= rtype)
|
||||||
error("Type mismatch");
|
error("Type mismatch");
|
||||||
|
@ -287,9 +278,9 @@ int ltype, rtype;
|
||||||
|
|
||||||
|
|
||||||
/* input/output handling */
|
/* input/output handling */
|
||||||
setchannel(val)
|
void setchannel(int val)
|
||||||
int val;
|
{
|
||||||
{ /* obtain file descroption */
|
/* obtain file descroption */
|
||||||
C_loc((arith)val);
|
C_loc((arith)val);
|
||||||
C_cal("_setchan");
|
C_cal("_setchan");
|
||||||
C_asp((arith)BEMINTSIZE);
|
C_asp((arith)BEMINTSIZE);
|
||||||
|
@ -298,8 +289,7 @@ int val;
|
||||||
|
|
||||||
|
|
||||||
/* The if-then-else statements */
|
/* The if-then-else statements */
|
||||||
ifstmt(type)
|
int ifstmt(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
/* This BASIC follows the True= -1 rule */
|
/* This BASIC follows the True= -1 rule */
|
||||||
int nr;
|
int nr;
|
||||||
|
@ -322,8 +312,7 @@ int type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
thenpart( elselab)
|
int thenpart(int elselab)
|
||||||
int elselab;
|
|
||||||
{
|
{
|
||||||
int nr;
|
int nr;
|
||||||
|
|
||||||
|
@ -335,7 +324,7 @@ int elselab;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
elsepart(lab)int lab;
|
void elsepart(int lab)
|
||||||
{
|
{
|
||||||
C_df_ilb((label)lab);
|
C_df_ilb((label)lab);
|
||||||
}
|
}
|
||||||
|
@ -359,8 +348,7 @@ int forcnt= -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
forinit(s)
|
void forinit(Symbol *s)
|
||||||
Symbol *s;
|
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
struct FORSTRUCT *f;
|
struct FORSTRUCT *f;
|
||||||
|
@ -388,8 +376,7 @@ Symbol *s;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
forexpr(type)
|
void forexpr(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
/* save start value of loop variable in a save place*/
|
/* save start value of loop variable in a save place*/
|
||||||
/* to avoid clashing with final value and step expression */
|
/* to avoid clashing with final value and step expression */
|
||||||
|
@ -402,8 +389,7 @@ int type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
forlimit(type)
|
void forlimit(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
/* save the limit value too*/
|
/* save the limit value too*/
|
||||||
int result;
|
int result;
|
||||||
|
@ -415,8 +401,7 @@ int type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
forskipped(f)
|
void forskipped(struct FORSTRUCT *f)
|
||||||
struct FORSTRUCT *f;
|
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
|
@ -452,8 +437,7 @@ struct FORSTRUCT *f;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
forstep(type)
|
void forstep(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
int varaddress;
|
int varaddress;
|
||||||
|
@ -522,8 +506,7 @@ int type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nextstmt(s)
|
void nextstmt(Symbol *s)
|
||||||
Symbol *s;
|
|
||||||
{
|
{
|
||||||
if (forcnt>MAXFORDEPTH || forcnt<0 ||
|
if (forcnt>MAXFORDEPTH || forcnt<0 ||
|
||||||
(s && s!= fortable[forcnt].loopvar))
|
(s && s!= fortable[forcnt].loopvar))
|
||||||
|
@ -538,8 +521,7 @@ Symbol *s;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pokestmt(type1,type2)
|
void pokestmt(int type1,int type2)
|
||||||
int type1,type2;
|
|
||||||
{
|
{
|
||||||
conversion(type1,INTTYPE);
|
conversion(type1,INTTYPE);
|
||||||
conversion(type2,INTTYPE);
|
conversion(type2,INTTYPE);
|
||||||
|
@ -553,7 +535,7 @@ int type1,type2;
|
||||||
|
|
||||||
int whilecnt, whilelabels[MAXDEPTH][2]; /*0=head,1=out */
|
int whilecnt, whilelabels[MAXDEPTH][2]; /*0=head,1=out */
|
||||||
|
|
||||||
whilestart()
|
void whilestart(void)
|
||||||
{
|
{
|
||||||
whilecnt++;
|
whilecnt++;
|
||||||
if ( whilecnt==MAXDEPTH)
|
if ( whilecnt==MAXDEPTH)
|
||||||
|
@ -567,8 +549,7 @@ whilestart()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
whiletst(exprtype)
|
void whiletst(int exprtype)
|
||||||
int exprtype;
|
|
||||||
{
|
{
|
||||||
/* test expression type */
|
/* test expression type */
|
||||||
conversion(exprtype,INTTYPE);
|
conversion(exprtype,INTTYPE);
|
||||||
|
@ -577,7 +558,7 @@ int exprtype;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
wend()
|
void wend(void)
|
||||||
{
|
{
|
||||||
if ( whilecnt<1)
|
if ( whilecnt<1)
|
||||||
error("not part of while statement");
|
error("not part of while statement");
|
||||||
|
@ -591,7 +572,7 @@ wend()
|
||||||
|
|
||||||
|
|
||||||
/* generate code for the final version */
|
/* generate code for the final version */
|
||||||
prologcode()
|
void prologcode(void)
|
||||||
{
|
{
|
||||||
/* generate the EM prolog code */
|
/* generate the EM prolog code */
|
||||||
C_df_dnam("fltnull");
|
C_df_dnam("fltnull");
|
||||||
|
@ -623,7 +604,7 @@ prologcode()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
prolog2()
|
void prolog2(void)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
label l = genlabel(), l2;
|
label l = genlabel(), l2;
|
||||||
|
@ -659,7 +640,7 @@ prolog2()
|
||||||
|
|
||||||
|
|
||||||
/* NEW */
|
/* NEW */
|
||||||
gendata()
|
void gendata(void)
|
||||||
{
|
{
|
||||||
C_loc((arith)0);
|
C_loc((arith)0);
|
||||||
C_cal("_setchan");
|
C_cal("_setchan");
|
||||||
|
@ -685,7 +666,7 @@ gendata()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
epilogcode()
|
void epilogcode(void)
|
||||||
{
|
{
|
||||||
/* finalization code */
|
/* finalization code */
|
||||||
int nr;
|
int nr;
|
||||||
|
|
64
lang/basic/src/gencode.h
Normal file
64
lang/basic/src/gencode.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __GENCODE_H_INCLUDED__
|
||||||
|
#define __GENCODE_H_INCLUDED__
|
||||||
|
|
||||||
|
#include "symbols.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------- Utilities -----------------------*/
|
||||||
|
|
||||||
|
/** Return a global value identifier used for code generation */
|
||||||
|
extern int genlabel(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------- Code generation ---------------------*/
|
||||||
|
|
||||||
|
/** Emit a label definition and return the label identifier generated. */
|
||||||
|
extern int genemlabel(void);
|
||||||
|
|
||||||
|
|
||||||
|
void newemblock(int nr);
|
||||||
|
void newblock(int nr);
|
||||||
|
void datastmt(void);
|
||||||
|
void datatable(void);
|
||||||
|
/* ERROR and exception handling */
|
||||||
|
void exceptstmt(int lab);
|
||||||
|
void errorstmt(int exprtype);
|
||||||
|
/* BASIC IO */
|
||||||
|
void openstmt(int recsize);
|
||||||
|
void printstmt(int exprtype);
|
||||||
|
void zone(int i);
|
||||||
|
void writestmt(int exprtype, int comma);
|
||||||
|
void restore(int lab);
|
||||||
|
void prompt(int qst);
|
||||||
|
void linestmt(int type);
|
||||||
|
void readelm(int type);
|
||||||
|
/* Swap exchanges the variable values */
|
||||||
|
void swapstmt(int ltype,int rtype);
|
||||||
|
void setchannel(int val);
|
||||||
|
int ifstmt(int type);
|
||||||
|
int thenpart(int elselab);
|
||||||
|
void elsepart(int lab);
|
||||||
|
void forinit(Symbol *s);
|
||||||
|
void forexpr(int type);
|
||||||
|
void forlimit(int type);
|
||||||
|
void forstep(int type);
|
||||||
|
void nextstmt(Symbol *s);
|
||||||
|
void pokestmt(int type1,int type2);
|
||||||
|
void whilestart(void);
|
||||||
|
void whiletst(int exprtype);
|
||||||
|
void wend(void);
|
||||||
|
/* generate code for the final version */
|
||||||
|
void prologcode(void);
|
||||||
|
void prolog2(void);
|
||||||
|
void gendata(void);
|
||||||
|
void epilogcode(void);
|
||||||
|
void setchannel(int val);
|
||||||
|
void gendata(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __GENCODE_H_INCLUDED__ */
|
|
@ -4,8 +4,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "bem.h"
|
#include "bem.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "eval.h"
|
||||||
|
#include "gencode.h"
|
||||||
|
|
||||||
#ifndef NORSCID
|
#ifndef NORCSID
|
||||||
static char rcs_id[] = "$Id$" ;
|
static char rcs_id[] = "$Id$" ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -18,7 +21,7 @@ Linerecord *firstline,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List *newlist()
|
List *newlist(void)
|
||||||
{
|
{
|
||||||
List *l;
|
List *l;
|
||||||
|
|
||||||
|
@ -29,8 +32,7 @@ List *newlist()
|
||||||
|
|
||||||
/* Line management is handled here */
|
/* Line management is handled here */
|
||||||
|
|
||||||
Linerecord *srchline(nr)
|
Linerecord *srchline(int nr)
|
||||||
int nr;
|
|
||||||
{
|
{
|
||||||
Linerecord *l;
|
Linerecord *l;
|
||||||
|
|
||||||
|
@ -41,8 +43,7 @@ int nr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List *srchforward(nr)
|
List *srchforward(int nr)
|
||||||
int nr;
|
|
||||||
{
|
{
|
||||||
List *l;
|
List *l;
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ int nr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
linewarnings()
|
void linewarnings(void)
|
||||||
{
|
{
|
||||||
List *l;
|
List *l;
|
||||||
extern int errorcnt;
|
extern int errorcnt;
|
||||||
|
@ -72,8 +73,7 @@ linewarnings()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
newblock(nr)
|
void newblock(int nr)
|
||||||
int nr;
|
|
||||||
{
|
{
|
||||||
Linerecord *l;
|
Linerecord *l;
|
||||||
List *frwrd;
|
List *frwrd;
|
||||||
|
@ -111,8 +111,7 @@ int nr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gotolabel(nr)
|
int gotolabel(int nr)
|
||||||
int nr;
|
|
||||||
{
|
{
|
||||||
/* simulate a goto statement in the line record table */
|
/* simulate a goto statement in the line record table */
|
||||||
Linerecord *l1;
|
Linerecord *l1;
|
||||||
|
@ -146,8 +145,7 @@ int nr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gotostmt(nr)
|
void gotostmt(int nr)
|
||||||
int nr;
|
|
||||||
{
|
{
|
||||||
C_bra((label) gotolabel(nr));
|
C_bra((label) gotolabel(nr));
|
||||||
}
|
}
|
||||||
|
@ -160,7 +158,7 @@ int gosubcnt=1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List *gosublabel()
|
List *gosublabel(void)
|
||||||
{
|
{
|
||||||
List *l;
|
List *l;
|
||||||
|
|
||||||
|
@ -177,8 +175,7 @@ List *gosublabel()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gosubstmt(lab)
|
void gosubstmt(int lab)
|
||||||
int lab;
|
|
||||||
{
|
{
|
||||||
List *l;
|
List *l;
|
||||||
int nr,n;
|
int nr,n;
|
||||||
|
@ -197,7 +194,7 @@ int lab;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
genreturns()
|
void genreturns(void)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
int nr;
|
int nr;
|
||||||
|
@ -227,7 +224,7 @@ genreturns()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
returnstmt()
|
void returnstmt(void)
|
||||||
{
|
{
|
||||||
C_cal("_retstmt");
|
C_cal("_retstmt");
|
||||||
C_lfr((arith) BEMINTSIZE);
|
C_lfr((arith) BEMINTSIZE);
|
||||||
|
@ -242,8 +239,7 @@ List *jumphead,*jumptail;
|
||||||
int jumpcnt;
|
int jumpcnt;
|
||||||
|
|
||||||
|
|
||||||
jumpelm(nr)
|
void jumpelm(int nr)
|
||||||
int nr;
|
|
||||||
{
|
{
|
||||||
List *l;
|
List *l;
|
||||||
|
|
||||||
|
@ -260,8 +256,7 @@ int nr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ongotostmt(type)
|
void ongotostmt(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
/* generate the code itself, index in on top of the stack */
|
/* generate the code itself, index in on top of the stack */
|
||||||
/* blurh, store the number of entries in the descriptor */
|
/* blurh, store the number of entries in the descriptor */
|
||||||
|
@ -294,8 +289,7 @@ int type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ongosubstmt(type)
|
void ongosubstmt(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
List *l;
|
List *l;
|
||||||
int firstlabel;
|
int firstlabel;
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __GRAPH_H_INCLUDED__
|
||||||
|
#define __GRAPH_H_INCLUDED__
|
||||||
|
|
||||||
#ifndef NORCSID
|
#ifndef NORCSID
|
||||||
# define RCS_GRAPH "$Id$"
|
# define RCS_GRAPH "$Id$"
|
||||||
#endif
|
#endif
|
||||||
|
@ -35,3 +38,18 @@ extern Linerecord *firstline,
|
||||||
extern List *forwardlabel;
|
extern List *forwardlabel;
|
||||||
|
|
||||||
extern List *gosublabel();
|
extern List *gosublabel();
|
||||||
|
extern void jumpelm(int nr);
|
||||||
|
extern int gotolabel(int nr);
|
||||||
|
extern void linewarnings(void);
|
||||||
|
|
||||||
|
/*-------------------------- Code generation ---------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
extern void genreturns(void);
|
||||||
|
extern void gosubstmt(int lab);
|
||||||
|
extern void gotostmt(int nr);
|
||||||
|
extern void returnstmt(void);
|
||||||
|
extern void ongosubstmt(int type);
|
||||||
|
extern void ongotostmt(int type);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "bem.h"
|
#include "bem.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#ifndef NORSCID
|
#ifndef NORCSID
|
||||||
static char rcs_id[] = "$Id$";
|
static char rcs_id[] = "$Id$";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -13,9 +15,9 @@ static char rcs_id[] = "$Id$";
|
||||||
|
|
||||||
File *datfile;
|
File *datfile;
|
||||||
|
|
||||||
|
extern void fillkex(void);
|
||||||
|
|
||||||
|
void initialize(void)
|
||||||
initialize()
|
|
||||||
{
|
{
|
||||||
register char *cindex, *cptr;
|
register char *cindex, *cptr;
|
||||||
int result1, result2;
|
int result1, result2;
|
||||||
|
@ -33,7 +35,7 @@ initialize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cptr=datfname;
|
cptr=datfname;
|
||||||
while ( *cptr++ = *cindex++ );
|
while ( (*cptr++ = *cindex++) !=0 );
|
||||||
/* Strip trailing suffix */
|
/* Strip trailing suffix */
|
||||||
if ( cptr>datfname+3 && cptr[-3]=='.' ) cptr[-3]=0;
|
if ( cptr>datfname+3 && cptr[-3]=='.' ) cptr[-3]=0;
|
||||||
strcat(datfname,".d");
|
strcat(datfname,".d");
|
||||||
|
|
|
@ -3,16 +3,17 @@
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "tokentab.h"
|
#include "tokentab.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
/* Mod van gertjan */
|
/* Mod van gertjan */
|
||||||
extern int LLsymb;
|
extern int LLsymb;
|
||||||
extern int toknum;
|
extern int toknum;
|
||||||
|
|
||||||
|
|
||||||
error_char(format,ch)
|
void error_char(char *format,char ch)
|
||||||
char *format;
|
|
||||||
char ch;
|
|
||||||
{
|
{
|
||||||
extern int listing,errorcnt;
|
extern int listing,errorcnt;
|
||||||
extern int basicline;
|
extern int basicline;
|
||||||
|
@ -24,9 +25,7 @@ char ch;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
error_string(format,str)
|
void error_string(char* format,char* str)
|
||||||
char *format;
|
|
||||||
char *str;
|
|
||||||
{
|
{
|
||||||
extern int listing,errorcnt;
|
extern int listing,errorcnt;
|
||||||
extern int basicline;
|
extern int basicline;
|
||||||
|
@ -38,8 +37,7 @@ char *str;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LLmessage( insertedtok )
|
void LLmessage(int insertedtok )
|
||||||
int insertedtok;
|
|
||||||
{
|
{
|
||||||
if ( insertedtok < 0 ) {
|
if ( insertedtok < 0 ) {
|
||||||
error("Fatal stack overflow\n");
|
error("Fatal stack overflow\n");
|
||||||
|
|
11
lang/basic/src/options
Normal file
11
lang/basic/src/options
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
User options:
|
||||||
|
D parser debugging
|
||||||
|
t line tracing
|
||||||
|
d debug information
|
||||||
|
E generate full listing
|
||||||
|
L don't generate linenumbers and filename indications
|
||||||
|
w suppress warning diagnostics
|
||||||
|
VwN set word size to N bytes
|
||||||
|
VpN set pointer size to N bytes
|
||||||
|
VfN set real size to N bytes
|
||||||
|
|
|
@ -3,9 +3,15 @@
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "parsepar.h"
|
||||||
#include "bem.h"
|
#include "bem.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "print.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#ifndef NORSCID
|
|
||||||
|
#ifndef NORCSID
|
||||||
static char rcs_id[] = "$Id$" ;
|
static char rcs_id[] = "$Id$" ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -18,9 +24,7 @@ int nolins=0; /* generate no LIN statements */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
parseparams(argc,argv)
|
void parseparams(int argc,char **argv)
|
||||||
int argc;
|
|
||||||
char **argv;
|
|
||||||
{
|
{
|
||||||
int files=0 ;
|
int files=0 ;
|
||||||
int i;
|
int i;
|
||||||
|
|
23
lang/basic/src/parsepar.h
Normal file
23
lang/basic/src/parsepar.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __PARSEPAR_H_INCLUDED__
|
||||||
|
#define __PARSEPAR_H_INCLUDED__
|
||||||
|
|
||||||
|
/** -l listing required */
|
||||||
|
extern int listing;
|
||||||
|
/** -d compiler debugging */
|
||||||
|
extern int debug;
|
||||||
|
/** -w warning flags */
|
||||||
|
extern int wflag;
|
||||||
|
/** generate line tracing code. */
|
||||||
|
extern int traceflag;
|
||||||
|
/** generate LIN statements */
|
||||||
|
extern int nolins;
|
||||||
|
|
||||||
|
|
||||||
|
void parseparams(int argc,char **argv);
|
||||||
|
|
||||||
|
#endif /* __PARSEPAR_H_INCLUDED__ */
|
|
@ -3,9 +3,18 @@
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "symbols.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include "bem.h"
|
#include "bem.h"
|
||||||
|
#include "eval.h"
|
||||||
|
#include "gencode.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#ifndef NORSCID
|
|
||||||
|
|
||||||
|
#ifndef NORCSID
|
||||||
static char rcs_id[] = "$Id$" ;
|
static char rcs_id[] = "$Id$" ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -15,7 +24,11 @@ int deftype[128]; /* default type declarer */
|
||||||
/* which may be set by OPTION BASE */
|
/* which may be set by OPTION BASE */
|
||||||
|
|
||||||
|
|
||||||
initdeftype()
|
/* Local declarations */
|
||||||
|
static void get_space(int type,int size);
|
||||||
|
|
||||||
|
|
||||||
|
void initdeftype(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -31,8 +44,7 @@ Symbol *alternate = NIL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Symbol *srchsymbol(str)
|
Symbol *srchsymbol(char* str)
|
||||||
char *str;
|
|
||||||
{
|
{
|
||||||
Symbol *s;
|
Symbol *s;
|
||||||
|
|
||||||
|
@ -68,9 +80,7 @@ char *str;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void dcltype(Symbol *s)
|
||||||
dcltype(s)
|
|
||||||
Symbol *s;
|
|
||||||
{
|
{
|
||||||
/* type declarer */
|
/* type declarer */
|
||||||
int type;
|
int type;
|
||||||
|
@ -79,7 +89,7 @@ Symbol *s;
|
||||||
type=s->symtype;
|
type=s->symtype;
|
||||||
if (type==DEFAULTTYPE)
|
if (type==DEFAULTTYPE)
|
||||||
/* use the default rule */
|
/* use the default rule */
|
||||||
type= deftype[*s->symname];
|
type= deftype[(int)(*s->symname)];
|
||||||
/* generate the emlabel too */
|
/* generate the emlabel too */
|
||||||
if ( s->symalias==0)
|
if ( s->symalias==0)
|
||||||
s->symalias= dclspace(type);
|
s->symalias= dclspace(type);
|
||||||
|
@ -89,8 +99,7 @@ Symbol *s;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dclarray(s)
|
void dclarray(Symbol *s)
|
||||||
Symbol *s;
|
|
||||||
{
|
{
|
||||||
int i; int size;
|
int i; int size;
|
||||||
|
|
||||||
|
@ -122,8 +131,7 @@ Symbol *s;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
get_space(type,size)
|
static void get_space(int type,int size)
|
||||||
int type,size;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
switch ( type ) {
|
switch ( type ) {
|
||||||
|
@ -153,8 +161,7 @@ int type,size;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
defarray(s)
|
void defarray(Symbol *s)
|
||||||
Symbol *s;
|
|
||||||
{
|
{
|
||||||
/* array is used without dim statement, set default limits */
|
/* array is used without dim statement, set default limits */
|
||||||
int i;
|
int i;
|
||||||
|
@ -164,7 +171,7 @@ Symbol *s;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dclspace(type)
|
int dclspace(int type)
|
||||||
{
|
{
|
||||||
int nr;
|
int nr;
|
||||||
|
|
||||||
|
@ -189,8 +196,7 @@ dclspace(type)
|
||||||
|
|
||||||
|
|
||||||
/* SOME COMPILE TIME OPTIONS */
|
/* SOME COMPILE TIME OPTIONS */
|
||||||
optionbase(ival)
|
void optionbase(int ival)
|
||||||
int ival;
|
|
||||||
{
|
{
|
||||||
if ( ival<0 || ival>1)
|
if ( ival<0 || ival>1)
|
||||||
error("illegal option base value");
|
error("illegal option base value");
|
||||||
|
@ -199,8 +205,7 @@ int ival;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setdefaulttype(type)
|
void setdefaulttype(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
extern char *cptr;
|
extern char *cptr;
|
||||||
char first,last,i;
|
char first,last,i;
|
||||||
|
@ -233,8 +238,7 @@ Symbol *fcn;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
newscope(s)
|
void newscope(Symbol *s)
|
||||||
Symbol *s;
|
|
||||||
{
|
{
|
||||||
if (debug) print("new scope for %s\n",s->symname);
|
if (debug) print("new scope for %s\n",s->symname);
|
||||||
alternate= firstsym;
|
alternate= firstsym;
|
||||||
|
@ -253,7 +257,7 @@ Symbol *s;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
heading( )
|
void heading(void)
|
||||||
{
|
{
|
||||||
char procname[50];
|
char procname[50];
|
||||||
|
|
||||||
|
@ -265,7 +269,7 @@ heading( )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int fcnsize()
|
static int fcnsize(void)
|
||||||
{
|
{
|
||||||
/* generate portable function size */
|
/* generate portable function size */
|
||||||
int i,sum; /* sum is NEW */
|
int i,sum; /* sum is NEW */
|
||||||
|
@ -278,8 +282,7 @@ int fcnsize()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endscope(type)
|
void endscope(int type)
|
||||||
int type;
|
|
||||||
{
|
{
|
||||||
Symbol *s;
|
Symbol *s;
|
||||||
|
|
||||||
|
@ -304,8 +307,7 @@ int type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dclparm(s)
|
void dclparm(Symbol *s)
|
||||||
Symbol *s;
|
|
||||||
{
|
{
|
||||||
int size=0;
|
int size=0;
|
||||||
|
|
||||||
|
@ -327,8 +329,7 @@ int fcnindex= -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fcncall(s)
|
int fcncall(Symbol *s)
|
||||||
Symbol *s;
|
|
||||||
{
|
{
|
||||||
if ( !s->isfunction)
|
if ( !s->isfunction)
|
||||||
error("Function not declared");
|
error("Function not declared");
|
||||||
|
@ -342,8 +343,7 @@ Symbol *s;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fcnend(parmcount)
|
int fcnend(int parmcount)
|
||||||
int parmcount;
|
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
static char concatbuf[50]; /* NEW */
|
static char concatbuf[50]; /* NEW */
|
||||||
|
@ -366,8 +366,7 @@ int parmcount;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
callparm(ind,type)
|
void callparm(int ind,int type)
|
||||||
int ind,type;
|
|
||||||
{
|
{
|
||||||
if ( fcnindex<0) error("unexpected parameter");
|
if ( fcnindex<0) error("unexpected parameter");
|
||||||
if ( ind >= fcn->dimensions)
|
if ( ind >= fcn->dimensions)
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __SYMBOLS_H_INCLUDED__
|
||||||
|
#define __SYMBOLS_H_INCLUDED__
|
||||||
|
|
||||||
#ifndef NORCSID
|
#ifndef NORCSID
|
||||||
# define RCS_SYMB "$Id$"
|
# define RCS_SYMB "$Id$"
|
||||||
#endif
|
#endif
|
||||||
|
@ -85,4 +88,21 @@ typedef struct SYMBOL{
|
||||||
int isparam;
|
int isparam;
|
||||||
} Symbol;
|
} Symbol;
|
||||||
|
|
||||||
extern Symbol *srchsymbol();
|
void initdeftype(void);
|
||||||
|
Symbol *srchsymbol(char* str);
|
||||||
|
void dcltype(Symbol *s);
|
||||||
|
void dclarray(Symbol *s);
|
||||||
|
void defarray(Symbol *s);
|
||||||
|
int dclspace(int type);
|
||||||
|
void optionbase(int ival);
|
||||||
|
void setdefaulttype(int type);
|
||||||
|
void newscope(Symbol *s);
|
||||||
|
void heading(void);
|
||||||
|
void endscope(int type);
|
||||||
|
void dclparm(Symbol *s);
|
||||||
|
int fcncall(Symbol *s);
|
||||||
|
int fcnend(int parmcount);
|
||||||
|
void callparm(int ind,int type);
|
||||||
|
|
||||||
|
#endif /* __SYMBOLS_H_INCLUDED__ */
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,12 @@
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
#include "util.h"
|
||||||
#include "bem.h"
|
#include "bem.h"
|
||||||
|
|
||||||
#ifndef NORSCID
|
|
||||||
|
#ifndef NORCSID
|
||||||
static char rcs_id[] = "$Id$" ;
|
static char rcs_id[] = "$Id$" ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -16,25 +19,8 @@ int errorcnt;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
warning(str)
|
|
||||||
char *str;
|
|
||||||
{
|
|
||||||
if (wflag) return;
|
|
||||||
Xerror("WARNING", str);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
static void Xerror(char *type, char *str)
|
||||||
error(str)
|
|
||||||
char *str;
|
|
||||||
{
|
|
||||||
Xerror("ERROR", str);
|
|
||||||
errorcnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Xerror(type, str)
|
|
||||||
char *str;
|
|
||||||
char *type;
|
|
||||||
{
|
{
|
||||||
extern int listing;
|
extern int listing;
|
||||||
extern int basicline;
|
extern int basicline;
|
||||||
|
@ -45,8 +31,23 @@ char *type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fatal(str)
|
|
||||||
char *str;
|
void warning(char* str)
|
||||||
|
{
|
||||||
|
if (wflag) return;
|
||||||
|
Xerror("WARNING", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void error(char* str)
|
||||||
|
{
|
||||||
|
Xerror("ERROR", str);
|
||||||
|
errorcnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void fatal(char* str)
|
||||||
{
|
{
|
||||||
Xerror("FATAL",str);
|
Xerror("FATAL",str);
|
||||||
C_close();
|
C_close();
|
||||||
|
@ -55,22 +56,21 @@ char *str;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
notyetimpl()
|
void notyetimpl(void)
|
||||||
{
|
{
|
||||||
warning("not yet implemented");
|
warning("not yet implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
illegalcmd()
|
void illegalcmd(void)
|
||||||
{
|
{
|
||||||
warning("illegal command");
|
warning("illegal command");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *myitoa(i)
|
char *myitoa(int i)
|
||||||
int i;
|
|
||||||
{
|
{
|
||||||
static char buf[30];
|
static char buf[30];
|
||||||
|
|
||||||
|
@ -79,12 +79,7 @@ int i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *salloc(unsigned int length)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *salloc(length)
|
|
||||||
unsigned length;
|
|
||||||
{
|
{
|
||||||
char *s,*c;
|
char *s,*c;
|
||||||
|
|
||||||
|
|
32
lang/basic/src/util.h
Normal file
32
lang/basic/src/util.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __UTIL_H_INCLUDED__
|
||||||
|
#define __UTIL_H_INCLUDED__
|
||||||
|
|
||||||
|
/** Raises a warning with the specified message. */
|
||||||
|
void warning(char* str);
|
||||||
|
/** Raises a non fatal error with the specified message. */
|
||||||
|
void error(char* str);
|
||||||
|
/** Raises a fatal error with the specified message and
|
||||||
|
quits the application. */
|
||||||
|
void fatal(char* str);
|
||||||
|
/** Error management to raise a warning on an unimplemented
|
||||||
|
* feature. */
|
||||||
|
void notyetimpl(void);
|
||||||
|
/** Error management to raise a warning on an illegal command
|
||||||
|
line option. */
|
||||||
|
void illegalcmd(void);
|
||||||
|
|
||||||
|
|
||||||
|
char *myitoa(int i);
|
||||||
|
|
||||||
|
/** Tries to allocates a memory block of the specified number of bytes, and exits
|
||||||
|
* with a fatal error upon a failure. Upon allocation success, fills the allocated
|
||||||
|
* memory block with binary 0.
|
||||||
|
*/
|
||||||
|
char *salloc(unsigned int length);
|
||||||
|
|
||||||
|
#endif /* __UTIL_H_INCLUDED__ */
|
|
@ -5,7 +5,9 @@
|
||||||
|
|
||||||
int toknum;
|
int toknum;
|
||||||
|
|
||||||
yylexp()
|
extern int yylex(void);
|
||||||
|
|
||||||
|
int yylexp(void)
|
||||||
{
|
{
|
||||||
/* als toknum != 0 dan bevat toknum een door LLmessage back-ge-pushed token */
|
/* als toknum != 0 dan bevat toknum een door LLmessage back-ge-pushed token */
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,9 @@
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
|
#include "replace.h"
|
||||||
#include "class.h"
|
#include "class.h"
|
||||||
|
#include "error.h"
|
||||||
#include "bits.h"
|
#include "bits.h"
|
||||||
|
|
||||||
#define BUFSIZ 1024
|
#define BUFSIZ 1024
|
||||||
|
@ -30,20 +32,26 @@ int AccFileSpecifier = 0; /* return filespecifier <...> */
|
||||||
int LexSave = 0; /* last character read by GetChar */
|
int LexSave = 0; /* last character read by GetChar */
|
||||||
extern int InputLevel; /* # of current macro expansions */
|
extern int InputLevel; /* # of current macro expansions */
|
||||||
|
|
||||||
extern char* string_token();
|
|
||||||
extern arith char_constant();
|
|
||||||
#define FLG_ESEEN 0x01 /* possibly a floating point number */
|
#define FLG_ESEEN 0x01 /* possibly a floating point number */
|
||||||
#define FLG_DOTSEEN 0x02 /* certainly a floating point number */
|
#define FLG_DOTSEEN 0x02 /* certainly a floating point number */
|
||||||
|
|
||||||
void skipcomment();
|
|
||||||
void skiplinecomment(void);
|
|
||||||
|
|
||||||
int LLlex()
|
/* Private forward definitions */
|
||||||
|
|
||||||
|
static arith char_constant(char*);
|
||||||
|
static char* string_token(char *, int);
|
||||||
|
static int quoted(register int);
|
||||||
|
static int val_in_base(register int, int);
|
||||||
|
static int trigraph(void);
|
||||||
|
|
||||||
|
|
||||||
|
int LLlex(void)
|
||||||
{
|
{
|
||||||
return (DOT != EOF) ? GetToken(&dot) : EOF;
|
return (DOT != EOF) ? GetToken(&dot) : EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetToken(ptok) register struct token* ptok;
|
int GetToken(register struct token* ptok)
|
||||||
{
|
{
|
||||||
/* GetToken() is the actual token recognizer. It calls the
|
/* GetToken() is the actual token recognizer. It calls the
|
||||||
control line interpreter if it encounters a "\n{w}*#"
|
control line interpreter if it encounters a "\n{w}*#"
|
||||||
|
@ -385,7 +393,7 @@ again: /* rescan the input after an error or replacement */
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void skipcomment()
|
void skipcomment(void)
|
||||||
{
|
{
|
||||||
/* The last character read has been the '*' of '/_*'. The
|
/* The last character read has been the '*' of '/_*'. The
|
||||||
characters, except NL and EOI, between '/_*' and the first
|
characters, except NL and EOI, between '/_*' and the first
|
||||||
|
@ -437,7 +445,7 @@ void skiplinecomment(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arith char_constant(nm) char* nm;
|
static arith char_constant(char* nm)
|
||||||
{
|
{
|
||||||
register arith val = 0;
|
register arith val = 0;
|
||||||
register int ch;
|
register int ch;
|
||||||
|
@ -471,7 +479,7 @@ arith char_constant(nm) char* nm;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* string_token(nm, stop_char) char* nm;
|
static char* string_token(char *nm, int stop_char)
|
||||||
{
|
{
|
||||||
register int ch;
|
register int ch;
|
||||||
register int str_size;
|
register int str_size;
|
||||||
|
@ -504,7 +512,7 @@ char* string_token(nm, stop_char) char* nm;
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
int quoted(ch) register int ch;
|
static int quoted(register int ch)
|
||||||
{
|
{
|
||||||
/* quoted() replaces an escaped character sequence by the
|
/* quoted() replaces an escaped character sequence by the
|
||||||
character meant.
|
character meant.
|
||||||
|
@ -567,7 +575,7 @@ int quoted(ch) register int ch;
|
||||||
return ch & 0377;
|
return ch & 0377;
|
||||||
}
|
}
|
||||||
|
|
||||||
int val_in_base(ch, base) register int ch;
|
static int val_in_base(register int ch, int base)
|
||||||
{
|
{
|
||||||
switch (base)
|
switch (base)
|
||||||
{
|
{
|
||||||
|
@ -583,7 +591,7 @@ int val_in_base(ch, base) register int ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetChar()
|
int GetChar(void)
|
||||||
{
|
{
|
||||||
/* The routines GetChar and trigraph parses the trigraph
|
/* The routines GetChar and trigraph parses the trigraph
|
||||||
sequences and removes occurences of \\\n.
|
sequences and removes occurences of \\\n.
|
||||||
|
@ -612,7 +620,7 @@ again:
|
||||||
return (LexSave = ch);
|
return (LexSave = ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
int trigraph()
|
static int trigraph(void)
|
||||||
{
|
{
|
||||||
register int ch;
|
register int ch;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
/* D E F I N I T I O N S F O R T H E L E X I C A L A N A L Y Z E R */
|
/* D E F I N I T I O N S F O R T H E L E X I C A L A N A L Y Z E R */
|
||||||
|
#ifndef LLLEX_H_
|
||||||
|
#define LLLEX_H_
|
||||||
|
|
||||||
/* A token from the input stream is represented by an integer,
|
/* A token from the input stream is represented by an integer,
|
||||||
called a "symbol", but it may have other information associated
|
called a "symbol", but it may have other information associated
|
||||||
|
@ -44,3 +46,14 @@ extern int err_occurred; /* "error.c" */
|
||||||
#define DOT dot.tk_symb
|
#define DOT dot.tk_symb
|
||||||
|
|
||||||
#define EOF (-1)
|
#define EOF (-1)
|
||||||
|
|
||||||
|
/* Public function declarations */
|
||||||
|
|
||||||
|
int LLlex(void);
|
||||||
|
int GetToken(register struct token* ptok);
|
||||||
|
void skipcomment(void);
|
||||||
|
void skiplinecomment(void);
|
||||||
|
/* Get next character input, with trigraph parsing and newline */
|
||||||
|
int GetChar(void);
|
||||||
|
|
||||||
|
#endif /* LLLLEX_H_ */
|
||||||
|
|
|
@ -8,15 +8,20 @@
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
|
#include "skip.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
extern char *symbol2str();
|
extern char *symbol2str();
|
||||||
|
|
||||||
LLmessage(tk) {
|
void LLmessage(int tk)
|
||||||
|
{
|
||||||
if (tk < 0)
|
if (tk < 0)
|
||||||
error("garbage at end of line");
|
error("garbage at end of line");
|
||||||
else if (tk) {
|
else if (tk)
|
||||||
|
{
|
||||||
error("%s missing", symbol2str(tk));
|
error("%s missing", symbol2str(tk));
|
||||||
if (DOT != EOF) SkipToNewLine();
|
if (DOT != EOF)
|
||||||
|
SkipToNewLine();
|
||||||
DOT = EOF;
|
DOT = EOF;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -7,10 +7,11 @@
|
||||||
|
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
|
#include "ch3bin.h"
|
||||||
|
#include "skip.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
ch3bin(pval, pis_uns, oper, val, is_uns)
|
void ch3bin(register arith *pval, int *pis_uns, int oper, register arith val, int is_uns)
|
||||||
register arith *pval, val;
|
|
||||||
int oper, is_uns, *pis_uns;
|
|
||||||
{
|
{
|
||||||
if (is_uns) *pis_uns = 1;
|
if (is_uns) *pis_uns = 1;
|
||||||
switch (oper) {
|
switch (oper) {
|
||||||
|
|
|
@ -5,13 +5,12 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
/* EVALUATION OF MONADIC OPERATORS */
|
/* EVALUATION OF MONADIC OPERATORS */
|
||||||
|
|
||||||
|
#include "ch3mon.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
|
|
||||||
/*ARGSUSED2*/
|
/*ARGSUSED2*/
|
||||||
ch3mon(oper, pval, puns)
|
void ch3mon(int oper, register arith *pval, int *puns)
|
||||||
register arith *pval;
|
|
||||||
int *puns;
|
|
||||||
{
|
{
|
||||||
switch (oper) {
|
switch (oper) {
|
||||||
case '~':
|
case '~':
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
At present such a class number is supposed to fit in 4 bits.
|
At present such a class number is supposed to fit in 4 bits.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define class(ch) ((tkclass)[ch])
|
#define class(ch) ((tkclass)[(unsigned int)ch])
|
||||||
|
|
||||||
/* Being the start of a token is, fortunately, a mutual exclusive
|
/* Being the start of a token is, fortunately, a mutual exclusive
|
||||||
property, so, as there are less than 16 classes they can be
|
property, so, as there are less than 16 classes they can be
|
||||||
|
@ -37,11 +37,11 @@
|
||||||
class. This is implemented as a collection of tables to speed up
|
class. This is implemented as a collection of tables to speed up
|
||||||
the decision whether a character has a special meaning.
|
the decision whether a character has a special meaning.
|
||||||
*/
|
*/
|
||||||
#define in_idf(ch) (inidf[ch])
|
#define in_idf(ch) (inidf[(unsigned int)ch])
|
||||||
#define is_oct(ch) (isoct[ch])
|
#define is_oct(ch) (isoct[(unsigned int)ch])
|
||||||
#define is_dig(ch) (isdig[ch])
|
#define is_dig(ch) (isdig[(unsigned int)ch])
|
||||||
#define is_hex(ch) (ishex[ch])
|
#define is_hex(ch) (ishex[(unsigned int)ch])
|
||||||
#define is_wsp(ch) (iswsp[ch])
|
#define is_wsp(ch) (iswsp[(unsigned int)ch])
|
||||||
|
|
||||||
extern char tkclass[];
|
extern char tkclass[];
|
||||||
extern char inidf[], isoct[], isdig[], ishex[], iswsp[];
|
extern char inidf[], isoct[], isdig[], ishex[], iswsp[];
|
||||||
|
|
|
@ -8,22 +8,26 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "domacro.h"
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
|
#include "preprocess.h"
|
||||||
#include <alloc.h>
|
#include <alloc.h>
|
||||||
#include "class.h"
|
#include "class.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
#include "LLlex.h"
|
||||||
#include "bits.h"
|
#include "bits.h"
|
||||||
|
#include "skip.h"
|
||||||
#include "replace.h"
|
#include "replace.h"
|
||||||
|
|
||||||
extern char options[];
|
extern char options[];
|
||||||
extern char** inctable; /* list of include directories */
|
extern char** inctable; /* list of include directories */
|
||||||
extern char* getwdir();
|
|
||||||
char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */
|
char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */
|
||||||
/* 1 if a corresponding ELSE has been */
|
/* 1 if a corresponding ELSE has been */
|
||||||
/* encountered. */
|
/* encountered. */
|
||||||
|
@ -33,10 +37,33 @@ int svnestlevel[30] = { -1 };
|
||||||
int nestcount;
|
int nestcount;
|
||||||
extern int do_preprocess;
|
extern int do_preprocess;
|
||||||
|
|
||||||
void macro_def();
|
/* Internal declarations */
|
||||||
void do_define();
|
|
||||||
|
|
||||||
char* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line on error */
|
|
||||||
|
static void do_define(void);
|
||||||
|
static void do_elif(void);
|
||||||
|
static void do_else(void);
|
||||||
|
static void push_if(void);
|
||||||
|
static void do_endif(void);
|
||||||
|
static void do_if(void);
|
||||||
|
static void do_ifdef(int);
|
||||||
|
static void do_include(void);
|
||||||
|
static void do_line(unsigned int);
|
||||||
|
static int find_name(char* , char* []);
|
||||||
|
static char* get_text(char* [], int* );
|
||||||
|
static int getparams(char* [], char []);
|
||||||
|
static int ifexpr(void);
|
||||||
|
static int macroeq(register char*, register char *);
|
||||||
|
static void skip_block(int);
|
||||||
|
static void do_error(void);
|
||||||
|
|
||||||
|
/* External dependencies to C files with no include files */
|
||||||
|
extern void If_expr(void);
|
||||||
|
extern void add_dependency(char *);
|
||||||
|
|
||||||
|
|
||||||
|
char* GetIdentifier(int skiponerr /* skip the rest of the line on error */
|
||||||
|
)
|
||||||
{
|
{
|
||||||
/* Returns a pointer to the identifier that is read from the
|
/* Returns a pointer to the identifier that is read from the
|
||||||
input stream. When the input does not contain an
|
input stream. When the input does not contain an
|
||||||
|
@ -62,16 +89,8 @@ char* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line on er
|
||||||
return tk.tk_str;
|
return tk.tk_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* domacro() is the control line interpreter. The '#' has already
|
|
||||||
been read by the lexical analyzer by which domacro() is called.
|
void domacro(void)
|
||||||
The token appearing directly after the '#' is obtained by calling
|
|
||||||
the basic lexical analyzing function GetToken() and is interpreted
|
|
||||||
to perform the action belonging to that token.
|
|
||||||
An error message is produced when the token is not recognized.
|
|
||||||
Pragma's are handled by do_pragma(). They are passed on to the
|
|
||||||
compiler.
|
|
||||||
*/
|
|
||||||
domacro()
|
|
||||||
{
|
{
|
||||||
struct token tk; /* the token itself */
|
struct token tk; /* the token itself */
|
||||||
register struct idf* id;
|
register struct idf* id;
|
||||||
|
@ -156,7 +175,7 @@ domacro()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void skip_block(to_endif) int to_endif;
|
static void skip_block(int to_endif)
|
||||||
{
|
{
|
||||||
/* skip_block() skips the input from
|
/* skip_block() skips the input from
|
||||||
1) a false #if, #ifdef, #ifndef or #elif until the
|
1) a false #if, #ifdef, #ifndef or #elif until the
|
||||||
|
@ -303,9 +322,9 @@ void skip_block(to_endif) int to_endif;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ifexpr()
|
static int ifexpr(void)
|
||||||
{
|
{
|
||||||
/* ifexpr() returns whether the restricted constant
|
/* Returns whether the restricted constant
|
||||||
expression following #if or #elif evaluates to true. This
|
expression following #if or #elif evaluates to true. This
|
||||||
is done by calling the LLgen generated subparser for
|
is done by calling the LLgen generated subparser for
|
||||||
constant expressions. The result of this expression will
|
constant expressions. The result of this expression will
|
||||||
|
@ -324,7 +343,7 @@ ifexpr()
|
||||||
return (errors == err_occurred) && (ifval != (arith)0);
|
return (errors == err_occurred) && (ifval != (arith)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
do_include()
|
static void do_include(void)
|
||||||
{
|
{
|
||||||
/* do_include() performs the inclusion of a file.
|
/* do_include() performs the inclusion of a file.
|
||||||
*/
|
*/
|
||||||
|
@ -368,7 +387,7 @@ do_include()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_define()
|
static void do_define(void)
|
||||||
{
|
{
|
||||||
/* do_define() interprets a #define control line.
|
/* do_define() interprets a #define control line.
|
||||||
*/
|
*/
|
||||||
|
@ -378,8 +397,7 @@ void do_define()
|
||||||
char parbuf[PARBUFSIZE]; /* names of formals */
|
char parbuf[PARBUFSIZE]; /* names of formals */
|
||||||
char* repl_text; /* start of the replacement text */
|
char* repl_text; /* start of the replacement text */
|
||||||
int length; /* length of the replacement text */
|
int length; /* length of the replacement text */
|
||||||
register ch;
|
register int ch;
|
||||||
char* get_text();
|
|
||||||
|
|
||||||
/* read the #defined macro's name */
|
/* read the #defined macro's name */
|
||||||
if (!(str = GetIdentifier(1)))
|
if (!(str = GetIdentifier(1)))
|
||||||
|
@ -411,7 +429,7 @@ void do_define()
|
||||||
LineNumber++;
|
LineNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
push_if()
|
static void push_if(void)
|
||||||
{
|
{
|
||||||
if (nestlevel >= IFDEPTH)
|
if (nestlevel >= IFDEPTH)
|
||||||
fatal("too many nested #if/#ifdef/#ifndef");
|
fatal("too many nested #if/#ifdef/#ifndef");
|
||||||
|
@ -419,7 +437,7 @@ push_if()
|
||||||
ifstack[++nestlevel] = 0;
|
ifstack[++nestlevel] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_elif()
|
static void do_elif(void)
|
||||||
{
|
{
|
||||||
if (nestlevel <= svnestlevel[nestcount])
|
if (nestlevel <= svnestlevel[nestcount])
|
||||||
{
|
{
|
||||||
|
@ -439,7 +457,7 @@ do_elif()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_else()
|
static void do_else(void)
|
||||||
{
|
{
|
||||||
if (SkipToNewLine())
|
if (SkipToNewLine())
|
||||||
{
|
{
|
||||||
|
@ -459,7 +477,7 @@ do_else()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_endif()
|
static void do_endif(void)
|
||||||
{
|
{
|
||||||
if (SkipToNewLine())
|
if (SkipToNewLine())
|
||||||
{
|
{
|
||||||
|
@ -474,14 +492,14 @@ do_endif()
|
||||||
nestlevel--;
|
nestlevel--;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_if()
|
static void do_if(void)
|
||||||
{
|
{
|
||||||
push_if();
|
push_if();
|
||||||
if (!ifexpr()) /* a false #if/#elif expression */
|
if (!ifexpr()) /* a false #if/#elif expression */
|
||||||
skip_block(0);
|
skip_block(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
do_ifdef(how)
|
static void do_ifdef(int how)
|
||||||
{
|
{
|
||||||
register struct idf* id;
|
register struct idf* id;
|
||||||
register char* str;
|
register char* str;
|
||||||
|
@ -513,7 +531,7 @@ do_ifdef(how)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* argstr != NULL when the undef came from a -U option */
|
/* argstr != NULL when the undef came from a -U option */
|
||||||
do_undef(argstr) char* argstr;
|
void do_undef(char* argstr)
|
||||||
{
|
{
|
||||||
register struct idf* id;
|
register struct idf* id;
|
||||||
register char* str = argstr;
|
register char* str = argstr;
|
||||||
|
@ -548,7 +566,7 @@ do_undef(argstr) char* argstr;
|
||||||
error("illegal #undef construction");
|
error("illegal #undef construction");
|
||||||
}
|
}
|
||||||
|
|
||||||
do_error()
|
static void do_error(void)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char* get_text();
|
char* get_text();
|
||||||
|
@ -559,8 +577,7 @@ do_error()
|
||||||
LineNumber++;
|
LineNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getparams(buf, parbuf) char* buf[];
|
static int getparams(char* buf[], char parbuf[])
|
||||||
char parbuf[];
|
|
||||||
{
|
{
|
||||||
/* getparams() reads the formal parameter list of a macro
|
/* getparams() reads the formal parameter list of a macro
|
||||||
definition.
|
definition.
|
||||||
|
@ -633,8 +650,7 @@ char parbuf[];
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void macro_def(id, text, nformals, length, flags) register struct idf* id;
|
void macro_def(register struct idf* id, char* text, int nformals, int length, int flags)
|
||||||
char* text;
|
|
||||||
{
|
{
|
||||||
register struct macro* newdef = id->id_macro;
|
register struct macro* newdef = id->id_macro;
|
||||||
|
|
||||||
|
@ -681,7 +697,7 @@ char* text;
|
||||||
newdef->mc_flag = flags; /* special flags */
|
newdef->mc_flag = flags; /* special flags */
|
||||||
}
|
}
|
||||||
|
|
||||||
int find_name(nm, index) char *nm, *index[];
|
static int find_name(char* nm, char *index[])
|
||||||
{
|
{
|
||||||
/* find_name() returns the index of "nm" in the namelist
|
/* find_name() returns the index of "nm" in the namelist
|
||||||
"index" if it can be found there. 0 is returned if it is
|
"index" if it can be found there. 0 is returned if it is
|
||||||
|
@ -698,8 +714,7 @@ int find_name(nm, index) char *nm, *index[];
|
||||||
|
|
||||||
#define BLANK(ch) ((ch == ' ') || (ch == '\t'))
|
#define BLANK(ch) ((ch == ' ') || (ch == '\t'))
|
||||||
|
|
||||||
char* get_text(formals, length) char* formals[];
|
static char* get_text(char* formals[], int* length)
|
||||||
int* length;
|
|
||||||
{
|
{
|
||||||
/* get_text() copies the replacement text of a macro
|
/* get_text() copies the replacement text of a macro
|
||||||
definition with zero, one or more parameters, thereby
|
definition with zero, one or more parameters, thereby
|
||||||
|
@ -811,7 +826,7 @@ int* length;
|
||||||
add2repl(repl, ' ');
|
add2repl(repl, ' ');
|
||||||
}
|
}
|
||||||
/* construct the formal parameter mark or identifier */
|
/* construct the formal parameter mark or identifier */
|
||||||
if (n = find_name(id_buf, formals))
|
if ((n = find_name(id_buf, formals)))
|
||||||
add2repl(repl, FORMALP | (char)n);
|
add2repl(repl, FORMALP | (char)n);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -873,7 +888,7 @@ int* length;
|
||||||
as strings, without taking care of the leading and trailing
|
as strings, without taking care of the leading and trailing
|
||||||
blanks (spaces and tabs).
|
blanks (spaces and tabs).
|
||||||
*/
|
*/
|
||||||
macroeq(s, t) register char* s, *t;
|
static int macroeq(register char* s, register char *t)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* skip leading spaces */
|
/* skip leading spaces */
|
||||||
|
@ -902,7 +917,7 @@ macroeq(s, t) register char* s, *t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_line(l) unsigned int l;
|
static void do_line(unsigned int l)
|
||||||
{
|
{
|
||||||
struct token tk;
|
struct token tk;
|
||||||
int t = GetToken(&tk);
|
int t = GetToken(&tk);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
|
#include "print.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
|
|
||||||
/* This file contains the (non-portable) error-message and diagnostic
|
/* This file contains the (non-portable) error-message and diagnostic
|
||||||
|
@ -23,8 +24,7 @@
|
||||||
|
|
||||||
int err_occurred;
|
int err_occurred;
|
||||||
|
|
||||||
err_hdr(s)
|
static void err_hdr(char *s)
|
||||||
char *s;
|
|
||||||
{
|
{
|
||||||
if (FileName) {
|
if (FileName) {
|
||||||
fprint(ERROUT, "\"%s\", line %d: %s", FileName, (int)LineNumber, s);
|
fprint(ERROUT, "\"%s\", line %d: %s", FileName, (int)LineNumber, s);
|
||||||
|
@ -34,7 +34,7 @@ err_hdr(s)
|
||||||
|
|
||||||
#if __STDC__
|
#if __STDC__
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
error(char *fmt, ...)
|
void error(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ error(char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
warning(char *fmt, ...)
|
void warning(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ warning(char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
strict(char *fmt, ...)
|
void strict(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ strict(char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
crash(char *fmt, ...)
|
void crash(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ crash(char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
fatal(char *fmt, ...)
|
void fatal(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ fatal(char *fmt, ...)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
error(va_alist)
|
void error(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
char *fmt;
|
char *fmt;
|
||||||
|
@ -113,7 +113,7 @@ error(va_alist)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
warning(va_alist)
|
void warning(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
char *fmt;
|
char *fmt;
|
||||||
|
@ -128,7 +128,7 @@ warning(va_alist)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
strict(va_alist)
|
void strict(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
char *fmt;
|
char *fmt;
|
||||||
|
@ -143,7 +143,7 @@ strict(va_alist)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
crash(va_alist)
|
void crash(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
char *fmt;
|
char *fmt;
|
||||||
|
@ -159,7 +159,7 @@ crash(va_alist)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
fatal(va_alist)
|
void fatal(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
char *fmt;
|
char *fmt;
|
||||||
|
|
|
@ -5,11 +5,10 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
/* OPERATOR HANDLING */
|
/* OPERATOR HANDLING */
|
||||||
|
|
||||||
|
#include "expr.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
|
|
||||||
int
|
int rank_of(int oper)
|
||||||
rank_of(oper)
|
|
||||||
int oper;
|
|
||||||
{
|
{
|
||||||
/* The rank of the operator oper is returned.
|
/* The rank of the operator oper is returned.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
{
|
{
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
|
#include "ch3mon.h"
|
||||||
|
#include "ch3bin.h"
|
||||||
|
#include "expr.h"
|
||||||
|
|
||||||
extern arith ifval;
|
extern arith ifval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,10 @@
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
#include "class.h"
|
#include "class.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "error.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
#include "domacro.h"
|
||||||
|
|
||||||
struct mkey {
|
struct mkey {
|
||||||
char *mk_reserved;
|
char *mk_reserved;
|
||||||
|
@ -34,9 +37,8 @@ struct mkey {
|
||||||
{0, K_UNKNOWN}
|
{0, K_UNKNOWN}
|
||||||
};
|
};
|
||||||
|
|
||||||
char *sprint();
|
|
||||||
|
|
||||||
init_pp()
|
void init_pp(void)
|
||||||
{
|
{
|
||||||
static char *months[12] = {
|
static char *months[12] = {
|
||||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||||
|
@ -74,7 +76,7 @@ init_pp()
|
||||||
/* __DATE__ */
|
/* __DATE__ */
|
||||||
sprint(dbuf, "\"%s %2d %d\"", months[tp->tm_mon],
|
sprint(dbuf, "\"%s %2d %d\"", months[tp->tm_mon],
|
||||||
tp->tm_mday, tp->tm_year+1900);
|
tp->tm_mday, tp->tm_year+1900);
|
||||||
/* if (tp->tm_mday < 10) dbuf[5] = ' '; /* hack */
|
/* if (tp->tm_mday < 10) dbuf[5] = ' '; */ /* hack */
|
||||||
macro_def(str2idf("__DATE__", 0), dbuf, -1, strlen(dbuf), NOUNDEF);
|
macro_def(str2idf("__DATE__", 0), dbuf, -1, strlen(dbuf), NOUNDEF);
|
||||||
|
|
||||||
/* __TIME__ */
|
/* __TIME__ */
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "file_info.h"
|
#include "file_info.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "replace.h"
|
||||||
|
|
||||||
#define INP_PUSHBACK 3
|
#define INP_PUSHBACK 3
|
||||||
#define INP_TYPE struct file_info
|
#define INP_TYPE struct file_info
|
||||||
|
@ -17,9 +19,7 @@ struct file_info finfo;
|
||||||
#include <inp_pkg.body>
|
#include <inp_pkg.body>
|
||||||
#include <alloc.h>
|
#include <alloc.h>
|
||||||
|
|
||||||
char *
|
char *getwdir(register char *fn)
|
||||||
getwdir(fn)
|
|
||||||
register char *fn;
|
|
||||||
{
|
{
|
||||||
register char *p;
|
register char *p;
|
||||||
char *strrchr();
|
char *strrchr();
|
||||||
|
@ -44,7 +44,7 @@ getwdir(fn)
|
||||||
int NoUnstack;
|
int NoUnstack;
|
||||||
int InputLevel;
|
int InputLevel;
|
||||||
|
|
||||||
AtEoIT()
|
int AtEoIT(void)
|
||||||
{
|
{
|
||||||
InputLevel--;
|
InputLevel--;
|
||||||
/* if (NoUnstack) warning("unexpected EOF"); ??? */
|
/* if (NoUnstack) warning("unexpected EOF"); ??? */
|
||||||
|
@ -52,7 +52,7 @@ AtEoIT()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
AtEoIF()
|
int AtEoIF(void)
|
||||||
{
|
{
|
||||||
extern int nestlevel;
|
extern int nestlevel;
|
||||||
extern int nestcount;
|
extern int nestcount;
|
||||||
|
|
|
@ -11,4 +11,11 @@
|
||||||
#define UnGetChar() ((LexSave != EOI) ? ChPushBack(LexSave) : 0)
|
#define UnGetChar() ((LexSave != EOI) ? ChPushBack(LexSave) : 0)
|
||||||
|
|
||||||
extern int LexSave; /* last character read by GetChar */
|
extern int LexSave; /* last character read by GetChar */
|
||||||
extern int GetChar(); /* character input, with trigraph parsing */
|
|
||||||
|
|
||||||
|
/* Returns the working directory from a complete path+filename specification.
|
||||||
|
* If there is just a filename and no path, it returns DOT e.g the current
|
||||||
|
* directory.
|
||||||
|
*/
|
||||||
|
char *getwdir(register char *fn);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,14 @@
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
#include "file_info.h"
|
#include "file_info.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
#include "init.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "options.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "input.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
#include "preprocess.h"
|
||||||
|
|
||||||
|
|
||||||
extern char *symbol2str();
|
extern char *symbol2str();
|
||||||
extern char *getwdir();
|
extern char *getwdir();
|
||||||
|
@ -24,7 +31,7 @@ extern int do_dependencies;
|
||||||
extern char *dep_file;
|
extern char *dep_file;
|
||||||
int idfsize = IDFSIZE;
|
int idfsize = IDFSIZE;
|
||||||
extern char options[];
|
extern char options[];
|
||||||
static File *dep_fd = STDOUT;
|
static File *dep_fd;
|
||||||
|
|
||||||
arith ifval;
|
arith ifval;
|
||||||
|
|
||||||
|
@ -33,13 +40,18 @@ char *prog_name;
|
||||||
extern char **inctable;
|
extern char **inctable;
|
||||||
extern int inc_max, inc_total;
|
extern int inc_max, inc_total;
|
||||||
|
|
||||||
void dependency();
|
/* Forward declarations */
|
||||||
|
void compile(int argc, char *argv[]);
|
||||||
|
void add_dependency(char *);
|
||||||
|
static void list_dependencies(char *);
|
||||||
|
static void dependency(char *, char *);
|
||||||
|
|
||||||
main(argc, argv)
|
|
||||||
char *argv[];
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
/* parse and interpret the command line options */
|
/* parse and interpret the command line options */
|
||||||
prog_name = argv[0];
|
prog_name = argv[0];
|
||||||
|
dep_fd = STDOUT;
|
||||||
|
|
||||||
init_idf();
|
init_idf();
|
||||||
|
|
||||||
|
@ -67,8 +79,7 @@ main(argc, argv)
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
compile(argc, argv)
|
void compile(int argc, char *argv[])
|
||||||
char *argv[];
|
|
||||||
{
|
{
|
||||||
register char *source = 0;
|
register char *source = 0;
|
||||||
char *dummy;
|
char *dummy;
|
||||||
|
@ -97,10 +108,9 @@ compile(argc, argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct idf *file_head;
|
struct idf *file_head;
|
||||||
extern char *strrchr();
|
|
||||||
|
|
||||||
list_dependencies(source)
|
|
||||||
char *source;
|
static void list_dependencies(char *source)
|
||||||
{
|
{
|
||||||
register struct idf *p = file_head;
|
register struct idf *p = file_head;
|
||||||
|
|
||||||
|
@ -115,7 +125,7 @@ list_dependencies(source)
|
||||||
* object generated, so don't include the pathname
|
* object generated, so don't include the pathname
|
||||||
* leading to it.
|
* leading to it.
|
||||||
*/
|
*/
|
||||||
if (s = strrchr(source, '/')) {
|
if ((s = strrchr(source, '/'))) {
|
||||||
source = s + 1;
|
source = s + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,8 +141,7 @@ list_dependencies(source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
add_dependency(s)
|
void add_dependency(char *s)
|
||||||
char *s;
|
|
||||||
{
|
{
|
||||||
register struct idf *p = str2idf(s, 0);
|
register struct idf *p = str2idf(s, 0);
|
||||||
|
|
||||||
|
@ -143,9 +152,7 @@ add_dependency(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void dependency(char *s, char *source)
|
||||||
dependency(s, source)
|
|
||||||
char *s, *source;
|
|
||||||
{
|
{
|
||||||
if (options['i'] && !strncmp(s, "/usr/include/", 13)) {
|
if (options['i'] && !strncmp(s, "/usr/include/", 13)) {
|
||||||
return;
|
return;
|
||||||
|
@ -156,8 +163,7 @@ dependency(s, source)
|
||||||
else fprint(dep_fd, "%s\n", s);
|
else fprint(dep_fd, "%s\n", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void No_Mem(void) /* called by alloc package */
|
||||||
No_Mem() /* called by alloc package */
|
|
||||||
{
|
{
|
||||||
fatal("out of memory");
|
fatal("out of memory");
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "class.h"
|
#include "class.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
#include "domacro.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
char options[128]; /* one for every char */
|
char options[128]; /* one for every char */
|
||||||
int inc_pos = 1; /* place where next -I goes */
|
int inc_pos = 1; /* place where next -I goes */
|
||||||
|
@ -23,10 +25,10 @@ char **inctable;
|
||||||
char *dep_file = 0;
|
char *dep_file = 0;
|
||||||
|
|
||||||
extern int idfsize;
|
extern int idfsize;
|
||||||
int txt2int();
|
|
||||||
|
|
||||||
do_option(text)
|
static int txt2int(char **tp);
|
||||||
char *text;
|
|
||||||
|
void do_option(char *text)
|
||||||
{
|
{
|
||||||
switch(*text++) {
|
switch(*text++) {
|
||||||
case '-':
|
case '-':
|
||||||
|
@ -127,9 +129,7 @@ do_option(text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int txt2int(char **tp)
|
||||||
txt2int(tp)
|
|
||||||
char **tp;
|
|
||||||
{
|
{
|
||||||
/* the integer pointed to by *tp is read, while increasing
|
/* the integer pointed to by *tp is read, while increasing
|
||||||
*tp; the resulting value is yielded.
|
*tp; the resulting value is yielded.
|
||||||
|
|
|
@ -9,14 +9,19 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
#include <alloc.h>
|
#include <alloc.h>
|
||||||
|
#include "preprocess.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "class.h"
|
#include "class.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
#include "domacro.h"
|
||||||
|
#include "replace.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
#include "error.h"
|
||||||
#include "bits.h"
|
#include "bits.h"
|
||||||
|
#include "skip.h"
|
||||||
|
|
||||||
char _obuf[OBUFSIZE];
|
char _obuf[OBUFSIZE];
|
||||||
#ifdef DOBITS
|
#ifdef DOBITS
|
||||||
|
@ -26,7 +31,7 @@ extern int InputLevel;
|
||||||
|
|
||||||
extern char* sprint();
|
extern char* sprint();
|
||||||
|
|
||||||
Xflush()
|
void Xflush(void)
|
||||||
{
|
{
|
||||||
sys_write(STDOUT, _obuf, OBUFSIZE);
|
sys_write(STDOUT, _obuf, OBUFSIZE);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +50,7 @@ struct prag_info
|
||||||
static struct prag_info* pragma_tab;
|
static struct prag_info* pragma_tab;
|
||||||
static int pragma_nr;
|
static int pragma_nr;
|
||||||
|
|
||||||
do_pragma()
|
void do_pragma(void)
|
||||||
{
|
{
|
||||||
register int size = ITEXTSIZE;
|
register int size = ITEXTSIZE;
|
||||||
char* cur_line = Malloc((unsigned)size);
|
char* cur_line = Malloc((unsigned)size);
|
||||||
|
@ -123,7 +128,7 @@ do_pragma()
|
||||||
|
|
||||||
char Xbuf[256];
|
char Xbuf[256];
|
||||||
|
|
||||||
void preprocess(fn) char* fn;
|
void preprocess(char *fn)
|
||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
register char* op = _obuf;
|
register char* op = _obuf;
|
||||||
|
@ -535,8 +540,7 @@ void preprocess(fn) char* fn;
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* SkipComment(op, lineno) char* op;
|
static char* SkipComment(char *op, int *lineno)
|
||||||
int* lineno;
|
|
||||||
{
|
{
|
||||||
char* ob = &_obuf[OBUFSIZE];
|
char* ob = &_obuf[OBUFSIZE];
|
||||||
register int c, oldc = '\0';
|
register int c, oldc = '\0';
|
||||||
|
|
|
@ -19,19 +19,25 @@
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "class.h"
|
#include "class.h"
|
||||||
|
#include "skip.h"
|
||||||
|
#include "domacro.h"
|
||||||
#include "replace.h"
|
#include "replace.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
extern char *GetIdentifier();
|
;
|
||||||
extern int InputLevel;
|
extern int InputLevel;
|
||||||
struct repl *ReplaceList; /* list of currently active macros */
|
struct repl *ReplaceList; /* list of currently active macros */
|
||||||
|
|
||||||
void expand_defined();
|
static int expand_macro(register struct repl *, register struct idf *);
|
||||||
void getactuals();
|
static void expand_defined(register struct repl *);
|
||||||
void macro2buffer();
|
static void getactuals(struct repl *, register struct idf *);
|
||||||
|
static int actual(struct repl *);
|
||||||
|
static void macro_func(register struct idf *);
|
||||||
|
static void macro2buffer(register struct repl *, register struct idf *, register struct args *);
|
||||||
|
static char *stringify( register struct repl *, register char *, register struct args *);
|
||||||
|
static void stash(struct repl *, register int ch, int );
|
||||||
|
|
||||||
int
|
int replace(register struct idf *idf)
|
||||||
replace(idf)
|
|
||||||
register struct idf *idf;
|
|
||||||
{
|
{
|
||||||
/* replace is called by the lexical analyzer to perform
|
/* replace is called by the lexical analyzer to perform
|
||||||
macro replacement. The routine actualy functions as a
|
macro replacement. The routine actualy functions as a
|
||||||
|
@ -57,13 +63,12 @@ replace(idf)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unstackrepl()
|
void unstackrepl(void)
|
||||||
{
|
{
|
||||||
Unstacked++;
|
Unstacked++;
|
||||||
}
|
}
|
||||||
|
|
||||||
freeargs(args)
|
static void freeargs(struct args *args)
|
||||||
struct args *args;
|
|
||||||
{
|
{
|
||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
|
@ -81,7 +86,7 @@ freeargs(args)
|
||||||
free_args(args);
|
free_args(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnableMacros()
|
void EnableMacros(void)
|
||||||
{
|
{
|
||||||
register struct repl *r = ReplaceList, *prev = 0;
|
register struct repl *r = ReplaceList, *prev = 0;
|
||||||
|
|
||||||
|
@ -103,9 +108,9 @@ EnableMacros()
|
||||||
Unstacked = 0;
|
Unstacked = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
expand_macro(repl, idf)
|
static int expand_macro(
|
||||||
register struct repl *repl;
|
register struct repl *repl,
|
||||||
register struct idf *idf;
|
register struct idf *idf)
|
||||||
{
|
{
|
||||||
/* expand_macro() does the actual macro replacement.
|
/* expand_macro() does the actual macro replacement.
|
||||||
"idf" is a description of the identifier which
|
"idf" is a description of the identifier which
|
||||||
|
@ -168,9 +173,7 @@ expand_macro(repl, idf)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void expand_defined(register struct repl *repl)
|
||||||
expand_defined(repl)
|
|
||||||
register struct repl *repl;
|
|
||||||
{
|
{
|
||||||
register int ch = GetChar();
|
register int ch = GetChar();
|
||||||
struct idf *id;
|
struct idf *id;
|
||||||
|
@ -205,17 +208,13 @@ expand_defined(repl)
|
||||||
add2repl(repl, ' ');
|
add2repl(repl, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
newarg(args)
|
static void newarg(struct args *args)
|
||||||
struct args *args;
|
|
||||||
{
|
{
|
||||||
args->a_expptr = args->a_expbuf = Malloc((unsigned)(args->a_expsize = ARGBUF));
|
args->a_expptr = args->a_expbuf = Malloc((unsigned)(args->a_expsize = ARGBUF));
|
||||||
args->a_rawptr = args->a_rawbuf = Malloc((unsigned)(args->a_rawsize = ARGBUF));
|
args->a_rawptr = args->a_rawbuf = Malloc((unsigned)(args->a_rawsize = ARGBUF));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void getactuals(struct repl *repl, register struct idf *idf)
|
||||||
getactuals(repl, idf)
|
|
||||||
struct repl *repl;
|
|
||||||
register struct idf *idf;
|
|
||||||
{
|
{
|
||||||
/* Get the actual parameters from the input stream.
|
/* Get the actual parameters from the input stream.
|
||||||
The hard part is done by actual(), only comma's and
|
The hard part is done by actual(), only comma's and
|
||||||
|
@ -256,8 +255,7 @@ getactuals(repl, idf)
|
||||||
error("too many macro arguments");
|
error("too many macro arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
saveraw(repl)
|
static void saveraw(struct repl *repl)
|
||||||
struct repl *repl;
|
|
||||||
{
|
{
|
||||||
register struct repl *nrepl = ReplaceList;
|
register struct repl *nrepl = ReplaceList;
|
||||||
register struct args *ap = nrepl->r_args;
|
register struct args *ap = nrepl->r_args;
|
||||||
|
@ -294,9 +292,7 @@ struct repl *repl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int actual(struct repl *repl)
|
||||||
actual(repl)
|
|
||||||
struct repl *repl;
|
|
||||||
{
|
{
|
||||||
/* This routine deals with the scanning of an actual parameter.
|
/* This routine deals with the scanning of an actual parameter.
|
||||||
It keeps in account the opening and closing brackets,
|
It keeps in account the opening and closing brackets,
|
||||||
|
@ -497,8 +493,7 @@ a_new_line: ch = GetChar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_func(idef)
|
static void macro_func(register struct idf *idef)
|
||||||
register struct idf *idef;
|
|
||||||
{
|
{
|
||||||
/* macro_func() performs the special actions needed with some
|
/* macro_func() performs the special actions needed with some
|
||||||
macros. These macros are __FILE__ and __LINE__ which
|
macros. These macros are __FILE__ and __LINE__ which
|
||||||
|
@ -526,11 +521,10 @@ macro_func(idef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void macro2buffer(
|
||||||
macro2buffer(repl, idf, args)
|
register struct repl *repl,
|
||||||
register struct repl *repl;
|
register struct idf *idf,
|
||||||
register struct idf *idf;
|
register struct args *args)
|
||||||
register struct args *args;
|
|
||||||
{
|
{
|
||||||
/* macro2buffer expands the replacement list and places the
|
/* macro2buffer expands the replacement list and places the
|
||||||
result onto the replacement buffer. It deals with the #
|
result onto the replacement buffer. It deals with the #
|
||||||
|
@ -680,11 +674,10 @@ macro2buffer(repl, idf, args)
|
||||||
error("illegal use of ## operator");
|
error("illegal use of ## operator");
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
static char *stringify(
|
||||||
stringify(repl, ptr, args)
|
register struct repl *repl,
|
||||||
register struct repl *repl;
|
register char *ptr,
|
||||||
register char *ptr;
|
register struct args *args)
|
||||||
register struct args *args;
|
|
||||||
{
|
{
|
||||||
/* If a parameter is immediately preceded by a # token
|
/* If a parameter is immediately preceded by a # token
|
||||||
both are replaced by a single string literal that
|
both are replaced by a single string literal that
|
||||||
|
@ -747,9 +740,7 @@ stringify(repl, ptr, args)
|
||||||
|
|
||||||
/* The following routine is also called from domacro.c.
|
/* The following routine is also called from domacro.c.
|
||||||
*/
|
*/
|
||||||
add2repl(repl, ch)
|
void add2repl(register struct repl *repl, int ch)
|
||||||
register struct repl *repl;
|
|
||||||
int ch;
|
|
||||||
{
|
{
|
||||||
register int index = repl->r_ptr - repl->r_text;
|
register int index = repl->r_ptr - repl->r_text;
|
||||||
|
|
||||||
|
@ -766,10 +757,7 @@ add2repl(repl, ch)
|
||||||
* buffer. If the variable is zero, we must only stash into the expanded
|
* buffer. If the variable is zero, we must only stash into the expanded
|
||||||
* buffer. Otherwise, we must use both buffers.
|
* buffer. Otherwise, we must use both buffers.
|
||||||
*/
|
*/
|
||||||
stash(repl, ch, stashraw)
|
static void stash(struct repl *repl, register int ch, int stashraw)
|
||||||
struct repl *repl;
|
|
||||||
register int ch;
|
|
||||||
int stashraw;
|
|
||||||
{
|
{
|
||||||
/* Stash characters into the macro expansion buffer.
|
/* Stash characters into the macro expansion buffer.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
/* DEFINITIONS FOR THE MACRO REPLACEMENT ROUTINES */
|
/* DEFINITIONS FOR THE MACRO REPLACEMENT ROUTINES */
|
||||||
|
#ifndef _REPLACE_H_
|
||||||
|
#define _REPLACE_H_
|
||||||
|
|
||||||
|
#include "parameters.h"
|
||||||
|
|
||||||
struct repl {
|
struct repl {
|
||||||
struct repl *next;
|
struct repl *next;
|
||||||
|
@ -48,3 +52,12 @@ struct args {
|
||||||
/* ALLOCDEF "args" 2 */
|
/* ALLOCDEF "args" 2 */
|
||||||
|
|
||||||
#define NO_ARGS (struct args *)0
|
#define NO_ARGS (struct args *)0
|
||||||
|
|
||||||
|
struct idf;
|
||||||
|
|
||||||
|
void unstackrepl(void);
|
||||||
|
int replace(register struct idf *idf);
|
||||||
|
void EnableMacros(void);
|
||||||
|
void add2repl(register struct repl *repl, int ch);
|
||||||
|
|
||||||
|
#endif /* REPLACE_H_ */
|
||||||
|
|
|
@ -9,14 +9,13 @@
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "class.h"
|
#include "class.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "domacro.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
extern int InputLevel;
|
extern int InputLevel;
|
||||||
|
|
||||||
int skipspaces(ch, skipnl) register int ch;
|
int skipspaces(register int ch, int skipnl)
|
||||||
{
|
{
|
||||||
/* skipspaces() skips any white space and returns the first
|
|
||||||
non-space character.
|
|
||||||
*/
|
|
||||||
register int nlseen = 0;
|
register int nlseen = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -65,9 +64,11 @@ int skipspaces(ch, skipnl) register int ch;
|
||||||
else
|
else
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
/* garbage */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkipToNewLine()
|
int SkipToNewLine(void)
|
||||||
{
|
{
|
||||||
register int ch;
|
register int ch;
|
||||||
register int garbage = 0;
|
register int garbage = 0;
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
|
|
||||||
!File: debugcst.h
|
!File: debugcst.h
|
||||||
/*#define DEBUG 1 /* perform various self-tests */
|
/*#define DEBUG 1 *//* perform various self-tests */
|
||||||
#define NDEBUG 1 /* disable assertions */
|
#define NDEBUG 1 /* disable assertions */
|
||||||
|
|
||||||
!File: inputtype.h
|
!File: inputtype.h
|
||||||
|
@ -57,22 +57,22 @@
|
||||||
|
|
||||||
|
|
||||||
!File: squeeze.h
|
!File: squeeze.h
|
||||||
/*#define SQUEEZE 1 /* define on "small" machines */
|
/*#define SQUEEZE 1 *//* define on "small" machines */
|
||||||
|
|
||||||
|
|
||||||
!File: strict3rd.h
|
!File: strict3rd.h
|
||||||
/*#define STRICT_3RD_ED 1 /* define on "small" machines, and if you want
|
/*#define STRICT_3RD_ED 1 *//* define on "small" machines, and if you want
|
||||||
a compiler that only implements "3rd edition"
|
a compiler that only implements "3rd edition"
|
||||||
Modula-2
|
Modula-2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
!File: nocross.h
|
!File: nocross.h
|
||||||
/*#define NOCROSS 1 /* define when cross-compiler not needed */
|
/*#define NOCROSS 1 *//* define when cross-compiler not needed */
|
||||||
|
|
||||||
|
|
||||||
!File: nostrict.h
|
!File: nostrict.h
|
||||||
/*#define NOSTRICT 1 /* define when STRICT warnings disabled
|
/*#define NOSTRICT 1 *//* define when STRICT warnings disabled
|
||||||
(yet another squeezing method)
|
(yet another squeezing method)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "class.h"
|
#include "class.h"
|
||||||
|
#include "error.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
@ -48,8 +49,7 @@ int tk_nmb_at_last_syn_err = -ERR_SHADOW;
|
||||||
extern char options[];
|
extern char options[];
|
||||||
extern int flt_status;
|
extern int flt_status;
|
||||||
|
|
||||||
STATIC
|
static void SkipComment(void)
|
||||||
SkipComment()
|
|
||||||
{
|
{
|
||||||
/* Skip Modula-2 comments (* ... *).
|
/* Skip Modula-2 comments (* ... *).
|
||||||
Note that comments may be nested (par. 3.5).
|
Note that comments may be nested (par. 3.5).
|
||||||
|
@ -122,8 +122,7 @@ SkipComment()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC struct string *
|
static struct string *GetString(int upto)
|
||||||
GetString(upto)
|
|
||||||
{
|
{
|
||||||
/* Read a Modula-2 string, delimited by the character "upto".
|
/* Read a Modula-2 string, delimited by the character "upto".
|
||||||
*/
|
*/
|
||||||
|
@ -169,8 +168,7 @@ GetString(upto)
|
||||||
|
|
||||||
static char *s_error = "illegal line directive";
|
static char *s_error = "illegal line directive";
|
||||||
|
|
||||||
STATIC int
|
static int getch(void)
|
||||||
getch()
|
|
||||||
{
|
{
|
||||||
register int ch;
|
register int ch;
|
||||||
|
|
||||||
|
@ -180,8 +178,7 @@ getch()
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CheckForLineDirective(void)
|
||||||
CheckForLineDirective()
|
|
||||||
{
|
{
|
||||||
register int ch = getch();
|
register int ch = getch();
|
||||||
register int i = 0;
|
register int i = 0;
|
||||||
|
@ -242,8 +239,7 @@ CheckForLineDirective()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
static void CheckForLet()
|
||||||
CheckForLet()
|
|
||||||
{
|
{
|
||||||
register int ch;
|
register int ch;
|
||||||
|
|
||||||
|
@ -256,8 +252,7 @@ CheckForLet()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int LLlex(void)
|
||||||
LLlex()
|
|
||||||
{
|
{
|
||||||
/* LLlex() is the Lexical Analyzer.
|
/* LLlex() is the Lexical Analyzer.
|
||||||
The putting aside of tokens is taken into account.
|
The putting aside of tokens is taken into account.
|
||||||
|
|
|
@ -68,3 +68,5 @@ extern struct type *toktype;
|
||||||
|
|
||||||
extern int token_nmb;
|
extern int token_nmb;
|
||||||
extern int tk_nmb_at_last_syn_err;
|
extern int tk_nmb_at_last_syn_err;
|
||||||
|
|
||||||
|
void CheckForLineDirective(void);
|
||||||
|
|
|
@ -19,16 +19,17 @@
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
#include <em_label.h>
|
#include <em_label.h>
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
#include "error.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
extern char *symbol2str();
|
extern char *symbol2str();
|
||||||
extern t_idf *gen_anon_idf();
|
|
||||||
|
|
||||||
LLmessage(tk)
|
|
||||||
register int tk;
|
void LLmessage(register int tk)
|
||||||
{
|
{
|
||||||
if (tk > 0) {
|
if (tk > 0) {
|
||||||
/* if (tk > 0), it represents the token to be inserted.
|
/* if (tk > 0), it represents the token to be inserted.
|
||||||
|
|
|
@ -16,21 +16,25 @@
|
||||||
cases themselves.
|
cases themselves.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <em_label.h>
|
|
||||||
#include <em_arith.h>
|
|
||||||
#include <em_code.h>
|
|
||||||
#include <alloc.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include "em_label.h"
|
||||||
|
#include "em_arith.h"
|
||||||
|
#include "em_code.h"
|
||||||
|
#include "alloc.h"
|
||||||
|
|
||||||
|
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
#include "error.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "desig.h"
|
#include "desig.h"
|
||||||
#include "walk.h"
|
#include "walk.h"
|
||||||
|
#include "code.h"
|
||||||
|
#include "typequiv.h"
|
||||||
#include "chk_expr.h"
|
#include "chk_expr.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
|
|
||||||
|
@ -54,11 +58,12 @@ struct case_entry {
|
||||||
arith ce_low, ce_up; /* lower and upper bound of range */
|
arith ce_low, ce_up; /* lower and upper bound of range */
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddCases();
|
|
||||||
void AddOneCase();
|
|
||||||
|
|
||||||
/* STATICALLOCDEF "case_entry" 20 */
|
/* STATICALLOCDEF "case_entry" 20 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* The constant DENSITY determines when CSA and when CSB instructions
|
/* The constant DENSITY determines when CSA and when CSB instructions
|
||||||
are generated. Reasonable values are: 2, 3, 4.
|
are generated. Reasonable values are: 2, 3, 4.
|
||||||
On machines that have lots of address space and memory, higher values
|
On machines that have lots of address space and memory, higher values
|
||||||
|
@ -66,8 +71,7 @@ void AddOneCase();
|
||||||
may be lower.
|
may be lower.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
compact(nr, low, up)
|
static int compact(int nr, arith low, arith up)
|
||||||
arith low, up;
|
|
||||||
{
|
{
|
||||||
/* Careful! up - low might not fit in an arith. And then,
|
/* Careful! up - low might not fit in an arith. And then,
|
||||||
the test "up-low < 0" might also not work to detect this
|
the test "up-low < 0" might also not work to detect this
|
||||||
|
@ -80,199 +84,7 @@ compact(nr, low, up)
|
||||||
}
|
}
|
||||||
#define nd_lab nd_symb
|
#define nd_lab nd_symb
|
||||||
|
|
||||||
int
|
static void AddOneCase(struct switch_hdr *sh, t_node *lnode, t_node *rnode, label lbl)
|
||||||
CaseCode(nd, exitlabel, end_reached)
|
|
||||||
t_node *nd;
|
|
||||||
label exitlabel;
|
|
||||||
{
|
|
||||||
/* Check the expression, stack a new case header and
|
|
||||||
fill in the necessary fields.
|
|
||||||
"exitlabel" is the exit-label of the closest enclosing
|
|
||||||
LOOP-statement, or 0.
|
|
||||||
*/
|
|
||||||
register struct switch_hdr *sh = new_switch_hdr();
|
|
||||||
register t_node *pnode = nd;
|
|
||||||
register struct case_entry *ce;
|
|
||||||
register arith val;
|
|
||||||
label CaseDescrLab;
|
|
||||||
int rval;
|
|
||||||
|
|
||||||
assert(pnode->nd_class == Stat && pnode->nd_symb == CASE);
|
|
||||||
|
|
||||||
if (ChkExpression(&(pnode->nd_LEFT))) {
|
|
||||||
MkCoercion(&(pnode->nd_LEFT),BaseType(pnode->nd_LEFT->nd_type));
|
|
||||||
CodePExpr(pnode->nd_LEFT);
|
|
||||||
}
|
|
||||||
sh->sh_type = pnode->nd_LEFT->nd_type;
|
|
||||||
sh->sh_break = ++text_label;
|
|
||||||
|
|
||||||
/* Now, create case label list
|
|
||||||
*/
|
|
||||||
while (pnode = pnode->nd_RIGHT) {
|
|
||||||
if (pnode->nd_class == Link && pnode->nd_symb == '|') {
|
|
||||||
if (pnode->nd_LEFT) {
|
|
||||||
/* non-empty case
|
|
||||||
*/
|
|
||||||
pnode->nd_LEFT->nd_lab = ++text_label;
|
|
||||||
AddCases(sh, /* to descriptor */
|
|
||||||
pnode->nd_LEFT->nd_LEFT,
|
|
||||||
/* of case labels */
|
|
||||||
(label) pnode->nd_LEFT->nd_lab
|
|
||||||
/* and code label */
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Else part
|
|
||||||
*/
|
|
||||||
|
|
||||||
sh->sh_default = ++text_label;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sh->sh_nrofentries) {
|
|
||||||
/* There were no cases, so we have to check the case-expression
|
|
||||||
here
|
|
||||||
*/
|
|
||||||
if (! (sh->sh_type->tp_fund & T_DISCRETE)) {
|
|
||||||
node_error(nd, "illegal type in CASE-expression");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now generate code for the switch itself
|
|
||||||
First the part that CSA and CSB descriptions have in common.
|
|
||||||
*/
|
|
||||||
CaseDescrLab = ++data_label; /* the rom must have a label */
|
|
||||||
C_df_dlb(CaseDescrLab);
|
|
||||||
if (sh->sh_default) C_rom_ilb(sh->sh_default);
|
|
||||||
else C_rom_ucon("0", pointer_size);
|
|
||||||
if (compact(sh->sh_nrofentries, sh->sh_lowerbd, sh->sh_upperbd)) {
|
|
||||||
/* CSA
|
|
||||||
*/
|
|
||||||
int gen = 1;
|
|
||||||
|
|
||||||
ce = sh->sh_entries;
|
|
||||||
while (! ce->ce_label) ce = ce->ce_next;
|
|
||||||
C_rom_cst((arith) 0);
|
|
||||||
C_rom_cst(sh->sh_upperbd - sh->sh_lowerbd);
|
|
||||||
for (val = sh->sh_lowerbd; val <= sh->sh_upperbd; val++) {
|
|
||||||
assert(ce);
|
|
||||||
if (gen || val == ce->ce_low) {
|
|
||||||
gen = 1;
|
|
||||||
C_rom_ilb(ce->ce_label);
|
|
||||||
if (val == ce->ce_up) {
|
|
||||||
gen = 0;
|
|
||||||
ce = ce->ce_next;
|
|
||||||
while (ce && ! ce->ce_label) ce = ce->ce_next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sh->sh_default) C_rom_ilb(sh->sh_default);
|
|
||||||
else C_rom_ucon("0", pointer_size);
|
|
||||||
}
|
|
||||||
C_loc(sh->sh_lowerbd);
|
|
||||||
C_sbu(word_size);
|
|
||||||
c_lae_dlb(CaseDescrLab); /* perform the switch */
|
|
||||||
C_csa(word_size);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* CSB
|
|
||||||
*/
|
|
||||||
C_rom_cst((arith)sh->sh_nrofentries);
|
|
||||||
for (ce = sh->sh_entries; ce; ce = ce->ce_next) {
|
|
||||||
/* generate the entries: value + prog.label
|
|
||||||
*/
|
|
||||||
if (! ce->ce_label) continue;
|
|
||||||
val = ce->ce_low;
|
|
||||||
do {
|
|
||||||
C_rom_cst(val);
|
|
||||||
C_rom_ilb(ce->ce_label);
|
|
||||||
} while (val++ != ce->ce_up);
|
|
||||||
}
|
|
||||||
c_lae_dlb(CaseDescrLab); /* perform the switch */
|
|
||||||
C_csb(word_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now generate code for the cases
|
|
||||||
*/
|
|
||||||
pnode = nd;
|
|
||||||
rval = 0;
|
|
||||||
while (pnode = pnode->nd_RIGHT) {
|
|
||||||
if (pnode->nd_class == Link && pnode->nd_symb == '|') {
|
|
||||||
if (pnode->nd_LEFT) {
|
|
||||||
rval |= LblWalkNode((label) pnode->nd_LEFT->nd_lab,
|
|
||||||
pnode->nd_LEFT->nd_RIGHT,
|
|
||||||
exitlabel, end_reached);
|
|
||||||
c_bra(sh->sh_break);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Else part
|
|
||||||
*/
|
|
||||||
assert(sh->sh_default != 0);
|
|
||||||
|
|
||||||
rval |= LblWalkNode(sh->sh_default,
|
|
||||||
pnode, exitlabel, end_reached);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def_ilb(sh->sh_break);
|
|
||||||
FreeSh(sh);
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
FreeSh(sh)
|
|
||||||
register struct switch_hdr *sh;
|
|
||||||
{
|
|
||||||
/* free the allocated switch structure
|
|
||||||
*/
|
|
||||||
register struct case_entry *ce;
|
|
||||||
|
|
||||||
ce = sh->sh_entries;
|
|
||||||
while (ce) {
|
|
||||||
struct case_entry *tmp = ce->ce_next;
|
|
||||||
|
|
||||||
free_case_entry(ce);
|
|
||||||
ce = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
free_switch_hdr(sh);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AddCases(sh, node, lbl)
|
|
||||||
struct switch_hdr *sh;
|
|
||||||
register t_node *node;
|
|
||||||
label lbl;
|
|
||||||
{
|
|
||||||
/* Add case labels to the case label list
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (node->nd_class == Link) {
|
|
||||||
if (node->nd_symb == UPTO) {
|
|
||||||
assert(node->nd_LEFT->nd_class == Value);
|
|
||||||
assert(node->nd_RIGHT->nd_class == Value);
|
|
||||||
|
|
||||||
AddOneCase(sh, node->nd_LEFT, node->nd_RIGHT, lbl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(node->nd_symb == ',');
|
|
||||||
AddCases(sh, node->nd_LEFT, lbl);
|
|
||||||
AddCases(sh, node->nd_RIGHT, lbl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(node->nd_class == Value);
|
|
||||||
AddOneCase(sh, node, node, lbl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AddOneCase(sh, lnode, rnode, lbl)
|
|
||||||
register struct switch_hdr *sh;
|
|
||||||
t_node *lnode, *rnode;
|
|
||||||
label lbl;
|
|
||||||
{
|
{
|
||||||
register struct case_entry *ce = new_case_entry();
|
register struct case_entry *ce = new_case_entry();
|
||||||
register struct case_entry *c1 = sh->sh_entries, *c2 = 0;
|
register struct case_entry *c1 = sh->sh_entries, *c2 = 0;
|
||||||
|
@ -387,3 +199,188 @@ node_error(rnode, "multiple case entry for value %ld", (long)(ce->ce_up));
|
||||||
}
|
}
|
||||||
if (ce->ce_label) sh->sh_nrofentries += ce->ce_up - ce->ce_low + 1;
|
if (ce->ce_label) sh->sh_nrofentries += ce->ce_up - ce->ce_low + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void AddCases(struct switch_hdr *sh, register t_node *node, label lbl)
|
||||||
|
{
|
||||||
|
/* Add case labels to the case label list
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (node->nd_class == Link) {
|
||||||
|
if (node->nd_symb == UPTO) {
|
||||||
|
assert(node->nd_LEFT->nd_class == Value);
|
||||||
|
assert(node->nd_RIGHT->nd_class == Value);
|
||||||
|
|
||||||
|
AddOneCase(sh, node->nd_LEFT, node->nd_RIGHT, lbl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(node->nd_symb == ',');
|
||||||
|
AddCases(sh, node->nd_LEFT, lbl);
|
||||||
|
AddCases(sh, node->nd_RIGHT, lbl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(node->nd_class == Value);
|
||||||
|
AddOneCase(sh, node, node, lbl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void FreeSh(struct switch_hdr *sh)
|
||||||
|
{
|
||||||
|
/* free the allocated switch structure
|
||||||
|
*/
|
||||||
|
register struct case_entry *ce;
|
||||||
|
|
||||||
|
ce = sh->sh_entries;
|
||||||
|
while (ce) {
|
||||||
|
struct case_entry *tmp = ce->ce_next;
|
||||||
|
|
||||||
|
free_case_entry(ce);
|
||||||
|
ce = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
free_switch_hdr(sh);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CaseCode(t_node *nd, label exitlabel, int end_reached)
|
||||||
|
{
|
||||||
|
/* Check the expression, stack a new case header and
|
||||||
|
fill in the necessary fields.
|
||||||
|
"exitlabel" is the exit-label of the closest enclosing
|
||||||
|
LOOP-statement, or 0.
|
||||||
|
*/
|
||||||
|
register struct switch_hdr *sh = new_switch_hdr();
|
||||||
|
register t_node *pnode = nd;
|
||||||
|
register struct case_entry *ce;
|
||||||
|
register arith val;
|
||||||
|
label CaseDescrLab;
|
||||||
|
int rval;
|
||||||
|
|
||||||
|
assert(pnode->nd_class == Stat && pnode->nd_symb == CASE);
|
||||||
|
|
||||||
|
if (ChkExpression(&(pnode->nd_LEFT))) {
|
||||||
|
MkCoercion(&(pnode->nd_LEFT),BaseType(pnode->nd_LEFT->nd_type));
|
||||||
|
CodePExpr(pnode->nd_LEFT);
|
||||||
|
}
|
||||||
|
sh->sh_type = pnode->nd_LEFT->nd_type;
|
||||||
|
sh->sh_break = ++text_label;
|
||||||
|
|
||||||
|
/* Now, create case label list
|
||||||
|
*/
|
||||||
|
while ( (pnode = pnode->nd_RIGHT) ) {
|
||||||
|
if (pnode->nd_class == Link && pnode->nd_symb == '|') {
|
||||||
|
if (pnode->nd_LEFT) {
|
||||||
|
/* non-empty case
|
||||||
|
*/
|
||||||
|
pnode->nd_LEFT->nd_lab = ++text_label;
|
||||||
|
AddCases(sh, /* to descriptor */
|
||||||
|
pnode->nd_LEFT->nd_LEFT,
|
||||||
|
/* of case labels */
|
||||||
|
(label) pnode->nd_LEFT->nd_lab
|
||||||
|
/* and code label */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Else part
|
||||||
|
*/
|
||||||
|
|
||||||
|
sh->sh_default = ++text_label;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sh->sh_nrofentries) {
|
||||||
|
/* There were no cases, so we have to check the case-expression
|
||||||
|
here
|
||||||
|
*/
|
||||||
|
if (! (sh->sh_type->tp_fund & T_DISCRETE)) {
|
||||||
|
node_error(nd, "illegal type in CASE-expression");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now generate code for the switch itself
|
||||||
|
First the part that CSA and CSB descriptions have in common.
|
||||||
|
*/
|
||||||
|
CaseDescrLab = ++data_label; /* the rom must have a label */
|
||||||
|
C_df_dlb(CaseDescrLab);
|
||||||
|
if (sh->sh_default) C_rom_ilb(sh->sh_default);
|
||||||
|
else C_rom_ucon("0", pointer_size);
|
||||||
|
if (compact(sh->sh_nrofentries, sh->sh_lowerbd, sh->sh_upperbd)) {
|
||||||
|
/* CSA
|
||||||
|
*/
|
||||||
|
int gen = 1;
|
||||||
|
|
||||||
|
ce = sh->sh_entries;
|
||||||
|
while (! ce->ce_label) ce = ce->ce_next;
|
||||||
|
C_rom_cst((arith) 0);
|
||||||
|
C_rom_cst(sh->sh_upperbd - sh->sh_lowerbd);
|
||||||
|
for (val = sh->sh_lowerbd; val <= sh->sh_upperbd; val++) {
|
||||||
|
assert(ce);
|
||||||
|
if (gen || val == ce->ce_low) {
|
||||||
|
gen = 1;
|
||||||
|
C_rom_ilb(ce->ce_label);
|
||||||
|
if (val == ce->ce_up) {
|
||||||
|
gen = 0;
|
||||||
|
ce = ce->ce_next;
|
||||||
|
while (ce && ! ce->ce_label) ce = ce->ce_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (sh->sh_default) C_rom_ilb(sh->sh_default);
|
||||||
|
else C_rom_ucon("0", pointer_size);
|
||||||
|
}
|
||||||
|
C_loc(sh->sh_lowerbd);
|
||||||
|
C_sbu(word_size);
|
||||||
|
c_lae_dlb(CaseDescrLab); /* perform the switch */
|
||||||
|
C_csa(word_size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* CSB
|
||||||
|
*/
|
||||||
|
C_rom_cst((arith)sh->sh_nrofentries);
|
||||||
|
for (ce = sh->sh_entries; ce; ce = ce->ce_next) {
|
||||||
|
/* generate the entries: value + prog.label
|
||||||
|
*/
|
||||||
|
if (! ce->ce_label) continue;
|
||||||
|
val = ce->ce_low;
|
||||||
|
do {
|
||||||
|
C_rom_cst(val);
|
||||||
|
C_rom_ilb(ce->ce_label);
|
||||||
|
} while (val++ != ce->ce_up);
|
||||||
|
}
|
||||||
|
c_lae_dlb(CaseDescrLab); /* perform the switch */
|
||||||
|
C_csb(word_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now generate code for the cases
|
||||||
|
*/
|
||||||
|
pnode = nd;
|
||||||
|
rval = 0;
|
||||||
|
while ( (pnode = pnode->nd_RIGHT) ) {
|
||||||
|
if (pnode->nd_class == Link && pnode->nd_symb == '|') {
|
||||||
|
if (pnode->nd_LEFT) {
|
||||||
|
rval |= LblWalkNode((label) pnode->nd_LEFT->nd_lab,
|
||||||
|
pnode->nd_LEFT->nd_RIGHT,
|
||||||
|
exitlabel, end_reached);
|
||||||
|
c_bra(sh->sh_break);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Else part
|
||||||
|
*/
|
||||||
|
assert(sh->sh_default != 0);
|
||||||
|
|
||||||
|
rval |= LblWalkNode(sh->sh_default,
|
||||||
|
pnode, exitlabel, end_reached);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_ilb(sh->sh_break);
|
||||||
|
FreeSh(sh);
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,15 +12,17 @@
|
||||||
/* Check expressions, and try to evaluate them as far as possible.
|
/* Check expressions, and try to evaluate them as far as possible.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
#include <em_label.h>
|
#include <em_label.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <alloc.h>
|
#include <alloc.h>
|
||||||
|
#include <flt_arith.h>
|
||||||
|
#include <system.h>
|
||||||
|
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
@ -29,21 +31,30 @@
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
|
#include "error.h"
|
||||||
#include "standards.h"
|
#include "standards.h"
|
||||||
#include "chk_expr.h"
|
#include "chk_expr.h"
|
||||||
|
#include "cstoper.h"
|
||||||
|
#include "typequiv.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "lookup.h"
|
||||||
|
#include "print.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
extern char *symbol2str();
|
extern char *symbol2str();
|
||||||
extern char *sprint();
|
|
||||||
extern arith flt_flt2arith();
|
|
||||||
|
|
||||||
STATIC
|
/* Forward file declarations */
|
||||||
df_error(nd, mess, edf)
|
static int ChkStandard(t_node **);
|
||||||
t_node *nd; /* node on which error occurred */
|
static int ChkCast(t_node **);
|
||||||
char *mess; /* error message */
|
|
||||||
register t_def *edf; /* do we have a name? */
|
|
||||||
|
|
||||||
|
|
||||||
|
static void df_error(
|
||||||
|
t_node *nd, /* node on which error occurred */
|
||||||
|
char *mess, /* error message */
|
||||||
|
register t_def *edf) /* do we have a name? */
|
||||||
{
|
{
|
||||||
if (edf) {
|
if (edf) {
|
||||||
if (edf->df_kind != D_ERROR) {
|
if (edf->df_kind != D_ERROR) {
|
||||||
|
@ -53,10 +64,7 @@ df_error(nd, mess, edf)
|
||||||
else node_error(nd, mess);
|
else node_error(nd, mess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void MkCoercion(t_node **pnd, register t_type *tp)
|
||||||
MkCoercion(pnd, tp)
|
|
||||||
t_node **pnd;
|
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* Make a coercion from the node indicated by *pnd to the
|
/* Make a coercion from the node indicated by *pnd to the
|
||||||
type indicated by tp. If the node indicated by *pnd
|
type indicated by tp. If the node indicated by *pnd
|
||||||
|
@ -162,9 +170,7 @@ MkCoercion(pnd, tp)
|
||||||
*pnd = nd;
|
*pnd = nd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int ChkVariable(register t_node **expp, int flags)
|
||||||
ChkVariable(expp, flags)
|
|
||||||
register t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* Check that "expp" indicates an item that can be
|
/* Check that "expp" indicates an item that can be
|
||||||
assigned to.
|
assigned to.
|
||||||
|
@ -182,9 +188,7 @@ ChkVariable(expp, flags)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkArrow(t_node **expp, int flags)
|
||||||
ChkArrow(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* Check an application of the '^' operator.
|
/* Check an application of the '^' operator.
|
||||||
The operand must be a variable of a pointer type.
|
The operand must be a variable of a pointer type.
|
||||||
|
@ -211,9 +215,7 @@ ChkArrow(expp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkArr(t_node **expp, int flags)
|
||||||
ChkArr(expp, flags)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* Check an array selection.
|
/* Check an array selection.
|
||||||
The left hand side must be a variable of an array type,
|
The left hand side must be a variable of an array type,
|
||||||
|
@ -255,9 +257,7 @@ ChkArr(expp, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
STATIC int
|
static int ChkValue(t_node **expp, int flags)
|
||||||
ChkValue(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
switch((*expp)->nd_symb) {
|
switch((*expp)->nd_symb) {
|
||||||
|
@ -273,9 +273,7 @@ ChkValue(expp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkSelOrName(t_node **expp, int flags)
|
||||||
ChkSelOrName(expp, flags)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* Check either an ID or a construction of the form
|
/* Check either an ID or a construction of the form
|
||||||
ID.ID [ .ID ]*
|
ID.ID [ .ID ]*
|
||||||
|
@ -348,9 +346,7 @@ ChkSelOrName(expp, flags)
|
||||||
return exp->nd_def->df_kind != D_ERROR;
|
return exp->nd_def->df_kind != D_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkExSelOrName(t_node **expp, int flags)
|
||||||
ChkExSelOrName(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* Check either an ID or an ID.ID [.ID]* occurring in an
|
/* Check either an ID or an ID.ID [.ID]* occurring in an
|
||||||
expression.
|
expression.
|
||||||
|
@ -422,20 +418,13 @@ ChkExSelOrName(expp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkEl(register t_node **expp, t_type *tp)
|
||||||
ChkEl(expp, tp)
|
|
||||||
register t_node **expp;
|
|
||||||
t_type *tp;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
return ChkExpression(expp) && ChkCompat(expp, tp, "set element");
|
return ChkExpression(expp) && ChkCompat(expp, tp, "set element");
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkElement(t_node **expp, t_type *tp, arith *set)
|
||||||
ChkElement(expp, tp, set)
|
|
||||||
t_node **expp;
|
|
||||||
t_type *tp;
|
|
||||||
arith *set;
|
|
||||||
{
|
{
|
||||||
/* Check elements of a set. This routine may call itself
|
/* Check elements of a set. This routine may call itself
|
||||||
recursively.
|
recursively.
|
||||||
|
@ -494,9 +483,7 @@ ChkElement(expp, tp, set)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
arith *
|
arith *MkSet(unsigned int size)
|
||||||
MkSet(size)
|
|
||||||
unsigned size;
|
|
||||||
{
|
{
|
||||||
register arith *s, *t;
|
register arith *s, *t;
|
||||||
|
|
||||||
|
@ -508,8 +495,7 @@ MkSet(size)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeSet(s)
|
void FreeSet(register arith *s)
|
||||||
register arith *s;
|
|
||||||
{
|
{
|
||||||
dec_refcount(s);
|
dec_refcount(s);
|
||||||
if (refcount(s) <= 0) {
|
if (refcount(s) <= 0) {
|
||||||
|
@ -518,9 +504,7 @@ FreeSet(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkSet(t_node **expp, int flags)
|
||||||
ChkSet(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* Check the legality of a SET aggregate, and try to evaluate it
|
/* Check the legality of a SET aggregate, and try to evaluate it
|
||||||
compile time. Unfortunately this is all rather complicated.
|
compile time. Unfortunately this is all rather complicated.
|
||||||
|
@ -586,10 +570,7 @@ ChkSet(expp)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC t_node *
|
static t_node *nextarg(t_node **argp, t_def *edf)
|
||||||
nextarg(argp, edf)
|
|
||||||
t_node **argp;
|
|
||||||
t_def *edf;
|
|
||||||
{
|
{
|
||||||
register t_node *arg = (*argp)->nd_RIGHT;
|
register t_node *arg = (*argp)->nd_RIGHT;
|
||||||
|
|
||||||
|
@ -602,10 +583,7 @@ nextarg(argp, edf)
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC t_node *
|
static t_node *getarg(t_node **argp, int bases, int designator, t_def *edf)
|
||||||
getarg(argp, bases, designator, edf)
|
|
||||||
t_node **argp;
|
|
||||||
t_def *edf;
|
|
||||||
{
|
{
|
||||||
/* This routine is used to fetch the next argument from an
|
/* This routine is used to fetch the next argument from an
|
||||||
argument list. The argument list is indicated by "argp".
|
argument list. The argument list is indicated by "argp".
|
||||||
|
@ -643,10 +621,7 @@ getarg(argp, bases, designator, edf)
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC t_node *
|
static t_node *getname(t_node **argp, int kinds, int bases, t_def *edf)
|
||||||
getname(argp, kinds, bases, edf)
|
|
||||||
t_node **argp;
|
|
||||||
t_def *edf;
|
|
||||||
{
|
{
|
||||||
/* Get the next argument from argument list "argp".
|
/* Get the next argument from argument list "argp".
|
||||||
The argument must indicate a definition, and the
|
The argument must indicate a definition, and the
|
||||||
|
@ -672,9 +647,7 @@ getname(argp, kinds, bases, edf)
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkProcCall(register t_node *exp)
|
||||||
ChkProcCall(exp)
|
|
||||||
register t_node *exp;
|
|
||||||
{
|
{
|
||||||
/* Check a procedure call
|
/* Check a procedure call
|
||||||
*/
|
*/
|
||||||
|
@ -735,9 +708,7 @@ ChkProcCall(exp)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkFunCall(register t_node **expp, int flags)
|
||||||
ChkFunCall(expp)
|
|
||||||
register t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* Check a call that must have a result
|
/* Check a call that must have a result
|
||||||
*/
|
*/
|
||||||
|
@ -750,12 +721,9 @@ ChkFunCall(expp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int ChkStandard();
|
|
||||||
STATIC int ChkCast();
|
|
||||||
|
|
||||||
int
|
|
||||||
ChkCall(expp)
|
int ChkCall(t_node **expp)
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* Check something that looks like a procedure or function call.
|
/* Check something that looks like a procedure or function call.
|
||||||
Of course this does not have to be a call at all,
|
Of course this does not have to be a call at all,
|
||||||
|
@ -795,9 +763,7 @@ ChkCall(expp)
|
||||||
return ChkProcCall(*expp);
|
return ChkProcCall(*expp);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC t_type *
|
static t_type *ResultOfOperation(int operator, t_type *tp)
|
||||||
ResultOfOperation(operator, tp)
|
|
||||||
t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* Return the result type of the binary operation "operator",
|
/* Return the result type of the binary operation "operator",
|
||||||
with operand type "tp".
|
with operand type "tp".
|
||||||
|
@ -819,8 +785,7 @@ ResultOfOperation(operator, tp)
|
||||||
|
|
||||||
#define Boolean(operator) (operator == OR || operator == AND)
|
#define Boolean(operator) (operator == OR || operator == AND)
|
||||||
|
|
||||||
STATIC int
|
static int AllowedTypes(int operator)
|
||||||
AllowedTypes(operator)
|
|
||||||
{
|
{
|
||||||
/* Return a bit mask indicating the allowed operand types
|
/* Return a bit mask indicating the allowed operand types
|
||||||
for binary operator "operator".
|
for binary operator "operator".
|
||||||
|
@ -854,10 +819,10 @@ AllowedTypes(operator)
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkAddressOper(
|
||||||
ChkAddressOper(tpl, tpr, expp)
|
register t_type *tpl,
|
||||||
register t_type *tpl, *tpr;
|
register t_type *tpr,
|
||||||
register t_node *expp;
|
register t_node *expp)
|
||||||
{
|
{
|
||||||
/* Check that either "tpl" or "tpr" are both of type
|
/* Check that either "tpl" or "tpr" are both of type
|
||||||
address_type, or that one of them is, but the other is
|
address_type, or that one of them is, but the other is
|
||||||
|
@ -901,9 +866,7 @@ ChkAddressOper(tpl, tpr, expp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkBinOper(t_node **expp, int flags)
|
||||||
ChkBinOper(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* Check a binary operation.
|
/* Check a binary operation.
|
||||||
*/
|
*/
|
||||||
|
@ -1018,9 +981,7 @@ ChkBinOper(expp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkUnOper(t_node **expp, int flags)
|
||||||
ChkUnOper(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* Check an unary operation.
|
/* Check an unary operation.
|
||||||
*/
|
*/
|
||||||
|
@ -1093,10 +1054,7 @@ ChkUnOper(expp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC t_node *
|
static t_node *getvariable(t_node **argp, t_def *edf, int flags)
|
||||||
getvariable(argp, edf, flags)
|
|
||||||
t_node **argp;
|
|
||||||
t_def *edf;
|
|
||||||
{
|
{
|
||||||
/* Get the next argument from argument list "argp".
|
/* Get the next argument from argument list "argp".
|
||||||
It must obey the rules of "ChkVariable".
|
It must obey the rules of "ChkVariable".
|
||||||
|
@ -1110,9 +1068,7 @@ getvariable(argp, edf, flags)
|
||||||
return arg->nd_LEFT;
|
return arg->nd_LEFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkStandard(t_node **expp)
|
||||||
ChkStandard(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* Check a call of a standard procedure or function
|
/* Check a call of a standard procedure or function
|
||||||
*/
|
*/
|
||||||
|
@ -1326,7 +1282,7 @@ ChkStandard(expp)
|
||||||
#endif
|
#endif
|
||||||
#ifndef STRICT_3RD_ED
|
#ifndef STRICT_3RD_ED
|
||||||
if (! options['3'] && edf->df_value.df_stdname == S_TSIZE) {
|
if (! options['3'] && edf->df_value.df_stdname == S_TSIZE) {
|
||||||
if (arg = arglink->nd_RIGHT) {
|
if ( (arg = arglink->nd_RIGHT) ) {
|
||||||
node_warning(arg,
|
node_warning(arg,
|
||||||
W_OLDFASHIONED,
|
W_OLDFASHIONED,
|
||||||
"TSIZE with multiple parameters, only first parameter used");
|
"TSIZE with multiple parameters, only first parameter used");
|
||||||
|
@ -1442,9 +1398,7 @@ ChkStandard(expp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int ChkCast(t_node **expp)
|
||||||
ChkCast(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* Check a cast and perform it if the argument is constant.
|
/* Check a cast and perform it if the argument is constant.
|
||||||
If the sizes don't match, only complain if at least one of them
|
If the sizes don't match, only complain if at least one of them
|
||||||
|
@ -1507,9 +1461,7 @@ ChkCast(expp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TryToString(nd, tp)
|
void TryToString(register t_node *nd, t_type *tp)
|
||||||
register t_node *nd;
|
|
||||||
t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* Try a coercion from character constant to string.
|
/* Try a coercion from character constant to string.
|
||||||
*/
|
*/
|
||||||
|
@ -1527,25 +1479,20 @@ TryToString(nd, tp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int no_desig(t_node **expp, int flags)
|
||||||
no_desig(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
node_error(*expp, "designator expected");
|
node_error(*expp, "designator expected");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int add_flags(t_node **expp, int flags)
|
||||||
add_flags(expp, flags)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
(*expp)->nd_def->df_flags |= flags;
|
(*expp)->nd_def->df_flags |= flags;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int PNodeCrash();
|
|
||||||
|
|
||||||
int (*ExprChkTable[])() = {
|
int (*ExprChkTable[])(t_node **, int) = {
|
||||||
ChkValue,
|
ChkValue,
|
||||||
ChkArr,
|
ChkArr,
|
||||||
ChkBinOper,
|
ChkBinOper,
|
||||||
|
@ -1561,7 +1508,7 @@ int (*ExprChkTable[])() = {
|
||||||
PNodeCrash,
|
PNodeCrash,
|
||||||
};
|
};
|
||||||
|
|
||||||
int (*DesigChkTable[])() = {
|
int (*DesigChkTable[])(t_node **, int) = {
|
||||||
no_desig,
|
no_desig,
|
||||||
ChkArr,
|
ChkArr,
|
||||||
no_desig,
|
no_desig,
|
||||||
|
|
|
@ -4,22 +4,38 @@
|
||||||
*
|
*
|
||||||
* Author: Ceriel J.H. Jacobs
|
* Author: Ceriel J.H. Jacobs
|
||||||
*/
|
*/
|
||||||
|
#ifndef CHK_EXPR_H_
|
||||||
|
#define CHK_EXPR_H_
|
||||||
|
|
||||||
/* E X P R E S S I O N C H E C K I N G */
|
/* E X P R E S S I O N C H E C K I N G */
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
extern int (*ExprChkTable[])(); /* table of expression checking
|
extern int (*ExprChkTable[])(t_node **, int); /* table of expression checking
|
||||||
functions, indexed by node class
|
functions, indexed by node class
|
||||||
*/
|
*/
|
||||||
extern int (*DesigChkTable[])(); /* table of designator checking
|
extern int (*DesigChkTable[])(t_node **, int); /* table of designator checking
|
||||||
functions, indexed by node class
|
functions, indexed by node class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ChkExpression(expp) ((*ExprChkTable[(*expp)->nd_class])(expp,D_USED))
|
#define ChkExpression(expp) ((*ExprChkTable[(unsigned int)((*expp)->nd_class)])(expp,D_USED))
|
||||||
#define ChkDesig(expp, flags) ((*DesigChkTable[(*expp)->nd_class])(expp,flags))
|
#define ChkDesig(expp, flags) ((*DesigChkTable[(unsigned int)((*expp)->nd_class)])(expp,flags))
|
||||||
|
|
||||||
/* handle reference counts for sets */
|
/* handle reference counts for sets */
|
||||||
#define inc_refcount(s) (*((int *)(s) - 1) += 1)
|
#define inc_refcount(s) (*((int *)(s) - 1) += 1)
|
||||||
#define dec_refcount(s) (*((int *)(s) - 1) -= 1)
|
#define dec_refcount(s) (*((int *)(s) - 1) -= 1)
|
||||||
#define refcount(s) (*((int *)(s) - 1))
|
#define refcount(s) (*((int *)(s) - 1))
|
||||||
|
|
||||||
|
void MkCoercion(t_node **pnd, register t_type *tp);
|
||||||
|
int ChkVariable(register t_node **expp, int flags);
|
||||||
|
int ChkCall(t_node **expp);
|
||||||
|
void TryToString(register t_node *nd, t_type *tp);
|
||||||
|
|
||||||
|
/* Generates a set of "size" bytes and increments its reference count. */
|
||||||
|
arith *MkSet(unsigned int size);
|
||||||
|
/* Decrements the reference counter of set "s" and if reference count
|
||||||
|
* is zero, then it frees the memory associated with the set.
|
||||||
|
*/
|
||||||
|
void FreeSet(register arith *s);
|
||||||
|
|
||||||
|
#endif /* CHK_EXPR_H_ */
|
||||||
|
|
|
@ -12,23 +12,27 @@
|
||||||
/* Code generation for expressions and coercions
|
/* Code generation for expressions and coercions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <em_arith.h>
|
|
||||||
#include <em_label.h>
|
|
||||||
#include <em_code.h>
|
|
||||||
#include <em_abs.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <alloc.h>
|
#include "em_arith.h"
|
||||||
|
#include "em_label.h"
|
||||||
|
#include "em_code.h"
|
||||||
|
#include "em_abs.h"
|
||||||
|
#include "alloc.h"
|
||||||
|
|
||||||
|
#include "code.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
#include "error.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "desig.h"
|
#include "desig.h"
|
||||||
|
#include "chk_expr.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
|
#include "tmpvar.h"
|
||||||
#include "standards.h"
|
#include "standards.h"
|
||||||
#include "walk.h"
|
#include "walk.h"
|
||||||
|
|
||||||
|
@ -37,17 +41,19 @@ extern char options[];
|
||||||
extern t_desig null_desig;
|
extern t_desig null_desig;
|
||||||
int fp_used;
|
int fp_used;
|
||||||
|
|
||||||
void RangeCheck();
|
/* Forward declarations */
|
||||||
void CodeParameters();
|
static void CodeParameters(t_param *, register t_node *);
|
||||||
void CodeCall();
|
static void CodeStd(t_node *);
|
||||||
|
static void compare(int, label);
|
||||||
|
static void truthvalue(int);
|
||||||
|
static void CodeUoper(register t_node *);
|
||||||
|
static void CodeSet(register t_node *, int);
|
||||||
|
static void CodeEl(register t_node *, register t_type *, int);
|
||||||
|
static void CodeDAddress(t_node *, int);
|
||||||
|
static void DoHIGH(register t_def *);
|
||||||
|
|
||||||
CodeConst(cst, size)
|
void CodeConst(arith cst, int size)
|
||||||
arith cst;
|
|
||||||
int size;
|
|
||||||
{
|
{
|
||||||
/* Generate code to push constant "cst" with size "size"
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (size <= (int) word_size) {
|
if (size <= (int) word_size) {
|
||||||
C_loc(cst);
|
C_loc(cst);
|
||||||
}
|
}
|
||||||
|
@ -59,9 +65,7 @@ CodeConst(cst, size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CodeString(register t_node *nd)
|
||||||
CodeString(nd)
|
|
||||||
register t_node *nd;
|
|
||||||
{
|
{
|
||||||
if (nd->nd_type->tp_fund != T_STRING) {
|
if (nd->nd_type->tp_fund != T_STRING) {
|
||||||
/* Character constant */
|
/* Character constant */
|
||||||
|
@ -73,10 +77,7 @@ CodeString(nd)
|
||||||
c_lae_dlb(data_label);
|
c_lae_dlb(data_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeExpr(nd, ds, true_label, false_label)
|
void CodeExpr(t_node *nd, t_desig *ds, label true_label, label false_label)
|
||||||
register t_node *nd;
|
|
||||||
register t_desig *ds;
|
|
||||||
label true_label, false_label;
|
|
||||||
{
|
{
|
||||||
register t_type *tp = nd->nd_type;
|
register t_type *tp = nd->nd_type;
|
||||||
|
|
||||||
|
@ -173,8 +174,7 @@ CodeExpr(nd, ds, true_label, false_label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeCoercion(t1, t2)
|
void CodeCoercion(t_type *t1, t_type *t2)
|
||||||
t_type *t1, *t2;
|
|
||||||
{
|
{
|
||||||
int fund1, fund2;
|
int fund1, fund2;
|
||||||
int sz1 = t1->tp_size;
|
int sz1 = t1->tp_size;
|
||||||
|
@ -293,13 +293,9 @@ CodeCoercion(t1, t2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CodeCall(t_node *nd)
|
||||||
CodeCall(nd)
|
|
||||||
register t_node *nd;
|
|
||||||
{
|
{
|
||||||
/* Generate code for a procedure call. Checking of parameters
|
|
||||||
and result is already done.
|
|
||||||
*/
|
|
||||||
register t_node *left = nd->nd_LEFT;
|
register t_node *left = nd->nd_LEFT;
|
||||||
t_type *result_tp;
|
t_type *result_tp;
|
||||||
int needs_fn;
|
int needs_fn;
|
||||||
|
@ -361,10 +357,8 @@ CodeCall(nd)
|
||||||
DoLineno(nd);
|
DoLineno(nd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/* Generates code to setup the parameters of a procedure call. */
|
||||||
CodeParameters(param, arg)
|
static void CodeParameters(t_param *param, register t_node *arg)
|
||||||
t_param *param;
|
|
||||||
register t_node *arg;
|
|
||||||
{
|
{
|
||||||
register t_type *tp;
|
register t_type *tp;
|
||||||
register t_type *arg_type;
|
register t_type *arg_type;
|
||||||
|
@ -445,9 +439,7 @@ CodeParameters(param, arg)
|
||||||
CodePExpr(arg);
|
CodePExpr(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodePString(nd, tp)
|
void CodePString(t_node *nd, t_type *tp)
|
||||||
t_node *nd;
|
|
||||||
t_type *tp;
|
|
||||||
{
|
{
|
||||||
arith szarg = WA(nd->nd_type->tp_size);
|
arith szarg = WA(nd->nd_type->tp_size);
|
||||||
register arith zersz = WA(tp->tp_size) - szarg;
|
register arith zersz = WA(tp->tp_size) - szarg;
|
||||||
|
@ -461,9 +453,9 @@ CodePString(nd, tp)
|
||||||
C_loi(szarg);
|
C_loi(szarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
subu(sz)
|
|
||||||
int sz;
|
static void subu(int sz)
|
||||||
{
|
{
|
||||||
if (! options['R']) {
|
if (! options['R']) {
|
||||||
C_cal(sz == (int) word_size ? "subuchk" : "subulchk");
|
C_cal(sz == (int) word_size ? "subuchk" : "subulchk");
|
||||||
|
@ -471,9 +463,7 @@ subu(sz)
|
||||||
C_sbu((arith) sz);
|
C_sbu((arith) sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static void addu(int sz)
|
||||||
addu(sz)
|
|
||||||
int sz;
|
|
||||||
{
|
{
|
||||||
if (! options['R']) {
|
if (! options['R']) {
|
||||||
C_cal(sz == (int) word_size ? "adduchk" : "addulchk");
|
C_cal(sz == (int) word_size ? "adduchk" : "addulchk");
|
||||||
|
@ -481,9 +471,7 @@ addu(sz)
|
||||||
C_adu((arith)sz);
|
C_adu((arith)sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int complex_lhs(register t_node *nd)
|
||||||
complex_lhs(nd)
|
|
||||||
register t_node *nd;
|
|
||||||
{
|
{
|
||||||
switch(nd->nd_class) {
|
switch(nd->nd_class) {
|
||||||
case Value:
|
case Value:
|
||||||
|
@ -498,8 +486,8 @@ complex_lhs(nd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeStd(nd)
|
/* Generate code for internal procedures */
|
||||||
t_node *nd;
|
static void CodeStd(t_node *nd)
|
||||||
{
|
{
|
||||||
register t_node *arg = nd->nd_RIGHT;
|
register t_node *arg = nd->nd_RIGHT;
|
||||||
register t_node *left = 0;
|
register t_node *left = 0;
|
||||||
|
@ -654,9 +642,7 @@ CodeStd(nd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int needs_rangecheck(register t_type *tpl, t_type *tpr)
|
||||||
needs_rangecheck(tpl, tpr)
|
|
||||||
register t_type *tpl, *tpr;
|
|
||||||
{
|
{
|
||||||
arith rlo, rhi;
|
arith rlo, rhi;
|
||||||
|
|
||||||
|
@ -679,13 +665,8 @@ needs_rangecheck(tpl, tpr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void RangeCheck(register t_type *tpl, t_type *tpr)
|
||||||
RangeCheck(tpl, tpr)
|
|
||||||
register t_type *tpl, *tpr;
|
|
||||||
{
|
{
|
||||||
/* Generate a range check if neccessary
|
|
||||||
*/
|
|
||||||
|
|
||||||
arith rlo, rhi;
|
arith rlo, rhi;
|
||||||
|
|
||||||
if (options['R']) return;
|
if (options['R']) return;
|
||||||
|
@ -709,8 +690,7 @@ RangeCheck(tpl, tpr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Operands(nd)
|
void Operands(register t_node *nd)
|
||||||
register t_node *nd;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
CodePExpr(nd->nd_LEFT);
|
CodePExpr(nd->nd_LEFT);
|
||||||
|
@ -718,10 +698,11 @@ Operands(nd)
|
||||||
DoLineno(nd);
|
DoLineno(nd);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeOper(expr, true_label, false_label)
|
void CodeOper(
|
||||||
register t_node *expr; /* the expression tree itself */
|
register t_node *expr, /* the expression tree itself */
|
||||||
label true_label;
|
label true_label,
|
||||||
label false_label; /* labels to jump to in logical expr's */
|
label false_label /* labels to jump to in logical expr's */
|
||||||
|
)
|
||||||
{
|
{
|
||||||
register t_node *leftop = expr->nd_LEFT;
|
register t_node *leftop = expr->nd_LEFT;
|
||||||
register t_node *rightop = expr->nd_RIGHT;
|
register t_node *rightop = expr->nd_RIGHT;
|
||||||
|
@ -1019,10 +1000,8 @@ CodeOper(expr, true_label, false_label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compare() serves as an auxiliary function of CodeOper */
|
/* Serves as an auxiliary function of CodeOper */
|
||||||
compare(relop, lbl)
|
static void compare(int relop, label lbl)
|
||||||
int relop;
|
|
||||||
register label lbl;
|
|
||||||
{
|
{
|
||||||
switch (relop) {
|
switch (relop) {
|
||||||
case '<':
|
case '<':
|
||||||
|
@ -1048,9 +1027,8 @@ compare(relop, lbl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* truthvalue() serves as an auxiliary function of CodeOper */
|
/* Serves as an auxiliary function of CodeOper */
|
||||||
truthvalue(relop)
|
static void truthvalue(int relop)
|
||||||
int relop;
|
|
||||||
{
|
{
|
||||||
switch (relop) {
|
switch (relop) {
|
||||||
case '<':
|
case '<':
|
||||||
|
@ -1076,8 +1054,9 @@ truthvalue(relop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeUoper(nd)
|
|
||||||
register t_node *nd;
|
/* Generates code for an unary expression */
|
||||||
|
void CodeUoper(register t_node *nd)
|
||||||
{
|
{
|
||||||
register t_type *tp = nd->nd_type;
|
register t_type *tp = nd->nd_type;
|
||||||
|
|
||||||
|
@ -1110,8 +1089,7 @@ CodeUoper(nd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeSet(nd, null_set)
|
static void CodeSet(register t_node *nd, int null_set)
|
||||||
register t_node *nd;
|
|
||||||
{
|
{
|
||||||
register t_type *tp = nd->nd_type;
|
register t_type *tp = nd->nd_type;
|
||||||
|
|
||||||
|
@ -1128,9 +1106,7 @@ CodeSet(nd, null_set)
|
||||||
if (null_set) C_zer(tp->tp_size);
|
if (null_set) C_zer(tp->tp_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeEl(nd, tp, null_set)
|
static void CodeEl(register t_node *nd, register t_type *tp, int null_set)
|
||||||
register t_node *nd;
|
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
register t_type *eltype = ElementType(tp);
|
register t_type *eltype = ElementType(tp);
|
||||||
|
|
||||||
|
@ -1155,12 +1131,9 @@ CodeEl(nd, tp, null_set)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodePExpr(nd)
|
void CodePExpr(register t_node *nd)
|
||||||
register t_node *nd;
|
|
||||||
{
|
{
|
||||||
/* Generate code to push the value of the expression "nd"
|
|
||||||
on the stack.
|
|
||||||
*/
|
|
||||||
t_desig designator;
|
t_desig designator;
|
||||||
|
|
||||||
designator = null_desig;
|
designator = null_desig;
|
||||||
|
@ -1168,8 +1141,7 @@ CodePExpr(nd)
|
||||||
CodeValue(&designator, nd->nd_type);
|
CodeValue(&designator, nd->nd_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeDAddress(nd, chk_controlvar)
|
static void CodeDAddress(t_node *nd, int chk_controlvar)
|
||||||
t_node *nd;
|
|
||||||
{
|
{
|
||||||
/* Generate code to push the address of the designator "nd"
|
/* Generate code to push the address of the designator "nd"
|
||||||
on the stack.
|
on the stack.
|
||||||
|
@ -1195,12 +1167,9 @@ CodeDAddress(nd, chk_controlvar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeDStore(nd)
|
void CodeDStore(register t_node *nd)
|
||||||
register t_node *nd;
|
|
||||||
{
|
{
|
||||||
/* Generate code to store the expression on the stack into the
|
|
||||||
designator "nd".
|
|
||||||
*/
|
|
||||||
|
|
||||||
t_desig designator;
|
t_desig designator;
|
||||||
|
|
||||||
|
@ -1210,8 +1179,7 @@ CodeDStore(nd)
|
||||||
CodeStore(&designator, nd->nd_type);
|
CodeStore(&designator, nd->nd_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
DoHIGH(df)
|
static void DoHIGH(register t_def *df)
|
||||||
register t_def *df;
|
|
||||||
{
|
{
|
||||||
/* Get the high index of a conformant array, indicated by "nd".
|
/* Get the high index of a conformant array, indicated by "nd".
|
||||||
The high index is the second field in the descriptor of
|
The high index is the second field in the descriptor of
|
||||||
|
@ -1235,26 +1203,22 @@ DoHIGH(df)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SQUEEZE
|
#ifdef SQUEEZE
|
||||||
c_bra(l)
|
void c_bra(label l)
|
||||||
label l;
|
|
||||||
{
|
{
|
||||||
C_bra((label) l);
|
C_bra((label) l);
|
||||||
}
|
}
|
||||||
|
|
||||||
c_loc(n)
|
void c_loc(int n)
|
||||||
{
|
{
|
||||||
C_loc((arith) n);
|
C_loc((arith) n);
|
||||||
}
|
}
|
||||||
|
|
||||||
c_lae_dlb(l)
|
void c_lae_dlb(label l)
|
||||||
label l;
|
|
||||||
{
|
{
|
||||||
C_lae_dlb(l, (arith) 0);
|
C_lae_dlb(l, (arith) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CAL(name, ssp)
|
void CAL(char *name, int ssp)
|
||||||
char *name;
|
|
||||||
int ssp;
|
|
||||||
{
|
{
|
||||||
C_cal(name);
|
C_cal(name);
|
||||||
C_asp((arith) ssp);
|
C_asp((arith) ssp);
|
||||||
|
|
53
lang/m2/comp/code.h
Normal file
53
lang/m2/comp/code.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
* Created on: 2019-02-26
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef CODE_H_
|
||||||
|
#define CODE_H_
|
||||||
|
|
||||||
|
#include "parameters.h"
|
||||||
|
#include <em_arith.h>
|
||||||
|
#include <em_label.h>
|
||||||
|
|
||||||
|
/* Forward declarations. */
|
||||||
|
typedef struct node t_node;
|
||||||
|
typedef struct desig t_desig;
|
||||||
|
typedef struct type t_type;
|
||||||
|
|
||||||
|
/* Generate code to push constant "cst" with size "size" bytes. */
|
||||||
|
void CodeConst(arith cst, int size);
|
||||||
|
/* Generate constant character or string. */
|
||||||
|
void CodeString(register t_node *nd);
|
||||||
|
/* Generate code for an expression contained in "nd". */
|
||||||
|
void CodeExpr(t_node *nd, t_desig *ds, label true_label, label false_label);
|
||||||
|
/* Generate implicit type conversion code. */
|
||||||
|
void CodeCoercion(t_type *t1, t_type *t2);
|
||||||
|
/* Generate code for a procedure call including parameter setup. Checking of parameters
|
||||||
|
and result is already done. */
|
||||||
|
void CodeCall(t_node *nd);
|
||||||
|
void CodePString(t_node *nd, t_type *tp);
|
||||||
|
/* Generate a range check if necessary */
|
||||||
|
void RangeCheck(register t_type *tpl, t_type *tpr);
|
||||||
|
void CodeOper(register t_node *expr, label true_label, label false_label);
|
||||||
|
/* Generate code to push the value of the expression "nd"
|
||||||
|
on the stack. */
|
||||||
|
void CodePExpr(register t_node *nd);
|
||||||
|
/* Generate code to store the expression on the stack into the
|
||||||
|
designator "nd".
|
||||||
|
*/
|
||||||
|
void CodeDStore(register t_node *nd);
|
||||||
|
|
||||||
|
#ifdef SQUEEZE
|
||||||
|
void c_bra(label l);
|
||||||
|
void c_loc(int n);
|
||||||
|
void c_lae_dlb(label l);
|
||||||
|
void CAL(char *name, int ssp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* CODE_H_ */
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
|
@ -24,7 +24,10 @@
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "standards.h"
|
#include "standards.h"
|
||||||
|
#include "cstoper.h"
|
||||||
|
#include "chk_expr.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
extern char *symbol2str();
|
extern char *symbol2str();
|
||||||
|
|
||||||
|
@ -45,19 +48,17 @@ arith min_int[] = { 0L, -128L, -32768L, 0L, -2147483647L-1 };
|
||||||
|
|
||||||
extern char options[];
|
extern char options[];
|
||||||
|
|
||||||
void CutSize();
|
static void CutSize(register t_node *);
|
||||||
|
|
||||||
overflow(expp)
|
|
||||||
t_node *expp;
|
static void overflow(t_node *expp)
|
||||||
{
|
{
|
||||||
if (expp->nd_type != address_type) {
|
if (expp->nd_type != address_type) {
|
||||||
node_warning(expp, W_ORDINARY, "overflow in constant expression");
|
node_warning(expp, W_ORDINARY, "overflow in constant expression");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
static void commonbin(t_node **expp)
|
||||||
commonbin(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
register t_node *exp = *expp;
|
register t_node *exp = *expp;
|
||||||
t_type *tp = exp->nd_type;
|
t_type *tp = exp->nd_type;
|
||||||
|
@ -69,11 +70,10 @@ commonbin(expp)
|
||||||
right->nd_type = tp;
|
right->nd_type = tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
cstunary(expp)
|
void cstunary(t_node **expp)
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* The unary operation in "expp" is performed on the constant
|
/* The unary operation in "expp" is performed on the constant
|
||||||
expression below it, and the result restored in expp.
|
expression below it, and the result stored in expp.
|
||||||
*/
|
*/
|
||||||
register t_node *exp = *expp;
|
register t_node *exp = *expp;
|
||||||
register t_node *right = exp->nd_RIGHT;
|
register t_node *right = exp->nd_RIGHT;
|
||||||
|
@ -107,9 +107,7 @@ cstunary(expp)
|
||||||
CutSize(*expp);
|
CutSize(*expp);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
static void divide(arith *pdiv, arith *prem)
|
||||||
divide(pdiv, prem)
|
|
||||||
arith *pdiv, *prem;
|
|
||||||
{
|
{
|
||||||
/* Unsigned divide *pdiv by *prem, and store result in *pdiv,
|
/* Unsigned divide *pdiv by *prem, and store result in *pdiv,
|
||||||
remainder in *prem
|
remainder in *prem
|
||||||
|
@ -121,9 +119,7 @@ divide(pdiv, prem)
|
||||||
*prem = (unsigned arith) o1 % (unsigned arith) o2;
|
*prem = (unsigned arith) o1 % (unsigned arith) o2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void cstibin(t_node **expp)
|
||||||
cstibin(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* The binary operation in "expp" is performed on the constant
|
/* The binary operation in "expp" is performed on the constant
|
||||||
expressions below it, and the result restored in expp.
|
expressions below it, and the result restored in expp.
|
||||||
|
@ -232,8 +228,7 @@ cstibin(expp)
|
||||||
CutSize(*expp);
|
CutSize(*expp);
|
||||||
}
|
}
|
||||||
|
|
||||||
cstfbin(expp)
|
void cstfbin(t_node **expp)
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* The binary operation in "expp" is performed on the constant
|
/* The binary operation in "expp" is performed on the constant
|
||||||
expressions below it, and the result restored in expp.
|
expressions below it, and the result restored in expp.
|
||||||
|
@ -320,9 +315,7 @@ cstfbin(expp)
|
||||||
CutSize(exp);
|
CutSize(exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void cstubin(t_node **expp)
|
||||||
cstubin(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* The binary operation in "expp" is performed on the constant
|
/* The binary operation in "expp" is performed on the constant
|
||||||
expressions below it, and the result restored in
|
expressions below it, and the result restored in
|
||||||
|
@ -427,9 +420,7 @@ cstubin(expp)
|
||||||
CutSize(exp);
|
CutSize(exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void cstset(t_node **expp)
|
||||||
cstset(expp)
|
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
extern arith *MkSet();
|
extern arith *MkSet();
|
||||||
register t_node *exp = *expp;
|
register t_node *exp = *expp;
|
||||||
|
@ -544,8 +535,7 @@ cstset(expp)
|
||||||
FreeNode(exp);
|
FreeNode(exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
cstcall(expp, call)
|
void cstcall(t_node **expp, int call)
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
/* a standard procedure call is found that can be evaluated
|
/* a standard procedure call is found that can be evaluated
|
||||||
compile time, so do so.
|
compile time, so do so.
|
||||||
|
@ -619,9 +609,7 @@ cstcall(expp, call)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void CutSize(register t_node *expr)
|
||||||
CutSize(expr)
|
|
||||||
register t_node *expr;
|
|
||||||
{
|
{
|
||||||
/* The constant value of the expression expr is made to
|
/* The constant value of the expression expr is made to
|
||||||
conform to the size of the type of the expression.
|
conform to the size of the type of the expression.
|
||||||
|
@ -640,7 +628,7 @@ CutSize(expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InitCst()
|
void InitCst(void)
|
||||||
{
|
{
|
||||||
register int i = 0;
|
register int i = 0;
|
||||||
#ifndef NOCROSS
|
#ifndef NOCROSS
|
||||||
|
|
29
lang/m2/comp/cstoper.h
Normal file
29
lang/m2/comp/cstoper.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
* Created on: 2019-02-25
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef CSTOPER_H_
|
||||||
|
#define CSTOPER_H_
|
||||||
|
|
||||||
|
/* Compile time constant evaluations */
|
||||||
|
|
||||||
|
|
||||||
|
void cstunary(t_node **expp);
|
||||||
|
void cstibin(t_node **expp);
|
||||||
|
void cstfbin(t_node **expp);
|
||||||
|
void cstubin(t_node **expp);
|
||||||
|
/** Evaluates the constant set operators at compile time
|
||||||
|
* and returns the result in "expp".
|
||||||
|
*/
|
||||||
|
void cstset(t_node **expp);
|
||||||
|
/* Evaluates the result of internal procedures on constants
|
||||||
|
* at compile time, and returns the result in "expp".
|
||||||
|
*/
|
||||||
|
void cstcall(t_node **expp, int call);
|
||||||
|
/* Compile time constant evaluator system initialization. */
|
||||||
|
void InitCst(void);
|
||||||
|
|
||||||
|
#endif /* CSTOPER_H_ */
|
|
@ -10,13 +10,13 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
{
|
{
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <em_arith.h>
|
|
||||||
#include <em_label.h>
|
|
||||||
#include <alloc.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include "em_arith.h"
|
||||||
|
#include "em_label.h"
|
||||||
|
#include "alloc.h"
|
||||||
|
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
|
@ -24,8 +24,11 @@
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "enter.h"
|
||||||
|
#include "error.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "typequiv.h"
|
||||||
#include "chk_expr.h"
|
#include "chk_expr.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
|
|
||||||
|
|
|
@ -11,57 +11,64 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <alloc.h>
|
|
||||||
#include <em_arith.h>
|
|
||||||
#include <em_label.h>
|
|
||||||
#include <em_code.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include "alloc.h"
|
||||||
|
#include "em_arith.h"
|
||||||
|
#include "em_label.h"
|
||||||
|
#include "em_code.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "typequiv.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
#include "print.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
|
#include "lookup.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "misc.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
extern char *sprint();
|
|
||||||
|
|
||||||
STATIC
|
|
||||||
internal(c)
|
static void internal(register char *c)
|
||||||
register char *c;
|
|
||||||
{
|
{
|
||||||
if (options['x']) {
|
if (options['x'])
|
||||||
|
{
|
||||||
C_exp(c);
|
C_exp(c);
|
||||||
}
|
}
|
||||||
else C_inp(c);
|
else
|
||||||
|
C_inp(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
static void DefInFront(register t_def *df)
|
||||||
DefInFront(df)
|
|
||||||
register t_def *df;
|
|
||||||
{
|
{
|
||||||
/* Put definition "df" in front of the list of definitions
|
/* Put definition "df" in front of the list of definitions
|
||||||
in its scope.
|
in its scope.
|
||||||
This is neccessary because in some cases the order in this
|
This is neccessary because in some cases the order in this
|
||||||
list is important.
|
list is important.
|
||||||
*/
|
*/
|
||||||
register t_def *df1 = df->df_scope->sc_def;
|
register t_def *df1 = df->df_scope->sc_def;
|
||||||
|
|
||||||
if (df1 != df) {
|
if (df1 != df)
|
||||||
|
{
|
||||||
/* Definition "df" is not in front of the list
|
/* Definition "df" is not in front of the list
|
||||||
*/
|
*/
|
||||||
while (df1) {
|
while (df1)
|
||||||
|
{
|
||||||
/* Find definition "df"
|
/* Find definition "df"
|
||||||
*/
|
*/
|
||||||
if (df1->df_nextinscope == df) {
|
if (df1->df_nextinscope == df)
|
||||||
|
{
|
||||||
/* It already was in the list. Remove it
|
/* It already was in the list. Remove it
|
||||||
*/
|
*/
|
||||||
df1->df_nextinscope = df->df_nextinscope;
|
df1->df_nextinscope = df->df_nextinscope;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -69,20 +76,17 @@ DefInFront(df)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now put it in front
|
/* Now put it in front
|
||||||
*/
|
*/
|
||||||
df->df_nextinscope = df->df_scope->sc_def;
|
df->df_nextinscope = df->df_scope->sc_def;
|
||||||
df->df_scope->sc_def = df;
|
df->df_scope->sc_def = df;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_def *
|
t_def *MkDef(register t_idf *id, register t_scope *scope, int kind)
|
||||||
MkDef(id, scope, kind)
|
|
||||||
register t_idf *id;
|
|
||||||
register t_scope *scope;
|
|
||||||
{
|
{
|
||||||
/* Create a new definition structure in scope "scope", with
|
/* Create a new definition structure in scope "scope", with
|
||||||
id "id" and kind "kind".
|
id "id" and kind "kind".
|
||||||
*/
|
*/
|
||||||
register t_def *df;
|
register t_def *df;
|
||||||
|
|
||||||
df = new_def();
|
df = new_def();
|
||||||
|
@ -91,40 +95,42 @@ MkDef(id, scope, kind)
|
||||||
df->df_kind = kind;
|
df->df_kind = kind;
|
||||||
df->df_next = id->id_def;
|
df->df_next = id->id_def;
|
||||||
id->id_def = df;
|
id->id_def = df;
|
||||||
if (kind == D_ERROR || kind == D_FORWARD) df->df_type = error_type;
|
if (kind == D_ERROR || kind == D_FORWARD)
|
||||||
if (kind & (D_TYPE|D_PROCEDURE|D_CONST)) {
|
df->df_type = error_type;
|
||||||
|
if (kind & (D_TYPE | D_PROCEDURE | D_CONST))
|
||||||
|
{
|
||||||
df->df_flags = D_DEFINED;
|
df->df_flags = D_DEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* enter the definition in the list of definitions in this scope
|
/* enter the definition in the list of definitions in this scope
|
||||||
*/
|
*/
|
||||||
df->df_nextinscope = scope->sc_def;
|
df->df_nextinscope = scope->sc_def;
|
||||||
scope->sc_def = df;
|
scope->sc_def = df;
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_def *
|
t_def *define(register t_idf *id, register t_scope *scope, int kind)
|
||||||
define(id, scope, kind)
|
|
||||||
register t_idf *id;
|
|
||||||
register t_scope *scope;
|
|
||||||
int kind;
|
|
||||||
{
|
{
|
||||||
/* Declare an identifier in a scope, but first check if it
|
/* Declare an identifier in a scope, but first check if it
|
||||||
already has been defined.
|
already has been defined.
|
||||||
If so, then check for the cases in which this is legal,
|
If so, then check for the cases in which this is legal,
|
||||||
and otherwise give an error message.
|
and otherwise give an error message.
|
||||||
*/
|
*/
|
||||||
register t_def *df;
|
register t_def *df;
|
||||||
|
|
||||||
DO_DEBUG(options['S'], print("define %s, %x\n", id->id_text, kind));
|
DO_DEBUG(options['S'], print("define %s, %x\n", id->id_text, kind));
|
||||||
df = lookup(id, scope, D_IMPORT, 0);
|
df = lookup(id, scope, D_IMPORT, 0);
|
||||||
if ( /* Already in this scope */
|
if ( /* Already in this scope */
|
||||||
df
|
df)
|
||||||
) {
|
{
|
||||||
switch(df->df_kind) {
|
switch (df->df_kind)
|
||||||
|
{
|
||||||
case D_INUSE:
|
case D_INUSE:
|
||||||
if (kind != D_INUSE && kind != D_ERROR) {
|
if (kind != D_INUSE && kind != D_ERROR)
|
||||||
error("identifier \"%s\" already used; may not be redefined in this scope", df->df_idf->id_text);
|
{
|
||||||
|
error(
|
||||||
|
"identifier \"%s\" already used; may not be redefined in this scope",
|
||||||
|
df->df_idf->id_text);
|
||||||
df->df_kind = D_ERROR;
|
df->df_kind = D_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -132,10 +138,11 @@ define(id, scope, kind)
|
||||||
|
|
||||||
case D_HIDDEN:
|
case D_HIDDEN:
|
||||||
/* An opaque type. We may now have found the
|
/* An opaque type. We may now have found the
|
||||||
definition of this type.
|
definition of this type.
|
||||||
*/
|
*/
|
||||||
if (kind == D_TYPE && df->df_scope == CurrentScope &&
|
if (kind == D_TYPE && df->df_scope == CurrentScope
|
||||||
!DefinitionModule) {
|
&& !DefinitionModule)
|
||||||
|
{
|
||||||
df->df_kind = D_TYPE;
|
df->df_kind = D_TYPE;
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
@ -143,14 +150,16 @@ define(id, scope, kind)
|
||||||
|
|
||||||
case D_FORWMODULE:
|
case D_FORWMODULE:
|
||||||
/* A forward reference to a module. We may have found
|
/* A forward reference to a module. We may have found
|
||||||
another one, or we may have found the definition
|
another one, or we may have found the definition
|
||||||
for this module.
|
for this module.
|
||||||
*/
|
*/
|
||||||
if (kind & (D_FORWMODULE|D_FORWARD)) {
|
if (kind & (D_FORWMODULE | D_FORWARD))
|
||||||
|
{
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kind == D_MODULE) {
|
if (kind == D_MODULE)
|
||||||
|
{
|
||||||
FreeNode(df->for_node);
|
FreeNode(df->for_node);
|
||||||
df->mod_vis = df->for_vis;
|
df->mod_vis = df->for_vis;
|
||||||
df->df_kind = kind;
|
df->df_kind = kind;
|
||||||
|
@ -160,33 +169,38 @@ define(id, scope, kind)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D_TYPE:
|
case D_TYPE:
|
||||||
if (kind == D_FORWTYPE) return df;
|
if (kind == D_FORWTYPE)
|
||||||
|
return df;
|
||||||
break;
|
break;
|
||||||
case D_FORWTYPE:
|
case D_FORWTYPE:
|
||||||
if (kind & (D_FORWTYPE|D_TYPE)) return df;
|
if (kind & (D_FORWTYPE | D_TYPE))
|
||||||
|
return df;
|
||||||
error("identifier \"%s\" must be a type", id->id_text);
|
error("identifier \"%s\" must be a type", id->id_text);
|
||||||
df->df_kind = D_ERROR;
|
df->df_kind = D_ERROR;
|
||||||
break;
|
break;
|
||||||
case D_FORWARD:
|
case D_FORWARD:
|
||||||
/* A forward reference, for which we may now have
|
/* A forward reference, for which we may now have
|
||||||
found a definition.
|
found a definition.
|
||||||
*/
|
*/
|
||||||
if (! (kind & (D_FORWARD | D_FORWMODULE))) {
|
if (!(kind & (D_FORWARD | D_FORWMODULE)))
|
||||||
|
{
|
||||||
FreeNode(df->for_node);
|
FreeNode(df->for_node);
|
||||||
}
|
}
|
||||||
df->df_kind = D_ERROR; /* avoiding error message */
|
df->df_kind = D_ERROR; /* avoiding error message */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kind != D_ERROR && df->df_kind != D_ERROR) {
|
if (kind != D_ERROR && df->df_kind != D_ERROR)
|
||||||
|
{
|
||||||
/* Avoid spurious error messages
|
/* Avoid spurious error messages
|
||||||
*/
|
*/
|
||||||
error("identifier \"%s\" already declared",
|
error("identifier \"%s\" already declared", id->id_text);
|
||||||
id->id_text);
|
|
||||||
}
|
}
|
||||||
if (df->df_scope == scope || df->df_kind == D_ERROR) {
|
if (df->df_scope == scope || df->df_kind == D_ERROR)
|
||||||
|
{
|
||||||
df->df_kind = kind;
|
df->df_kind = kind;
|
||||||
if (kind & (D_TYPE|D_PROCEDURE|D_CONST)) {
|
if (kind & (D_TYPE | D_PROCEDURE | D_CONST))
|
||||||
|
{
|
||||||
df->df_flags = D_DEFINED;
|
df->df_flags = D_DEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,43 +211,49 @@ define(id, scope, kind)
|
||||||
return MkDef(id, scope, kind);
|
return MkDef(id, scope, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
end_definition_list(pdf)
|
void end_definition_list(register t_def **pdf)
|
||||||
register t_def **pdf;
|
|
||||||
{
|
{
|
||||||
/* Remove all imports from a definition module. This is
|
/* Remove all imports from a definition module. This is
|
||||||
neccesary because the implementation module might import
|
neccesary because the implementation module might import
|
||||||
them again.
|
them again.
|
||||||
Also, mark all other definitions "QUALIFIED EXPORT".
|
Also, mark all other definitions "QUALIFIED EXPORT".
|
||||||
*/
|
*/
|
||||||
register t_def *df;
|
register t_def *df;
|
||||||
|
|
||||||
while (df = *pdf) {
|
while ( (df = *pdf) )
|
||||||
if (df->df_kind & D_IMPORTED) {
|
{
|
||||||
if (! (df->df_flags & D_USED)) {
|
if (df->df_kind & D_IMPORTED)
|
||||||
warning(W_ORDINARY, "identifier \"%s\" imported but not used", df->df_idf->id_text);
|
{
|
||||||
|
if (!(df->df_flags & D_USED))
|
||||||
|
{
|
||||||
|
warning(W_ORDINARY, "identifier \"%s\" imported but not used",
|
||||||
|
df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
RemoveFromIdList(df);
|
RemoveFromIdList(df);
|
||||||
*pdf = df->df_nextinscope;
|
*pdf = df->df_nextinscope;
|
||||||
free_def(df);
|
free_def(df);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
df->df_flags |= D_QEXPORTED;
|
df->df_flags |= D_QEXPORTED;
|
||||||
pdf = &(df->df_nextinscope);
|
pdf = &(df->df_nextinscope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveFromIdList(df)
|
void RemoveFromIdList(register t_def *df)
|
||||||
register t_def *df;
|
|
||||||
{
|
{
|
||||||
/* Remove definition "df" from the definition list
|
/* Remove definition "df" from the definition list
|
||||||
*/
|
*/
|
||||||
register t_idf *id = df->df_idf;
|
register t_idf *id = df->df_idf;
|
||||||
register t_def *df1;
|
register t_def *df1;
|
||||||
|
|
||||||
if ((df1 = id->id_def) == df) id->id_def = df->df_next;
|
if ((df1 = id->id_def) == df)
|
||||||
else {
|
id->id_def = df->df_next;
|
||||||
while (df1->df_next != df) {
|
else
|
||||||
|
{
|
||||||
|
while (df1->df_next != df)
|
||||||
|
{
|
||||||
assert(df1->df_next != 0);
|
assert(df1->df_next != 0);
|
||||||
df1 = df1->df_next;
|
df1 = df1->df_next;
|
||||||
}
|
}
|
||||||
|
@ -241,14 +261,12 @@ RemoveFromIdList(df)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_def *
|
t_def * DeclProc(int type, register t_idf *id)
|
||||||
DeclProc(type, id)
|
|
||||||
register t_idf *id;
|
|
||||||
{
|
{
|
||||||
/* A procedure is declared, either in a definition or a program
|
/* A procedure is declared, either in a definition or a program
|
||||||
module. Create a def structure for it (if neccessary).
|
module. Create a def structure for it (if neccessary).
|
||||||
Also create a name for it.
|
Also create a name for it.
|
||||||
*/
|
*/
|
||||||
register t_def *df;
|
register t_def *df;
|
||||||
register t_scope *scope;
|
register t_scope *scope;
|
||||||
static int nmcount;
|
static int nmcount;
|
||||||
|
@ -256,38 +274,45 @@ DeclProc(type, id)
|
||||||
|
|
||||||
assert(type & (D_PROCEDURE | D_PROCHEAD));
|
assert(type & (D_PROCEDURE | D_PROCHEAD));
|
||||||
|
|
||||||
if (type == D_PROCHEAD) {
|
if (type == D_PROCHEAD)
|
||||||
|
{
|
||||||
/* In a definition module
|
/* In a definition module
|
||||||
*/
|
*/
|
||||||
df = define(id, CurrentScope, type);
|
df = define(id, CurrentScope, type);
|
||||||
df->for_node = dot2leaf(Name);
|
df->for_node = dot2leaf(Name);
|
||||||
df->df_flags |= D_USED | D_DEFINED;
|
df->df_flags |= D_USED | D_DEFINED;
|
||||||
if (CurrentScope->sc_definedby->df_flags & D_FOREIGN) {
|
if (CurrentScope->sc_definedby->df_flags & D_FOREIGN)
|
||||||
|
{
|
||||||
df->prc_name = id->id_text;
|
df->prc_name = id->id_text;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
sprint(buf,"%s_%s",CurrentScope->sc_name,id->id_text);
|
{
|
||||||
df->prc_name = Salloc(buf, (unsigned) (strlen(buf)+1));
|
sprint(buf, "%s_%s", CurrentScope->sc_name, id->id_text);
|
||||||
|
df->prc_name = Salloc(buf, (unsigned) (strlen(buf) + 1));
|
||||||
}
|
}
|
||||||
if (CurrVis == Defined->mod_vis) {
|
if (CurrVis == Defined->mod_vis)
|
||||||
|
{
|
||||||
/* The current module will define this routine.
|
/* The current module will define this routine.
|
||||||
make sure the name is exported.
|
make sure the name is exported.
|
||||||
*/
|
*/
|
||||||
C_exp(df->prc_name);
|
C_exp(df->prc_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
df = lookup(id, CurrentScope, D_IMPORTED, 0);
|
df = lookup(id, CurrentScope, D_IMPORTED, 0);
|
||||||
if (df && df->df_kind == D_PROCHEAD) {
|
if (df && df->df_kind == D_PROCHEAD)
|
||||||
|
{
|
||||||
/* C_exp already generated when we saw the definition
|
/* C_exp already generated when we saw the definition
|
||||||
in the definition module
|
in the definition module
|
||||||
*/
|
*/
|
||||||
DefInFront(df);
|
DefInFront(df);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
df = define(id, CurrentScope, type);
|
df = define(id, CurrentScope, type);
|
||||||
sprint(buf,"_%d_%s",++nmcount,id->id_text);
|
sprint(buf, "_%d_%s", ++nmcount, id->id_text);
|
||||||
df->prc_name = Salloc(buf, (unsigned)(strlen(buf)+1));
|
df->prc_name = Salloc(buf, (unsigned) (strlen(buf) + 1));
|
||||||
internal(buf);
|
internal(buf);
|
||||||
df->df_flags |= D_DEFINED;
|
df->df_flags |= D_DEFINED;
|
||||||
}
|
}
|
||||||
|
@ -301,32 +326,29 @@ DeclProc(type, id)
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
EndProc(df, id)
|
void EndProc(register t_def *df, t_idf *id)
|
||||||
register t_def *df;
|
|
||||||
t_idf *id;
|
|
||||||
{
|
{
|
||||||
/* The end of a procedure declaration.
|
/* The end of a procedure declaration.
|
||||||
Check that the closing identifier matches the name of the
|
Check that the closing identifier matches the name of the
|
||||||
procedure, close the scope, and check that a function
|
procedure, close the scope, and check that a function
|
||||||
procedure has at least one RETURN statement.
|
procedure has at least one RETURN statement.
|
||||||
*/
|
*/
|
||||||
extern int return_occurred;
|
extern int return_occurred;
|
||||||
|
|
||||||
match_id(id, df->df_idf);
|
match_id(id, df->df_idf);
|
||||||
close_scope(SC_CHKFORW|SC_REVERSE);
|
close_scope(SC_CHKFORW | SC_REVERSE);
|
||||||
if (! return_occurred && ResultType(df->df_type)) {
|
if (!return_occurred && ResultType(df->df_type))
|
||||||
|
{
|
||||||
error("function procedure %s does not return a value",
|
error("function procedure %s does not return a value",
|
||||||
df->df_idf->id_text);
|
df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_def *
|
t_def * DefineLocalModule(t_idf *id)
|
||||||
DefineLocalModule(id)
|
|
||||||
t_idf *id;
|
|
||||||
{
|
{
|
||||||
/* Create a definition for a local module. Also give it
|
/* Create a definition for a local module. Also give it
|
||||||
a name to be used for code generation.
|
a name to be used for code generation.
|
||||||
*/
|
*/
|
||||||
register t_def *df = define(id, CurrentScope, D_MODULE);
|
register t_def *df = define(id, CurrentScope, D_MODULE);
|
||||||
register t_scope *sc;
|
register t_scope *sc;
|
||||||
static int modulecount = 0;
|
static int modulecount = 0;
|
||||||
|
@ -335,12 +357,13 @@ DefineLocalModule(id)
|
||||||
|
|
||||||
sprint(buf, "_%d%s_", ++modulecount, id->id_text);
|
sprint(buf, "_%d%s_", ++modulecount, id->id_text);
|
||||||
|
|
||||||
if (!df->mod_vis) {
|
if (!df->mod_vis)
|
||||||
|
{
|
||||||
/* We never saw the name of this module before. Create a
|
/* We never saw the name of this module before. Create a
|
||||||
scope for it.
|
scope for it.
|
||||||
*/
|
*/
|
||||||
open_scope(CLOSEDSCOPE);
|
open_scope(CLOSEDSCOPE);
|
||||||
df->mod_vis = CurrVis;
|
df->mod_vis = CurrVis;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrVis = df->mod_vis;
|
CurrVis = df->mod_vis;
|
||||||
|
@ -351,35 +374,33 @@ DefineLocalModule(id)
|
||||||
sc->sc_name = Salloc(buf, (unsigned) (strlen(buf) + 1));
|
sc->sc_name = Salloc(buf, (unsigned) (strlen(buf) + 1));
|
||||||
|
|
||||||
/* Create a type for it
|
/* Create a type for it
|
||||||
*/
|
*/
|
||||||
df->df_type = standard_type(T_RECORD, 1, (arith) 0);
|
df->df_type = standard_type(T_RECORD, 1, (arith) 0);
|
||||||
df->df_type->rec_scope = sc;
|
df->df_type->rec_scope = sc;
|
||||||
|
|
||||||
/* Generate code that indicates that the initialization procedure
|
/* Generate code that indicates that the initialization procedure
|
||||||
for this module is local.
|
for this module is local.
|
||||||
*/
|
*/
|
||||||
internal(buf);
|
internal(buf);
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckWithDef(df, tp)
|
void CheckWithDef(register t_def *df, t_type *tp)
|
||||||
register t_def *df;
|
|
||||||
t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* Check the header of a procedure declaration against a
|
/* Check the header of a procedure declaration against a
|
||||||
possible earlier definition in the definition module.
|
possible earlier definition in the definition module.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (df->df_kind == D_PROCHEAD &&
|
if (df->df_kind == D_PROCHEAD && df->df_type && df->df_type != error_type)
|
||||||
df->df_type &&
|
{
|
||||||
df->df_type != error_type) {
|
|
||||||
/* We already saw a definition of this type
|
/* We already saw a definition of this type
|
||||||
in the definition module.
|
in the definition module.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!TstProcEquiv(tp, df->df_type)) {
|
if (!TstProcEquiv(tp, df->df_type))
|
||||||
|
{
|
||||||
error("inconsistent procedure declaration for \"%s\"",
|
error("inconsistent procedure declaration for \"%s\"",
|
||||||
df->df_idf->id_text);
|
df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
FreeType(df->df_type);
|
FreeType(df->df_type);
|
||||||
df->df_kind = D_PROCEDURE;
|
df->df_kind = D_PROCEDURE;
|
||||||
|
@ -388,8 +409,7 @@ CheckWithDef(df, tp)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PrDef(df)
|
void PrDef(register t_def *df)
|
||||||
register t_def *df;
|
|
||||||
{
|
{
|
||||||
print("n: %s, k: %d\n", df->df_idf->id_text, df->df_kind);
|
print("n: %s, k: %d\n", df->df_idf->id_text, df->df_kind);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
*
|
*
|
||||||
* Author: Ceriel J.H. Jacobs
|
* Author: Ceriel J.H. Jacobs
|
||||||
*/
|
*/
|
||||||
|
#ifndef DEF_H_
|
||||||
|
#define DEF_H_
|
||||||
|
|
||||||
/* I D E N T I F I E R D E S C R I P T O R S T R U C T U R E */
|
/* I D E N T I F I E R D E S C R I P T O R S T R U C T U R E */
|
||||||
|
|
||||||
|
@ -132,12 +134,20 @@ struct def { /* list of definitions for a name */
|
||||||
typedef struct def t_def;
|
typedef struct def t_def;
|
||||||
/* ALLOCDEF "def" 50 */
|
/* ALLOCDEF "def" 50 */
|
||||||
|
|
||||||
extern t_def
|
|
||||||
*define(),
|
|
||||||
*DefineLocalModule(),
|
|
||||||
*MkDef(),
|
|
||||||
*DeclProc(),
|
|
||||||
*lookup(),
|
|
||||||
*lookfor();
|
|
||||||
|
|
||||||
#define NULLDEF ((t_def *) 0)
|
#define NULLDEF ((t_def *) 0)
|
||||||
|
|
||||||
|
typedef struct scope t_scope;
|
||||||
|
typedef struct idf t_idf;
|
||||||
|
typedef struct type t_type;
|
||||||
|
|
||||||
|
t_def *MkDef(register t_idf *id, register t_scope *scope, int kind);
|
||||||
|
t_def *define(register t_idf *id, register t_scope *scope, int kind);
|
||||||
|
void RemoveFromIdList(register t_def *df);
|
||||||
|
t_def * DeclProc(int type, register t_idf *id);
|
||||||
|
void EndProc(register t_def *df, t_idf *id);
|
||||||
|
t_def * DefineLocalModule(t_idf *id);
|
||||||
|
void CheckWithDef(register t_def *df, t_type *tp);
|
||||||
|
void end_definition_list(register t_def **pdf);
|
||||||
|
|
||||||
|
#endif /* DEF_H_ */
|
|
@ -26,9 +26,12 @@
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "error.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "lookup.h"
|
||||||
|
#include "main.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
|
||||||
|
@ -36,13 +39,13 @@
|
||||||
size_t sys_filesize();
|
size_t sys_filesize();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern void DefModule(void); /* Lpars */
|
||||||
|
|
||||||
t_idf* DefId;
|
t_idf* DefId;
|
||||||
|
|
||||||
char*
|
char* getwdir(register char *fn)
|
||||||
getwdir(fn) register char* fn;
|
|
||||||
{
|
{
|
||||||
register char* p;
|
register char* p;
|
||||||
char* strrchr();
|
|
||||||
|
|
||||||
while ((p = strrchr(fn, '/')) && *(p + 1) == '\0')
|
while ((p = strrchr(fn, '/')) && *(p + 1) == '\0')
|
||||||
{
|
{
|
||||||
|
@ -60,8 +63,7 @@ char*
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
static int GetFile(char *name)
|
||||||
GetFile(name) char* name;
|
|
||||||
{
|
{
|
||||||
/* Try to find a file with basename "name" and extension ".def",
|
/* Try to find a file with basename "name" and extension ".def",
|
||||||
in the directories mentioned in "DEFPATH".
|
in the directories mentioned in "DEFPATH".
|
||||||
|
@ -88,8 +90,7 @@ GetFile(name) char* name;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_def*
|
t_def* GetDefinitionModule(register t_idf* id, int incr)
|
||||||
GetDefinitionModule(id, incr) register t_idf* id;
|
|
||||||
{
|
{
|
||||||
/* Return a pointer to the "def" structure of the definition
|
/* Return a pointer to the "def" structure of the definition
|
||||||
module indicated by "id".
|
module indicated by "id".
|
||||||
|
|
|
@ -16,14 +16,14 @@
|
||||||
or perform a store.
|
or perform a store.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <em_arith.h>
|
|
||||||
#include <em_label.h>
|
|
||||||
#include <em_code.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <alloc.h>
|
#include "em_arith.h"
|
||||||
|
#include "em_label.h"
|
||||||
|
#include "em_code.h"
|
||||||
|
#include "alloc.h"
|
||||||
|
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
|
@ -32,16 +32,15 @@
|
||||||
#include "desig.h"
|
#include "desig.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "code.h"
|
||||||
|
#include "tmpvar.h"
|
||||||
#include "walk.h"
|
#include "walk.h"
|
||||||
|
|
||||||
extern int proclevel;
|
extern int proclevel;
|
||||||
extern arith NewPtr();
|
|
||||||
extern char options[];
|
extern char options[];
|
||||||
|
|
||||||
int
|
static int WordOrDouble(t_desig *ds, arith size)
|
||||||
WordOrDouble(ds, size)
|
|
||||||
t_desig *ds;
|
|
||||||
arith size;
|
|
||||||
{
|
{
|
||||||
/* Check if designator is suitable for word or double-word
|
/* Check if designator is suitable for word or double-word
|
||||||
operation
|
operation
|
||||||
|
@ -53,8 +52,7 @@ WordOrDouble(ds, size)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOL(offset, size)
|
void LOL(arith offset, arith size)
|
||||||
arith offset, size;
|
|
||||||
{
|
{
|
||||||
if (size == word_size) {
|
if (size == word_size) {
|
||||||
C_lol(offset);
|
C_lol(offset);
|
||||||
|
@ -68,8 +66,7 @@ LOL(offset, size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STL(offset, size)
|
void STL(arith offset, arith size)
|
||||||
arith offset, size;
|
|
||||||
{
|
{
|
||||||
if (size == word_size) {
|
if (size == word_size) {
|
||||||
C_stl(offset);
|
C_stl(offset);
|
||||||
|
@ -83,10 +80,7 @@ STL(offset, size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int DoLoad(register t_desig *ds, arith size)
|
||||||
DoLoad(ds, size)
|
|
||||||
register t_desig *ds;
|
|
||||||
arith size;
|
|
||||||
{
|
{
|
||||||
/* Try to load designator with word or double-word operation.
|
/* Try to load designator with word or double-word operation.
|
||||||
Return 0 if not done
|
Return 0 if not done
|
||||||
|
@ -110,10 +104,7 @@ DoLoad(ds, size)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int DoStore(register t_desig *ds, arith size)
|
||||||
DoStore(ds, size)
|
|
||||||
register t_desig *ds;
|
|
||||||
arith size;
|
|
||||||
{
|
{
|
||||||
/* Try to store designator with word or double-word operation.
|
/* Try to store designator with word or double-word operation.
|
||||||
Return 0 if not done
|
Return 0 if not done
|
||||||
|
@ -161,9 +152,7 @@ DoStore(ds, size)
|
||||||
multiple of word_size only
|
multiple of word_size only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
STATIC int
|
static int suitable_move(register t_type *tp)
|
||||||
suitable_move(tp)
|
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* Find out how to load or store the value indicated by "ds".
|
/* Find out how to load or store the value indicated by "ds".
|
||||||
There are four ways:
|
There are four ways:
|
||||||
|
@ -181,9 +170,7 @@ suitable_move(tp)
|
||||||
return USE_BLM;
|
return USE_BLM;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeValue(ds, tp)
|
void CodeValue(register t_desig *ds, register t_type *tp)
|
||||||
register t_desig *ds;
|
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* Generate code to load the value of the designator described
|
/* Generate code to load the value of the designator described
|
||||||
in "ds".
|
in "ds".
|
||||||
|
@ -246,8 +233,7 @@ CodeValue(ds, tp)
|
||||||
ds->dsg_kind = DSG_LOADED;
|
ds->dsg_kind = DSG_LOADED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChkForFOR(nd)
|
void ChkForFOR(register t_node *nd)
|
||||||
register t_node *nd;
|
|
||||||
{
|
{
|
||||||
/* Check for an assignment to a FOR-loop control variable
|
/* Check for an assignment to a FOR-loop control variable
|
||||||
*/
|
*/
|
||||||
|
@ -264,9 +250,7 @@ ChkForFOR(nd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeStore(ds, tp)
|
void CodeStore(register t_desig *ds, register t_type *tp)
|
||||||
register t_desig *ds;
|
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* Generate code to store the value on the stack in the designator
|
/* Generate code to store the value on the stack in the designator
|
||||||
described in "ds"
|
described in "ds"
|
||||||
|
@ -311,9 +295,7 @@ CodeStore(ds, tp)
|
||||||
ds->dsg_kind = DSG_INIT;
|
ds->dsg_kind = DSG_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeCopy(lhs, rhs, sz, psize)
|
void CodeCopy(register t_desig *lhs, register t_desig *rhs, arith sz, arith *psize)
|
||||||
register t_desig *lhs, *rhs;
|
|
||||||
arith sz, *psize;
|
|
||||||
{
|
{
|
||||||
/* Do part of a copy, which is assumed to be "reasonable",
|
/* Do part of a copy, which is assumed to be "reasonable",
|
||||||
so that it can be done with LOI/STI or BLM.
|
so that it can be done with LOI/STI or BLM.
|
||||||
|
@ -338,10 +320,7 @@ CodeCopy(lhs, rhs, sz, psize)
|
||||||
|
|
||||||
t_desig null_desig;
|
t_desig null_desig;
|
||||||
|
|
||||||
CodeMove(rhs, left, rtp)
|
void CodeMove(register t_desig *rhs, register t_node *left, t_type *rtp)
|
||||||
register t_desig *rhs;
|
|
||||||
register t_node *left;
|
|
||||||
t_type *rtp;
|
|
||||||
{
|
{
|
||||||
/* Generate code for an assignment. Testing of type
|
/* Generate code for an assignment. Testing of type
|
||||||
compatibility and the like is already done.
|
compatibility and the like is already done.
|
||||||
|
@ -440,8 +419,7 @@ CodeMove(rhs, left, rtp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeAddress(ds)
|
void CodeAddress(register t_desig *ds)
|
||||||
register t_desig *ds;
|
|
||||||
{
|
{
|
||||||
/* Generate code to load the address of the designator described
|
/* Generate code to load the address of the designator described
|
||||||
in "ds"
|
in "ds"
|
||||||
|
@ -481,9 +459,7 @@ CodeAddress(ds)
|
||||||
ds->dsg_kind = DSG_PLOADED;
|
ds->dsg_kind = DSG_PLOADED;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeFieldDesig(df, ds)
|
void CodeFieldDesig(register t_def *df, register t_desig *ds)
|
||||||
register t_def *df;
|
|
||||||
register t_desig *ds;
|
|
||||||
{
|
{
|
||||||
/* Generate code for a field designator. Only the code common for
|
/* Generate code for a field designator. Only the code common for
|
||||||
address as well as value computation is generated, and the
|
address as well as value computation is generated, and the
|
||||||
|
@ -533,10 +509,7 @@ CodeFieldDesig(df, ds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void CodeVarDesig(register t_def *df, register t_desig *ds)
|
||||||
CodeVarDesig(df, ds)
|
|
||||||
register t_def *df;
|
|
||||||
register t_desig *ds;
|
|
||||||
{
|
{
|
||||||
/* Generate code for a variable represented by a "def" structure.
|
/* Generate code for a variable represented by a "def" structure.
|
||||||
Of course, there are numerous cases: the variable is local,
|
Of course, there are numerous cases: the variable is local,
|
||||||
|
@ -612,9 +585,7 @@ CodeVarDesig(df, ds)
|
||||||
ds->dsg_def = df;
|
ds->dsg_def = df;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeDesig(nd, ds)
|
void CodeDesig(register t_node *nd, register t_desig *ds)
|
||||||
register t_node *nd;
|
|
||||||
register t_desig *ds;
|
|
||||||
{
|
{
|
||||||
/* Generate code for a designator. Use divide and conquer
|
/* Generate code for a designator. Use divide and conquer
|
||||||
principle
|
principle
|
||||||
|
|
|
@ -4,11 +4,15 @@
|
||||||
*
|
*
|
||||||
* Author: Ceriel J.H. Jacobs
|
* Author: Ceriel J.H. Jacobs
|
||||||
*/
|
*/
|
||||||
|
#ifndef DESIG_H_
|
||||||
|
#define DESIG_H_
|
||||||
|
|
||||||
/* D E S I G N A T O R D E S C R I P T I O N S */
|
/* D E S I G N A T O R D E S C R I P T I O N S */
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <em_arith.h>
|
||||||
|
|
||||||
/* Generating code for designators is not particularly easy, especially if
|
/* Generating code for designators is not particularly easy, especially if
|
||||||
you don't know wether you want the address or the value.
|
you don't know wether you want the address or the value.
|
||||||
The next structure is used to generate code for designators.
|
The next structure is used to generate code for designators.
|
||||||
|
@ -65,3 +69,21 @@ struct withdesig {
|
||||||
extern struct withdesig *WithDesigs;
|
extern struct withdesig *WithDesigs;
|
||||||
|
|
||||||
#define NO_LABEL ((label) 0)
|
#define NO_LABEL ((label) 0)
|
||||||
|
|
||||||
|
typedef struct type t_type;
|
||||||
|
typedef struct node t_node;
|
||||||
|
|
||||||
|
|
||||||
|
void LOL(arith offset, arith size);
|
||||||
|
void STL(arith offset, arith size);
|
||||||
|
void CodeValue(register t_desig *ds, register t_type *tp);
|
||||||
|
void ChkForFOR(register t_node *nd);
|
||||||
|
void CodeStore(register t_desig *ds, register t_type *tp);
|
||||||
|
void CodeCopy(register t_desig *lhs, register t_desig *rhs, arith sz, arith *psize);
|
||||||
|
void CodeMove(register t_desig *rhs, register t_node *left, t_type *rtp);
|
||||||
|
void CodeAddress(register t_desig *ds);
|
||||||
|
void CodeFieldDesig(register t_def *df, register t_desig *ds);
|
||||||
|
void CodeVarDesig(register t_def *df, register t_desig *ds);
|
||||||
|
void CodeDesig(register t_node *nd, register t_desig *ds);
|
||||||
|
|
||||||
|
#endif /* DESIG_H_ */
|
||||||
|
|
|
@ -22,20 +22,24 @@
|
||||||
#include "em_code.h"
|
#include "em_code.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
|
||||||
|
#include "enter.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
#include "error.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "stab.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "lookup.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
|
|
||||||
t_def *
|
|
||||||
Enter(name, kind, type, pnam)
|
static t_def *DoImport(register t_def *, t_scope *, int);
|
||||||
char *name;
|
|
||||||
t_type *type;
|
t_def *Enter(char *name, int kind, t_type *type, int pnam)
|
||||||
{
|
{
|
||||||
/* Enter a definition for "name" with kind "kind" and type
|
/* Enter a definition for "name" with kind "kind" and type
|
||||||
"type" in the Current Scope. If it is a standard name, also
|
"type" in the Current Scope. If it is a standard name, also
|
||||||
|
@ -52,10 +56,7 @@ Enter(name, kind, type, pnam)
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_def *
|
t_def *EnterType(char *name, t_type *type)
|
||||||
EnterType(name, type)
|
|
||||||
char *name;
|
|
||||||
t_type *type;
|
|
||||||
{
|
{
|
||||||
/* Enter a type definition for "name" and type
|
/* Enter a type definition for "name" and type
|
||||||
"type" in the Current Scope.
|
"type" in the Current Scope.
|
||||||
|
@ -64,9 +65,7 @@ EnterType(name, type)
|
||||||
return Enter(name, D_TYPE, type, 0);
|
return Enter(name, D_TYPE, type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterEnumList(Idlist, type)
|
void EnterEnumList(t_node *Idlist, register t_type *type)
|
||||||
t_node *Idlist;
|
|
||||||
register t_type *type;
|
|
||||||
{
|
{
|
||||||
/* Put a list of enumeration literals in the symbol table.
|
/* Put a list of enumeration literals in the symbol table.
|
||||||
They all have type "type".
|
They all have type "type".
|
||||||
|
@ -92,11 +91,8 @@ EnterEnumList(Idlist, type)
|
||||||
FreeNode(Idlist);
|
FreeNode(Idlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterFieldList(Idlist, type, scope, addr)
|
void EnterFieldList(t_node *Idlist, register t_type *type, t_scope *scope,
|
||||||
t_node *Idlist;
|
arith *addr)
|
||||||
register t_type *type;
|
|
||||||
t_scope *scope;
|
|
||||||
arith *addr;
|
|
||||||
{
|
{
|
||||||
/* Put a list of fields in the symbol table.
|
/* Put a list of fields in the symbol table.
|
||||||
They all have type "type", and are put in scope "scope".
|
They all have type "type", and are put in scope "scope".
|
||||||
|
@ -116,15 +112,8 @@ EnterFieldList(Idlist, type, scope, addr)
|
||||||
FreeNode(Idlist);
|
FreeNode(Idlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterVarList(Idlist, type, local)
|
void EnterVarList(t_node *Idlist, t_type *type, int local)
|
||||||
t_node *Idlist;
|
|
||||||
t_type *type;
|
|
||||||
{
|
{
|
||||||
/* Enter a list of identifiers representing variables into the
|
|
||||||
name list. "type" represents the type of the variables.
|
|
||||||
"local" is set if the variables are declared local to a
|
|
||||||
procedure.
|
|
||||||
*/
|
|
||||||
register t_def *df;
|
register t_def *df;
|
||||||
register t_node *idlist = Idlist;
|
register t_node *idlist = Idlist;
|
||||||
register t_scopelist *sc = CurrVis;
|
register t_scopelist *sc = CurrVis;
|
||||||
|
@ -191,17 +180,12 @@ EnterVarList(Idlist, type, local)
|
||||||
FreeNode(Idlist);
|
FreeNode(Idlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterParamList(ppr, Idlist, type, VARp, off)
|
void EnterParamList(t_param **ppr,
|
||||||
t_param **ppr;
|
t_node *Idlist,
|
||||||
t_node *Idlist;
|
t_type *type,
|
||||||
t_type *type;
|
int VARp,
|
||||||
int VARp;
|
arith *off)
|
||||||
arith *off;
|
|
||||||
{
|
{
|
||||||
/* Create (part of) a parameterlist of a procedure.
|
|
||||||
"ids" indicates the list of identifiers, "tp" their type, and
|
|
||||||
"VARp" indicates D_VARPAR or D_VALPAR.
|
|
||||||
*/
|
|
||||||
register t_param *pr;
|
register t_param *pr;
|
||||||
register t_def *df;
|
register t_def *df;
|
||||||
register t_node *idlist = Idlist;
|
register t_node *idlist = Idlist;
|
||||||
|
@ -245,12 +229,8 @@ EnterParamList(ppr, Idlist, type, VARp, off)
|
||||||
FreeNode(Idlist);
|
FreeNode(Idlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC t_def *DoImport();
|
|
||||||
|
|
||||||
void
|
static void ImportEffects(register t_def *idef, t_scope *scope, int flag)
|
||||||
ImportEffects(idef, scope, flag)
|
|
||||||
register t_def *idef;
|
|
||||||
t_scope *scope;
|
|
||||||
{
|
{
|
||||||
/* Handle side effects of an import:
|
/* Handle side effects of an import:
|
||||||
- a module could have unqualified exports ???
|
- a module could have unqualified exports ???
|
||||||
|
@ -316,10 +296,7 @@ ImportEffects(idef, scope, flag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC t_def *
|
static t_def *DoImport(register t_def *df, t_scope *scope, int flag)
|
||||||
DoImport(df, scope, flag)
|
|
||||||
register t_def *df;
|
|
||||||
t_scope *scope;
|
|
||||||
{
|
{
|
||||||
/* Definition "df" is imported to scope "scope".
|
/* Definition "df" is imported to scope "scope".
|
||||||
*/
|
*/
|
||||||
|
@ -332,10 +309,7 @@ DoImport(df, scope, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
STATIC
|
static void ForwModule(register t_def *df, t_node *nd)
|
||||||
ForwModule(df, nd)
|
|
||||||
register t_def *df;
|
|
||||||
t_node *nd;
|
|
||||||
{
|
{
|
||||||
/* An import is done from a not yet defined module "df".
|
/* An import is done from a not yet defined module "df".
|
||||||
We could also end up here for not found DEFINITION MODULES.
|
We could also end up here for not found DEFINITION MODULES.
|
||||||
|
@ -360,10 +334,7 @@ ForwModule(df, nd)
|
||||||
df->for_node = nd;
|
df->for_node = nd;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC t_def *
|
static t_def *ForwDef(register t_node *ids, t_scope *scope)
|
||||||
ForwDef(ids, scope)
|
|
||||||
register t_node *ids;
|
|
||||||
t_scope *scope;
|
|
||||||
{
|
{
|
||||||
/* Enter a forward definition of "ids" in scope "scope",
|
/* Enter a forward definition of "ids" in scope "scope",
|
||||||
if it is not already defined.
|
if it is not already defined.
|
||||||
|
@ -379,14 +350,8 @@ ForwDef(ids, scope)
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterExportList(Idlist, qualified)
|
void EnterExportList(t_node *Idlist, int qualified)
|
||||||
t_node *Idlist;
|
|
||||||
{
|
{
|
||||||
/* From the current scope, the list of identifiers "ids" is
|
|
||||||
exported. Note this fact. If the export is not qualified, make
|
|
||||||
all the "ids" visible in the enclosing scope by defining them
|
|
||||||
in this scope as "imported".
|
|
||||||
*/
|
|
||||||
register t_node *idlist = Idlist;
|
register t_node *idlist = Idlist;
|
||||||
register t_def *df, *df1;
|
register t_def *df, *df1;
|
||||||
|
|
||||||
|
@ -461,8 +426,7 @@ EnterExportList(Idlist, qualified)
|
||||||
FreeNode(Idlist);
|
FreeNode(Idlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckForImports(df)
|
void CheckForImports(t_def *df)
|
||||||
t_def *df;
|
|
||||||
{
|
{
|
||||||
/* We have a definition for "df"; check all imports of
|
/* We have a definition for "df"; check all imports of
|
||||||
it for side-effects
|
it for side-effects
|
||||||
|
@ -482,11 +446,7 @@ CheckForImports(df)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void EnterFromImportList(t_node *idlist, t_def *FromDef, t_node *FromId)
|
||||||
EnterFromImportList(idlist, FromDef, FromId)
|
|
||||||
register t_node *idlist;
|
|
||||||
register t_def *FromDef;
|
|
||||||
t_node *FromId;
|
|
||||||
{
|
{
|
||||||
/* Import the list Idlist from the module indicated by Fromdef.
|
/* Import the list Idlist from the module indicated by Fromdef.
|
||||||
*/
|
*/
|
||||||
|
@ -544,9 +504,7 @@ node_error(FromId,"identifier \"%s\" does not represent a module",module_name);
|
||||||
FreeNode(FromId);
|
FreeNode(FromId);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterImportList(idlist, local, sc)
|
void EnterImportList(t_node *idlist, int local, t_scope *sc)
|
||||||
register t_node *idlist;
|
|
||||||
t_scope *sc;
|
|
||||||
{
|
{
|
||||||
/* Import "idlist" from scope "sc".
|
/* Import "idlist" from scope "sc".
|
||||||
If the import is not local, definition modules must be read
|
If the import is not local, definition modules must be read
|
||||||
|
|
46
lang/m2/comp/enter.h
Normal file
46
lang/m2/comp/enter.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
* Created on: 2019-02-27
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef ENTER_H_
|
||||||
|
#define ENTER_H_
|
||||||
|
|
||||||
|
/* Forward declarations. */
|
||||||
|
typedef struct type t_type;
|
||||||
|
typedef struct def t_def;
|
||||||
|
typedef struct node t_node;
|
||||||
|
typedef struct scope t_scope;
|
||||||
|
typedef struct paramlist t_param;
|
||||||
|
|
||||||
|
|
||||||
|
t_def *Enter(char *name, int kind, t_type *type, int pnam);
|
||||||
|
t_def *EnterType(char *name, t_type *type);
|
||||||
|
void EnterEnumList(t_node *Idlist, register t_type *type);
|
||||||
|
void EnterFieldList(t_node *Idlist, register t_type *type, t_scope *scope,
|
||||||
|
arith *addr);
|
||||||
|
/* Enter a list of identifiers representing variables into the
|
||||||
|
name list. "type" represents the type of the variables.
|
||||||
|
"local" is set if the variables are declared local to a
|
||||||
|
procedure.
|
||||||
|
*/
|
||||||
|
void EnterVarList(t_node *Idlist, t_type *type, int local);
|
||||||
|
/* Create (part of) a parameterlist of a procedure.
|
||||||
|
"ids" indicates the list of identifiers, "tp" their type, and
|
||||||
|
"VARp" indicates D_VARPAR or D_VALPAR.
|
||||||
|
*/
|
||||||
|
void EnterParamList(t_param **ppr, t_node *Idlist, t_type *type,
|
||||||
|
int VARp, arith *off);
|
||||||
|
/* From the current scope, the list of identifiers "ids" is
|
||||||
|
exported. Note this fact. If the export is not qualified, make
|
||||||
|
all the "ids" visible in the enclosing scope by defining them
|
||||||
|
in this scope as "imported".
|
||||||
|
*/
|
||||||
|
void EnterExportList(t_node *Idlist, int qualified);
|
||||||
|
void CheckForImports(t_def *df);
|
||||||
|
void EnterFromImportList(t_node *idlist, t_def *FromDef, t_node *FromId);
|
||||||
|
void EnterImportList(t_node *idlist, int local, t_scope *sc);
|
||||||
|
|
||||||
|
#endif /* ENTER_H_ */
|
|
@ -30,10 +30,12 @@
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
|
#include "print.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
/* error classes */
|
/* error classes */
|
||||||
#define ERROR 1
|
#define ERROR 1
|
||||||
|
@ -60,13 +62,12 @@ extern char *symbol2str();
|
||||||
FileName, node errors get their information from the
|
FileName, node errors get their information from the
|
||||||
node, whereas other errors use the information in the token.
|
node, whereas other errors use the information in the token.
|
||||||
*/
|
*/
|
||||||
|
static void _error(int, t_node *, char *, register va_list, int);
|
||||||
void _error();
|
|
||||||
|
|
||||||
#if __STDC__
|
#if __STDC__
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
debug(char *fmt, ...)
|
void debug(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -79,7 +80,7 @@ debug(char *fmt, ...)
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
error(char *fmt, ...)
|
void error(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ error(char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
node_error(t_node *node, char *fmt, ...)
|
void node_error(t_node *node, char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -103,7 +104,7 @@ node_error(t_node *node, char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
warning(int class, char *fmt, ...)
|
void warning(int class, char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ warning(int class, char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
node_warning(t_node *node, int class, char *fmt, ...)
|
void node_warning(t_node *node, int class, char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -127,7 +128,7 @@ node_warning(t_node *node, int class, char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
lexerror(char *fmt, ...)
|
void lexerror(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -139,7 +140,7 @@ lexerror(char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
lexwarning(int class, char *fmt, ...)
|
void lexwarning(int class, char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -151,7 +152,7 @@ lexwarning(int class, char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
fatal(char *fmt, ...)
|
void fatal(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -164,7 +165,7 @@ fatal(char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
crash(char *fmt, ...)
|
void crash(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -182,7 +183,7 @@ crash(char *fmt, ...)
|
||||||
#else
|
#else
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
debug(va_alist)
|
void debug(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -197,7 +198,7 @@ debug(va_alist)
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
error(va_alist)
|
void error(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -211,7 +212,7 @@ error(va_alist)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
node_error(va_alist)
|
void node_error(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -226,7 +227,7 @@ node_error(va_alist)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
warning(va_alist)
|
void warning(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -241,7 +242,7 @@ warning(va_alist)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
node_warning(va_alist)
|
void node_warning(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -257,7 +258,7 @@ node_warning(va_alist)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
lexerror(va_alist)
|
void lexerror(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -271,7 +272,7 @@ lexerror(va_alist)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
lexwarning(va_alist)
|
void lexwarning(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -286,7 +287,7 @@ lexwarning(va_alist)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
fatal(va_alist)
|
void fatal(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -301,7 +302,7 @@ fatal(va_alist)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*VARARGS*/
|
/*VARARGS*/
|
||||||
crash(va_alist)
|
void crash(va_alist)
|
||||||
va_dcl
|
va_dcl
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -320,13 +321,7 @@ crash(va_alist)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
static void _error(int class, t_node *node, char *fmt, register va_list ap, int warn_class)
|
||||||
_error(class, node, fmt, ap, warn_class)
|
|
||||||
int class;
|
|
||||||
t_node *node;
|
|
||||||
char *fmt;
|
|
||||||
register va_list ap;
|
|
||||||
int warn_class;
|
|
||||||
{
|
{
|
||||||
/* _error attempts to limit the number of error messages
|
/* _error attempts to limit the number of error messages
|
||||||
for a given line to MAXERR_LINE.
|
for a given line to MAXERR_LINE.
|
||||||
|
|
60
lang/m2/comp/error.h
Normal file
60
lang/m2/comp/error.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
* Created on: 2019-02-26
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef ERROR_H_
|
||||||
|
#define ERROR_H_
|
||||||
|
|
||||||
|
typedef struct node t_node;
|
||||||
|
|
||||||
|
#if __STDC__
|
||||||
|
#ifdef DEBUG
|
||||||
|
/*VARARGS*/
|
||||||
|
void debug(char *fmt, ...);
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
/*VARARGS*/
|
||||||
|
void error(char *fmt, ...);
|
||||||
|
/*VARARGS*/
|
||||||
|
void node_error(t_node *node, char *fmt, ...);
|
||||||
|
/*VARARGS*/
|
||||||
|
void warning(int class, char *fmt, ...);
|
||||||
|
/*VARARGS*/
|
||||||
|
void node_warning(t_node *node, int class, char *fmt, ...);
|
||||||
|
/*VARARGS*/
|
||||||
|
void lexerror(char *fmt, ...);
|
||||||
|
/*VARARGS*/
|
||||||
|
void lexwarning(int class, char *fmt, ...);
|
||||||
|
/*VARARGS*/
|
||||||
|
void fatal(char *fmt, ...);
|
||||||
|
/*VARARGS*/
|
||||||
|
void crash(char *fmt, ...);
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
/*VARARGS*/
|
||||||
|
void debug(va_alist);
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
/*VARARGS*/
|
||||||
|
void error(va_alist);
|
||||||
|
/*VARARGS*/
|
||||||
|
void node_error(va_alist);
|
||||||
|
/*VARARGS*/
|
||||||
|
void warning(va_alist);
|
||||||
|
/*VARARGS*/
|
||||||
|
void node_warning(va_alist);
|
||||||
|
/*VARARGS*/
|
||||||
|
void lexerror(va_alist);
|
||||||
|
/*VARARGS*/
|
||||||
|
void lexwarning(va_alist);
|
||||||
|
/*VARARGS*/
|
||||||
|
void fatal(va_alist);
|
||||||
|
/*VARARGS*/
|
||||||
|
void crash(va_alist);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ERROR_H_ */
|
|
@ -10,12 +10,12 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
{
|
{
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <alloc.h>
|
#include "alloc.h"
|
||||||
#include <em_arith.h>
|
#include "em_arith.h"
|
||||||
#include <em_label.h>
|
#include "em_label.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
#include "error.h"
|
||||||
#include "chk_expr.h"
|
#include "chk_expr.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include <idf_pkg.body>
|
#include <idf_pkg.body>
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
struct f_info file_info;
|
struct f_info file_info;
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include <inp_pkg.body>
|
#include <inp_pkg.body>
|
||||||
|
|
||||||
|
|
||||||
int AtEoIF(void)
|
int AtEoIF(void)
|
||||||
|
|
|
@ -9,13 +9,14 @@
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
#include <em_label.h>
|
#include <em_label.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "lookup.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
@ -29,10 +30,7 @@ extern int pass_1;
|
||||||
extern char options[];
|
extern char options[];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
t_def *
|
t_def *lookup(register t_idf *id, t_scope *scope, int import, int flags)
|
||||||
lookup(id, scope, import, flags)
|
|
||||||
register t_idf *id;
|
|
||||||
t_scope *scope;
|
|
||||||
{
|
{
|
||||||
/* Look up a definition of an identifier in scope "scope".
|
/* Look up a definition of an identifier in scope "scope".
|
||||||
Make the "def" list self-organizing.
|
Make the "def" list self-organizing.
|
||||||
|
@ -74,10 +72,7 @@ lookup(id, scope, import, flags)
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_def *
|
t_def *lookfor(register t_node *id, register t_scopelist *vis, int message, int flags)
|
||||||
lookfor(id, vis, message, flags)
|
|
||||||
register t_node *id;
|
|
||||||
register t_scopelist *vis;
|
|
||||||
{
|
{
|
||||||
/* Look for an identifier in the visibility range started by "vis".
|
/* Look for an identifier in the visibility range started by "vis".
|
||||||
If it is not defined create a dummy definition and,
|
If it is not defined create a dummy definition and,
|
||||||
|
|
21
lang/m2/comp/lookup.h
Normal file
21
lang/m2/comp/lookup.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
* Created on: 2019-02-27
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LOOKUP_H_
|
||||||
|
#define LOOKUP_H_
|
||||||
|
|
||||||
|
/* Forward declarations. */
|
||||||
|
typedef struct idf t_idf;
|
||||||
|
typedef struct scope t_scope;
|
||||||
|
typedef struct node t_node;
|
||||||
|
typedef struct def t_def;
|
||||||
|
typedef struct scopelist t_scopelist;
|
||||||
|
|
||||||
|
t_def *lookup(register t_idf *id, t_scope *scope, int import, int flags);
|
||||||
|
t_def *lookfor(register t_node *id, register t_scopelist *vis, int message, int flags);
|
||||||
|
|
||||||
|
#endif /* LOOKUP_H_ */
|
|
@ -9,15 +9,17 @@
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <system.h>
|
|
||||||
#include <em_arith.h>
|
|
||||||
#include <em_label.h>
|
|
||||||
#include <em_code.h>
|
|
||||||
#include <alloc.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include "system.h"
|
||||||
|
#include "em_arith.h"
|
||||||
|
#include "em_label.h"
|
||||||
|
#include "em_code.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "alloc.h"
|
||||||
|
|
||||||
#include <stb.h>
|
#include <stb.h>
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
@ -31,24 +33,39 @@
|
||||||
#include "standards.h"
|
#include "standards.h"
|
||||||
#include "tokenname.h"
|
#include "tokenname.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "walk.h"
|
||||||
|
#include "cstoper.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "options.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
#include "SYSTEM.h"
|
#include "SYSTEMM2.h"
|
||||||
|
|
||||||
int state; /* either IMPLEMENTATION or PROGRAM */
|
int state; /* either IMPLEMENTATION or PROGRAM */
|
||||||
char options[128];
|
char options[128];
|
||||||
int DefinitionModule;
|
int DefinitionModule;
|
||||||
char *ProgName;
|
char *ProgName;
|
||||||
char **DEFPATH;
|
char **DEFPATH;
|
||||||
int nDEF = 2, mDEF = 10;
|
int nDEF = 2, mDEF = 10;
|
||||||
int pass_1 = 1;
|
int pass_1 = 1;
|
||||||
t_def *Defined;
|
t_def *Defined;
|
||||||
extern int err_occurred;
|
extern int err_occurred;
|
||||||
extern int fp_used; /* set if floating point used */
|
extern int fp_used; /* set if floating point used */
|
||||||
static t_node _emptystat = { Stat, 0, NULLTYPE, { ';' }};
|
static t_node _emptystat = { Stat, 0, NULLTYPE, { ';' }};
|
||||||
t_node *EmptyStatement = &_emptystat;
|
t_node *EmptyStatement = &_emptystat;
|
||||||
|
|
||||||
main(argc, argv)
|
|
||||||
register char **argv;
|
/* Forward declarations. */
|
||||||
|
struct stdproc;
|
||||||
|
int Compile(char *, char *);
|
||||||
|
static void AddProcs(register struct stdproc *);
|
||||||
|
static void AddStandards(void);
|
||||||
|
/* External function declarations */
|
||||||
|
extern void CompUnit(void);
|
||||||
|
extern void DefModule(void); /* Lpars */
|
||||||
|
extern void reserve(register struct tokenname *); /* tokenname */
|
||||||
|
char* getwdir(register char *); /* defmodule */
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
register int Nargc = 1;
|
register int Nargc = 1;
|
||||||
register char **Nargv = &argv[0];
|
register char **Nargv = &argv[0];
|
||||||
|
@ -72,11 +89,9 @@ main(argc, argv)
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
Compile(src, dst)
|
int Compile(char *src, char *dst)
|
||||||
char *src, *dst;
|
|
||||||
{
|
{
|
||||||
extern struct tokenname tkidf[];
|
extern struct tokenname tkidf[];
|
||||||
extern char *getwdir();
|
|
||||||
|
|
||||||
if (! InsertFile(src, (char **) 0, &src)) {
|
if (! InsertFile(src, (char **) 0, &src)) {
|
||||||
fprint(STDERR,"%s: cannot open %s\n", ProgName, src);
|
fprint(STDERR,"%s: cannot open %s\n", ProgName, src);
|
||||||
|
@ -126,7 +141,7 @@ Compile(src, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LexScan()
|
void LexScan(void)
|
||||||
{
|
{
|
||||||
register t_token *tkp = ˙
|
register t_token *tkp = ˙
|
||||||
extern char *symbol2str();
|
extern char *symbol2str();
|
||||||
|
@ -198,8 +213,7 @@ static struct stdproc sysprocs[] = {
|
||||||
|
|
||||||
extern t_def *Enter(), *EnterType();
|
extern t_def *Enter(), *EnterType();
|
||||||
|
|
||||||
AddProcs(p)
|
static void AddProcs(register struct stdproc *p)
|
||||||
register struct stdproc *p;
|
|
||||||
{
|
{
|
||||||
for (; p->st_nam != 0; p++) {
|
for (; p->st_nam != 0; p++) {
|
||||||
if (! Enter(p->st_nam, D_PROCEDURE, std_type, p->st_con)) {
|
if (! Enter(p->st_nam, D_PROCEDURE, std_type, p->st_con)) {
|
||||||
|
@ -208,7 +222,7 @@ AddProcs(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AddStandards()
|
static void AddStandards(void)
|
||||||
{
|
{
|
||||||
register t_def *df;
|
register t_def *df;
|
||||||
static t_token nilconst = { INTEGER, 0};
|
static t_token nilconst = { INTEGER, 0};
|
||||||
|
@ -238,7 +252,7 @@ AddStandards()
|
||||||
EnterType("BOOLEAN", bool_type);
|
EnterType("BOOLEAN", bool_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
do_SYSTEM()
|
void do_SYSTEM(void)
|
||||||
{
|
{
|
||||||
/* Simulate the reading of the SYSTEM definition module
|
/* Simulate the reading of the SYSTEM definition module
|
||||||
*/
|
*/
|
||||||
|
@ -258,7 +272,7 @@ do_SYSTEM()
|
||||||
|
|
||||||
int cntlines;
|
int cntlines;
|
||||||
|
|
||||||
Info()
|
void Info(void)
|
||||||
{
|
{
|
||||||
extern int cnt_def, cnt_node, cnt_paramlist, cnt_type,
|
extern int cnt_def, cnt_node, cnt_paramlist, cnt_type,
|
||||||
cnt_switch_hdr, cnt_case_entry,
|
cnt_switch_hdr, cnt_case_entry,
|
||||||
|
@ -274,14 +288,12 @@ print("\nNumber of lines read: %d\n", cntlines);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void No_Mem(void)
|
||||||
No_Mem()
|
|
||||||
{
|
{
|
||||||
fatal("out of memory");
|
fatal("out of memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void C_failed(void)
|
||||||
C_failed()
|
|
||||||
{
|
{
|
||||||
fatal("write failed");
|
fatal("write failed");
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* S O M E G L O B A L V A R I A B L E S */
|
/* S O M E G L O B A L V A R I A B L E S */
|
||||||
|
#ifndef MAIN_H_
|
||||||
/* $Id$ */
|
#define MAIN_H_
|
||||||
|
|
||||||
extern char options[]; /* indicating which options were given */
|
extern char options[]; /* indicating which options were given */
|
||||||
|
|
||||||
|
@ -23,3 +23,7 @@ extern struct def *Defined;
|
||||||
extern char **DEFPATH; /* search path for DEFINITION MODULE's */
|
extern char **DEFPATH; /* search path for DEFINITION MODULE's */
|
||||||
extern int mDEF, nDEF;
|
extern int mDEF, nDEF;
|
||||||
extern int state; /* either IMPLEMENTATION or PROGRAM */
|
extern int state; /* either IMPLEMENTATION or PROGRAM */
|
||||||
|
|
||||||
|
void do_SYSTEM(void);
|
||||||
|
|
||||||
|
#endif /* MAIN_H_ */
|
||||||
|
|
|
@ -17,15 +17,15 @@
|
||||||
#include "em_arith.h"
|
#include "em_arith.h"
|
||||||
#include "em_label.h"
|
#include "em_label.h"
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
match_id(id1, id2)
|
void match_id(register t_idf *id1, t_idf *id2)
|
||||||
register t_idf *id1, *id2;
|
|
||||||
{
|
{
|
||||||
/* Check that identifiers id1 and id2 are equal. If they
|
/* Check that identifiers id1 and id2 are equal. If they
|
||||||
are not, check that we did'nt generate them in the
|
are not, check that we did'nt generate them in the
|
||||||
|
@ -39,8 +39,7 @@ match_id(id1, id2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_idf *
|
t_idf *gen_anon_idf(void)
|
||||||
gen_anon_idf()
|
|
||||||
{
|
{
|
||||||
/* A new idf is created out of nowhere, to serve as an
|
/* A new idf is created out of nowhere, to serve as an
|
||||||
anonymous name.
|
anonymous name.
|
||||||
|
@ -55,9 +54,7 @@ gen_anon_idf()
|
||||||
return str2idf(s, 0);
|
return str2idf(s, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
not_declared(what, id, where)
|
void not_declared(char *what, t_node *id, char *where)
|
||||||
char *what, *where;
|
|
||||||
register t_node *id;
|
|
||||||
{
|
{
|
||||||
/* The identifier "id" is not declared. If it is not generated,
|
/* The identifier "id" is not declared. If it is not generated,
|
||||||
give an error message
|
give an error message
|
||||||
|
|
|
@ -12,5 +12,10 @@
|
||||||
#define is_anon_idf(x) ((x)->id_text[0] == '#')
|
#define is_anon_idf(x) ((x)->id_text[0] == '#')
|
||||||
#define id_not_declared(x) (not_declared("identifier", (x), ""))
|
#define id_not_declared(x) (not_declared("identifier", (x), ""))
|
||||||
|
|
||||||
extern struct idf
|
/* Forward declarations. */
|
||||||
*gen_anon_idf();
|
typedef struct idf t_idf;
|
||||||
|
typedef struct node t_node;
|
||||||
|
|
||||||
|
void match_id(register t_idf *id1, t_idf *id2);
|
||||||
|
t_idf *gen_anon_idf(void);
|
||||||
|
void not_declared(char *what, t_node *id, char *where);
|
||||||
|
|
1
lang/m2/comp/next.in
Normal file
1
lang/m2/comp/next.in
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#include "parameters.h"
|
|
@ -22,6 +22,7 @@
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
static int nsubnodes[] = {
|
static int nsubnodes[] = {
|
||||||
0,
|
0,
|
||||||
|
@ -39,8 +40,7 @@ static int nsubnodes[] = {
|
||||||
2
|
2
|
||||||
};
|
};
|
||||||
|
|
||||||
t_node *
|
t_node *getnode(int class)
|
||||||
getnode(class)
|
|
||||||
{
|
{
|
||||||
register t_node *nd = new_node();
|
register t_node *nd = new_node();
|
||||||
|
|
||||||
|
@ -50,9 +50,7 @@ getnode(class)
|
||||||
return nd;
|
return nd;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_node *
|
t_node *dot2node(int class, t_node *left, t_node *right)
|
||||||
dot2node(class, left, right)
|
|
||||||
t_node *left, *right;
|
|
||||||
{
|
{
|
||||||
register t_node *nd = getnode(class);
|
register t_node *nd = getnode(class);
|
||||||
|
|
||||||
|
@ -63,8 +61,7 @@ dot2node(class, left, right)
|
||||||
return nd;
|
return nd;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_node *
|
t_node *dot2leaf(int class)
|
||||||
dot2leaf(class)
|
|
||||||
{
|
{
|
||||||
register t_node *nd = getnode(class);
|
register t_node *nd = getnode(class);
|
||||||
|
|
||||||
|
@ -81,15 +78,13 @@ dot2leaf(class)
|
||||||
return nd;
|
return nd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void FreeNode(register t_node *nd)
|
||||||
FreeNode(nd)
|
|
||||||
register t_node *nd;
|
|
||||||
{
|
{
|
||||||
/* Put nodes that are no longer needed back onto the free
|
/* Put nodes that are no longer needed back onto the free
|
||||||
list
|
list
|
||||||
*/
|
*/
|
||||||
if (!nd) return;
|
if (!nd) return;
|
||||||
switch(nsubnodes[nd->nd_class]) {
|
switch(nsubnodes[(unsigned int)nd->nd_class]) {
|
||||||
case 2:
|
case 2:
|
||||||
FreeNode(nd->nd_LEFT);
|
FreeNode(nd->nd_LEFT);
|
||||||
FreeNode(nd->nd_RIGHT);
|
FreeNode(nd->nd_RIGHT);
|
||||||
|
@ -102,15 +97,13 @@ FreeNode(nd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
NodeCrash(expp)
|
int NodeCrash(register t_node* expp, label exit_label, int end_reached)
|
||||||
t_node *expp;
|
|
||||||
{
|
{
|
||||||
crash("(NodeCrash) Illegal node");
|
crash("(NodeCrash) Illegal node");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
PNodeCrash(expp)
|
int PNodeCrash(t_node **expp, int flags)
|
||||||
t_node **expp;
|
|
||||||
{
|
{
|
||||||
crash("(PNodeCrash) Illegal node");
|
crash("(PNodeCrash) Illegal node");
|
||||||
}
|
}
|
||||||
|
@ -119,15 +112,14 @@ PNodeCrash(expp)
|
||||||
|
|
||||||
extern char *symbol2str();
|
extern char *symbol2str();
|
||||||
|
|
||||||
indnt(lvl)
|
void indnt(int lvl)
|
||||||
{
|
{
|
||||||
while (lvl--) {
|
while (lvl--) {
|
||||||
print(" ");
|
print(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printnode(nd, lvl)
|
void printnode(register t_node *nd, int lvl)
|
||||||
register t_node *nd;
|
|
||||||
{
|
{
|
||||||
indnt(lvl);
|
indnt(lvl);
|
||||||
print("Class: %d; Symbol: %s; Flags: %d\n", nd->nd_class, symbol2str(nd->nd_symb), nd->nd_flags);
|
print("Class: %d; Symbol: %s; Flags: %d\n", nd->nd_class, symbol2str(nd->nd_symb), nd->nd_flags);
|
||||||
|
@ -139,8 +131,7 @@ printnode(nd, lvl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrNode(nd, lvl)
|
void PrNode(register t_node *nd, int lvl)
|
||||||
register t_node *nd;
|
|
||||||
{
|
{
|
||||||
if (! nd) {
|
if (! nd) {
|
||||||
indnt(lvl); print("<nilnode>\n");
|
indnt(lvl); print("<nilnode>\n");
|
||||||
|
|
|
@ -61,3 +61,13 @@ extern t_node *dot2node(), *dot2leaf(), *getnode();
|
||||||
|
|
||||||
#define IsCast(lnd) ((lnd)->nd_class == Def && is_type((lnd)->nd_def))
|
#define IsCast(lnd) ((lnd)->nd_class == Def && is_type((lnd)->nd_def))
|
||||||
#define IsProc(lnd) ((lnd)->nd_type->tp_fund == T_PROCEDURE)
|
#define IsProc(lnd) ((lnd)->nd_type->tp_fund == T_PROCEDURE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
t_node *getnode(int class);
|
||||||
|
t_node *dot2node(int class, t_node *left, t_node *right);
|
||||||
|
t_node *dot2leaf(int class);
|
||||||
|
void FreeNode(register t_node *nd);
|
||||||
|
int NodeCrash(register t_node* expp, label exit_label, int end_reached);
|
||||||
|
int PNodeCrash(t_node **expp, int flags);
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
#include "class.h"
|
#include "class.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
#define MINIDFSIZE 14
|
#define MINIDFSIZE 14
|
||||||
|
|
||||||
|
@ -32,13 +33,30 @@ static int ndirs = 1;
|
||||||
int warning_classes = W_INITIAL;
|
int warning_classes = W_INITIAL;
|
||||||
int gdb_flag;
|
int gdb_flag;
|
||||||
|
|
||||||
DoOption(text)
|
#if (!SQUEEZE) | (!NOCROSS)
|
||||||
register char *text;
|
static int txt2int(register char **tp)
|
||||||
|
{
|
||||||
|
/* the integer pointed to by *tp is read, while increasing
|
||||||
|
*tp; the resulting value is yielded.
|
||||||
|
*/
|
||||||
|
register int val = 0;
|
||||||
|
register int ch;
|
||||||
|
|
||||||
|
while (ch = **tp, ch >= '0' && ch <= '9') {
|
||||||
|
val = val * 10 + ch - '0';
|
||||||
|
(*tp)++;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void DoOption(register char *text)
|
||||||
{
|
{
|
||||||
switch(*text++) {
|
switch(*text++) {
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
options[*text]++; /* debug options etc. */
|
options[(unsigned int)*text]++; /* debug options etc. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'U': /* allow underscores in identifiers */
|
case 'U': /* allow underscores in identifiers */
|
||||||
|
@ -54,7 +72,7 @@ DoOption(text)
|
||||||
case 's': /* symmetric: MIN(INTEGER) = -MAX(INTEGER) */
|
case 's': /* symmetric: MIN(INTEGER) = -MAX(INTEGER) */
|
||||||
case '3': /* strict 3rd edition Modula-2 */
|
case '3': /* strict 3rd edition Modula-2 */
|
||||||
case 'l': /* local additions enabled */
|
case 'l': /* local additions enabled */
|
||||||
options[text[-1]]++;
|
options[(unsigned int)text[-1]]++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef DBSYMTAB
|
#ifdef DBSYMTAB
|
||||||
|
@ -162,7 +180,7 @@ DoOption(text)
|
||||||
char c;
|
char c;
|
||||||
char *t;
|
char *t;
|
||||||
|
|
||||||
while (c = *text++) {
|
while ( (c = *text++) != 0) {
|
||||||
char *strchr();
|
char *strchr();
|
||||||
|
|
||||||
t = text;
|
t = text;
|
||||||
|
@ -235,21 +253,3 @@ DoOption(text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (!SQUEEZE) | (!NOCROSS)
|
|
||||||
int
|
|
||||||
txt2int(tp)
|
|
||||||
register char **tp;
|
|
||||||
{
|
|
||||||
/* the integer pointed to by *tp is read, while increasing
|
|
||||||
*tp; the resulting value is yielded.
|
|
||||||
*/
|
|
||||||
register int val = 0;
|
|
||||||
register int ch;
|
|
||||||
|
|
||||||
while (ch = **tp, ch >= '0' && ch <= '9') {
|
|
||||||
val = val * 10 + ch - '0';
|
|
||||||
(*tp)++;
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
13
lang/m2/comp/options.h
Normal file
13
lang/m2/comp/options.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
* Created on: 2019-02-27
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef OPTIONS_H_
|
||||||
|
#define OPTIONS_H_
|
||||||
|
|
||||||
|
void DoOption(register char *text);
|
||||||
|
|
||||||
|
#endif /* OPTIONS_H_ */
|
|
@ -12,14 +12,14 @@
|
||||||
{
|
{
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <alloc.h>
|
#include "alloc.h"
|
||||||
#include <em_arith.h>
|
#include "em_arith.h"
|
||||||
#include <em_label.h>
|
#include "em_label.h"
|
||||||
#include <em_code.h>
|
#include "em_code.h"
|
||||||
#include <stb.h>
|
#include "stb.h"
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
@ -27,6 +27,10 @@
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
#include "lookup.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "stab.h"
|
||||||
|
#include "enter.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
|
|
|
@ -6,8 +6,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* S C O P E M E C H A N I S M */
|
/* S C O P E M E C H A N I S M */
|
||||||
|
#ifndef SCOPE_H_
|
||||||
|
#define SCOPE_H_
|
||||||
|
|
||||||
|
|
||||||
/* $Id$ */
|
|
||||||
|
|
||||||
#define OPENSCOPE 0 /* Indicating an open scope */
|
#define OPENSCOPE 0 /* Indicating an open scope */
|
||||||
#define CLOSEDSCOPE 1 /* Indicating a closed scope (module) */
|
#define CLOSEDSCOPE 1 /* Indicating a closed scope (module) */
|
||||||
|
@ -58,4 +60,17 @@ extern t_scopelist
|
||||||
#define scopeclosed(x) ((x)->sc_scopeclosed)
|
#define scopeclosed(x) ((x)->sc_scopeclosed)
|
||||||
#define nextvisible(x) ((x)->sc_next) /* use with scopelists */
|
#define nextvisible(x) ((x)->sc_next) /* use with scopelists */
|
||||||
|
|
||||||
t_scope *open_and_close_scope();
|
|
||||||
|
typedef struct def t_def;
|
||||||
|
|
||||||
|
void Reverse(t_def **pdf);
|
||||||
|
void open_scope(int scopetype);
|
||||||
|
t_scope * open_and_close_scope(int scopetype);
|
||||||
|
void InitScope(void);
|
||||||
|
void close_scope(int flag);
|
||||||
|
#ifdef DEBUG
|
||||||
|
void DumpScope(register t_def *df);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* SCOPE_H_ */
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <alloc.h>
|
#include "alloc.h"
|
||||||
#include <em_arith.h>
|
#include "em_arith.h"
|
||||||
#include <em_label.h>
|
#include "em_label.h"
|
||||||
|
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
@ -23,6 +23,8 @@
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "lookup.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
t_scope *PervasiveScope;
|
t_scope *PervasiveScope;
|
||||||
t_scopelist *CurrVis, *GlobalVis;
|
t_scopelist *CurrVis, *GlobalVis;
|
||||||
|
@ -35,7 +37,7 @@ extern char options[];
|
||||||
|
|
||||||
static int sc_count;
|
static int sc_count;
|
||||||
|
|
||||||
open_scope(scopetype)
|
void open_scope(int scopetype)
|
||||||
{
|
{
|
||||||
/* Open a scope that is either open (automatic imports) or closed.
|
/* Open a scope that is either open (automatic imports) or closed.
|
||||||
*/
|
*/
|
||||||
|
@ -55,8 +57,7 @@ open_scope(scopetype)
|
||||||
CurrVis = ls;
|
CurrVis = ls;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_scope *
|
t_scope * open_and_close_scope(int scopetype)
|
||||||
open_and_close_scope(scopetype)
|
|
||||||
{
|
{
|
||||||
t_scope *sc;
|
t_scope *sc;
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ open_and_close_scope(scopetype)
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitScope()
|
void InitScope(void)
|
||||||
{
|
{
|
||||||
register t_scope *sc = new_scope();
|
register t_scope *sc = new_scope();
|
||||||
register t_scopelist *ls = new_scopelist();
|
register t_scopelist *ls = new_scopelist();
|
||||||
|
@ -77,9 +78,7 @@ InitScope()
|
||||||
CurrVis = ls;
|
CurrVis = ls;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
static void chk_proc(register t_def *df)
|
||||||
chk_proc(df)
|
|
||||||
register t_def *df;
|
|
||||||
{
|
{
|
||||||
/* Called at scope closing. Check all definitions, and if one
|
/* Called at scope closing. Check all definitions, and if one
|
||||||
is a D_PROCHEAD, the procedure was not defined.
|
is a D_PROCHEAD, the procedure was not defined.
|
||||||
|
@ -101,9 +100,7 @@ chk_proc(df)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
static void chk_forw(t_def **pdf)
|
||||||
chk_forw(pdf)
|
|
||||||
t_def **pdf;
|
|
||||||
{
|
{
|
||||||
/* Called at scope close. Look for all forward definitions and
|
/* Called at scope close. Look for all forward definitions and
|
||||||
if the scope was a closed scope, give an error message for
|
if the scope was a closed scope, give an error message for
|
||||||
|
@ -111,7 +108,7 @@ chk_forw(pdf)
|
||||||
*/
|
*/
|
||||||
register t_def *df;
|
register t_def *df;
|
||||||
|
|
||||||
while (df = *pdf) {
|
while ( (df = *pdf) ) {
|
||||||
if (df->df_kind == D_FORWTYPE) {
|
if (df->df_kind == D_FORWTYPE) {
|
||||||
pdf = &df->df_nextinscope;
|
pdf = &df->df_nextinscope;
|
||||||
ForceForwardTypeDef(df); /* removes df */
|
ForceForwardTypeDef(df); /* removes df */
|
||||||
|
@ -157,8 +154,7 @@ df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Reverse(pdf)
|
void Reverse(t_def **pdf)
|
||||||
t_def **pdf;
|
|
||||||
{
|
{
|
||||||
/* Reverse the order in the list of definitions in a scope.
|
/* Reverse the order in the list of definitions in a scope.
|
||||||
This is neccesary because this list is built in reverse.
|
This is neccesary because this list is built in reverse.
|
||||||
|
@ -184,8 +180,7 @@ Reverse(pdf)
|
||||||
*pdf = df;
|
*pdf = df;
|
||||||
}
|
}
|
||||||
|
|
||||||
close_scope(flag)
|
void close_scope(int flag)
|
||||||
register int flag;
|
|
||||||
{
|
{
|
||||||
/* Close a scope. If "flag" is set, check for forward declarations,
|
/* Close a scope. If "flag" is set, check for forward declarations,
|
||||||
either POINTER declarations, or EXPORTs, or forward references
|
either POINTER declarations, or EXPORTs, or forward references
|
||||||
|
@ -208,8 +203,7 @@ close_scope(flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DumpScope(df)
|
void DumpScope(register t_def *df)
|
||||||
register t_def *df;
|
|
||||||
{
|
{
|
||||||
while (df) {
|
while (df) {
|
||||||
PrDef(df);
|
PrDef(df);
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "stab.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
extern int gdb_flag;
|
extern int gdb_flag;
|
||||||
|
@ -40,8 +42,7 @@ static struct db_str {
|
||||||
char *currpos;
|
char *currpos;
|
||||||
} db_str;
|
} db_str;
|
||||||
|
|
||||||
static
|
static void create_db_str(void)
|
||||||
create_db_str()
|
|
||||||
{
|
{
|
||||||
if (! db_str.base) {
|
if (! db_str.base) {
|
||||||
db_str.base = Malloc(INCR_SIZE);
|
db_str.base = Malloc(INCR_SIZE);
|
||||||
|
@ -50,9 +51,7 @@ create_db_str()
|
||||||
db_str.currpos = db_str.base;
|
db_str.currpos = db_str.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static void addc_db_str(int c)
|
||||||
addc_db_str(c)
|
|
||||||
int c;
|
|
||||||
{
|
{
|
||||||
int df = db_str.currpos - db_str.base;
|
int df = db_str.currpos - db_str.base;
|
||||||
if (df >= db_str.sz-1) {
|
if (df >= db_str.sz-1) {
|
||||||
|
@ -64,16 +63,12 @@ addc_db_str(c)
|
||||||
*db_str.currpos = '\0';
|
*db_str.currpos = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static void adds_db_str(char *s)
|
||||||
adds_db_str(s)
|
|
||||||
char *s;
|
|
||||||
{
|
{
|
||||||
while (*s) addc_db_str(*s++);
|
while (*s) addc_db_str(*s++);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void stb_type(register t_type *tp, int assign_num)
|
||||||
stb_type(tp, assign_num)
|
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
char buf[128];
|
char buf[128];
|
||||||
static int stb_count;
|
static int stb_count;
|
||||||
|
@ -254,9 +249,7 @@ stb_type(tp, assign_num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stb_addtp(s, tp)
|
void stb_addtp(char *s, t_type *tp)
|
||||||
char *s;
|
|
||||||
t_type *tp;
|
|
||||||
{
|
{
|
||||||
create_db_str();
|
create_db_str();
|
||||||
adds_db_str(s);
|
adds_db_str(s);
|
||||||
|
@ -272,8 +265,7 @@ stb_addtp(s, tp)
|
||||||
(arith) 0);
|
(arith) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
stb_string(df, kind)
|
void stb_string(register t_def *df, int kind)
|
||||||
register t_def *df;
|
|
||||||
{
|
{
|
||||||
register t_type *tp = df->df_type;
|
register t_type *tp = df->df_type;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
19
lang/m2/comp/stab.h
Normal file
19
lang/m2/comp/stab.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
* Created on: 2019-02-27
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef STAB_H_
|
||||||
|
#define STAB_H_
|
||||||
|
/* D E B U G G E R S Y M B O L T A B L E */
|
||||||
|
|
||||||
|
typedef struct type t_type;
|
||||||
|
typedef struct def t_def;
|
||||||
|
|
||||||
|
void stb_addtp(char *s, t_type *tp);
|
||||||
|
void stb_string(register t_def *df, int kind);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* STAB_H_ */
|
|
@ -11,15 +11,16 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <em_arith.h>
|
#include "em_arith.h"
|
||||||
#include <em_label.h>
|
#include "em_label.h"
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
#include "error.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
|
||||||
static int loopcount = 0; /* Count nested loops */
|
static int loopcount = 0; /* Count nested loops */
|
||||||
|
|
26
lang/m2/comp/tmpvar.h
Normal file
26
lang/m2/comp/tmpvar.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
* Created on: 2019-02-27
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* T E M P O R A R Y V A R I A B L E S */
|
||||||
|
#ifndef TMPVAR_H_
|
||||||
|
#define TMPVAR_H_
|
||||||
|
|
||||||
|
#include "em_arith.h"
|
||||||
|
|
||||||
|
typedef struct scope t_scope;
|
||||||
|
|
||||||
|
void TmpOpen(t_scope *sc);
|
||||||
|
arith TmpSpace(arith sz, int al);
|
||||||
|
arith NewInt(void);
|
||||||
|
arith NewPtr(void);
|
||||||
|
void FreeInt(arith off);
|
||||||
|
void FreePtr(arith off);
|
||||||
|
void TmpClose(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* TMPVAR_H_ */
|
|
@ -16,7 +16,7 @@
|
||||||
have local variabes.
|
have local variabes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
|
#include "tmpvar.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
struct tmpvar {
|
struct tmpvar {
|
||||||
|
@ -45,16 +46,14 @@ static t_scope *ProcScope; /* scope of procedure in which the
|
||||||
temporaries are allocated
|
temporaries are allocated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TmpOpen(sc) t_scope *sc;
|
void TmpOpen(t_scope *sc)
|
||||||
{
|
{
|
||||||
/* Initialize for temporaries in scope "sc".
|
/* Initialize for temporaries in scope "sc".
|
||||||
*/
|
*/
|
||||||
ProcScope = sc;
|
ProcScope = sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
arith
|
arith TmpSpace(arith sz, int al)
|
||||||
TmpSpace(sz, al)
|
|
||||||
arith sz;
|
|
||||||
{
|
{
|
||||||
register t_scope *sc = ProcScope;
|
register t_scope *sc = ProcScope;
|
||||||
|
|
||||||
|
@ -62,10 +61,7 @@ TmpSpace(sz, al)
|
||||||
return sc->sc_off;
|
return sc->sc_off;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC arith
|
static arith NewTmp(struct tmpvar **plist, arith sz, int al, int regtype)
|
||||||
NewTmp(plist, sz, al, regtype)
|
|
||||||
register struct tmpvar **plist;
|
|
||||||
arith sz;
|
|
||||||
{
|
{
|
||||||
register arith offset;
|
register arith offset;
|
||||||
register struct tmpvar *tmp;
|
register struct tmpvar *tmp;
|
||||||
|
@ -83,22 +79,18 @@ NewTmp(plist, sz, al, regtype)
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
arith
|
arith NewInt(void)
|
||||||
NewInt()
|
|
||||||
{
|
{
|
||||||
return NewTmp(&TmpInts, int_size, int_align, reg_any);
|
return NewTmp(&TmpInts, int_size, int_align, reg_any);
|
||||||
}
|
}
|
||||||
|
|
||||||
arith
|
arith NewPtr(void)
|
||||||
NewPtr()
|
|
||||||
{
|
{
|
||||||
return NewTmp(&TmpPtrs, pointer_size, pointer_align, reg_pointer);
|
return NewTmp(&TmpPtrs, pointer_size, pointer_align, reg_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
|
||||||
FreeTmp(plist, off)
|
static void FreeTmp(struct tmpvar **plist, arith off)
|
||||||
struct tmpvar **plist;
|
|
||||||
arith off;
|
|
||||||
{
|
{
|
||||||
register struct tmpvar *tmp = new_tmpvar();
|
register struct tmpvar *tmp = new_tmpvar();
|
||||||
|
|
||||||
|
@ -107,19 +99,17 @@ FreeTmp(plist, off)
|
||||||
*plist = tmp;
|
*plist = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeInt(off)
|
void FreeInt(arith off)
|
||||||
arith off;
|
|
||||||
{
|
{
|
||||||
FreeTmp(&TmpInts, off);
|
FreeTmp(&TmpInts, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
FreePtr(off)
|
void FreePtr(arith off)
|
||||||
arith off;
|
|
||||||
{
|
{
|
||||||
FreeTmp(&TmpPtrs, off);
|
FreeTmp(&TmpPtrs, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
TmpClose()
|
void TmpClose(void)
|
||||||
{
|
{
|
||||||
register struct tmpvar *tmp, *tmp1;
|
register struct tmpvar *tmp, *tmp1;
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,11 @@
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "tokenname.h"
|
#include "tokenname.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
/* To centralize the declaration of %tokens, their presence in this
|
/* To centralize the declaration of %tokens, their presence in this
|
||||||
file is taken as their declaration. The Makefile will produce
|
file is taken as their declaration. The Makefile will produce
|
||||||
|
@ -98,8 +99,7 @@ struct tokenname tkstandard[] = { /* standard identifiers */
|
||||||
|
|
||||||
/* Some routines to handle tokennames */
|
/* Some routines to handle tokennames */
|
||||||
|
|
||||||
reserve(resv)
|
void reserve(register struct tokenname *resv)
|
||||||
register struct tokenname *resv;
|
|
||||||
{
|
{
|
||||||
/* The names of the tokens described in resv are entered
|
/* The names of the tokens described in resv are entered
|
||||||
as reserved words.
|
as reserved words.
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -25,7 +25,12 @@
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
|
#include "error.h"
|
||||||
#include "walk.h"
|
#include "walk.h"
|
||||||
|
#include "lookup.h"
|
||||||
|
#include "stab.h"
|
||||||
|
#include "enter.h"
|
||||||
|
#include "typequiv.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "chk_expr.h"
|
#include "chk_expr.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
|
@ -73,12 +78,8 @@ t_type
|
||||||
*std_type,
|
*std_type,
|
||||||
*error_type;
|
*error_type;
|
||||||
|
|
||||||
void ArraySizes();
|
|
||||||
|
|
||||||
t_type *
|
t_type *construct_type(int fund, register t_type *tp)
|
||||||
construct_type(fund, tp)
|
|
||||||
int fund;
|
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* fund must be a type constructor.
|
/* fund must be a type constructor.
|
||||||
The pointer to the constructed type is returned.
|
The pointer to the constructed type is returned.
|
||||||
|
@ -117,10 +118,10 @@ construct_type(fund, tp)
|
||||||
return dtp;
|
return dtp;
|
||||||
}
|
}
|
||||||
|
|
||||||
arith
|
/* Aligns "pos" to the specified alignment "al"
|
||||||
align(pos, al)
|
* and returns the aligned "pos".
|
||||||
arith pos;
|
*/
|
||||||
int al;
|
arith align(arith pos, int al)
|
||||||
{
|
{
|
||||||
int i = pos % al;
|
int i = pos % al;
|
||||||
|
|
||||||
|
@ -128,11 +129,7 @@ align(pos, al)
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_type *
|
t_type *standard_type(int fund, int algn, arith size)
|
||||||
standard_type(fund, algn, size)
|
|
||||||
int fund;
|
|
||||||
int algn;
|
|
||||||
arith size;
|
|
||||||
{
|
{
|
||||||
register t_type *tp = new_type();
|
register t_type *tp = new_type();
|
||||||
|
|
||||||
|
@ -146,10 +143,8 @@ standard_type(fund, algn, size)
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitTypes()
|
void InitTypes(void)
|
||||||
{
|
{
|
||||||
/* Initialize the predefined types
|
|
||||||
*/
|
|
||||||
register t_type *tp;
|
register t_type *tp;
|
||||||
|
|
||||||
/* first, do some checking
|
/* first, do some checking
|
||||||
|
@ -221,17 +216,12 @@ InitTypes()
|
||||||
void_type = error_type;
|
void_type = error_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int fit(arith sz, int nbytes)
|
||||||
fit(sz, nbytes)
|
|
||||||
arith sz;
|
|
||||||
{
|
{
|
||||||
return ((sz) + ((arith)0x80<<(((nbytes)-1)*8)) & ~full_mask[(nbytes)]) == 0;
|
return ((sz) + ((arith)0x80<<(((nbytes)-1)*8)) & ~full_mask[(nbytes)]) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
static void u_small(register t_type *tp, arith n)
|
||||||
u_small(tp, n)
|
|
||||||
register t_type *tp;
|
|
||||||
arith n;
|
|
||||||
{
|
{
|
||||||
if (ufit(n, 1)) {
|
if (ufit(n, 1)) {
|
||||||
tp->tp_size = 1;
|
tp->tp_size = 1;
|
||||||
|
@ -243,9 +233,7 @@ u_small(tp, n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_type *
|
t_type *enum_type(t_node *EnumList)
|
||||||
enum_type(EnumList)
|
|
||||||
t_node *EnumList;
|
|
||||||
{
|
{
|
||||||
register t_type *tp =
|
register t_type *tp =
|
||||||
standard_type(T_ENUMERATION, int_align, int_size);
|
standard_type(T_ENUMERATION, int_align, int_size);
|
||||||
|
@ -258,9 +246,7 @@ enum_type(EnumList)
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_type *
|
t_type *qualified_type(t_node **pnd)
|
||||||
qualified_type(pnd)
|
|
||||||
t_node **pnd;
|
|
||||||
{
|
{
|
||||||
register t_def *df;
|
register t_def *df;
|
||||||
|
|
||||||
|
@ -296,26 +282,18 @@ node_error(nd, "identifier \"%s\" is not a type", df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int chk_bounds(arith l1, arith l2, int fund)
|
||||||
chk_bounds(l1, l2, fund)
|
|
||||||
arith l1, l2;
|
|
||||||
{
|
{
|
||||||
/* compare to arith's, but be careful. They might be unsigned
|
|
||||||
*/
|
|
||||||
if (fund == T_INTEGER) {
|
if (fund == T_INTEGER) {
|
||||||
return l2 >= l1;
|
return l2 >= l1;
|
||||||
}
|
}
|
||||||
return (unsigned arith) l2 >= (unsigned arith) l1;
|
return (unsigned arith) l2 >= (unsigned arith) l1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int in_range(arith i, register t_type *tp)
|
||||||
in_range(i, tp)
|
|
||||||
arith i;
|
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* Check that the value i fits in the subrange or enumeration
|
|
||||||
type tp. Return 1 if so, 0 otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch(tp->tp_fund) {
|
switch(tp->tp_fund) {
|
||||||
case T_ENUMERATION:
|
case T_ENUMERATION:
|
||||||
|
@ -330,16 +308,8 @@ in_range(i, tp)
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
t_type *
|
t_type *subr_type(t_node *lb, t_node *ub, t_type *base)
|
||||||
subr_type(lb, ub, base)
|
|
||||||
register t_node *lb;
|
|
||||||
t_node *ub;
|
|
||||||
t_type *base;
|
|
||||||
{
|
{
|
||||||
/* Construct a subrange type from the constant expressions
|
|
||||||
indicated by "lb" and "ub", but first perform some
|
|
||||||
checks. "base" is either a user-specified base-type, or NULL.
|
|
||||||
*/
|
|
||||||
register t_type *tp = BaseType(lb->nd_type);
|
register t_type *tp = BaseType(lb->nd_type);
|
||||||
register t_type *res;
|
register t_type *res;
|
||||||
|
|
||||||
|
@ -428,11 +398,7 @@ subr_type(lb, ub, base)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_type *
|
t_type *proc_type(t_type *result_type, t_param *parameters, arith n_bytes_params)
|
||||||
proc_type(result_type, parameters, n_bytes_params)
|
|
||||||
t_type *result_type;
|
|
||||||
t_param *parameters;
|
|
||||||
arith n_bytes_params;
|
|
||||||
{
|
{
|
||||||
register t_type *tp = construct_type(T_PROCEDURE, result_type);
|
register t_type *tp = construct_type(T_PROCEDURE, result_type);
|
||||||
|
|
||||||
|
@ -447,8 +413,7 @@ proc_type(result_type, parameters, n_bytes_params)
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
genrck(tp)
|
void genrck(register t_type *tp)
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* generate a range check descriptor for type "tp" when
|
/* generate a range check descriptor for type "tp" when
|
||||||
neccessary. Return its label.
|
neccessary. Return its label.
|
||||||
|
@ -483,13 +448,8 @@ genrck(tp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getbounds(tp, plo, phi)
|
void getbounds(register t_type *tp, arith *plo, arith *phi)
|
||||||
register t_type *tp;
|
|
||||||
arith *plo, *phi;
|
|
||||||
{
|
{
|
||||||
/* Get the bounds of a bounded type
|
|
||||||
*/
|
|
||||||
|
|
||||||
assert(bounded(tp));
|
assert(bounded(tp));
|
||||||
|
|
||||||
if (tp->tp_fund == T_SUBRANGE) {
|
if (tp->tp_fund == T_SUBRANGE) {
|
||||||
|
@ -502,13 +462,9 @@ getbounds(tp, plo, phi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_type *
|
t_type *set_type(register t_type *tp)
|
||||||
set_type(tp)
|
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* Construct a set type with base type "tp", but first
|
|
||||||
perform some checks
|
|
||||||
*/
|
|
||||||
arith lb, ub, diff, alloc_size;
|
arith lb, ub, diff, alloc_size;
|
||||||
|
|
||||||
if (! bounded(tp) || tp->tp_size > word_size) {
|
if (! bounded(tp) || tp->tp_size > word_size) {
|
||||||
|
@ -542,8 +498,7 @@ set_type(tp)
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayElSize(tp)
|
void ArrayElSize(register t_type *tp)
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* Align element size to alignment requirement of element type.
|
/* Align element size to alignment requirement of element type.
|
||||||
Also make sure that its size is either a dividor of the word_size,
|
Also make sure that its size is either a dividor of the word_size,
|
||||||
|
@ -569,9 +524,7 @@ ArrayElSize(tp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ArraySizes(register t_type *tp)
|
||||||
ArraySizes(tp)
|
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* Assign sizes to an array type, and check index type
|
/* Assign sizes to an array type, and check index type
|
||||||
*/
|
*/
|
||||||
|
@ -610,8 +563,7 @@ ArraySizes(tp)
|
||||||
C_rom_cst(tp->arr_elsize);
|
C_rom_cst(tp->arr_elsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeType(tp)
|
void FreeType(register t_type *tp)
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* Release type structures indicated by "tp".
|
/* Release type structures indicated by "tp".
|
||||||
This procedure is only called for types, constructed with
|
This procedure is only called for types, constructed with
|
||||||
|
@ -632,10 +584,7 @@ FreeType(tp)
|
||||||
free_type(tp);
|
free_type(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclareType(nd, df, tp)
|
void DeclareType(t_node *nd, register t_def *df, register t_type *tp)
|
||||||
register t_def *df;
|
|
||||||
register t_type *tp;
|
|
||||||
t_node *nd;
|
|
||||||
{
|
{
|
||||||
/* A type with type-description "tp" is declared and must
|
/* A type with type-description "tp" is declared and must
|
||||||
be bound to definition "df".
|
be bound to definition "df".
|
||||||
|
@ -677,8 +626,7 @@ DeclareType(nd, df, tp)
|
||||||
SolveForwardTypeRefs(df);
|
SolveForwardTypeRefs(df);
|
||||||
}
|
}
|
||||||
|
|
||||||
SolveForwardTypeRefs(df)
|
void SolveForwardTypeRefs(register t_def *df)
|
||||||
register t_def *df;
|
|
||||||
{
|
{
|
||||||
register t_node *nd;
|
register t_node *nd;
|
||||||
|
|
||||||
|
@ -700,8 +648,7 @@ SolveForwardTypeRefs(df)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ForceForwardTypeDef(df)
|
void ForceForwardTypeDef(register t_def *df)
|
||||||
register t_def *df;
|
|
||||||
{
|
{
|
||||||
register t_def *df1 = df, *df2;
|
register t_def *df1 = df, *df2;
|
||||||
register t_node *nd = df->df_forw_node;
|
register t_node *nd = df->df_forw_node;
|
||||||
|
@ -735,18 +682,14 @@ ForceForwardTypeDef(df)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t_type *
|
t_type *RemoveEqual(register t_type *tpx)
|
||||||
RemoveEqual(tpx)
|
|
||||||
register t_type *tpx;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
if (tpx) while (tpx->tp_fund == T_EQUAL) tpx = tpx->tp_next;
|
if (tpx) while (tpx->tp_fund == T_EQUAL) tpx = tpx->tp_next;
|
||||||
return tpx;
|
return tpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int type_or_forward(t_type *tp)
|
||||||
type_or_forward(tp)
|
|
||||||
t_type *tp;
|
|
||||||
{
|
{
|
||||||
/* POINTER TO IDENTIFIER construction. The IDENTIFIER resides
|
/* POINTER TO IDENTIFIER construction. The IDENTIFIER resides
|
||||||
in "dot". This routine handles the different cases.
|
in "dot". This routine handles the different cases.
|
||||||
|
@ -809,9 +752,7 @@ type_or_forward(tp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int gcd(int m, int n)
|
||||||
gcd(m, n)
|
|
||||||
register int m, n;
|
|
||||||
{
|
{
|
||||||
/* Greatest Common Divisor
|
/* Greatest Common Divisor
|
||||||
*/
|
*/
|
||||||
|
@ -825,18 +766,14 @@ gcd(m, n)
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int lcm(int m, int n)
|
||||||
lcm(m, n)
|
|
||||||
int m, n;
|
|
||||||
{
|
{
|
||||||
/* Least Common Multiple
|
/* Least Common Multiple
|
||||||
*/
|
*/
|
||||||
return m * (n / gcd(m, n));
|
return m * (n / gcd(m, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
t_type *
|
t_type *intorcard(register t_type *left, register t_type *right)
|
||||||
intorcard(left, right)
|
|
||||||
register t_type *left, *right;
|
|
||||||
{
|
{
|
||||||
if (left->tp_fund == T_INTORCARD) {
|
if (left->tp_fund == T_INTORCARD) {
|
||||||
t_type *tmp = left;
|
t_type *tmp = left;
|
||||||
|
@ -852,8 +789,7 @@ intorcard(left, right)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DumpType(tp)
|
void DumpType(register t_type *tp)
|
||||||
register t_type *tp;
|
|
||||||
{
|
{
|
||||||
if (!tp) return;
|
if (!tp) return;
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,17 @@
|
||||||
*
|
*
|
||||||
* Author: Ceriel J.H. Jacobs
|
* Author: Ceriel J.H. Jacobs
|
||||||
*/
|
*/
|
||||||
|
#ifndef TYPE_H_
|
||||||
|
#define TYPE_H_
|
||||||
|
|
||||||
/* T Y P E D E S C R I P T O R S T R U C T U R E */
|
/* T Y P E D E S C R I P T O R S T R U C T U R E */
|
||||||
|
|
||||||
/* $Id$ */
|
#include "em_arith.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct def t_def;
|
||||||
|
typedef struct node t_node;
|
||||||
|
|
||||||
struct paramlist { /* structure for parameterlist of a PROCEDURE */
|
struct paramlist { /* structure for parameterlist of a PROCEDURE */
|
||||||
struct paramlist *par_next;
|
struct paramlist *par_next;
|
||||||
|
@ -189,19 +196,7 @@ extern unsigned int
|
||||||
extern arith
|
extern arith
|
||||||
ret_area_size;
|
ret_area_size;
|
||||||
|
|
||||||
extern arith
|
|
||||||
align(); /* type.c */
|
|
||||||
|
|
||||||
extern t_type
|
|
||||||
*construct_type(),
|
|
||||||
*standard_type(),
|
|
||||||
*set_type(),
|
|
||||||
*subr_type(),
|
|
||||||
*proc_type(),
|
|
||||||
*enum_type(),
|
|
||||||
*qualified_type(),
|
|
||||||
*intorcard(),
|
|
||||||
*RemoveEqual(); /* All from type.c */
|
|
||||||
|
|
||||||
#define NULLTYPE ((t_type *) 0)
|
#define NULLTYPE ((t_type *) 0)
|
||||||
|
|
||||||
|
@ -240,3 +235,59 @@ extern arith max_int[];
|
||||||
extern arith min_int[];
|
extern arith min_int[];
|
||||||
|
|
||||||
#define ufit(n, i) (((n) & ~full_mask[(i)]) == 0)
|
#define ufit(n, i) (((n) & ~full_mask[(i)]) == 0)
|
||||||
|
|
||||||
|
/* Forward declarations. */
|
||||||
|
|
||||||
|
/* Initialize predefined types. */
|
||||||
|
void InitTypes(void);
|
||||||
|
/* Compare arith's, and return 1 if "l2" is
|
||||||
|
* greater or equal than "l1", otherwise returns 0.
|
||||||
|
* Takes into account that arith might be unsigned. */
|
||||||
|
int chk_bounds(arith l1, arith l2, int fund);
|
||||||
|
/* Aligns "pos" to the specified alignment "al" and returns the
|
||||||
|
aligned "pos".
|
||||||
|
*/
|
||||||
|
arith align(arith pos, int al);
|
||||||
|
/* Create a new standard type "fund" with specified
|
||||||
|
alignment "algn" and "size" bytes. */
|
||||||
|
t_type *standard_type(int fund, int algn, arith size);
|
||||||
|
t_type *enum_type(t_node *EnumList);
|
||||||
|
t_type *construct_type(int fund, register t_type *tp);
|
||||||
|
t_type *qualified_type(t_node **pnd);
|
||||||
|
/* Check that the value "i" fits in the subrange or enumeration
|
||||||
|
type "tp". Return 1 if so, 0 otherwise
|
||||||
|
*/
|
||||||
|
int in_range(arith i, register t_type *tp);
|
||||||
|
/* Construct a subrange type from the constant expressions
|
||||||
|
indicated by "lb" and "ub", but first perform some
|
||||||
|
checks. "base" is either a user-specified base-type, or NULL.
|
||||||
|
*/
|
||||||
|
t_type *subr_type(t_node *lb, t_node *ub, t_type *base);
|
||||||
|
t_type *proc_type(t_type *result_type, t_param *parameters, arith n_bytes_params);
|
||||||
|
void genrck(register t_type *tp);
|
||||||
|
/* Get the bounds of a bounded type. */
|
||||||
|
void getbounds(register t_type *tp, arith *plo, arith *phi);
|
||||||
|
/* Construct a set type with base type "tp", but first
|
||||||
|
* perform some checks */
|
||||||
|
t_type *set_type(register t_type *tp);
|
||||||
|
void ArrayElSize(register t_type *tp);
|
||||||
|
void ArraySizes(register t_type *tp);
|
||||||
|
void FreeType(register t_type *tp);
|
||||||
|
void DeclareType(t_node *nd, register t_def *df, register t_type *tp);
|
||||||
|
void SolveForwardTypeRefs(register t_def *df);
|
||||||
|
void ForceForwardTypeDef(register t_def *df);
|
||||||
|
t_type *RemoveEqual(register t_type *tpx);
|
||||||
|
int type_or_forward(t_type *tp);
|
||||||
|
t_type *intorcard(register t_type *left, register t_type *right);
|
||||||
|
#ifdef DEBUG
|
||||||
|
void DumpType(register t_type *tp);
|
||||||
|
#endif
|
||||||
|
int fit(arith sz, int nbytes);
|
||||||
|
/* Greatest common divisotr. */
|
||||||
|
int gcd(int m, int n);
|
||||||
|
/* Least common multiple. */
|
||||||
|
int lcm(int m, int n);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* TYPE_H_ */
|
|
@ -12,41 +12,40 @@
|
||||||
/* Routines for testing type equivalence, type compatibility, and
|
/* Routines for testing type equivalence, type compatibility, and
|
||||||
assignment compatibility
|
assignment compatibility
|
||||||
*/
|
*/
|
||||||
#include "parameters.h"
|
#include "parameters.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
#include <em_label.h>
|
#include <em_label.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "typequiv.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "stab.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "chk_expr.h"
|
||||||
|
|
||||||
extern char *sprint();
|
|
||||||
|
|
||||||
int
|
static int TstTypeEquiv(t_type *tp1, t_type *tp2)
|
||||||
TstTypeEquiv(tp1, tp2)
|
|
||||||
t_type *tp1, *tp2;
|
|
||||||
{
|
{
|
||||||
/* test if two types are equivalent.
|
/* test if two types are equivalent.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return tp1 == tp2
|
return (tp1 == tp2) ||
|
||||||
||
|
(tp1 == error_type) ||
|
||||||
tp1 == error_type
|
(tp2 == error_type);
|
||||||
||
|
|
||||||
tp2 == error_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int TstParEquiv(register t_type *tp1, register t_type *tp2)
|
||||||
TstParEquiv(tp1, tp2)
|
|
||||||
register t_type *tp1, *tp2;
|
|
||||||
{
|
{
|
||||||
/* test if two parameter types are equivalent. This routine
|
/* test if two parameter types are equivalent. This routine
|
||||||
is used to check if two different procedure declarations
|
is used to check if two different procedure declarations
|
||||||
|
@ -67,9 +66,7 @@ TstParEquiv(tp1, tp2)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int TstProcEquiv(t_type *tp1, t_type *tp2)
|
||||||
TstProcEquiv(tp1, tp2)
|
|
||||||
t_type *tp1, *tp2;
|
|
||||||
{
|
{
|
||||||
/* Test if two procedure types are equivalent. This routine
|
/* Test if two procedure types are equivalent. This routine
|
||||||
may also be used for the testing of assignment compatibility
|
may also be used for the testing of assignment compatibility
|
||||||
|
@ -99,9 +96,7 @@ TstProcEquiv(tp1, tp2)
|
||||||
return p1 == p2;
|
return p1 == p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int TstCompat(register t_type *tp1, register t_type *tp2)
|
||||||
TstCompat(tp1, tp2)
|
|
||||||
register t_type *tp1, *tp2;
|
|
||||||
{
|
{
|
||||||
/* test if two types are compatible. See section 6.3 of the
|
/* test if two types are compatible. See section 6.3 of the
|
||||||
Modula-2 Report for a definition of "compatible".
|
Modula-2 Report for a definition of "compatible".
|
||||||
|
@ -138,9 +133,7 @@ TstCompat(tp1, tp2)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int TstAssCompat(register t_type *tp1, register t_type *tp2)
|
||||||
TstAssCompat(tp1, tp2)
|
|
||||||
register t_type *tp1, *tp2;
|
|
||||||
{
|
{
|
||||||
/* Test if two types are assignment compatible.
|
/* Test if two types are assignment compatible.
|
||||||
See Def 9.1.
|
See Def 9.1.
|
||||||
|
@ -177,9 +170,7 @@ TstAssCompat(tp1, tp2)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *incompat(register t_type *tp1, register t_type *tp2)
|
||||||
incompat(tp1, tp2)
|
|
||||||
register t_type *tp1, *tp2;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
if (tp1->tp_fund == T_HIDDEN || tp2->tp_fund == T_HIDDEN) {
|
if (tp1->tp_fund == T_HIDDEN || tp2->tp_fund == T_HIDDEN) {
|
||||||
|
@ -188,11 +179,7 @@ incompat(tp1, tp2)
|
||||||
return "type incompatibility";
|
return "type incompatibility";
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int TstParCompat(int parno, register t_type *formaltype, int VARflag, t_node **nd, t_def *edf)
|
||||||
TstParCompat(parno, formaltype, VARflag, nd, edf)
|
|
||||||
register t_type *formaltype;
|
|
||||||
t_node **nd;
|
|
||||||
t_def *edf;
|
|
||||||
{
|
{
|
||||||
/* Check type compatibility for a parameter in a procedure call.
|
/* Check type compatibility for a parameter in a procedure call.
|
||||||
Assignment compatibility may do if the parameter is
|
Assignment compatibility may do if the parameter is
|
||||||
|
@ -268,11 +255,7 @@ TstParCompat(parno, formaltype, VARflag, nd, edf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CompatCheck(nd, tp, message, fc)
|
int CompatCheck(register t_node **nd, t_type *tp, char *message, int (*fc)())
|
||||||
register t_node **nd;
|
|
||||||
t_type *tp;
|
|
||||||
char *message;
|
|
||||||
int (*fc)();
|
|
||||||
{
|
{
|
||||||
if (! (*fc)(tp, (*nd)->nd_type)) {
|
if (! (*fc)(tp, (*nd)->nd_type)) {
|
||||||
if (message) {
|
if (message) {
|
||||||
|
@ -286,10 +269,7 @@ CompatCheck(nd, tp, message, fc)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChkAssCompat(nd, tp, message)
|
int ChkAssCompat(t_node **nd, t_type *tp, char *message)
|
||||||
t_node **nd;
|
|
||||||
t_type *tp;
|
|
||||||
char *message;
|
|
||||||
{
|
{
|
||||||
/* Check assignment compatibility of node "nd" with type "tp".
|
/* Check assignment compatibility of node "nd" with type "tp".
|
||||||
Give an error message when it fails
|
Give an error message when it fails
|
||||||
|
@ -301,10 +281,7 @@ ChkAssCompat(nd, tp, message)
|
||||||
return CompatCheck(nd, tp, message, TstAssCompat);
|
return CompatCheck(nd, tp, message, TstAssCompat);
|
||||||
}
|
}
|
||||||
|
|
||||||
ChkCompat(nd, tp, message)
|
int ChkCompat(t_node **nd, t_type *tp, char *message)
|
||||||
t_node **nd;
|
|
||||||
t_type *tp;
|
|
||||||
char *message;
|
|
||||||
{
|
{
|
||||||
/* Check compatibility of node "nd" with type "tp".
|
/* Check compatibility of node "nd" with type "tp".
|
||||||
Give an error message when it fails
|
Give an error message when it fails
|
||||||
|
|
25
lang/m2/comp/typequiv.h
Normal file
25
lang/m2/comp/typequiv.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
* Created on: 2019-02-25
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef TYPEQUIV_H_
|
||||||
|
#define TYPEQUIV_H_
|
||||||
|
|
||||||
|
typedef struct type t_type;
|
||||||
|
typedef struct node t_node;
|
||||||
|
typedef struct def t_def;
|
||||||
|
|
||||||
|
int TstProcEquiv(t_type *tp1, t_type *tp2);
|
||||||
|
int TstCompat(register t_type *tp1, register t_type *tp2);
|
||||||
|
int TstAssCompat(register t_type *tp1, register t_type *tp2);
|
||||||
|
int TstParCompat(int parno, register t_type *formaltype, int VARflag, t_node **nd, t_def *edf);
|
||||||
|
|
||||||
|
int ChkCompat(t_node **nd, t_type *tp, char *message);
|
||||||
|
int ChkAssCompat(t_node **nd, t_type *tp, char *message);
|
||||||
|
|
||||||
|
char *incompat(register t_type *tp1, register t_type *tp2);
|
||||||
|
|
||||||
|
#endif /* TYPEQUIV_H_ */
|
|
@ -35,16 +35,19 @@
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "desig.h"
|
#include "desig.h"
|
||||||
|
#include "typequiv.h"
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "chk_expr.h"
|
#include "chk_expr.h"
|
||||||
#include "walk.h"
|
#include "walk.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "tmpvar.h"
|
||||||
|
#include "stab.h"
|
||||||
|
#include "code.h"
|
||||||
#include "warning.h"
|
#include "warning.h"
|
||||||
|
|
||||||
extern arith NewPtr();
|
int CaseCode(t_node *, label, int);
|
||||||
extern arith NewInt();
|
|
||||||
extern arith TmpSpace();
|
|
||||||
|
|
||||||
extern int proclevel;
|
extern int proclevel;
|
||||||
extern int gdb_flag;
|
extern int gdb_flag;
|
||||||
|
@ -58,13 +61,8 @@ static t_type* func_type;
|
||||||
static t_node* priority;
|
static t_node* priority;
|
||||||
static int oldlineno;
|
static int oldlineno;
|
||||||
|
|
||||||
static int RegisterMessage();
|
|
||||||
static int WalkDef();
|
|
||||||
#ifdef DBSYMTAB
|
|
||||||
static int stabdef();
|
|
||||||
#endif
|
|
||||||
static int MkCalls();
|
|
||||||
static void UseWarnings();
|
|
||||||
|
|
||||||
#define NO_EXIT_LABEL ((label)0)
|
#define NO_EXIT_LABEL ((label)0)
|
||||||
#define RETURN_LABEL ((label)1)
|
#define RETURN_LABEL ((label)1)
|
||||||
|
@ -72,13 +70,18 @@ static void UseWarnings();
|
||||||
#define REACH_FLAG 1
|
#define REACH_FLAG 1
|
||||||
#define EXIT_FLAG 2
|
#define EXIT_FLAG 2
|
||||||
|
|
||||||
void DoAssign();
|
/* Forward declarations. */
|
||||||
|
static void WalkDef(register t_def*);
|
||||||
|
static void MkCalls(register t_def*);
|
||||||
|
static void UseWarnings(register t_def*);
|
||||||
|
static void RegisterMessage(register t_def*);
|
||||||
|
static void WalkDefList(register t_def*, void (*proc)(t_def*));
|
||||||
|
#ifdef DBSYMTAB
|
||||||
|
static void stabdef(t_def*);
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
|
||||||
LblWalkNode(lbl, nd, exit, reach)
|
int LblWalkNode(label lbl, t_node *nd, int exit, int reach)
|
||||||
label lbl,
|
|
||||||
exit;
|
|
||||||
t_node* nd;
|
|
||||||
{
|
{
|
||||||
/* Generate code for node "nd", after generating instruction
|
/* Generate code for node "nd", after generating instruction
|
||||||
label "lbl". "exit" is the exit label for the closest
|
label "lbl". "exit" is the exit label for the closest
|
||||||
|
@ -91,8 +94,7 @@ t_node* nd;
|
||||||
|
|
||||||
static arith tmpprio;
|
static arith tmpprio;
|
||||||
|
|
||||||
STATIC
|
static void DoPriority(void)
|
||||||
DoPriority()
|
|
||||||
{
|
{
|
||||||
/* For the time being (???), handle priorities by calls to
|
/* For the time being (???), handle priorities by calls to
|
||||||
the runtime system
|
the runtime system
|
||||||
|
@ -107,8 +109,7 @@ DoPriority()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
static void EndPriority(void)
|
||||||
EndPriority()
|
|
||||||
{
|
{
|
||||||
if (priority)
|
if (priority)
|
||||||
{
|
{
|
||||||
|
@ -118,8 +119,7 @@ EndPriority()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def_ilb(l)
|
void def_ilb(label l)
|
||||||
label l;
|
|
||||||
{
|
{
|
||||||
/* Instruction label definition. Forget about line number.
|
/* Instruction label definition. Forget about line number.
|
||||||
*/
|
*/
|
||||||
|
@ -127,10 +127,8 @@ def_ilb(l)
|
||||||
oldlineno = 0;
|
oldlineno = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoLineno(nd) register t_node* nd;
|
void DoLineno(register t_node* nd)
|
||||||
{
|
{
|
||||||
/* Generate line number information, if necessary.
|
|
||||||
*/
|
|
||||||
if ((!options['L']
|
if ((!options['L']
|
||||||
#ifdef DBSYMTAB
|
#ifdef DBSYMTAB
|
||||||
|| options['g']
|
|| options['g']
|
||||||
|
@ -156,13 +154,8 @@ DoLineno(nd) register t_node* nd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DoFilename(needed)
|
void DoFilename(int needed)
|
||||||
{
|
{
|
||||||
/* Generate filename information, when needed.
|
|
||||||
This routine is called at the generation of a
|
|
||||||
procedure entry, and after generating a call to
|
|
||||||
another procedure.
|
|
||||||
*/
|
|
||||||
static label filename_label = 0;
|
static label filename_label = 0;
|
||||||
|
|
||||||
oldlineno = 0; /* always invalidate remembered line number */
|
oldlineno = 0; /* always invalidate remembered line number */
|
||||||
|
@ -180,12 +173,8 @@ DoFilename(needed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkModule(module) register t_def* module;
|
void WalkModule(register t_def* module)
|
||||||
{
|
{
|
||||||
/* Walk through a module, and all its local definitions.
|
|
||||||
Also generate code for its body.
|
|
||||||
This code is collected in an initialization routine.
|
|
||||||
*/
|
|
||||||
register t_scope* sc;
|
register t_scope* sc;
|
||||||
t_scopelist* savevis = CurrVis;
|
t_scopelist* savevis = CurrVis;
|
||||||
|
|
||||||
|
@ -284,11 +273,9 @@ WalkModule(module) register t_def* module;
|
||||||
WalkDefList(sc->sc_def, UseWarnings);
|
WalkDefList(sc->sc_def, UseWarnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkProcedure(procedure) register t_def* procedure;
|
void WalkProcedure(register t_def* procedure)
|
||||||
{
|
{
|
||||||
/* Walk through the definition of a procedure and all its
|
|
||||||
local definitions, checking and generating code.
|
|
||||||
*/
|
|
||||||
t_scopelist* savevis = CurrVis;
|
t_scopelist* savevis = CurrVis;
|
||||||
register t_type* tp;
|
register t_type* tp;
|
||||||
register t_param* param;
|
register t_param* param;
|
||||||
|
@ -574,10 +561,10 @@ WalkProcedure(procedure) register t_def* procedure;
|
||||||
WalkDefList(procscope->sc_def, UseWarnings);
|
WalkDefList(procscope->sc_def, UseWarnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WalkDef(df) register t_def* df;
|
/* Walk through a list of definitions */
|
||||||
|
static void WalkDef(register t_def* df)
|
||||||
{
|
{
|
||||||
/* Walk through a list of definitions
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (df->df_kind)
|
switch (df->df_kind)
|
||||||
{
|
{
|
||||||
|
@ -602,10 +589,10 @@ static WalkDef(df) register t_def* df;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static MkCalls(df) register t_def* df;
|
/* Generate calls to initialization routines of modules */
|
||||||
|
static void MkCalls(register t_def* df)
|
||||||
{
|
{
|
||||||
/* Generate calls to initialization routines of modules
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (df->df_kind == D_MODULE)
|
if (df->df_kind == D_MODULE)
|
||||||
{
|
{
|
||||||
|
@ -614,14 +601,8 @@ static MkCalls(df) register t_def* df;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkLink(nd, exit_label, end_reached) register t_node* nd;
|
int WalkLink(register t_node* nd, label exit_label, int end_reached)
|
||||||
label exit_label;
|
|
||||||
{
|
{
|
||||||
/* Walk node "nd", which is a link.
|
|
||||||
"exit_label" is set to a label number when inside a LOOP.
|
|
||||||
"end_reached" maintains info about reachability (REACH_FLAG),
|
|
||||||
and whether an EXIT statement was seen (EXIT_FLAG).
|
|
||||||
*/
|
|
||||||
|
|
||||||
while (nd && nd->nd_class == Link)
|
while (nd && nd->nd_class == Link)
|
||||||
{ /* statement list */
|
{ /* statement list */
|
||||||
|
@ -632,8 +613,7 @@ label exit_label;
|
||||||
return WalkNode(nd, exit_label, end_reached);
|
return WalkNode(nd, exit_label, end_reached);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
static void ForLoopVarExpr(register t_node* nd)
|
||||||
ForLoopVarExpr(nd) register t_node* nd;
|
|
||||||
{
|
{
|
||||||
register t_type* tp = nd->nd_type;
|
register t_type* tp = nd->nd_type;
|
||||||
|
|
||||||
|
@ -641,12 +621,9 @@ ForLoopVarExpr(nd) register t_node* nd;
|
||||||
CodeCoercion(tp, BaseType(tp));
|
CodeCoercion(tp, BaseType(tp));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int WalkStat(register t_node* nd, label exit_label, int end_reached)
|
||||||
WalkStat(nd, exit_label, end_reached) register t_node* nd;
|
|
||||||
label exit_label;
|
|
||||||
{
|
{
|
||||||
/* Walk through a statement, generating code for it.
|
|
||||||
*/
|
|
||||||
register t_node* left = nd->nd_LEFT;
|
register t_node* left = nd->nd_LEFT;
|
||||||
register t_node* right = nd->nd_RIGHT;
|
register t_node* right = nd->nd_RIGHT;
|
||||||
|
|
||||||
|
@ -940,9 +917,8 @@ label exit_label;
|
||||||
return end_reached;
|
return end_reached;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int NodeCrash();
|
|
||||||
|
|
||||||
int (*WalkTable[])() = {
|
int (*WalkTable[])(t_node*, label, int) = {
|
||||||
NodeCrash,
|
NodeCrash,
|
||||||
NodeCrash,
|
NodeCrash,
|
||||||
NodeCrash,
|
NodeCrash,
|
||||||
|
@ -960,12 +936,9 @@ int (*WalkTable[])() = {
|
||||||
|
|
||||||
extern t_desig null_desig;
|
extern t_desig null_desig;
|
||||||
|
|
||||||
ExpectBool(pnd, true_label, false_label) register t_node** pnd;
|
void ExpectBool(register t_node** pnd, label true_label, label false_label)
|
||||||
label true_label, false_label;
|
|
||||||
{
|
{
|
||||||
/* "pnd" must indicate a boolean expression. Check this and
|
|
||||||
generate code to evaluate the expression.
|
|
||||||
*/
|
|
||||||
t_desig ds;
|
t_desig ds;
|
||||||
|
|
||||||
ds = null_desig;
|
ds = null_desig;
|
||||||
|
@ -980,13 +953,8 @@ label true_label, false_label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int WalkDesignator(t_node** pnd, t_desig* ds, int flags)
|
||||||
WalkDesignator(pnd, ds, flags)
|
|
||||||
t_node** pnd;
|
|
||||||
t_desig* ds;
|
|
||||||
{
|
{
|
||||||
/* Check designator and generate code for it
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!ChkVariable(pnd, flags))
|
if (!ChkVariable(pnd, flags))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -996,8 +964,7 @@ t_desig* ds;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoForInit(nd)
|
int DoForInit(t_node* nd)
|
||||||
t_node* nd;
|
|
||||||
{
|
{
|
||||||
register t_node* right = nd->nd_RIGHT;
|
register t_node* right = nd->nd_RIGHT;
|
||||||
register t_def* df;
|
register t_def* df;
|
||||||
|
@ -1074,8 +1041,8 @@ DoForInit(nd)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
DoAssign(nd) register t_node* nd;
|
void DoAssign(register t_node* nd)
|
||||||
{
|
{
|
||||||
/* May we do it in this order (expression first) ???
|
/* May we do it in this order (expression first) ???
|
||||||
The reference manual sais nothing about it, but the book does:
|
The reference manual sais nothing about it, but the book does:
|
||||||
|
@ -1111,7 +1078,7 @@ void
|
||||||
CodeMove(&dsr, nd->nd_LEFT, tp);
|
CodeMove(&dsr, nd->nd_LEFT, tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterMessage(df) register t_def* df;
|
static void RegisterMessage(register t_def* df)
|
||||||
{
|
{
|
||||||
register t_type* tp;
|
register t_type* tp;
|
||||||
|
|
||||||
|
@ -1140,11 +1107,7 @@ static RegisterMessage(df) register t_def* df;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void df_warning(t_node* nd, t_def* df, char* warning)
|
||||||
df_warning(nd, df, warning)
|
|
||||||
t_node* nd;
|
|
||||||
t_def* df;
|
|
||||||
char* warning;
|
|
||||||
{
|
{
|
||||||
if (!(df->df_kind & (D_VARIABLE | D_PROCEDURE | D_TYPE | D_CONST | D_PROCHEAD)))
|
if (!(df->df_kind & (D_VARIABLE | D_PROCEDURE | D_TYPE | D_CONST | D_PROCHEAD)))
|
||||||
{
|
{
|
||||||
|
@ -1160,8 +1123,7 @@ char* warning;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void UseWarnings(register t_def* df)
|
||||||
UseWarnings(df) register t_def* df;
|
|
||||||
{
|
{
|
||||||
t_node* nd = df->df_scope->sc_end;
|
t_node* nd = df->df_scope->sc_end;
|
||||||
|
|
||||||
|
@ -1208,8 +1170,7 @@ static void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkDefList(df, proc) register t_def* df;
|
static void WalkDefList(register t_def* df, void (*proc)(t_def*))
|
||||||
int (*proc)();
|
|
||||||
{
|
{
|
||||||
for (; df; df = df->df_nextinscope)
|
for (; df; df = df->df_nextinscope)
|
||||||
{
|
{
|
||||||
|
@ -1218,9 +1179,7 @@ int (*proc)();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DBSYMTAB
|
#ifdef DBSYMTAB
|
||||||
static int
|
static void stabdef(t_def* df)
|
||||||
stabdef(df)
|
|
||||||
t_def* df;
|
|
||||||
{
|
{
|
||||||
switch (df->df_kind)
|
switch (df->df_kind)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,17 +4,22 @@
|
||||||
*
|
*
|
||||||
* Author: Ceriel J.H. Jacobs
|
* Author: Ceriel J.H. Jacobs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* P A R S E T R E E W A L K E R */
|
/* P A R S E T R E E W A L K E R */
|
||||||
|
#ifndef WALK_H_
|
||||||
|
#define WALK_H_
|
||||||
|
|
||||||
/* $Id$ */
|
#include "em_label.h"
|
||||||
|
|
||||||
|
/* Forward type declarations. */
|
||||||
|
typedef struct node t_node;
|
||||||
|
typedef struct def t_def;
|
||||||
|
typedef struct desig t_desig;
|
||||||
|
|
||||||
/* Definition of WalkNode macro
|
/* Definition of WalkNode macro
|
||||||
*/
|
*/
|
||||||
|
extern int (*WalkTable[])(t_node*, label, int);
|
||||||
|
|
||||||
extern int (*WalkTable[])();
|
#define WalkNode(xnd, xlab, rch) (*WalkTable[(unsigned int)((xnd)->nd_class)])((xnd), (xlab),(rch))
|
||||||
|
|
||||||
#define WalkNode(xnd, xlab, rch) (*WalkTable[(xnd)->nd_class])((xnd), (xlab),(rch))
|
|
||||||
|
|
||||||
extern label text_label;
|
extern label text_label;
|
||||||
extern label data_label;
|
extern label data_label;
|
||||||
|
@ -25,3 +30,46 @@ extern label data_label;
|
||||||
#define CAL(nm, sz) (C_cal(nm), C_asp((arith)(sz)))
|
#define CAL(nm, sz) (C_cal(nm), C_asp((arith)(sz)))
|
||||||
#define c_bra(x) C_bra((label) (x))
|
#define c_bra(x) C_bra((label) (x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int LblWalkNode(label lbl, t_node *nd, int exit, int reach);
|
||||||
|
void def_ilb(label l);
|
||||||
|
/* Generate line information as necessary for "nd". */
|
||||||
|
void DoLineno(register t_node* nd);
|
||||||
|
/* Generate filename information, when needed.
|
||||||
|
This routine is called at the generation of a
|
||||||
|
procedure entry, and after generating a call to
|
||||||
|
another procedure. The current active filename
|
||||||
|
is used.
|
||||||
|
*/
|
||||||
|
void DoFilename(int needed);
|
||||||
|
|
||||||
|
/* Walk through a module, and all its local definitions.
|
||||||
|
Also generate code for its body.
|
||||||
|
This code is collected in an initialization routine.
|
||||||
|
*/
|
||||||
|
void WalkModule(register t_def* module);
|
||||||
|
/* Walk through the definition of a procedure and all its
|
||||||
|
local definitions, checking and generating code.
|
||||||
|
*/
|
||||||
|
void WalkProcedure(register t_def* procedure);
|
||||||
|
|
||||||
|
/* Walk node "nd", which is a link.
|
||||||
|
"exit_label" is set to a label number when inside a LOOP.
|
||||||
|
"end_reached" maintains info about reachability (REACH_FLAG),
|
||||||
|
and whether an EXIT statement was seen (EXIT_FLAG).
|
||||||
|
*/
|
||||||
|
int WalkLink(register t_node* nd, label exit_label, int end_reached);
|
||||||
|
/* Walk through a statement node "nd", generating code for it. */
|
||||||
|
int WalkStat(register t_node* nd, label exit_label, int end_reached);
|
||||||
|
/* Generate code to evaluate a boolean expression "pnd" */
|
||||||
|
void ExpectBool(register t_node** pnd, label true_label, label false_label);
|
||||||
|
/* Check designator and generate code for it */
|
||||||
|
int WalkDesignator(t_node** pnd, t_desig* ds, int flags);
|
||||||
|
|
||||||
|
void DoAssign(register t_node* nd);
|
||||||
|
|
||||||
|
int DoForInit(t_node* nd);
|
||||||
|
|
||||||
|
#endif /* WALK_H_ */
|
||||||
|
|
|
@ -1383,7 +1383,7 @@ int (*ExprChkTable[])(struct node*) =
|
||||||
NodeCrash
|
NodeCrash
|
||||||
};
|
};
|
||||||
|
|
||||||
int (*VarAccChkTable[])() =
|
int (*VarAccChkTable[])(struct node*) =
|
||||||
{
|
{
|
||||||
no_var_access,
|
no_var_access,
|
||||||
ChkLinkOrName,
|
ChkLinkOrName,
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
struct node;
|
struct node;
|
||||||
|
|
||||||
extern int (*ExprChkTable[])(); /* table of expression checking
|
extern int (*ExprChkTable[])(struct node*); /* table of expression checking
|
||||||
functions, indexed by node class
|
functions, indexed by node class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern int (*VarAccChkTable[])(); /* table of variable-access checking
|
extern int (*VarAccChkTable[])(struct node*); /* table of variable-access checking
|
||||||
functions, indexed by node class
|
functions, indexed by node class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue