many bug fixes
This commit is contained in:
parent
c967d1ab3a
commit
c3d4d40d1b
21 changed files with 480 additions and 398 deletions
|
@ -25,10 +25,10 @@ static char *RcsId = "$Header$";
|
||||||
|
|
||||||
long str2long();
|
long str2long();
|
||||||
|
|
||||||
struct token dot, aside;
|
struct token dot,
|
||||||
struct type *toktype;
|
aside;
|
||||||
struct string string;
|
struct type *toktype;
|
||||||
int idfsize = IDFSIZE;
|
int idfsize = IDFSIZE;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
extern int cntlines;
|
extern int cntlines;
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,10 +40,9 @@ SkipComment()
|
||||||
Note that comments may be nested (par. 3.5).
|
Note that comments may be nested (par. 3.5).
|
||||||
*/
|
*/
|
||||||
register int ch;
|
register int ch;
|
||||||
register int NestLevel = 0;
|
|
||||||
|
|
||||||
LoadChar(ch);
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
LoadChar(ch);
|
||||||
if (class(ch) == STNL) {
|
if (class(ch) == STNL) {
|
||||||
LineNumber++;
|
LineNumber++;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -52,32 +51,26 @@ SkipComment()
|
||||||
}
|
}
|
||||||
else if (ch == '(') {
|
else if (ch == '(') {
|
||||||
LoadChar(ch);
|
LoadChar(ch);
|
||||||
if (ch == '*') ++NestLevel;
|
if (ch == '*') SkipComment();
|
||||||
else continue;
|
|
||||||
}
|
}
|
||||||
else if (ch == '*') {
|
else if (ch == '*') {
|
||||||
LoadChar(ch);
|
LoadChar(ch);
|
||||||
if (ch == ')') {
|
if (ch == ')') break;
|
||||||
if (NestLevel-- == 0) return;
|
|
||||||
}
|
|
||||||
else continue;
|
|
||||||
}
|
}
|
||||||
LoadChar(ch);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC struct string *
|
||||||
GetString(upto)
|
GetString(upto)
|
||||||
{
|
{
|
||||||
/* Read a Modula-2 string, delimited by the character "upto".
|
/* Read a Modula-2 string, delimited by the character "upto".
|
||||||
*/
|
*/
|
||||||
register int ch;
|
register int ch;
|
||||||
register struct string *str = &string;
|
register struct string *str = (struct string *) Malloc(sizeof(struct string));
|
||||||
register char *p;
|
register char *p;
|
||||||
|
|
||||||
str->s_str = p = Malloc((unsigned int) (str->s_length = ISTRSIZE));
|
str->s_str = p = Malloc((unsigned int) (str->s_length = ISTRSIZE));
|
||||||
LoadChar(ch);
|
while (LoadChar(ch), ch != upto) {
|
||||||
while (ch != upto) {
|
|
||||||
if (class(ch) == STNL) {
|
if (class(ch) == STNL) {
|
||||||
lexerror("newline in string");
|
lexerror("newline in string");
|
||||||
LineNumber++;
|
LineNumber++;
|
||||||
|
@ -86,7 +79,7 @@ GetString(upto)
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ch == EOI) {
|
if (ch == EOI) {
|
||||||
lexerror("end-of-file in string");
|
lexerror("end-of-file in string");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -97,10 +90,10 @@ GetString(upto)
|
||||||
p = str->s_str + str->s_length;
|
p = str->s_str + str->s_length;
|
||||||
str->s_length += RSTRSIZE;
|
str->s_length += RSTRSIZE;
|
||||||
}
|
}
|
||||||
LoadChar(ch);
|
|
||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
str->s_length = p - str->s_str;
|
str->s_length = p - str->s_str;
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -131,15 +124,15 @@ again:
|
||||||
|
|
||||||
switch (class(ch)) {
|
switch (class(ch)) {
|
||||||
|
|
||||||
case STSKIP:
|
|
||||||
goto again;
|
|
||||||
|
|
||||||
case STNL:
|
case STNL:
|
||||||
LineNumber++;
|
LineNumber++;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cntlines++;
|
cntlines++;
|
||||||
#endif
|
#endif
|
||||||
tk->tk_lineno++;
|
tk->tk_lineno++;
|
||||||
|
/* Fall Through */
|
||||||
|
|
||||||
|
case STSKIP:
|
||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
case STGARB:
|
case STGARB:
|
||||||
|
@ -172,15 +165,13 @@ again:
|
||||||
if (nch == '.') {
|
if (nch == '.') {
|
||||||
return tk->tk_symb = UPTO;
|
return tk->tk_symb = UPTO;
|
||||||
}
|
}
|
||||||
PushBack(nch);
|
break;
|
||||||
return tk->tk_symb = ch;
|
|
||||||
|
|
||||||
case ':':
|
case ':':
|
||||||
if (nch == '=') {
|
if (nch == '=') {
|
||||||
return tk->tk_symb = BECOMES;
|
return tk->tk_symb = BECOMES;
|
||||||
}
|
}
|
||||||
PushBack(nch);
|
break;
|
||||||
return tk->tk_symb = ch;
|
|
||||||
|
|
||||||
case '<':
|
case '<':
|
||||||
if (nch == '=') {
|
if (nch == '=') {
|
||||||
|
@ -190,50 +181,52 @@ again:
|
||||||
lexwarning("'<>' is old-fashioned; use '#'");
|
lexwarning("'<>' is old-fashioned; use '#'");
|
||||||
return tk->tk_symb = '#';
|
return tk->tk_symb = '#';
|
||||||
}
|
}
|
||||||
PushBack(nch);
|
break;
|
||||||
return tk->tk_symb = ch;
|
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
if (nch == '=') {
|
if (nch == '=') {
|
||||||
return tk->tk_symb = GREATEREQUAL;
|
return tk->tk_symb = GREATEREQUAL;
|
||||||
}
|
}
|
||||||
PushBack(nch);
|
break;
|
||||||
return tk->tk_symb = ch;
|
|
||||||
|
|
||||||
default :
|
default :
|
||||||
crash("(LLlex, STCOMP)");
|
crash("(LLlex, STCOMP)");
|
||||||
}
|
}
|
||||||
|
PushBack(nch);
|
||||||
|
return tk->tk_symb = ch;
|
||||||
|
|
||||||
case STIDF:
|
case STIDF:
|
||||||
{
|
{
|
||||||
register char *tg = &buf[0];
|
register char *tag = &buf[0];
|
||||||
register struct idf *id;
|
register struct idf *id;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (tg - buf < idfsize) *tg++ = ch;
|
if (tag - buf < idfsize) *tag++ = ch;
|
||||||
LoadChar(ch);
|
LoadChar(ch);
|
||||||
} while(in_idf(ch));
|
} while(in_idf(ch));
|
||||||
|
|
||||||
if (ch != EOI) PushBack(ch);
|
if (ch != EOI) PushBack(ch);
|
||||||
*tg++ = '\0';
|
*tag++ = '\0';
|
||||||
|
|
||||||
tk->TOK_IDF = id = str2idf(buf, 1);
|
tk->TOK_IDF = id = str2idf(buf, 1);
|
||||||
return tk->tk_symb = id->id_reserved ? id->id_reserved : IDENT;
|
return tk->tk_symb = id->id_reserved ? id->id_reserved : IDENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
case STSTR:
|
case STSTR: {
|
||||||
GetString(ch);
|
register struct string *str = GetString(ch);
|
||||||
if (string.s_length == 1) {
|
|
||||||
tk->TOK_INT = *(string.s_str) & 0377;
|
if (str->s_length == 1) {
|
||||||
|
tk->TOK_INT = *(str->s_str) & 0377;
|
||||||
toktype = char_type;
|
toktype = char_type;
|
||||||
|
free(str->s_str);
|
||||||
|
free((char *) str);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tk->tk_data.tk_str = (struct string *)
|
tk->tk_data.tk_str = str;
|
||||||
Malloc(sizeof (struct string));
|
toktype = standard_type(T_STRING, 1, str->s_length);
|
||||||
*(tk->tk_data.tk_str) = string;
|
|
||||||
toktype = standard_type(T_STRING, 1, string.s_length);
|
|
||||||
}
|
}
|
||||||
return tk->tk_symb = STRING;
|
return tk->tk_symb = STRING;
|
||||||
|
}
|
||||||
|
|
||||||
case STNUM:
|
case STNUM:
|
||||||
{
|
{
|
||||||
|
@ -241,172 +234,157 @@ again:
|
||||||
is that we don't know the base in advance so we
|
is that we don't know the base in advance so we
|
||||||
have to read the number with the help of a rather
|
have to read the number with the help of a rather
|
||||||
complex finite automaton.
|
complex finite automaton.
|
||||||
Excuses for the very ugly code!
|
|
||||||
*/
|
*/
|
||||||
|
enum statetp {Oct,Hex,Dec,OctEndOrHex,End,OptReal,Real};
|
||||||
|
register enum statetp state;
|
||||||
|
register int base;
|
||||||
register char *np = &buf[1];
|
register char *np = &buf[1];
|
||||||
/* allow a '-' to be added */
|
/* allow a '-' to be added */
|
||||||
|
|
||||||
buf[0] = '-';
|
buf[0] = '-';
|
||||||
*np++ = ch;
|
*np++ = ch;
|
||||||
|
state = is_oct(ch) ? Oct : Dec;
|
||||||
LoadChar(ch);
|
LoadChar(ch);
|
||||||
while (is_oct(ch)) {
|
for (;;) {
|
||||||
if (np < &buf[NUMSIZE]) {
|
switch(state) {
|
||||||
*np++ = ch;
|
case Oct:
|
||||||
}
|
while (is_oct(ch)) {
|
||||||
LoadChar(ch);
|
if (np < &buf[NUMSIZE]) *np++ = ch;
|
||||||
}
|
LoadChar(ch);
|
||||||
switch (ch) {
|
|
||||||
case 'H':
|
|
||||||
Shex: *np++ = '\0';
|
|
||||||
tk->TOK_INT = str2long(&buf[1], 16);
|
|
||||||
if (tk->TOK_INT >= 0 && tk->TOK_INT <= max_int) {
|
|
||||||
toktype = intorcard_type;
|
|
||||||
}
|
|
||||||
else toktype = card_type;
|
|
||||||
return tk->tk_symb = INTEGER;
|
|
||||||
|
|
||||||
case '8':
|
|
||||||
case '9':
|
|
||||||
do {
|
|
||||||
if (np < &buf[NUMSIZE]) {
|
|
||||||
*np++ = ch;
|
|
||||||
}
|
}
|
||||||
LoadChar(ch);
|
if (ch == 'B' || ch == 'C') {
|
||||||
} while (is_dig(ch));
|
base = 8;
|
||||||
|
state = OctEndOrHex;
|
||||||
if (is_hex(ch))
|
break;
|
||||||
goto S2;
|
|
||||||
if (ch == 'H')
|
|
||||||
goto Shex;
|
|
||||||
if (ch == '.')
|
|
||||||
goto Sreal;
|
|
||||||
PushBack(ch);
|
|
||||||
goto Sdec;
|
|
||||||
|
|
||||||
case 'B':
|
|
||||||
case 'C':
|
|
||||||
if (np < &buf[NUMSIZE]) {
|
|
||||||
*np++ = ch;
|
|
||||||
}
|
|
||||||
LoadChar(ch);
|
|
||||||
if (ch == 'H')
|
|
||||||
goto Shex;
|
|
||||||
if (is_hex(ch))
|
|
||||||
goto S2;
|
|
||||||
PushBack(ch);
|
|
||||||
ch = *--np;
|
|
||||||
*np++ = '\0';
|
|
||||||
tk->TOK_INT = str2long(&buf[1], 8);
|
|
||||||
if (ch == 'C') {
|
|
||||||
toktype = char_type;
|
|
||||||
if (tk->TOK_INT < 0 || tk->TOK_INT > 255) {
|
|
||||||
lexwarning("Character constant out of range");
|
|
||||||
}
|
}
|
||||||
}
|
/* Fall Through */
|
||||||
else if (tk->TOK_INT >= 0 && tk->TOK_INT <= max_int) {
|
case Dec:
|
||||||
toktype = intorcard_type;
|
base = 10;
|
||||||
}
|
while (is_dig(ch)) {
|
||||||
else toktype = card_type;
|
|
||||||
return tk->tk_symb = INTEGER;
|
|
||||||
|
|
||||||
case 'A':
|
|
||||||
case 'D':
|
|
||||||
case 'E':
|
|
||||||
case 'F':
|
|
||||||
S2:
|
|
||||||
do {
|
|
||||||
if (np < &buf[NUMSIZE]) {
|
|
||||||
*np++ = ch;
|
|
||||||
}
|
|
||||||
LoadChar(ch);
|
|
||||||
} while (is_hex(ch));
|
|
||||||
if (ch != 'H') {
|
|
||||||
lexerror("H expected after hex number");
|
|
||||||
PushBack(ch);
|
|
||||||
}
|
|
||||||
goto Shex;
|
|
||||||
|
|
||||||
case '.':
|
|
||||||
Sreal:
|
|
||||||
/* This '.' could be the first of the '..'
|
|
||||||
token. At this point, we need a look-ahead
|
|
||||||
of two characters.
|
|
||||||
*/
|
|
||||||
LoadChar(ch);
|
|
||||||
if (ch == '.') {
|
|
||||||
/* Indeed the '..' token
|
|
||||||
*/
|
|
||||||
PushBack(ch);
|
|
||||||
PushBack(ch);
|
|
||||||
goto Sdec;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* a real constant */
|
|
||||||
if (np < &buf[NUMSIZE]) {
|
|
||||||
*np++ = '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_dig(ch)) {
|
|
||||||
/* Fractional part
|
|
||||||
*/
|
|
||||||
do {
|
|
||||||
if (np < &buf[NUMSIZE]) {
|
if (np < &buf[NUMSIZE]) {
|
||||||
*np++ = ch;
|
*np++ = ch;
|
||||||
}
|
}
|
||||||
LoadChar(ch);
|
LoadChar(ch);
|
||||||
|
}
|
||||||
|
if (is_hex(ch)) state = Hex;
|
||||||
|
else if (ch == '.') state = OptReal;
|
||||||
|
else {
|
||||||
|
state = End;
|
||||||
|
if (ch == 'H') base = 16;
|
||||||
|
else PushBack(ch);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Hex:
|
||||||
|
while (is_hex(ch)) {
|
||||||
|
if (np < &buf[NUMSIZE]) *np++ = ch;
|
||||||
|
LoadChar(ch);
|
||||||
|
}
|
||||||
|
base = 16;
|
||||||
|
state = End;
|
||||||
|
if (ch != 'H') {
|
||||||
|
lexerror("H expected after hex number");
|
||||||
|
PushBack(ch);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OctEndOrHex:
|
||||||
|
if (np < &buf[NUMSIZE]) *np++ = ch;
|
||||||
|
LoadChar(ch);
|
||||||
|
if (ch == 'H') {
|
||||||
|
base = 16;
|
||||||
|
state = End;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (is_hex(ch)) {
|
||||||
|
state = Hex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PushBack(ch);
|
||||||
|
ch = *--np;
|
||||||
|
*np++ = '\0';
|
||||||
|
base = 8;
|
||||||
|
/* Fall through */
|
||||||
|
|
||||||
|
case End:
|
||||||
|
*np++ = '\0';
|
||||||
|
tk->TOK_INT = str2long(&buf[1], base);
|
||||||
|
if (ch == 'C' && base == 8) {
|
||||||
|
toktype = char_type;
|
||||||
|
if (tk->TOK_INT<0 || tk->TOK_INT>255) {
|
||||||
|
lexwarning("Character constant out of range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tk->TOK_INT>=0 &&
|
||||||
|
tk->TOK_INT<=max_int) {
|
||||||
|
toktype = intorcard_type;
|
||||||
|
}
|
||||||
|
else toktype = card_type;
|
||||||
|
return tk->tk_symb = INTEGER;
|
||||||
|
|
||||||
|
case OptReal:
|
||||||
|
/* The '.' could be the first of the '..'
|
||||||
|
token. At this point, we need a
|
||||||
|
look-ahead of two characters.
|
||||||
|
*/
|
||||||
|
LoadChar(ch);
|
||||||
|
if (ch == '.') {
|
||||||
|
/* Indeed the '..' token
|
||||||
|
*/
|
||||||
|
PushBack(ch);
|
||||||
|
PushBack(ch);
|
||||||
|
state = End;
|
||||||
|
base = 10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
state = Real;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (state == Real) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* a real real constant */
|
||||||
|
if (np < &buf[NUMSIZE]) *np++ = '.';
|
||||||
|
|
||||||
|
while (is_dig(ch)) {
|
||||||
|
/* Fractional part
|
||||||
|
*/
|
||||||
|
if (np < &buf[NUMSIZE]) *np++ = ch;
|
||||||
|
LoadChar(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == 'E') {
|
||||||
|
/* Scale factor
|
||||||
|
*/
|
||||||
|
if (np < &buf[NUMSIZE]) *np++ = 'E';
|
||||||
|
LoadChar(ch);
|
||||||
|
if (ch == '+' || ch == '-') {
|
||||||
|
/* Signed scalefactor
|
||||||
|
*/
|
||||||
|
if (np < &buf[NUMSIZE]) *np++ = ch;
|
||||||
|
LoadChar(ch);
|
||||||
|
}
|
||||||
|
if (is_dig(ch)) {
|
||||||
|
do {
|
||||||
|
if (np < &buf[NUMSIZE]) *np++ = ch;
|
||||||
|
LoadChar(ch);
|
||||||
} while (is_dig(ch));
|
} while (is_dig(ch));
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if (ch == 'E') {
|
lexerror("bad scale factor");
|
||||||
/* Scale factor
|
|
||||||
*/
|
|
||||||
if (np < &buf[NUMSIZE]) {
|
|
||||||
*np++ = 'E';
|
|
||||||
}
|
|
||||||
LoadChar(ch);
|
|
||||||
if (ch == '+' || ch == '-') {
|
|
||||||
/* Signed scalefactor
|
|
||||||
*/
|
|
||||||
if (np < &buf[NUMSIZE]) {
|
|
||||||
*np++ = ch;
|
|
||||||
}
|
|
||||||
LoadChar(ch);
|
|
||||||
}
|
|
||||||
if (is_dig(ch)) {
|
|
||||||
do {
|
|
||||||
if (np < &buf[NUMSIZE]) {
|
|
||||||
*np++ = ch;
|
|
||||||
}
|
|
||||||
LoadChar(ch);
|
|
||||||
} while (is_dig(ch));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lexerror("bad scale factor");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PushBack(ch);
|
|
||||||
|
|
||||||
if (np == &buf[NUMSIZE + 1]) {
|
|
||||||
tk->TOK_REL = Salloc("0.0", 5);
|
|
||||||
lexerror("floating constant too long");
|
|
||||||
}
|
|
||||||
else tk->TOK_REL = Salloc(buf, np - buf) + 1;
|
|
||||||
toktype = real_type;
|
|
||||||
return tk->tk_symb = REAL;
|
|
||||||
|
|
||||||
default:
|
|
||||||
PushBack(ch);
|
|
||||||
Sdec:
|
|
||||||
*np++ = '\0';
|
|
||||||
tk->TOK_INT = str2long(&buf[1], 10);
|
|
||||||
if (tk->TOK_INT < 0 || tk->TOK_INT > max_int) {
|
|
||||||
toktype = card_type;
|
|
||||||
}
|
|
||||||
else toktype = intorcard_type;
|
|
||||||
return tk->tk_symb = INTEGER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PushBack(ch);
|
||||||
|
|
||||||
|
if (np >= &buf[NUMSIZE]) {
|
||||||
|
tk->TOK_REL = Salloc("0.0", 5);
|
||||||
|
lexerror("floating constant too long");
|
||||||
|
}
|
||||||
|
else tk->TOK_REL = Salloc(buf, np - buf) + 1;
|
||||||
|
toktype = real_type;
|
||||||
|
return tk->tk_symb = REAL;
|
||||||
|
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,17 @@
|
||||||
|
|
||||||
/* $Header$ */
|
/* $Header$ */
|
||||||
|
|
||||||
|
/* Structure to store a string constant
|
||||||
|
*/
|
||||||
struct string {
|
struct string {
|
||||||
arith s_length; /* length of a string */
|
arith s_length; /* length of a string */
|
||||||
char *s_str; /* the string itself */
|
char *s_str; /* the string itself */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Token structure. Keep it small, as it is part of a parse-tree node
|
||||||
|
*/
|
||||||
struct token {
|
struct token {
|
||||||
short tk_symb; /* token itself */
|
short tk_symb; /* token itself */
|
||||||
unsigned short tk_lineno; /* linenumber on which it occurred */
|
unsigned short tk_lineno; /* linenumber on which it occurred */
|
||||||
union {
|
union {
|
||||||
struct idf *tk_idf; /* IDENT */
|
struct idf *tk_idf; /* IDENT */
|
||||||
|
|
|
@ -20,12 +20,11 @@ static char *RcsId = "$Header$";
|
||||||
|
|
||||||
extern char *symbol2str();
|
extern char *symbol2str();
|
||||||
extern struct idf *gen_anon_idf();
|
extern struct idf *gen_anon_idf();
|
||||||
int err_occurred = 0;
|
extern int err_occurred;
|
||||||
|
|
||||||
LLmessage(tk)
|
LLmessage(tk)
|
||||||
int tk;
|
int tk;
|
||||||
{
|
{
|
||||||
++err_occurred;
|
|
||||||
if (tk) {
|
if (tk) {
|
||||||
/* if (tk != 0), it represents the token to be inserted.
|
/* if (tk != 0), it represents the token to be inserted.
|
||||||
otherwize, the current token is deleted
|
otherwize, the current token is deleted
|
||||||
|
|
|
@ -11,7 +11,7 @@ INCLUDES = -I$(MHDIR) -I$(EMDIR)/h -I$(PKGDIR)
|
||||||
LSRC = tokenfile.g program.g declar.g expression.g statement.g
|
LSRC = tokenfile.g program.g declar.g expression.g statement.g
|
||||||
CC = cc
|
CC = cc
|
||||||
LLGENOPTIONS =
|
LLGENOPTIONS =
|
||||||
PROFILE =
|
PROFILE =
|
||||||
CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC=
|
CFLAGS = $(PROFILE) $(INCLUDES) -DSTATIC=
|
||||||
LINTFLAGS = -DSTATIC= -DNORCSID
|
LINTFLAGS = -DSTATIC= -DNORCSID
|
||||||
LFLAGS = $(PROFILE)
|
LFLAGS = $(PROFILE)
|
||||||
|
@ -52,13 +52,13 @@ lint: Cfiles
|
||||||
@rm -f nmclash.o a.out
|
@rm -f nmclash.o a.out
|
||||||
|
|
||||||
mkdep: mkdep.o
|
mkdep: mkdep.o
|
||||||
$(CC) -o mkdep mkdep.o
|
$(CC) $(LFLAGS) -o mkdep mkdep.o
|
||||||
|
|
||||||
cclash: cclash.o
|
cclash: cclash.o
|
||||||
$(CC) -o cclash cclash.o
|
$(CC) $(LFLAGS) -o cclash cclash.o
|
||||||
|
|
||||||
cid: cid.o
|
cid: cid.o
|
||||||
$(CC) -o cid cid.o
|
$(CC) $(LFLAGS) -o cid cid.o
|
||||||
|
|
||||||
# entry points not to be used directly
|
# entry points not to be used directly
|
||||||
|
|
||||||
|
|
43
lang/m2/comp/Resolve
Executable file
43
lang/m2/comp/Resolve
Executable file
|
@ -0,0 +1,43 @@
|
||||||
|
case $# in
|
||||||
|
1)
|
||||||
|
;;
|
||||||
|
*) echo "$0: one argument expected" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case $1 in
|
||||||
|
main)
|
||||||
|
;;
|
||||||
|
Xlint)
|
||||||
|
;;
|
||||||
|
*) echo "$0: $1: Illegal argument" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
if test -d ../Xsrc
|
||||||
|
then
|
||||||
|
:
|
||||||
|
else mkdir ../Xsrc
|
||||||
|
fi
|
||||||
|
make cclash
|
||||||
|
make cid
|
||||||
|
./cclash -c -l7 `cat Cfiles` > clashes
|
||||||
|
sed '/^C_/d' < clashes > ../Xsrc/Xclashes
|
||||||
|
cd ../Xsrc
|
||||||
|
if cmp -s Xclashes clashes
|
||||||
|
then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
mv Xclashes clashes
|
||||||
|
fi
|
||||||
|
rm -f Makefile
|
||||||
|
for i in `cat ../src/Cfiles`
|
||||||
|
do
|
||||||
|
cat >> Makefile <<EOF
|
||||||
|
$i: clashes ../src/$i
|
||||||
|
../src/cid -Fclashes < ../src/$i > $i
|
||||||
|
|
||||||
|
EOF
|
||||||
|
done
|
||||||
|
make `cat ../src/Cfiles`
|
||||||
|
make -f ../src/Makefile $1
|
|
@ -64,7 +64,7 @@ ChkArrow(expp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
expp->nd_type = PointedtoType(tp);
|
expp->nd_type = RemoveEqual(PointedtoType(tp));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ ChkArr(expp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
expp->nd_type = tpl->arr_elem;
|
expp->nd_type = RemoveEqual(tpl->arr_elem);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ ChkLinkOrName(expp)
|
||||||
if (expp->nd_class == Name) {
|
if (expp->nd_class == Name) {
|
||||||
expp->nd_def = lookfor(expp, CurrVis, 1);
|
expp->nd_def = lookfor(expp, CurrVis, 1);
|
||||||
expp->nd_class = Def;
|
expp->nd_class = Def;
|
||||||
expp->nd_type = expp->nd_def->df_type;
|
expp->nd_type = RemoveEqual(expp->nd_def->df_type);
|
||||||
}
|
}
|
||||||
else if (expp->nd_class == Link) {
|
else if (expp->nd_class == Link) {
|
||||||
register struct node *left = expp->nd_left;
|
register struct node *left = expp->nd_left;
|
||||||
|
@ -161,7 +161,7 @@ ChkLinkOrName(expp)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
expp->nd_def = df;
|
expp->nd_def = df;
|
||||||
expp->nd_type = df->df_type;
|
expp->nd_type = RemoveEqual(df->df_type);
|
||||||
expp->nd_class = LinkDef;
|
expp->nd_class = LinkDef;
|
||||||
if (!(df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
|
if (!(df->df_flags & (D_EXPORTED|D_QEXPORTED))) {
|
||||||
/* Fields of a record are always D_QEXPORTED,
|
/* Fields of a record are always D_QEXPORTED,
|
||||||
|
@ -418,19 +418,17 @@ getarg(argp, bases, designator)
|
||||||
variable.
|
variable.
|
||||||
*/
|
*/
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
register struct node *arg = *argp;
|
register struct node *arg = (*argp)->nd_right;
|
||||||
register struct node *left;
|
register struct node *left;
|
||||||
|
|
||||||
if (! arg->nd_right) {
|
if (! arg) {
|
||||||
node_error(arg, "too few arguments supplied");
|
node_error(*argp, "too few arguments supplied");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg = arg->nd_right;
|
|
||||||
left = arg->nd_left;
|
left = arg->nd_left;
|
||||||
|
|
||||||
if ((!designator && !ChkExpression(left)) ||
|
if (designator ? !ChkVariable(left) : !ChkExpression(left)) {
|
||||||
(designator && !ChkVariable(left))) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,11 +436,12 @@ getarg(argp, bases, designator)
|
||||||
left->nd_def->df_flags |= D_NOREG;
|
left->nd_def->df_flags |= D_NOREG;
|
||||||
}
|
}
|
||||||
|
|
||||||
tp = BaseType(left->nd_type);
|
if (bases) {
|
||||||
|
tp = BaseType(left->nd_type);
|
||||||
if (bases && !(tp->tp_fund & bases)) {
|
if (!(tp->tp_fund & bases)) {
|
||||||
node_error(arg, "unexpected type");
|
node_error(arg, "unexpected type");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*argp = arg;
|
*argp = arg;
|
||||||
|
@ -489,14 +488,14 @@ ChkProcCall(expp)
|
||||||
|
|
||||||
left = expp->nd_left;
|
left = expp->nd_left;
|
||||||
arg = expp;
|
arg = expp;
|
||||||
expp->nd_type = ResultType(left->nd_type);
|
expp->nd_type = RemoveEqual(ResultType(left->nd_type));
|
||||||
|
|
||||||
for (param = ParamList(left->nd_type); param; param = param->next) {
|
for (param = ParamList(left->nd_type); param; param = param->next) {
|
||||||
if (!(left = getarg(&arg, 0, IsVarParam(param)))) return 0;
|
if (!(left = getarg(&arg, 0, IsVarParam(param)))) return 0;
|
||||||
if (left->nd_symb == STRING) {
|
if (left->nd_symb == STRING) {
|
||||||
TryToString(left, TypeOfParam(param));
|
TryToString(left, TypeOfParam(param));
|
||||||
}
|
}
|
||||||
if (! TstParCompat(TypeOfParam(param),
|
if (! TstParCompat(RemoveEqual(TypeOfParam(param)),
|
||||||
left->nd_type,
|
left->nd_type,
|
||||||
IsVarParam(param),
|
IsVarParam(param),
|
||||||
left)) {
|
left)) {
|
||||||
|
@ -689,15 +688,29 @@ node_error(expp, "IN operator: type of LHS not compatible with element type of R
|
||||||
}
|
}
|
||||||
|
|
||||||
allowed = AllowedTypes(expp->nd_symb);
|
allowed = AllowedTypes(expp->nd_symb);
|
||||||
if (!(tpl->tp_fund & allowed) ||
|
|
||||||
(tpl != bool_type && Boolean(expp->nd_symb))) {
|
/* Check that the application of the operator is allowed on the type
|
||||||
if (!(tpl->tp_fund == T_POINTER &&
|
of the operands.
|
||||||
(T_CARDINAL & allowed) &&
|
There are two tricky parts:
|
||||||
ChkAddress(tpl, tpr))) {
|
- Boolean operators are only allowed on boolean operands, but
|
||||||
|
the "allowed-mask" of "AllowedTypes" can only indicate
|
||||||
|
an enumeration type.
|
||||||
|
- All operations that are allowed on CARDINALS are also allowed
|
||||||
|
on ADDRESS.
|
||||||
|
*/
|
||||||
|
if (Boolean(expp->nd_symb) && tpl != bool_type) {
|
||||||
|
node_error(expp,"operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_symb));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!(tpl->tp_fund & allowed)) {
|
||||||
|
if (!(tpl->tp_fund == T_POINTER &&
|
||||||
|
(T_CARDINAL & allowed) &&
|
||||||
|
ChkAddress(tpl, tpr))) {
|
||||||
node_error(expp,"operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_symb));
|
node_error(expp,"operator \"%s\": illegal operand type(s)", symbol2str(expp->nd_symb));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
expp->nd_type = card_type;
|
if (expp->nd_type == card_type) expp->nd_type = address_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tpl->tp_fund == T_SET) {
|
if (tpl->tp_fund == T_SET) {
|
||||||
|
@ -1058,6 +1071,9 @@ TryToString(nd, tp)
|
||||||
{
|
{
|
||||||
/* Try a coercion from character constant to string.
|
/* Try a coercion from character constant to string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
assert(nd->nd_symb == STRING);
|
||||||
|
|
||||||
if (tp->tp_fund == T_ARRAY && nd->nd_type == char_type) {
|
if (tp->tp_fund == T_ARRAY && nd->nd_type == char_type) {
|
||||||
int ch = nd->nd_INT;
|
int ch = nd->nd_INT;
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,10 @@
|
||||||
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) ((unsigned)ch < 0177 && inidf[ch])
|
||||||
#define is_oct(ch) (isoct[ch])
|
#define is_oct(ch) ((unsigned)ch < 0177 && isoct[ch])
|
||||||
#define is_dig(ch) (isdig[ch])
|
#define is_dig(ch) ((unsigned)ch < 0177 && isdig[ch])
|
||||||
#define is_hex(ch) (ishex[ch])
|
#define is_hex(ch) ((unsigned)ch < 0177 && ishex[ch])
|
||||||
|
|
||||||
extern char tkclass[];
|
extern char tkclass[];
|
||||||
extern char inidf[], isoct[], isdig[], ishex[];
|
extern char inidf[], isoct[], isdig[], ishex[];
|
||||||
|
|
|
@ -55,7 +55,7 @@ CodeString(nd)
|
||||||
{
|
{
|
||||||
label lab;
|
label lab;
|
||||||
|
|
||||||
if (nd->nd_type == char_type) {
|
if (nd->nd_type->tp_fund != T_STRING) {
|
||||||
C_loc(nd->nd_INT);
|
C_loc(nd->nd_INT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -237,6 +237,7 @@ CodeCoercion(t1, t2)
|
||||||
case T_CHAR:
|
case T_CHAR:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
|
case T_EQUAL:
|
||||||
case T_INTORCARD:
|
case T_INTORCARD:
|
||||||
if (t2->tp_size > word_size) {
|
if (t2->tp_size > word_size) {
|
||||||
C_loc(word_size);
|
C_loc(word_size);
|
||||||
|
@ -353,7 +354,7 @@ CodeParameters(param, arg)
|
||||||
register struct type *tp;
|
register struct type *tp;
|
||||||
register struct node *left;
|
register struct node *left;
|
||||||
register struct type *left_type;
|
register struct type *left_type;
|
||||||
|
|
||||||
assert(param != 0 && arg != 0);
|
assert(param != 0 && arg != 0);
|
||||||
|
|
||||||
if (param->next) {
|
if (param->next) {
|
||||||
|
@ -406,7 +407,7 @@ CodeParameters(param, arg)
|
||||||
CodePadString(left, tp->tp_size);
|
CodePadString(left, tp->tp_size);
|
||||||
}
|
}
|
||||||
else CodePExpr(left);
|
else CodePExpr(left);
|
||||||
CheckAssign(left_type, tp);
|
RangeCheck(left_type, tp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +452,7 @@ CodeStd(nd)
|
||||||
|
|
||||||
case S_CHR:
|
case S_CHR:
|
||||||
CodePExpr(left);
|
CodePExpr(left);
|
||||||
CheckAssign(char_type, tp);
|
RangeCheck(char_type, tp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_FLOAT:
|
case S_FLOAT:
|
||||||
|
@ -489,7 +490,7 @@ CodeStd(nd)
|
||||||
|
|
||||||
case S_VAL:
|
case S_VAL:
|
||||||
CodePExpr(left);
|
CodePExpr(left);
|
||||||
CheckAssign(nd->nd_type, tp);
|
RangeCheck(nd->nd_type, tp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_ADR:
|
case S_ADR:
|
||||||
|
@ -510,7 +511,7 @@ CodeStd(nd)
|
||||||
if (tp->tp_fund == T_INTEGER) C_adi(word_size);
|
if (tp->tp_fund == T_INTEGER) C_adi(word_size);
|
||||||
else C_adu(word_size);
|
else C_adu(word_size);
|
||||||
}
|
}
|
||||||
CheckAssign(tp, int_type);
|
RangeCheck(tp, int_type);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CodeCoercion(int_type, tp);
|
CodeCoercion(int_type, tp);
|
||||||
|
@ -576,7 +577,7 @@ CodeAssign(nd, dss, dst)
|
||||||
C_blm(nd->nd_left->nd_type->tp_size);
|
C_blm(nd->nd_left->nd_type->tp_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckAssign(tpl, tpr)
|
RangeCheck(tpl, tpr)
|
||||||
register struct type *tpl, *tpr;
|
register struct type *tpl, *tpr;
|
||||||
{
|
{
|
||||||
/* Generate a range check if neccessary
|
/* Generate a range check if neccessary
|
||||||
|
@ -634,6 +635,7 @@ CodeOper(expr, true_label, false_label)
|
||||||
C_adf(tp->tp_size);
|
C_adf(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
|
case T_EQUAL:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
case T_INTORCARD:
|
case T_INTORCARD:
|
||||||
C_adu(tp->tp_size);
|
C_adu(tp->tp_size);
|
||||||
|
@ -655,6 +657,7 @@ CodeOper(expr, true_label, false_label)
|
||||||
C_sbf(tp->tp_size);
|
C_sbf(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
|
case T_EQUAL:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
case T_INTORCARD:
|
case T_INTORCARD:
|
||||||
C_sbu(tp->tp_size);
|
C_sbu(tp->tp_size);
|
||||||
|
@ -674,6 +677,7 @@ CodeOper(expr, true_label, false_label)
|
||||||
C_mli(tp->tp_size);
|
C_mli(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
|
case T_EQUAL:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
case T_INTORCARD:
|
case T_INTORCARD:
|
||||||
C_mlu(tp->tp_size);
|
C_mlu(tp->tp_size);
|
||||||
|
@ -708,6 +712,7 @@ CodeOper(expr, true_label, false_label)
|
||||||
C_dvi(tp->tp_size);
|
C_dvi(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
|
case T_EQUAL:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
case T_INTORCARD:
|
case T_INTORCARD:
|
||||||
C_dvu(tp->tp_size);
|
C_dvu(tp->tp_size);
|
||||||
|
@ -723,6 +728,7 @@ CodeOper(expr, true_label, false_label)
|
||||||
C_rmi(tp->tp_size);
|
C_rmi(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
|
case T_EQUAL:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
case T_INTORCARD:
|
case T_INTORCARD:
|
||||||
C_rmu(tp->tp_size);
|
C_rmu(tp->tp_size);
|
||||||
|
@ -744,8 +750,9 @@ CodeOper(expr, true_label, false_label)
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
C_cmi(tp->tp_size);
|
C_cmi(tp->tp_size);
|
||||||
break;
|
break;
|
||||||
case T_HIDDEN:
|
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
|
case T_EQUAL:
|
||||||
|
case T_HIDDEN:
|
||||||
case T_CARDINAL:
|
case T_CARDINAL:
|
||||||
case T_INTORCARD:
|
case T_INTORCARD:
|
||||||
C_cmu(tp->tp_size);
|
C_cmu(tp->tp_size);
|
||||||
|
|
|
@ -31,7 +31,7 @@ int return_occurred; /* set if a return occurred in a
|
||||||
ProcedureDeclaration
|
ProcedureDeclaration
|
||||||
{
|
{
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
struct def *df1;
|
struct def *df1; /* only exists because &df is illegal */
|
||||||
} :
|
} :
|
||||||
{ ++proclevel;
|
{ ++proclevel;
|
||||||
return_occurred = 0;
|
return_occurred = 0;
|
||||||
|
@ -53,9 +53,10 @@ error("function procedure %s does not return a value", df->df_idf->id_text);
|
||||||
ProcedureHeading(struct def **pdf; int type;)
|
ProcedureHeading(struct def **pdf; int type;)
|
||||||
{
|
{
|
||||||
struct paramlist *params = 0;
|
struct paramlist *params = 0;
|
||||||
struct type *tp = 0;
|
register struct type *tp;
|
||||||
|
struct type *tp1 = 0;
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
arith NBytesParams;
|
arith NBytesParams; /* parameter offset counter */
|
||||||
} :
|
} :
|
||||||
PROCEDURE IDENT
|
PROCEDURE IDENT
|
||||||
{ df = DeclProc(type);
|
{ df = DeclProc(type);
|
||||||
|
@ -64,8 +65,8 @@ ProcedureHeading(struct def **pdf; int type;)
|
||||||
}
|
}
|
||||||
else NBytesParams = 0;
|
else NBytesParams = 0;
|
||||||
}
|
}
|
||||||
FormalParameters(¶ms, &tp, &NBytesParams)?
|
FormalParameters(¶ms, &tp1, &NBytesParams)?
|
||||||
{ tp = construct_type(T_PROCEDURE, tp);
|
{ tp = construct_type(T_PROCEDURE, tp1);
|
||||||
tp->prc_params = params;
|
tp->prc_params = params;
|
||||||
tp->prc_nbpar = NBytesParams;
|
tp->prc_nbpar = NBytesParams;
|
||||||
if (df->df_type) {
|
if (df->df_type) {
|
||||||
|
@ -151,7 +152,7 @@ TypeDeclaration
|
||||||
struct def *df;
|
struct def *df;
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
}:
|
}:
|
||||||
IDENT { df = define(dot.TOK_IDF,CurrentScope,D_TYPE); }
|
IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
|
||||||
'=' type(&tp)
|
'=' type(&tp)
|
||||||
{ DeclareType(df, tp); }
|
{ DeclareType(df, tp); }
|
||||||
;
|
;
|
||||||
|
@ -398,9 +399,7 @@ node_error(nd1,"type incompatibility in case label");
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
SetType(struct type **ptp;)
|
SetType(struct type **ptp;) :
|
||||||
{
|
|
||||||
} :
|
|
||||||
SET OF SimpleType(ptp)
|
SET OF SimpleType(ptp)
|
||||||
{ *ptp = set_type(*ptp); }
|
{ *ptp = set_type(*ptp); }
|
||||||
;
|
;
|
||||||
|
@ -411,7 +410,6 @@ SetType(struct type **ptp;)
|
||||||
*/
|
*/
|
||||||
PointerType(struct type **ptp;)
|
PointerType(struct type **ptp;)
|
||||||
{
|
{
|
||||||
register struct def *df;
|
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
} :
|
} :
|
||||||
POINTER TO
|
POINTER TO
|
||||||
|
@ -422,10 +420,9 @@ PointerType(struct type **ptp;)
|
||||||
*/
|
*/
|
||||||
qualtype(&((*ptp)->next))
|
qualtype(&((*ptp)->next))
|
||||||
| %if ( nd = new_node(), nd->nd_token = dot,
|
| %if ( nd = new_node(), nd->nd_token = dot,
|
||||||
df = lookfor(nd, CurrVis, 0),
|
lookfor(nd, CurrVis, 0)->df_kind == D_MODULE)
|
||||||
df->df_kind == D_MODULE)
|
{ if (dot.tk_symb == IDENT) free_node(nd); }
|
||||||
type(&((*ptp)->next))
|
type(&((*ptp)->next))
|
||||||
{ free_node(nd); }
|
|
||||||
|
|
|
|
||||||
IDENT { Forward(nd, (*ptp)); }
|
IDENT { Forward(nd, (*ptp)); }
|
||||||
]
|
]
|
||||||
|
@ -436,11 +433,10 @@ qualtype(struct type **ptp;)
|
||||||
struct def *df;
|
struct def *df;
|
||||||
} :
|
} :
|
||||||
qualident(D_ISTYPE, &df, "type", (struct node **) 0)
|
qualident(D_ISTYPE, &df, "type", (struct node **) 0)
|
||||||
{ if (!df->df_type) {
|
{ if (!(*ptp = df->df_type)) {
|
||||||
error("type \"%s\" not declared", df->df_idf->id_text);
|
error("type \"%s\" not declared", df->df_idf->id_text);
|
||||||
*ptp = error_type;
|
*ptp = error_type;
|
||||||
}
|
}
|
||||||
else *ptp = df->df_type;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,8 @@ struct def { /* list of definitions for a name */
|
||||||
} df_value;
|
} df_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SetUsed(df) ((df)->df_flags |= D_USED)
|
||||||
|
|
||||||
/* ALLOCDEF "def" */
|
/* ALLOCDEF "def" */
|
||||||
|
|
||||||
extern struct def
|
extern struct def
|
||||||
|
|
|
@ -60,6 +60,7 @@ InitDef()
|
||||||
struct idf *gen_anon_idf();
|
struct idf *gen_anon_idf();
|
||||||
|
|
||||||
ill_df = MkDef(gen_anon_idf(), CurrentScope, D_ERROR);
|
ill_df = MkDef(gen_anon_idf(), CurrentScope, D_ERROR);
|
||||||
|
ill_df->df_type = error_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct def *
|
struct def *
|
||||||
|
@ -204,7 +205,6 @@ DeclProc(type)
|
||||||
sprint(buf,"%s_%s",CurrentScope->sc_name,df->df_idf->id_text);
|
sprint(buf,"%s_%s",CurrentScope->sc_name,df->df_idf->id_text);
|
||||||
df->for_name = Salloc(buf, (unsigned) (strlen(buf)+1));
|
df->for_name = Salloc(buf, (unsigned) (strlen(buf)+1));
|
||||||
if (CurrVis == Defined->mod_vis) C_exp(df->for_name);
|
if (CurrVis == Defined->mod_vis) C_exp(df->for_name);
|
||||||
open_scope(OPENSCOPE);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
df = lookup(dot.TOK_IDF, CurrentScope);
|
df = lookup(dot.TOK_IDF, CurrentScope);
|
||||||
|
|
|
@ -166,18 +166,17 @@ CodeFieldDesig(df, ds)
|
||||||
in "ds". "df" indicates the definition of the field.
|
in "ds". "df" indicates the definition of the field.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
register struct withdesig *wds;
|
|
||||||
|
|
||||||
if (ds->dsg_kind == DSG_INIT) {
|
if (ds->dsg_kind == DSG_INIT) {
|
||||||
/* In a WITH statement. We must find the designator in the
|
/* In a WITH statement. We must find the designator in the
|
||||||
WITH statement, and act as if the field is a selection
|
WITH statement, and act as if the field is a selection
|
||||||
of this designator.
|
of this designator.
|
||||||
So, first find the right WITH statement, which is the
|
So, first find the right WITH statement, which is the
|
||||||
first one of the proper record type.
|
first one of the proper record type, which is
|
||||||
Notice that the proper record type is recognized by its
|
recognized by its scope indication.
|
||||||
scope indication.
|
|
||||||
*/
|
*/
|
||||||
wds = WithDesigs;
|
register struct withdesig *wds = WithDesigs;
|
||||||
|
|
||||||
assert(wds != 0);
|
assert(wds != 0);
|
||||||
|
|
||||||
while (wds->w_scope != df->df_scope) {
|
while (wds->w_scope != df->df_scope) {
|
||||||
|
@ -225,7 +224,7 @@ CodeVarDesig(df, ds)
|
||||||
*/
|
*/
|
||||||
assert(ds->dsg_kind == DSG_INIT);
|
assert(ds->dsg_kind == DSG_INIT);
|
||||||
|
|
||||||
df->df_flags |= D_USED;
|
SetUsed(df);
|
||||||
if (df->var_addrgiven) {
|
if (df->var_addrgiven) {
|
||||||
/* the programmer specified an address in the declaration of
|
/* the programmer specified an address in the declaration of
|
||||||
the variable. Generate code to push the address.
|
the variable. Generate code to push the address.
|
||||||
|
@ -258,7 +257,9 @@ CodeVarDesig(df, ds)
|
||||||
C_lxa((arith) (proclevel - sc->sc_level));
|
C_lxa((arith) (proclevel - sc->sc_level));
|
||||||
if ((df->df_flags & D_VARPAR) ||
|
if ((df->df_flags & D_VARPAR) ||
|
||||||
IsConformantArray(df->df_type)) {
|
IsConformantArray(df->df_type)) {
|
||||||
/* var parameter
|
/* var parameter or conformant array.
|
||||||
|
For conformant array's, the address is
|
||||||
|
passed.
|
||||||
*/
|
*/
|
||||||
C_adp(df->var_off);
|
C_adp(df->var_off);
|
||||||
C_loi(pointer_size);
|
C_loi(pointer_size);
|
||||||
|
@ -297,7 +298,7 @@ CodeDesig(nd, ds)
|
||||||
case Def:
|
case Def:
|
||||||
df = nd->nd_def;
|
df = nd->nd_def;
|
||||||
|
|
||||||
df->df_flags |= D_USED;
|
SetUsed(df);
|
||||||
switch(df->df_kind) {
|
switch(df->df_kind) {
|
||||||
case D_FIELD:
|
case D_FIELD:
|
||||||
CodeFieldDesig(df, ds);
|
CodeFieldDesig(df, ds);
|
||||||
|
|
|
@ -172,6 +172,7 @@ EnterParamList(ppr, Idlist, type, VARp, off)
|
||||||
static struct paramlist *last;
|
static struct paramlist *last;
|
||||||
|
|
||||||
if (! idlist) {
|
if (! idlist) {
|
||||||
|
/* Can only happen when a procedure type is defined */
|
||||||
dummy = Idlist = idlist = MkLeaf(Name, &dot);
|
dummy = Idlist = idlist = MkLeaf(Name, &dot);
|
||||||
}
|
}
|
||||||
for ( ; idlist; idlist = idlist->next) {
|
for ( ; idlist; idlist = idlist->next) {
|
||||||
|
@ -182,7 +183,7 @@ EnterParamList(ppr, Idlist, type, VARp, off)
|
||||||
}
|
}
|
||||||
else last->next = pr;
|
else last->next = pr;
|
||||||
last = pr;
|
last = pr;
|
||||||
if (idlist != dummy) {
|
if (!DefinitionModule && idlist != dummy) {
|
||||||
df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE);
|
df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE);
|
||||||
df->var_off = *off;
|
df->var_off = *off;
|
||||||
}
|
}
|
||||||
|
@ -222,22 +223,20 @@ DoImport(df, scope)
|
||||||
if (df->df_kind == D_TYPE && df->df_type->tp_fund == T_ENUMERATION) {
|
if (df->df_kind == D_TYPE && df->df_type->tp_fund == T_ENUMERATION) {
|
||||||
/* Also import all enumeration literals
|
/* Also import all enumeration literals
|
||||||
*/
|
*/
|
||||||
df = df->df_type->enm_enums;
|
for (df = df->df_type->enm_enums; df; df = df->enm_next) {
|
||||||
while (df) {
|
|
||||||
define(df->df_idf, scope, D_IMPORT)->imp_def = df;
|
define(df->df_idf, scope, D_IMPORT)->imp_def = df;
|
||||||
df = df->enm_next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (df->df_kind == D_MODULE) {
|
else if (df->df_kind == D_MODULE) {
|
||||||
/* Also import all definitions that are exported from this
|
/* Also import all definitions that are exported from this
|
||||||
module
|
module
|
||||||
*/
|
*/
|
||||||
df = df->mod_vis->sc_scope->sc_def;
|
for (df = df->mod_vis->sc_scope->sc_def;
|
||||||
while (df) {
|
df;
|
||||||
|
df = df->df_nextinscope) {
|
||||||
if (df->df_flags & D_EXPORTED) {
|
if (df->df_flags & D_EXPORTED) {
|
||||||
define(df->df_idf,scope,D_IMPORT)->imp_def = df;
|
define(df->df_idf,scope,D_IMPORT)->imp_def = df;
|
||||||
}
|
}
|
||||||
df = df->df_nextinscope;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,18 +336,22 @@ idlist->nd_IDF->id_text);
|
||||||
scope. There are two legal possibilities,
|
scope. There are two legal possibilities,
|
||||||
which are examined below.
|
which are examined below.
|
||||||
*/
|
*/
|
||||||
if ((df1->df_kind == D_PROCHEAD &&
|
if (df1->df_kind == D_PROCHEAD &&
|
||||||
df->df_kind == D_PROCEDURE) ||
|
df->df_kind == D_PROCEDURE) {
|
||||||
(df1->df_kind == D_HIDDEN &&
|
|
||||||
df->df_kind == D_TYPE)) {
|
|
||||||
if (df->df_kind == D_TYPE &&
|
|
||||||
df->df_type->tp_fund != T_POINTER) {
|
|
||||||
node_error(idlist, "opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
|
||||||
}
|
|
||||||
df1->df_kind = D_IMPORT;
|
df1->df_kind = D_IMPORT;
|
||||||
df1->imp_def = df;
|
df1->imp_def = df;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (df1->df_kind == D_HIDDEN &&
|
||||||
|
df->df_kind == D_TYPE) {
|
||||||
|
if (df->df_type->tp_fund != T_POINTER) {
|
||||||
|
node_error(idlist, "opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
||||||
|
}
|
||||||
|
assert(df1->df_type->next == NULLTYPE);
|
||||||
|
df1->df_kind = D_TYPE;
|
||||||
|
df1->df_type->next = df->df_type;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DoImport(df, enclosing(CurrVis)->sc_scope);
|
DoImport(df, enclosing(CurrVis)->sc_scope);
|
||||||
|
|
|
@ -15,6 +15,7 @@ static char *RcsId = "$Header$";
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "LLlex.h"
|
#include "LLlex.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "type.h"
|
||||||
|
|
||||||
struct def *
|
struct def *
|
||||||
lookup(id, scope)
|
lookup(id, scope)
|
||||||
|
@ -73,5 +74,7 @@ lookfor(id, vis, give_error)
|
||||||
|
|
||||||
if (give_error) id_not_declared(id);
|
if (give_error) id_not_declared(id);
|
||||||
|
|
||||||
return MkDef(id->nd_IDF, vis->sc_scope, D_ERROR);
|
df = MkDef(id->nd_IDF, vis->sc_scope, D_ERROR);
|
||||||
|
df->df_type = error_type;
|
||||||
|
return df;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,14 @@ DoOption(text)
|
||||||
default:
|
default:
|
||||||
options[text[-1]]++; /* flags, debug options etc. */
|
options[text[-1]]++; /* flags, debug options etc. */
|
||||||
break;
|
break;
|
||||||
|
/* recognized flags:
|
||||||
|
-L: don't generate fil/lin
|
||||||
|
-p: generate procentry/procexit
|
||||||
|
-w: no warnings
|
||||||
|
-n: no register messages
|
||||||
|
and many more if DEBUG
|
||||||
|
*/
|
||||||
|
|
||||||
case 'L' : /* don't generate fil/lin */
|
|
||||||
options['L'] = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'M': /* maximum identifier length */
|
case 'M': /* maximum identifier length */
|
||||||
idfsize = txt2int(&text);
|
idfsize = txt2int(&text);
|
||||||
|
@ -37,10 +41,6 @@ DoOption(text)
|
||||||
fatal("maximum identifier length is %d", IDFSIZE);
|
fatal("maximum identifier length is %d", IDFSIZE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p' : /* generate profiling code procentry/procexit ???? */
|
|
||||||
options['p'] = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'I' :
|
case 'I' :
|
||||||
if (++ndirs >= NDIRS) {
|
if (++ndirs >= NDIRS) {
|
||||||
fatal("Too many -I options");
|
fatal("Too many -I options");
|
||||||
|
@ -99,14 +99,6 @@ DoOption(text)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'n':
|
|
||||||
options['n'] = 1; /* use no registers */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'w':
|
|
||||||
options['w'] = 1; /* no warnings will be given */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,6 @@ definition
|
||||||
VAR [ VariableDeclaration Semicolon ]*
|
VAR [ VariableDeclaration Semicolon ]*
|
||||||
|
|
|
|
||||||
ProcedureHeading(&dummy, D_PROCHEAD)
|
ProcedureHeading(&dummy, D_PROCHEAD)
|
||||||
{ close_scope(0); }
|
|
||||||
Semicolon
|
Semicolon
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -90,19 +90,6 @@ Forward(tk, ptp)
|
||||||
CurrentScope->sc_forw = f;
|
CurrentScope->sc_forw = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChForward(was, becomes)
|
|
||||||
struct type *was, *becomes;
|
|
||||||
{
|
|
||||||
/* The declaration of a hidden type had a forward reference.
|
|
||||||
In this case, the "forwards" list must be adapted.
|
|
||||||
*/
|
|
||||||
register struct forwards *f = CurrentScope->sc_forw;
|
|
||||||
|
|
||||||
while (f && f->fo_ptyp != was) f = f->next;
|
|
||||||
assert(f != 0);
|
|
||||||
f->fo_ptyp = becomes;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
chk_proc(df)
|
chk_proc(df)
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
|
@ -114,7 +101,7 @@ chk_proc(df)
|
||||||
if (df->df_kind == D_PROCHEAD) {
|
if (df->df_kind == D_PROCHEAD) {
|
||||||
/* A not defined procedure
|
/* A not defined procedure
|
||||||
*/
|
*/
|
||||||
node_error(df->for_node, "procedure \"%s\" not defined", df->df_idf->id_text);
|
error("procedure \"%s\" not defined", df->df_idf->id_text);
|
||||||
FreeNode(df->for_node);
|
FreeNode(df->for_node);
|
||||||
}
|
}
|
||||||
df = df->df_nextinscope;
|
df = df->df_nextinscope;
|
||||||
|
|
|
@ -85,7 +85,7 @@ StatementSequence(register struct node **pnd;)
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
} :
|
} :
|
||||||
statement(pnd)
|
statement(pnd)
|
||||||
[
|
[ %persistent
|
||||||
';' statement(&nd)
|
';' statement(&nd)
|
||||||
{ if (nd) {
|
{ if (nd) {
|
||||||
*pnd = MkNode(Link, *pnd, nd, &dot);
|
*pnd = MkNode(Link, *pnd, nd, &dot);
|
||||||
|
|
|
@ -52,14 +52,14 @@ struct proc {
|
||||||
|
|
||||||
struct type {
|
struct type {
|
||||||
struct type *next; /* used with ARRAY, PROCEDURE, POINTER, SET,
|
struct type *next; /* used with ARRAY, PROCEDURE, POINTER, SET,
|
||||||
SUBRANGE
|
SUBRANGE, EQUAL
|
||||||
*/
|
*/
|
||||||
int tp_fund; /* fundamental type or constructor */
|
int tp_fund; /* fundamental type or constructor */
|
||||||
#define T_RECORD 0x0001
|
#define T_RECORD 0x0001
|
||||||
#define T_ENUMERATION 0x0002
|
#define T_ENUMERATION 0x0002
|
||||||
#define T_INTEGER 0x0004
|
#define T_INTEGER 0x0004
|
||||||
#define T_CARDINAL 0x0008
|
#define T_CARDINAL 0x0008
|
||||||
/* #define T_LONGINT 0x0010 */
|
#define T_EQUAL 0x0010
|
||||||
#define T_REAL 0x0020
|
#define T_REAL 0x0020
|
||||||
#define T_HIDDEN 0x0040
|
#define T_HIDDEN 0x0040
|
||||||
#define T_POINTER 0x0080
|
#define T_POINTER 0x0080
|
||||||
|
@ -129,7 +129,8 @@ struct type
|
||||||
*construct_type(),
|
*construct_type(),
|
||||||
*standard_type(),
|
*standard_type(),
|
||||||
*set_type(),
|
*set_type(),
|
||||||
*subr_type(); /* All from type.c */
|
*subr_type(),
|
||||||
|
*RemoveEqual(); /* All from type.c */
|
||||||
|
|
||||||
#define NULLTYPE ((struct type *) 0)
|
#define NULLTYPE ((struct type *) 0)
|
||||||
|
|
||||||
|
@ -147,6 +148,6 @@ struct type
|
||||||
(tpx)->next)
|
(tpx)->next)
|
||||||
#define PointedtoType(tpx) (assert((tpx)->tp_fund == T_POINTER),\
|
#define PointedtoType(tpx) (assert((tpx)->tp_fund == T_POINTER),\
|
||||||
(tpx)->next)
|
(tpx)->next)
|
||||||
#define BaseType(tpx) ((tpx)->tp_fund == T_SUBRANGE ? (tpx)->next\
|
#define BaseType(tpx) ((tpx)->tp_fund == T_SUBRANGE ? (tpx)->next : \
|
||||||
: (tpx))
|
(tpx))
|
||||||
#define IsConstructed(tpx) ((tpx)->tp_fund & T_CONSTRUCTED)
|
#define IsConstructed(tpx) ((tpx)->tp_fund & T_CONSTRUCTED)
|
||||||
|
|
|
@ -224,6 +224,8 @@ chk_basesubrange(tp, base)
|
||||||
/* A subrange had a specified base. Check that the bases conform.
|
/* A subrange had a specified base. Check that the bases conform.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
assert(tp->tp_fund == T_SUBRANGE);
|
||||||
|
|
||||||
if (base->tp_fund == T_SUBRANGE) {
|
if (base->tp_fund == T_SUBRANGE) {
|
||||||
/* Check that the bounds of "tp" fall within the range
|
/* Check that the bounds of "tp" fall within the range
|
||||||
of "base".
|
of "base".
|
||||||
|
@ -231,22 +233,22 @@ chk_basesubrange(tp, base)
|
||||||
if (base->sub_lb > tp->sub_lb || base->sub_ub < tp->sub_ub) {
|
if (base->sub_lb > tp->sub_lb || base->sub_ub < tp->sub_ub) {
|
||||||
error("Base type has insufficient range");
|
error("Base type has insufficient range");
|
||||||
}
|
}
|
||||||
base = BaseType(base);
|
base = base->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base->tp_fund & (T_ENUMERATION|T_CHAR)) {
|
if (base->tp_fund & (T_ENUMERATION|T_CHAR)) {
|
||||||
if (BaseType(tp) != base) {
|
if (tp->next != base) {
|
||||||
error("Specified base does not conform");
|
error("Specified base does not conform");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (base != card_type && base != int_type) {
|
else if (base != card_type && base != int_type) {
|
||||||
error("Illegal base for a subrange");
|
error("Illegal base for a subrange");
|
||||||
}
|
}
|
||||||
else if (base == int_type && BaseType(tp) == card_type &&
|
else if (base == int_type && tp->next == card_type &&
|
||||||
(tp->sub_ub > max_int || tp->sub_ub < 0)) {
|
(tp->sub_ub > max_int || tp->sub_ub < 0)) {
|
||||||
error("Upperbound to large for type INTEGER");
|
error("Upperbound to large for type INTEGER");
|
||||||
}
|
}
|
||||||
else if (base != BaseType(tp) && base != int_type) {
|
else if (base != tp->next && base != int_type) {
|
||||||
error("Specified base does not conform");
|
error("Specified base does not conform");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,24 +464,31 @@ DeclareType(df, tp)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (df->df_type && df->df_type->tp_fund == T_HIDDEN) {
|
if (df->df_type && df->df_type->tp_fund == T_HIDDEN) {
|
||||||
if (tp->tp_fund != T_POINTER) {
|
if (! (tp->tp_fund & (T_POINTER|T_HIDDEN|T_EQUAL))) {
|
||||||
error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
error("opaque type \"%s\" is not a pointer type", df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
/* Careful now ... we might have declarations
|
df->df_type->next = tp;
|
||||||
referring to the hidden type.
|
df->df_type->tp_fund = T_EQUAL;
|
||||||
*/
|
while (tp != df->df_type && tp->tp_fund == T_EQUAL) {
|
||||||
*(df->df_type) = *tp;
|
tp = tp->next;
|
||||||
if (! tp->next) {
|
}
|
||||||
/* It also contains a forward reference,
|
if (tp == df->df_type) {
|
||||||
so update the forwardlist
|
/* Circular definition! */
|
||||||
*/
|
error("opaque type \"%s\" has a circular definition", df->df_idf->id_text);
|
||||||
ChForward(tp, df->df_type);
|
|
||||||
}
|
}
|
||||||
free_type(tp);
|
|
||||||
}
|
}
|
||||||
else df->df_type = tp;
|
else df->df_type = tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct type *
|
||||||
|
RemoveEqual(tpx)
|
||||||
|
register struct type *tpx;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (tpx) while (tpx->tp_fund == T_EQUAL) tpx = tpx->next;
|
||||||
|
return tpx;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
gcd(m, n)
|
gcd(m, n)
|
||||||
register int m, n;
|
register int m, n;
|
||||||
|
@ -532,6 +541,10 @@ DumpType(tp)
|
||||||
print("CARDINAL"); break;
|
print("CARDINAL"); break;
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
print("REAL"); break;
|
print("REAL"); break;
|
||||||
|
case T_HIDDEN:
|
||||||
|
print("HIDDEN"); break;
|
||||||
|
case T_EQUAL:
|
||||||
|
print("EQUAL"); break;
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
print("POINTER"); break;
|
print("POINTER"); break;
|
||||||
case T_CHAR:
|
case T_CHAR:
|
||||||
|
|
|
@ -38,6 +38,9 @@ static struct type *func_type;
|
||||||
struct withdesig *WithDesigs;
|
struct withdesig *WithDesigs;
|
||||||
struct node *Modules;
|
struct node *Modules;
|
||||||
|
|
||||||
|
#define NO_EXIT_LABEL ((label) 0)
|
||||||
|
#define RETURN_LABEL ((label) 1)
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
DoProfil()
|
DoProfil()
|
||||||
{
|
{
|
||||||
|
@ -59,6 +62,7 @@ WalkModule(module)
|
||||||
{
|
{
|
||||||
/* Walk through a module, and all its local definitions.
|
/* Walk through a module, and all its local definitions.
|
||||||
Also generate code for its body.
|
Also generate code for its body.
|
||||||
|
This code is collected in an initialization routine.
|
||||||
*/
|
*/
|
||||||
register struct scope *sc;
|
register struct scope *sc;
|
||||||
struct scopelist *savevis = CurrVis;
|
struct scopelist *savevis = CurrVis;
|
||||||
|
@ -75,7 +79,7 @@ WalkModule(module)
|
||||||
this module.
|
this module.
|
||||||
*/
|
*/
|
||||||
sc->sc_off = 0; /* no locals (yet) */
|
sc->sc_off = 0; /* no locals (yet) */
|
||||||
text_label = 1;
|
text_label = 1; /* label at end of initialization routine */
|
||||||
TmpOpen(sc); /* Initialize for temporaries */
|
TmpOpen(sc); /* Initialize for temporaries */
|
||||||
C_pro_narg(sc->sc_name);
|
C_pro_narg(sc->sc_name);
|
||||||
DoProfil();
|
DoProfil();
|
||||||
|
@ -93,10 +97,12 @@ WalkModule(module)
|
||||||
*/
|
*/
|
||||||
C_df_dlb(l1);
|
C_df_dlb(l1);
|
||||||
C_bss_cst(word_size, (arith) 0, 1);
|
C_bss_cst(word_size, (arith) 0, 1);
|
||||||
|
/* if this one is set to non-zero, the initialization
|
||||||
|
was already done.
|
||||||
|
*/
|
||||||
C_loe_dlb(l1, (arith) 0);
|
C_loe_dlb(l1, (arith) 0);
|
||||||
C_zne((label) 1);
|
C_zne(RETURN_LABEL);
|
||||||
C_loc((arith) 1);
|
C_ine_dlb(l1, (arith) 0);
|
||||||
C_ste_dlb(l1, (arith) 0);
|
|
||||||
/* Prevent this module from calling its own
|
/* Prevent this module from calling its own
|
||||||
initialization routine
|
initialization routine
|
||||||
*/
|
*/
|
||||||
|
@ -111,8 +117,8 @@ WalkModule(module)
|
||||||
MkCalls(sc->sc_def);
|
MkCalls(sc->sc_def);
|
||||||
proclevel++;
|
proclevel++;
|
||||||
DO_DEBUG(options['X'], PrNode(module->mod_body, 0));
|
DO_DEBUG(options['X'], PrNode(module->mod_body, 0));
|
||||||
WalkNode(module->mod_body, (label) 0);
|
WalkNode(module->mod_body, NO_EXIT_LABEL);
|
||||||
C_df_ilb((label) 1);
|
C_df_ilb(RETURN_LABEL);
|
||||||
C_ret((arith) 0);
|
C_ret((arith) 0);
|
||||||
C_end(-sc->sc_off);
|
C_end(-sc->sc_off);
|
||||||
proclevel--;
|
proclevel--;
|
||||||
|
@ -132,8 +138,9 @@ WalkProcedure(procedure)
|
||||||
register struct type *tp;
|
register struct type *tp;
|
||||||
register struct paramlist *param;
|
register struct paramlist *param;
|
||||||
label func_res_label = 0;
|
label func_res_label = 0;
|
||||||
arith tmpvar1 = 0;
|
arith StackAdjustment = 0;
|
||||||
arith retsav = 0;
|
arith retsav = 0;
|
||||||
|
arith func_res_size = 0;
|
||||||
|
|
||||||
proclevel++;
|
proclevel++;
|
||||||
CurrVis = procedure->prc_vis;
|
CurrVis = procedure->prc_vis;
|
||||||
|
@ -152,11 +159,19 @@ WalkProcedure(procedure)
|
||||||
func_type = tp = ResultType(procedure->df_type);
|
func_type = tp = ResultType(procedure->df_type);
|
||||||
|
|
||||||
if (tp && IsConstructed(tp)) {
|
if (tp && IsConstructed(tp)) {
|
||||||
|
/* The result type of this procedure is constructed.
|
||||||
|
The actual procedure will return a pointer to a global
|
||||||
|
data area in which the function result is stored.
|
||||||
|
Notice that this does make the code non-reentrant.
|
||||||
|
Here, we create the data area for the function result.
|
||||||
|
*/
|
||||||
func_res_label = ++data_label;
|
func_res_label = ++data_label;
|
||||||
C_df_dlb(func_res_label);
|
C_df_dlb(func_res_label);
|
||||||
C_bss_cst(tp->tp_size, (arith) 0, 0);
|
C_bss_cst(tp->tp_size, (arith) 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tp) func_res_size = WA(tp->tp_size);
|
||||||
|
|
||||||
/* Generate calls to initialization routines of modules defined within
|
/* Generate calls to initialization routines of modules defined within
|
||||||
this procedure
|
this procedure
|
||||||
*/
|
*/
|
||||||
|
@ -192,22 +207,25 @@ WalkProcedure(procedure)
|
||||||
*/
|
*/
|
||||||
arith tmpvar = NewInt();
|
arith tmpvar = NewInt();
|
||||||
|
|
||||||
if (! tmpvar1) {
|
if (! StackAdjustment) {
|
||||||
|
/* First time we get here
|
||||||
|
*/
|
||||||
if (tp && !func_res_label) {
|
if (tp && !func_res_label) {
|
||||||
/* Some local space, only
|
/* Some local space, only
|
||||||
needed if the value itself
|
needed if the value itself
|
||||||
is returned
|
is returned
|
||||||
*/
|
*/
|
||||||
sc->sc_off -= WA(tp->tp_size);
|
sc->sc_off -= func_res_size;
|
||||||
retsav = sc->sc_off;
|
retsav = sc->sc_off;
|
||||||
}
|
}
|
||||||
tmpvar1 = NewInt();
|
StackAdjustment = NewInt();
|
||||||
C_loc((arith) 0);
|
C_loc((arith) 0);
|
||||||
C_stl(tmpvar1);
|
C_stl(StackAdjustment);
|
||||||
}
|
}
|
||||||
/* First compute the size */
|
/* First compute the size of the array */
|
||||||
C_lol(param->par_def->var_off +
|
C_lol(param->par_def->var_off +
|
||||||
pointer_size + word_size);
|
pointer_size + word_size);
|
||||||
|
/* upper - lower */
|
||||||
C_inc(); /* gives number of elements */
|
C_inc(); /* gives number of elements */
|
||||||
C_loc(tp->arr_elem->tp_size);
|
C_loc(tp->arr_elem->tp_size);
|
||||||
C_cal("_wa");
|
C_cal("_wa");
|
||||||
|
@ -219,15 +237,22 @@ WalkProcedure(procedure)
|
||||||
/* size in bytes */
|
/* size in bytes */
|
||||||
C_stl(tmpvar);
|
C_stl(tmpvar);
|
||||||
C_lol(tmpvar);
|
C_lol(tmpvar);
|
||||||
C_dup(word_size);
|
C_lol(tmpvar);
|
||||||
C_lol(tmpvar1);
|
C_lol(StackAdjustment);
|
||||||
C_adi(word_size);
|
C_adi(word_size);
|
||||||
C_stl(tmpvar1); /* remember all stack adjustments */
|
C_stl(StackAdjustment);
|
||||||
|
/* remember stack adjustments */
|
||||||
C_ngi(word_size);
|
C_ngi(word_size);
|
||||||
|
/* Assumption: stack grows
|
||||||
|
downwards!! ???
|
||||||
|
*/
|
||||||
C_ass(word_size);
|
C_ass(word_size);
|
||||||
/* adjusted stack pointer */
|
/* adjusted stack pointer */
|
||||||
C_lor((arith) 1);
|
C_lor((arith) 1);
|
||||||
/* destination address */
|
/* destination address (sp),
|
||||||
|
also assumes stack grows
|
||||||
|
downwards ???
|
||||||
|
*/
|
||||||
C_lal(param->par_def->var_off);
|
C_lal(param->par_def->var_off);
|
||||||
C_loi(pointer_size);
|
C_loi(pointer_size);
|
||||||
/* push source address */
|
/* push source address */
|
||||||
|
@ -237,7 +262,9 @@ WalkProcedure(procedure)
|
||||||
C_bls(word_size);
|
C_bls(word_size);
|
||||||
/* copy */
|
/* copy */
|
||||||
C_lor((arith) 1);
|
C_lor((arith) 1);
|
||||||
/* push new address of array */
|
/* push new address of array
|
||||||
|
... downwards ... ???
|
||||||
|
*/
|
||||||
C_lal(param->par_def->var_off);
|
C_lal(param->par_def->var_off);
|
||||||
C_sti(pointer_size);
|
C_sti(pointer_size);
|
||||||
FreeInt(tmpvar);
|
FreeInt(tmpvar);
|
||||||
|
@ -245,41 +272,50 @@ WalkProcedure(procedure)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
text_label = 1;
|
text_label = 1; /* label at end of procedure */
|
||||||
|
|
||||||
DO_DEBUG(options['X'], PrNode(procedure->prc_body, 0));
|
DO_DEBUG(options['X'], PrNode(procedure->prc_body, 0));
|
||||||
WalkNode(procedure->prc_body, (label) 0);
|
WalkNode(procedure->prc_body, NO_EXIT_LABEL);
|
||||||
C_df_ilb((label) 1);
|
C_df_ilb(RETURN_LABEL); /* label at end */
|
||||||
tp = func_type;
|
tp = func_type;
|
||||||
if (func_res_label) {
|
if (func_res_label) {
|
||||||
|
/* Fill the data area reserved for the function result
|
||||||
|
with the result
|
||||||
|
*/
|
||||||
C_lae_dlb(func_res_label, (arith) 0);
|
C_lae_dlb(func_res_label, (arith) 0);
|
||||||
C_sti(tp->tp_size);
|
C_sti(tp->tp_size);
|
||||||
if (tmpvar1) {
|
if (StackAdjustment) {
|
||||||
C_lol(tmpvar1);
|
/* Remove copies of conformant arrays
|
||||||
|
*/
|
||||||
|
C_lol(StackAdjustment);
|
||||||
C_ass(word_size);
|
C_ass(word_size);
|
||||||
}
|
}
|
||||||
C_lae_dlb(func_res_label, (arith) 0);
|
C_lae_dlb(func_res_label, (arith) 0);
|
||||||
C_ret(pointer_size);
|
C_ret(pointer_size);
|
||||||
}
|
}
|
||||||
else if (tp) {
|
else if (tp) {
|
||||||
if (tmpvar1) {
|
if (StackAdjustment) {
|
||||||
|
/* First save the function result in a safe place.
|
||||||
|
Then remove copies of conformant arrays,
|
||||||
|
and put function result back on the stack
|
||||||
|
*/
|
||||||
C_lal(retsav);
|
C_lal(retsav);
|
||||||
C_sti(WA(tp->tp_size));
|
C_sti(func_res_size);
|
||||||
C_lol(tmpvar1);
|
C_lol(StackAdjustment);
|
||||||
C_ass(word_size);
|
C_ass(word_size);
|
||||||
C_lal(retsav);
|
C_lal(retsav);
|
||||||
C_loi(WA(tp->tp_size));
|
C_loi(func_res_size);
|
||||||
}
|
}
|
||||||
C_ret(WA(tp->tp_size));
|
C_ret(func_res_size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (tmpvar1) {
|
if (StackAdjustment) {
|
||||||
C_lol(tmpvar1);
|
C_lol(StackAdjustment);
|
||||||
C_ass(word_size);
|
C_ass(word_size);
|
||||||
}
|
}
|
||||||
C_ret((arith) 0);
|
C_ret((arith) 0);
|
||||||
}
|
}
|
||||||
if (tmpvar1) FreeInt(tmpvar1);
|
if (StackAdjustment) FreeInt(StackAdjustment);
|
||||||
if (! options['n']) RegisterMessages(sc->sc_def);
|
if (! options['n']) RegisterMessages(sc->sc_def);
|
||||||
C_end(-sc->sc_off);
|
C_end(-sc->sc_off);
|
||||||
TmpClose();
|
TmpClose();
|
||||||
|
@ -293,20 +329,26 @@ WalkDef(df)
|
||||||
/* Walk through a list of definitions
|
/* Walk through a list of definitions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (df) {
|
for ( ; df; df = df->df_nextinscope) {
|
||||||
if (df->df_kind == D_MODULE) {
|
switch(df->df_kind) {
|
||||||
|
case D_MODULE:
|
||||||
WalkModule(df);
|
WalkModule(df);
|
||||||
}
|
break;
|
||||||
else if (df->df_kind == D_PROCEDURE) {
|
case D_PROCEDURE:
|
||||||
WalkProcedure(df);
|
WalkProcedure(df);
|
||||||
|
break;
|
||||||
|
case D_VARIABLE:
|
||||||
|
if (!proclevel) {
|
||||||
|
C_df_dnam(df->var_name);
|
||||||
|
C_bss_cst(
|
||||||
|
WA(df->df_type->tp_size),
|
||||||
|
(arith) 0, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* nothing */
|
||||||
|
;
|
||||||
}
|
}
|
||||||
else if (!proclevel && df->df_kind == D_VARIABLE) {
|
|
||||||
C_df_dnam(df->var_name);
|
|
||||||
C_bss_cst(
|
|
||||||
WA(df->df_type->tp_size),
|
|
||||||
(arith) 0, 0);
|
|
||||||
}
|
|
||||||
df = df->df_nextinscope;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,31 +358,28 @@ MkCalls(df)
|
||||||
/* Generate calls to initialization routines of modules
|
/* Generate calls to initialization routines of modules
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (df) {
|
for ( ; df; df = df->df_nextinscope) {
|
||||||
if (df->df_kind == D_MODULE) {
|
if (df->df_kind == D_MODULE) {
|
||||||
C_lxl((arith) 0);
|
C_lxl((arith) 0);
|
||||||
C_cal(df->mod_vis->sc_scope->sc_name);
|
C_cal(df->mod_vis->sc_scope->sc_name);
|
||||||
C_asp(pointer_size);
|
C_asp(pointer_size);
|
||||||
}
|
}
|
||||||
df = df->df_nextinscope;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkLink(nd, lab)
|
WalkLink(nd, exit_label)
|
||||||
register struct node *nd;
|
register struct node *nd;
|
||||||
label lab;
|
label exit_label;
|
||||||
{
|
{
|
||||||
/* Walk node "nd", which is a link.
|
/* Walk node "nd", which is a link.
|
||||||
"lab" represents the label that must be jumped to on
|
|
||||||
encountering an EXIT statement.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (nd && nd->nd_class == Link) { /* statement list */
|
while (nd && nd->nd_class == Link) { /* statement list */
|
||||||
WalkNode(nd->nd_left, lab);
|
WalkNode(nd->nd_left, exit_label);
|
||||||
nd = nd->nd_right;
|
nd = nd->nd_right;
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkNode(nd, lab);
|
WalkNode(nd, exit_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkCall(nd)
|
WalkCall(nd)
|
||||||
|
@ -358,13 +397,11 @@ WalkCall(nd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkStat(nd, lab)
|
WalkStat(nd, exit_label)
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
label lab;
|
label exit_label;
|
||||||
{
|
{
|
||||||
/* Walk through a statement, generating code for it.
|
/* Walk through a statement, generating code for it.
|
||||||
"lab" represents the label that must be jumped to on
|
|
||||||
encountering an EXIT statement.
|
|
||||||
*/
|
*/
|
||||||
register struct node *left = nd->nd_left;
|
register struct node *left = nd->nd_left;
|
||||||
register struct node *right = nd->nd_right;
|
register struct node *right = nd->nd_right;
|
||||||
|
@ -386,12 +423,12 @@ WalkStat(nd, lab)
|
||||||
ExpectBool(left, l3, l1);
|
ExpectBool(left, l3, l1);
|
||||||
assert(right->nd_symb == THEN);
|
assert(right->nd_symb == THEN);
|
||||||
C_df_ilb(l3);
|
C_df_ilb(l3);
|
||||||
WalkNode(right->nd_left, lab);
|
WalkNode(right->nd_left, exit_label);
|
||||||
|
|
||||||
if (right->nd_right) { /* ELSE part */
|
if (right->nd_right) { /* ELSE part */
|
||||||
C_bra(l2);
|
C_bra(l2);
|
||||||
C_df_ilb(l1);
|
C_df_ilb(l1);
|
||||||
WalkNode(right->nd_right, lab);
|
WalkNode(right->nd_right, exit_label);
|
||||||
C_df_ilb(l2);
|
C_df_ilb(l2);
|
||||||
}
|
}
|
||||||
else C_df_ilb(l1);
|
else C_df_ilb(l1);
|
||||||
|
@ -399,7 +436,7 @@ WalkStat(nd, lab)
|
||||||
}
|
}
|
||||||
|
|
||||||
case CASE:
|
case CASE:
|
||||||
CaseCode(nd, lab);
|
CaseCode(nd, exit_label);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WHILE:
|
case WHILE:
|
||||||
|
@ -411,7 +448,7 @@ WalkStat(nd, lab)
|
||||||
C_df_ilb(l1);
|
C_df_ilb(l1);
|
||||||
ExpectBool(left, l3, l2);
|
ExpectBool(left, l3, l2);
|
||||||
C_df_ilb(l3);
|
C_df_ilb(l3);
|
||||||
WalkNode(right, lab);
|
WalkNode(right, exit_label);
|
||||||
C_bra(l1);
|
C_bra(l1);
|
||||||
C_df_ilb(l2);
|
C_df_ilb(l2);
|
||||||
break;
|
break;
|
||||||
|
@ -423,7 +460,7 @@ WalkStat(nd, lab)
|
||||||
l1 = ++text_label;
|
l1 = ++text_label;
|
||||||
l2 = ++text_label;
|
l2 = ++text_label;
|
||||||
C_df_ilb(l1);
|
C_df_ilb(l1);
|
||||||
WalkNode(left, lab);
|
WalkNode(left, exit_label);
|
||||||
ExpectBool(right, l2, l1);
|
ExpectBool(right, l2, l1);
|
||||||
C_df_ilb(l2);
|
C_df_ilb(l2);
|
||||||
break;
|
break;
|
||||||
|
@ -457,9 +494,9 @@ WalkStat(nd, lab)
|
||||||
}
|
}
|
||||||
C_bra(l1);
|
C_bra(l1);
|
||||||
C_df_ilb(l2);
|
C_df_ilb(l2);
|
||||||
CheckAssign(nd->nd_type, int_type);
|
RangeCheck(nd->nd_type, int_type);
|
||||||
CodeDStore(nd);
|
CodeDStore(nd);
|
||||||
WalkNode(right, lab);
|
WalkNode(right, exit_label);
|
||||||
CodePExpr(nd);
|
CodePExpr(nd);
|
||||||
C_loc(left->nd_INT);
|
C_loc(left->nd_INT);
|
||||||
C_adi(int_size);
|
C_adi(int_size);
|
||||||
|
@ -493,8 +530,7 @@ WalkStat(nd, lab)
|
||||||
wds.w_scope = left->nd_type->rec_scope;
|
wds.w_scope = left->nd_type->rec_scope;
|
||||||
CodeAddress(&ds);
|
CodeAddress(&ds);
|
||||||
ds.dsg_kind = DSG_FIXED;
|
ds.dsg_kind = DSG_FIXED;
|
||||||
/* Create a designator structure for the
|
/* Create a designator structure for the temporary.
|
||||||
temporary.
|
|
||||||
*/
|
*/
|
||||||
ds.dsg_offset = tmp = NewPtr();
|
ds.dsg_offset = tmp = NewPtr();
|
||||||
ds.dsg_name = 0;
|
ds.dsg_name = 0;
|
||||||
|
@ -505,7 +541,7 @@ WalkStat(nd, lab)
|
||||||
link.sc_scope = wds.w_scope;
|
link.sc_scope = wds.w_scope;
|
||||||
link.next = CurrVis;
|
link.next = CurrVis;
|
||||||
CurrVis = &link;
|
CurrVis = &link;
|
||||||
WalkNode(right, lab);
|
WalkNode(right, exit_label);
|
||||||
CurrVis = link.next;
|
CurrVis = link.next;
|
||||||
WithDesigs = wds.w_next;
|
WithDesigs = wds.w_next;
|
||||||
FreePtr(tmp);
|
FreePtr(tmp);
|
||||||
|
@ -513,9 +549,9 @@ WalkStat(nd, lab)
|
||||||
}
|
}
|
||||||
|
|
||||||
case EXIT:
|
case EXIT:
|
||||||
assert(lab != 0);
|
assert(exit_label != 0);
|
||||||
|
|
||||||
C_bra(lab);
|
C_bra(exit_label);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RETURN:
|
case RETURN:
|
||||||
|
@ -529,7 +565,7 @@ WalkStat(nd, lab)
|
||||||
node_error(right, "type incompatibility in RETURN statement");
|
node_error(right, "type incompatibility in RETURN statement");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
C_bra((label) 1);
|
C_bra(RETURN_LABEL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -576,7 +612,7 @@ ExpectBool(nd, true_label, false_label)
|
||||||
|
|
||||||
int
|
int
|
||||||
WalkExpr(nd)
|
WalkExpr(nd)
|
||||||
struct node *nd;
|
register struct node *nd;
|
||||||
{
|
{
|
||||||
/* Check an expression and generate code for it
|
/* Check an expression and generate code for it
|
||||||
*/
|
*/
|
||||||
|
@ -664,12 +700,15 @@ DoAssign(nd, left, right)
|
||||||
struct node *nd;
|
struct node *nd;
|
||||||
register struct node *left, *right;
|
register struct node *left, *right;
|
||||||
{
|
{
|
||||||
/* 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:
|
||||||
|
it sais that the left hand side is evaluated first.
|
||||||
|
*/
|
||||||
struct desig dsl, dsr;
|
struct desig dsl, dsr;
|
||||||
|
|
||||||
if (! ChkExpression(right)) return;
|
if (! ChkExpression(right)) return;
|
||||||
if (! ChkVariable(left)) return;
|
if (! ChkVariable(left)) return;
|
||||||
TryToString(right, left->nd_type);
|
if (right->nd_symb == STRING) TryToString(right, left->nd_type);
|
||||||
dsr = InitDesig;
|
dsr = InitDesig;
|
||||||
CodeExpr(right, &dsr, NO_LABEL, NO_LABEL);
|
CodeExpr(right, &dsr, NO_LABEL, NO_LABEL);
|
||||||
|
|
||||||
|
@ -683,7 +722,7 @@ DoAssign(nd, left, right)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CodeValue(&dsr, right->nd_type->tp_size);
|
CodeValue(&dsr, right->nd_type->tp_size);
|
||||||
CheckAssign(left->nd_type, right->nd_type);
|
RangeCheck(left->nd_type, right->nd_type);
|
||||||
}
|
}
|
||||||
dsl = InitDesig;
|
dsl = InitDesig;
|
||||||
CodeDesig(left, &dsl);
|
CodeDesig(left, &dsl);
|
||||||
|
@ -702,12 +741,11 @@ RegisterMessages(df)
|
||||||
*/
|
*/
|
||||||
tp = BaseType(df->df_type);
|
tp = BaseType(df->df_type);
|
||||||
if ((df->df_flags & D_VARPAR) ||
|
if ((df->df_flags & D_VARPAR) ||
|
||||||
tp->tp_fund == T_POINTER) {
|
(tp->tp_fund & (T_POINTER|T_HIDDEN|T_EQUAL))) {
|
||||||
C_ms_reg(df->var_off, pointer_size,
|
C_ms_reg(df->var_off, pointer_size,
|
||||||
reg_pointer, 0);
|
reg_pointer, 0);
|
||||||
}
|
}
|
||||||
else if ((tp->tp_fund & T_NUMERIC) &&
|
else if (tp->tp_fund & T_NUMERIC) {
|
||||||
tp->tp_size <= dword_size) {
|
|
||||||
C_ms_reg(df->var_off,
|
C_ms_reg(df->var_off,
|
||||||
tp->tp_size,
|
tp->tp_size,
|
||||||
tp->tp_fund == T_REAL ?
|
tp->tp_fund == T_REAL ?
|
||||||
|
|
Loading…
Reference in a new issue