lots and lots of changes & improvements
authoreck <none@none>
Tue, 19 Sep 1989 16:13:23 +0000 (16:13 +0000)
committereck <none@none>
Tue, 19 Sep 1989 16:13:23 +0000 (16:13 +0000)
59 files changed:
lang/cem/cemcom.ansi/BigPars
lang/cem/cemcom.ansi/LLlex.c
lang/cem/cemcom.ansi/LLlex.h
lang/cem/cemcom.ansi/LLmessage.c
lang/cem/cemcom.ansi/LintPars
lang/cem/cemcom.ansi/Makefile
lang/cem/cemcom.ansi/SmallPars
lang/cem/cemcom.ansi/align.h
lang/cem/cemcom.ansi/arith.c
lang/cem/cemcom.ansi/arith.h
lang/cem/cemcom.ansi/ch7.c
lang/cem/cemcom.ansi/ch7bin.c
lang/cem/cemcom.ansi/ch7mon.c
lang/cem/cemcom.ansi/char.tab
lang/cem/cemcom.ansi/class.h
lang/cem/cemcom.ansi/code.c
lang/cem/cemcom.ansi/conversion.c
lang/cem/cemcom.ansi/cstoper.c
lang/cem/cemcom.ansi/declar.g
lang/cem/cemcom.ansi/declarator.c
lang/cem/cemcom.ansi/decspecs.c
lang/cem/cemcom.ansi/domacro.c
lang/cem/cemcom.ansi/dumpidf.c
lang/cem/cemcom.ansi/error.c
lang/cem/cemcom.ansi/eval.c
lang/cem/cemcom.ansi/expr.c
lang/cem/cemcom.ansi/expr.str
lang/cem/cemcom.ansi/expression.g
lang/cem/cemcom.ansi/field.c
lang/cem/cemcom.ansi/idf.c
lang/cem/cemcom.ansi/idf.str
lang/cem/cemcom.ansi/init.c
lang/cem/cemcom.ansi/input.c
lang/cem/cemcom.ansi/input.h
lang/cem/cemcom.ansi/ival.g
lang/cem/cemcom.ansi/l_ev_ord.c
lang/cem/cemcom.ansi/l_lint.c
lang/cem/cemcom.ansi/l_misc.c
lang/cem/cemcom.ansi/l_outdef.c
lang/cem/cemcom.ansi/l_states.c
lang/cem/cemcom.ansi/label.c
lang/cem/cemcom.ansi/macro.str
lang/cem/cemcom.ansi/main.c
lang/cem/cemcom.ansi/options.c
lang/cem/cemcom.ansi/pragma.c
lang/cem/cemcom.ansi/program.g
lang/cem/cemcom.ansi/proto.c
lang/cem/cemcom.ansi/proto.str
lang/cem/cemcom.ansi/replace.c
lang/cem/cemcom.ansi/replace.str
lang/cem/cemcom.ansi/scan.c
lang/cem/cemcom.ansi/sizes.h
lang/cem/cemcom.ansi/skip.c
lang/cem/cemcom.ansi/stack.c
lang/cem/cemcom.ansi/statement.g
lang/cem/cemcom.ansi/struct.c
lang/cem/cemcom.ansi/switch.c
lang/cem/cemcom.ansi/type.c
lang/cem/cemcom.ansi/type.str

index 1f0a513..c00a753 100644 (file)
 #define SZ_WORD                (arith)4
 #define        SZ_INT          (arith)4
 #define        SZ_LONG         (arith)4
-#ifndef NOFLOAT
 #define        SZ_FLOAT        (arith)4
 #define        SZ_DOUBLE       (arith)8
 #define        SZ_LNGDBL       (arith)8        /* for now */
-#endif NOFLOAT
 #define        SZ_POINTER      (arith)4
 
 /* target machine alignment requirements       */
 #define AL_WORD                SZ_WORD
 #define        AL_INT          SZ_WORD
 #define        AL_LONG         SZ_WORD
-#ifndef NOFLOAT
 #define        AL_FLOAT        SZ_WORD
 #define        AL_DOUBLE       SZ_WORD
 #define        AL_LNGDBL       SZ_WORD
-#endif NOFLOAT
 #define        AL_POINTER      SZ_WORD
 #define AL_STRUCT      1
 #define AL_UNION       1
 #define GSTATIC                        /* for large global "static" arrays */
 
 
-!File: nofloat.h
-#undef NOFLOAT         1       /* if NOT defined, floats are implemented */
-
-
-!File: noRoption.h
-#undef NOROPTION       1       /* if NOT defined, R option is implemented */
-
-
 !File: nocross.h
 #undef NOCROSS         1       /* if NOT defined, cross compiler */
 
index 0064f67..3011aa8 100644 (file)
@@ -7,7 +7,6 @@
 
 #include       "lint.h"
 #include       <alloc.h>
-#include       "nofloat.h"
 #include       "idfsize.h"
 #include       "numsize.h"
 #include       "debug.h"
@@ -32,6 +31,7 @@ int ReplaceMacros = 1;                /* replacing macros                     */
 int AccDefined = 0;            /* accept "defined(...)"                */
 int UnknownIdIsZero = 0;       /* interpret unknown id as integer 0    */
 int Unstacked = 0;             /* an unstack is done                   */
+extern int InputLevel;
 #endif
 int AccFileSpecifier = 0;      /* return filespecifier <...>           */
 int EoiForNewline = 0;         /* return EOI upon encountering newline */
@@ -39,6 +39,11 @@ int File_Inserted = 0;               /* a file has just been inserted        */
 int LexSave = 0;               /* last character read by GetChar       */
 #define MAX_LL_DEPTH   2
 
+#define        FLG_ESEEN       0x01    /* possibly a floating point number */
+#define        FLG_DOTSEEN     0x02    /* certainly a floating point number */
+extern arith full_mask[];
+extern arith max_int;
+
 static struct token LexStack[MAX_LL_DEPTH];
 static LexSP = 0;
 
@@ -49,7 +54,7 @@ static LexSP = 0;
 */
 PushLex()
 {
-       ASSERT(LexSP < 2);
+       ASSERT(LexSP < MAX_LL_DEPTH);
        ASSERT(ASIDE == 0);     /* ASIDE = 0;   */
        GetToken(&ahead);
        LexStack[LexSP++] = dot;
@@ -95,12 +100,11 @@ LLlex()
 char   *string_token();
 arith  char_constant();
 
-
 int
 GetToken(ptok)
        register struct token *ptok;
 {
-       /*      LexToken() 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}*#"
                combination. Macro replacement is also performed if it is
                needed.
@@ -117,7 +121,9 @@ again:      /* rescan the input after an error or replacement       */
        ch = GetChar();
 go_on: /* rescan, the following character has been read        */
        if ((ch & 0200) && ch != EOI) /* stop on non-ascii character */
+       {
                fatal("non-ascii '\\%03o' read", ch & 0377);
+       }
        /* keep track of the place of the token in the file     */
        ptok->tk_file = FileName;
        ptok->tk_line = LineNumber;
@@ -152,23 +158,13 @@ firstline:
        case STSKIP:            /* just skip the skip characters        */
                goto again;
        case STGARB:            /* garbage character                    */
+garbage:
                if (040 < ch && ch < 0177)
                        lexerror("garbage char %c", ch);
                else
                        lexerror("garbage char \\%03o", ch);
                goto again;
        case STSIMP:    /* a simple character, no part of compound token*/
-               if (ch == '/') { /* probably the start of comment       */
-                       ch = GetChar();
-                       if (ch == '*') { /* start of comment */
-                               skipcomment();
-                               goto again;
-                       }
-                       else {
-                               UnGetChar();
-                               ch = '/';       /* restore ch   */
-                       }
-               }
                return ptok->tk_symb = ch;
        case STCOMP:    /* maybe the start of a compound token          */
                nch = GetChar();                /* character lookahead  */
@@ -181,18 +177,24 @@ firstline:
                case '&':
                        if (nch == '&')
                                return ptok->tk_symb = AND;
+                       else if (nch == '=')
+                               return ptok->tk_symb = ANDAB;
                        UnGetChar();
                        return ptok->tk_symb = ch;
                case '+':
                        if (nch == '+')
                                return ptok->tk_symb = PLUSPLUS;
+                       else if (nch == '=')
+                               return ptok->tk_symb = PLUSAB;
                        UnGetChar();
                        return ptok->tk_symb = ch;
                case '-':
                        if (nch == '-')
                                return ptok->tk_symb = MINMIN;
-                       if (nch == '>')
+                       else if (nch == '>')
                                return ptok->tk_symb = ARROW;
+                       else if (nch == '=')
+                               return ptok->tk_symb = MINAB;
                        UnGetChar();
                        return ptok->tk_symb = ch;
                case '<':
@@ -202,8 +204,12 @@ firstline:
                                                        '>', &(ptok->tk_len));
                                return ptok->tk_symb = FILESPECIFIER;
                        }
-                       if (nch == '<')
+                       if (nch == '<') {
+                               if ((nch = GetChar()) == '=')
+                                       return ptok->tk_symb = LEFTAB;
+                               UnGetChar();
                                return ptok->tk_symb = LEFT;
+                       }
                        if (nch == '=')
                                return ptok->tk_symb = LESSEQ;
                        UnGetChar();
@@ -211,64 +217,53 @@ firstline:
                case '=':
                        if (nch == '=')
                                return ptok->tk_symb = EQUAL;
-
-                       /*      The following piece of code tries to recognise
-                               old-fashioned assignment operators `=op'
-                               Note however, that these are removed from the
-                               ANSI C standard.
-                       */
-                       switch (nch) {
-                       case '+':
-                               ptok->tk_symb = PLUSAB;
-                               goto warn;
-                       case '-':
-                               ptok->tk_symb = MINAB;
-                               goto warn;
-                       case '*':
-                               ptok->tk_symb = TIMESAB;
-                               goto warn;
-                       case '/':
-                               ptok->tk_symb = DIVAB;
-                               goto warn;
-                       case '%':
-                               ptok->tk_symb = MODAB;
-                               goto warn;
-                       case '>':
-                       case '<':
-                               GetChar(ch);
-                               if (ch != nch) {
-                                       UnGetChar();
-                                       lexerror("illegal combination '=%c'",
-                                               nch);
-                               }
-                               ptok->tk_symb = nch == '<' ? LEFTAB : RIGHTAB;
-                               goto warn;
-                       case '&':
-                               ptok->tk_symb = ANDAB;
-                               goto warn;
-                       case '^':
-                               ptok->tk_symb = XORAB;
-                               goto warn;
-                       case '|':
-                               ptok->tk_symb = ORAB;
-                       warn:
-                               warning("Old-fashioned assignment operator");
-                               return ptok->tk_symb;
-                       }
                        UnGetChar();
                        return ptok->tk_symb = ch;
                case '>':
                        if (nch == '=')
                                return ptok->tk_symb = GREATEREQ;
-                       if (nch == '>')
+                       if (nch == '>') {
+                               if ((nch = GetChar()) == '=')
+                                       return ptok->tk_symb = RIGHTAB;
+                               UnGetChar();
                                return ptok->tk_symb = RIGHT;
+                       }
                        UnGetChar();
                        return ptok->tk_symb = ch;
                case '|':
                        if (nch == '|')
                                return ptok->tk_symb = OR;
+                       else if (nch == '=')
+                               return ptok->tk_symb = ORAB;
+                       UnGetChar();
+                       return ptok->tk_symb = ch;
+               case '%':
+                       if (nch == '=')
+                               return ptok->tk_symb = MODAB;
+                       UnGetChar();
+                       return ptok->tk_symb = ch;
+               case '*':
+                       if (nch == '=')
+                               return ptok->tk_symb = TIMESAB;
                        UnGetChar();
                        return ptok->tk_symb = ch;
+               case '^':
+                       if (nch == '=')
+                               return ptok->tk_symb = XORAB;
+                       UnGetChar();
+                       return ptok->tk_symb = ch;
+               case '/':
+                       if (nch == '*' && !InputLevel) {
+                               skipcomment();
+                               goto again;
+                       }
+                       else if (nch == '=')
+                               return ptok->tk_symb = DIVAB;
+                       UnGetChar();
+                       return ptok->tk_symb = ch;
+               default:
+                       crash("bad class for char 0%o", ch);
+                       /* NOTREACHED */
                }
        case STCHAR:                            /* character constant   */
                ptok->tk_ival = char_constant("character");
@@ -291,6 +286,7 @@ firstline:
                        return ptok->tk_symb = INTEGER;
                }
                UnGetChar();
+               /* fallthrough */
        case STIDF:
        {
                register char *tg = &buf[0];
@@ -298,7 +294,15 @@ firstline:
                register int hash;
                register struct idf *idef;
                extern int idfsize;             /* ??? */
+#ifndef        NOPP
+               int NoExpandNext = 0;
 
+               if (Unstacked) EnableMacros();  /* unstack macro's when allowed. */
+               if (ch == NOEXPM)  {
+                       NoExpandNext = 1;
+                       ch = GetChar();
+               }
+#endif
                hash = STARTHASH();
                do      {                       /* read the identifier  */
                        if (++pos < idfsize) {
@@ -316,12 +320,16 @@ firstline:
                idef->id_file = ptok->tk_file;
                idef->id_line = ptok->tk_line;
 #ifndef NOPP
-               if (idef->id_macro && ReplaceMacros) {
+               if (idef->id_macro && ReplaceMacros && !NoExpandNext) {
+#if 0
                        if (idef->id_macro->mc_count > 0)
                                idef->id_macro->mc_count--;
-                       else if (replace(idef))
-                               goto again;
+                       else
+#endif /* 0 */
+                       if (replace(idef))
+                                       goto again;
                }
+               NoExpandNext = 0;
                if (UnknownIdIsZero && idef->id_reserved != SIZEOF) {
                        ptok->tk_ival = (arith)0;
                        ptok->tk_fund = INT;
@@ -338,171 +346,85 @@ firstline:
        }
        case STNUM:                             /* a numeric constant   */
        {
-               register char *np = &buf[1];
-               register int base = 10;
-               register int vch;
-               register arith val = 0;
+               register int siz_left = NUMSIZE - 1;
+               register char *np = &buf[0];
+               int flags = 0;
+
+#define        store(ch)       if (--siz_left >= 0)            \
+                               *np++ = ch;
 
                if (ch == '.') {
-#ifndef NOFLOAT
-                       /*      A very embarrasing ambiguity. We have either a
-                               floating point number or field operator or
-                               ELLIPSIS.
+                       /*      An embarrasing ambiguity. We have either a
+                               pp-number, a field operator, an ELLIPSIS or
+                               an error (..).
                        */
-                       vch = GetChar();
-                       if (!is_dig(vch)) {     /* . or ... */
-                               if (vch == '.') {
-                                       if ((vch = GetChar()) == '.')
+                       ch = GetChar();
+                       if (!is_dig(ch)) {      /* . or ... */
+                               if (ch == '.') {
+                                       if ((ch = GetChar()) == '.')
                                                return ptok->tk_symb = ELLIPSIS;
-                                       /* This is funny: we can't push the
-                                          second dot back. But then again
-                                          ..<ch> is already an error in C,
-                                          so why bother ?
-                                       */
-                                       UnGetChar();
-                                       lexerror("illegal combination '..'");
-                               }
-                               UnGetChar();
+                                       UnGetChar();            /* not '.' */
+                                       ChPushBack('.');        /* sigh ... */
+                               } else
+                                       UnGetChar();            /* not '.' */
                                return ptok->tk_symb = '.';
                        }
-                       *np++ = '0';
-                       UnGetChar();
-#else
-                       if ((vch = GetChar()) == '.') {
-                               if ((vch = GetChar()) == '.')
-                                       return ptok->tk_symb = ELLIPSIS;
-                               UnGetChar();
-                               lexerror("illegal combination '..'");
-                       }
                        UnGetChar();
-                       return ptok->tk_symb = '.';
-#endif
-               }
-               if (ch == '0') {
-                       *np++ = ch;
-                       ch = GetChar();
-                       if (ch == 'x' || ch == 'X') {
-                               base = 16;
+                       ch = '.';
+                       flags |= FLG_DOTSEEN;
+                }
+               store(ch);
+               ch = GetChar();
+               while(in_idf(ch) || ch == '.') {
+                       store(ch);
+                       if (ch == '.') flags |= FLG_DOTSEEN;
+                       if (ch == 'e' || ch == 'E') {
+                               flags |= FLG_ESEEN;
                                ch = GetChar();
-                       }
-                       else
-                               base = 8;
-               }
-               while (vch = val_in_base(ch, base), vch >= 0) {
-                       val = val*base + vch;
-                       if (np < &buf[NUMSIZE])
-                               *np++ = ch;
-                       ch = GetChar();
-               }
-               if (is_suf(ch)) {
-                       register int suf_long = 0;
-                       register int suf_unsigned = 0;
-
-                       /*      The type of the integal constant is
-                               based on its suffix.
-                       */
-                       do {
-                               switch (ch) {
-                               case 'l':
-                               case 'L':
-                                       suf_long++;
-                                       break;
-                               case 'u':
-                               case 'U':
-                                       suf_unsigned++;
-                                       break;
+                               if (ch == '+' || ch == '-') {
+                                       flags |= FLG_DOTSEEN;   /* trick */
+                                       store(ch);
+                                       ch = GetChar();
                                }
-                               ch = GetChar();
-                       } while (is_suf(ch));
-                       UnGetChar();
-
-                       if (suf_long > 1)
-                               lexerror("only one long suffix allowed");
-                       if (suf_unsigned > 1)
-                               lexerror("only one unsigned suffix allowed");
-
-                       ptok->tk_fund = (suf_long && suf_unsigned) ? ULONG :
-                                       (suf_long) ? LONG : UNSIGNED;
-                       ptok->tk_ival = val;
-                       return ptok->tk_symb = INTEGER;
-               }
-#ifndef NOFLOAT
-               if (base == 16 || !(ch == '.' || ch == 'e' || ch == 'E'))
-#endif NOFLOAT
-               {
-                       UnGetChar();
-                       ptok->tk_ival = val;
-                       /*      The semantic analyser must know if the
-                               integral constant is given in octal/hexa-
-                               decimal form, in which case its type is
-                               UNSIGNED, or in decimal form, in which case
-                               its type is signed, indicated by
-                               the fund INTEGER.
-                       */
-                       ptok->tk_fund = 
-                               (base == 10 || (base == 8 && val == (arith)0))
-                                       ? INTEGER : UNSIGNED;
-                       return ptok->tk_symb = INTEGER;
-               }
-               /* where's the test for the length of the integral ???  */
-#ifndef NOFLOAT
-               if (ch == '.'){
-                       if (np < &buf[NUMSIZE])
-                               *np++ = ch;
-                       ch = GetChar();
-               }
-               while (is_dig(ch)){
-                       if (np < &buf[NUMSIZE])
-                               *np++ = ch;
-                       ch = GetChar();
-               }
-               if (ch == 'e' || ch == 'E') {
-                       if (np < &buf[NUMSIZE])
-                               *np++ = ch;
-                       ch = GetChar();
-                       if (ch == '+' || ch == '-') {
-                               if (np < &buf[NUMSIZE])
-                                       *np++ = ch;
-                               ch = GetChar();
-                       }
-                       if (!is_dig(ch)) {
-                               lexerror("malformed floating constant");
-                               if (np < &buf[NUMSIZE])
-                                       *np++ = ch;
-                       }
-                       while (is_dig(ch)) {
-                               if (np < &buf[NUMSIZE])
-                                       *np++ = ch;
-                               ch = GetChar();
-                       }
+                       } else ch = GetChar();
                }
+               store('\0');
+               UnGetChar();
 
-               /*      The type of an integral floating point
-                       constant may be given by the float (f)
-                       or long double (l) suffix.
-               */
-               if (ch == 'f' || ch == 'F')
-                       ptok->tk_fund = FLOAT;
-               else if (ch == 'l' || ch == 'L')
-                       ptok->tk_fund = LNGDBL;
-               else {
-                       ptok->tk_fund = DOUBLE;
-                       UnGetChar();
+               np = &buf[0];
+               ch = *np++;
+               if (siz_left < 0) {
+                       lexerror("number too long");
+                       if ((flags & FLG_DOTSEEN)
+                           || (flags & FLG_ESEEN
+                               && !(ch == '0'
+                                   && (*np == 'x' || *np == 'X')))) {
+                           ptok->tk_fval = Salloc("0.0", (unsigned) 4);
+                           ptok->tk_fund = DOUBLE;
+                           return ptok->tk_symb = FLOATING;
+                       }
+                       ptok->tk_ival = 1;
+                       ptok->tk_fund = ULONG;
+                       ptok->tk_symb = INTEGER;
                }
-
-               *np++ = '\0';
-               buf[0] = '-';   /* good heavens...      */
-               if (np == &buf[NUMSIZE+1]) {
-                       lexerror("floating constant too long");
-                       ptok->tk_fval = Salloc("0.0",(unsigned) 5) + 1;
+               /* Now, the pp-number must be converted into a token */
+               if ((flags & FLG_DOTSEEN)
+                       || (flags & FLG_ESEEN
+                           && !(ch == '0' && (*np == 'x' || *np == 'X')))) {
+                       strflt2tok(&buf[0], ptok);
+                       return ptok->tk_symb = FLOATING;
                }
-               else
-                       ptok->tk_fval = Salloc(buf,(unsigned) (np - buf)) + 1;
-               return ptok->tk_symb = FLOATING;
-#endif NOFLOAT
+               strint2tok(&buf[0], ptok);
+               return ptok->tk_symb = INTEGER;
        }
        case STEOI:                     /* end of text on source file   */
                return ptok->tk_symb = EOI;
+#ifndef        NOPP
+       case STMSPEC:
+               if (!InputLevel) goto garbage;
+               if (ch == TOKSEP) goto again;
+               /* fallthrough shouldn't happen */
+#endif
        default:                                /* this cannot happen   */
                crash("bad class for char 0%o", ch);
        }
@@ -533,16 +455,13 @@ skipcomment()
                while (c != '*') {
                        if (class(c) == STNL) {
                                ++LineNumber;
-                       } else
-                       if (c == EOI) {
+                       } else if (c == EOI) {
                                NoUnstack--;
 #ifdef LINT
                                lint_end_comment();
 #endif LINT
                                return;
                        }
-                       if (c == '/' && (c = GetChar()) == '*')
-                               strict("extra comment delimiter found");
                        c = GetChar();
 #ifdef LINT
                        lint_comment_char(c);
@@ -580,7 +499,8 @@ char_constant(nm)
                if (ch == '\\')
                        ch = quoted(GetChar());
                if (ch >= 128) ch -= 256;
-               val = val*256 + ch;
+               if (size < (int)int_size)
+                       val |= ch << 8 * size;
                size++;
                ch = GetChar();
        }
@@ -612,7 +532,7 @@ string_token(nm, stop_char, plen)
                        lexerror("end-of-file inside %s", nm);
                        break;
                }
-               if (ch == '\\')
+               if (ch == '\\' && !AccFileSpecifier)
                        ch = quoted(GetChar());
                str[pos++] = ch;
                if (pos == str_size)
@@ -776,3 +696,134 @@ trigraph()
        PushBack();
        return('?');
 }
+
+/* strflt2tok only checks the syntax of the floating-point number and
+ * selects the right type for the number.
+ */
+strflt2tok(fltbuf, ptok)
+char fltbuf[];
+struct token *ptok;
+{
+       register char *cp = fltbuf;
+       int malformed = 0;
+
+       while (is_dig(*cp)) cp++;
+       if (*cp == '.') {
+               cp++;
+               while (is_dig(*cp)) cp++;
+       }
+       if (*cp == 'e' || *cp == 'E') {
+               cp++;
+               if (*cp == '+' || *cp == '-')
+                       cp++;
+               if (!is_dig(*cp)) malformed++;
+               while (is_dig(*cp)) cp++;
+       }
+       if (*cp == 'f' || *cp == 'F') {
+               if (*(cp + 1)) malformed++;
+               *cp = '\0';
+               ptok->tk_fund = FLOAT;
+       } else if (*cp == 'l' || *cp == 'L') {
+               if (*(cp + 1)) malformed++;
+               *cp = '\0';
+               ptok->tk_fund = LNGDBL;
+       } else {
+               ptok->tk_fund = DOUBLE;
+       }
+       if (*cp) malformed++;
+       if (malformed) {
+               lexerror("malformed floating constant");
+               ptok->tk_fval = Salloc("0.0", (unsigned) 4);
+       } else {
+               ptok->tk_fval = Salloc(fltbuf, (unsigned) (cp - fltbuf + 1));
+       }
+}
+
+strint2tok(intbuf, ptok)
+char intbuf[];
+struct token *ptok;
+{
+       register char *cp = intbuf;
+       int base = 10;
+       arith val = 0, dig, ubound;
+       int uns_flg = 0, lng_flg = 0, malformed = 0, ovfl = 0;
+       int fund;
+
+       ASSERT(*cp != '-');
+       if (*cp == '0') {
+               cp++;
+               if (*cp == 'x' || *cp == 'X') {
+                       cp++;
+                       base = 16;
+               } else base = 8;
+       }
+       /* The upperbound will be the same as when computed with
+        * max_unsigned_arith / base (since base is even). The problem here
+        * is that unsigned arith is not accepted by all compilers.
+        */
+       ubound = max_arith / (base / 2);
+
+       while (is_hex(*cp)) {
+               dig = is_dig(*cp) ? *cp - '0'
+                                   : (( *cp >= 'A' && *cp <= 'F' ? *cp - 'A'
+                                                               : *cp - 'a')
+                                       + 10) ;
+               if (dig >= base) {
+                       malformed++;                    /* ignore */
+               }
+               else {
+                       if (val < 0 || val > ubound) ovfl++;
+                       val *= base;
+                       if (val < 0 && val + dig >= 0) ovfl++;
+                       val += dig;
+               }
+               cp++;
+       }
+
+       while (*cp) {
+               if (*cp == 'l' || *cp == 'L') lng_flg++;
+               else if (*cp == 'u' || *cp == 'U') uns_flg++;
+               else break;
+               cp++;
+       }
+       if (*cp) {
+           malformed++;
+       }
+       if (malformed) {
+               lexerror("malformed %s integer constant",
+                               (base == 10 ? "decimal"
+                                           : (base == 8 ? "octal"
+                                                       : "hexadecimal")));
+       } else {
+               if (lng_flg > 1)
+                       lexerror("only one long suffix allowed");
+               if (uns_flg > 1)
+                       lexerror("only one unsigned suffix allowed");
+       }
+       if (ovfl) {
+               lexwarning("overflow in constant");
+               fund = ULONG;
+       } else if ((val & full_mask[(int)int_size]) == val) {
+               if (val >= 0 && val <= max_int) fund = INT;
+               else fund = (base == 10 ? LONG : UNSIGNED);
+       } else if((val & full_mask[(int)long_size]) == val) {
+               if (val > 0) fund = LONG;
+               else fund = ULONG;
+       } else {        /* sizeof(arith) is greater than long_size */
+               ASSERT(arith_size > long_size);
+               lexwarning("constant too large for target machine");
+               /* cut the size to prevent further complaints */
+               val &= full_mask[(int)long_size];
+               fund = ULONG;
+       }
+       if (lng_flg) {
+           if (fund == INT) fund = LONG;
+           else if (fund == UNSIGNED) fund = ULONG;
+       }
+       if (uns_flg) {
+           if (fund == INT) fund = UNSIGNED;
+           else if (fund == LONG) fund = ULONG;
+       }
+       ptok->tk_fund = fund;
+       ptok->tk_ival = val;
+}
index fb1318c..9487199 100644 (file)
@@ -10,7 +10,6 @@
        to it.
 */
 
-#include "nofloat.h"
 #include "file_info.h"
 #include "nopp.h"
 
@@ -27,9 +26,7 @@ struct token  {
                        int tok_len;    /* length of row of bytes */
                } tok_string;
                arith tok_ival;         /* for INTEGER */
-#ifndef NOFLOAT
                char *tok_fval;         /* for FLOATING */
-#endif NOFLOAT
        } tok_data;
 };
 
@@ -41,9 +38,7 @@ struct token  {
 #define tk_bts tok_data.tok_string.tok_bts
 #define tk_len tok_data.tok_string.tok_len
 #define tk_ival        tok_data.tok_ival
-#ifndef NOFLOAT
 #define tk_fval        tok_data.tok_fval
-#endif NOFLOAT
 
 extern struct token dot, ahead, aside;
 
index 23005c9..c72f47d 100644 (file)
@@ -6,7 +6,6 @@
 /*             PARSER ERROR ADMINISTRATION             */
 
 #include       <alloc.h>
-#include       "nofloat.h"
 #include       "idf.h"
 #include       "arith.h"
 #include       "LLlex.h"
@@ -50,10 +49,8 @@ insert_token(tk)
                dot.tk_fund = INT;
                dot.tk_ival = 1;
                break;
-#ifndef NOFLOAT
        case FLOATING:
                dot.tk_fval = Salloc("0.0", 4);
                break;
-#endif NOFLOAT
        }
 }
index 37266f8..14f4838 100644 (file)
 #define SZ_WORD                (arith)4
 #define        SZ_INT          (arith)4
 #define        SZ_LONG         (arith)4
-#ifndef NOFLOAT
 #define        SZ_FLOAT        (arith)4
 #define        SZ_DOUBLE       (arith)8
-#endif NOFLOAT
 #define        SZ_POINTER      (arith)4
 
 /* target machine alignment requirements       */
 #define AL_WORD                SZ_WORD
 #define        AL_INT          SZ_WORD
 #define        AL_LONG         SZ_WORD
-#ifndef NOFLOAT
 #define        AL_FLOAT        SZ_WORD
 #define        AL_DOUBLE       SZ_WORD
-#endif NOFLOAT
 #define        AL_POINTER      SZ_WORD
 #define AL_STRUCT      1
 #define AL_UNION       1
 #define GSTATIC                        /* for large global "static" arrays */
 
 
-!File: nofloat.h
-#undef NOFLOAT         1       /* if NOT defined, floats are implemented */
-
-
-!File: noRoption.h
-#undef NOROPTION       1       /* if NOT defined, R option is implemented */
-
-
 !File: nocross.h
 #undef NOCROSS         1       /* if NOT defined, cross compiler */
 
index f4c92f3..f90d145 100644 (file)
@@ -4,7 +4,7 @@
 # Machine and environ dependent definitions
 EMHOME = ../../..
 CC = cc
-CC = /proj/em/Work/bin/fcc.cc
+CC = $(EMHOME)/bin/fcc
 CFLOW = cflow
 MKDEP = $(EMHOME)/bin/mkdep
 PRID = $(EMHOME)/bin/prid
@@ -17,6 +17,7 @@ EMOLIB = $(EMHOME)/modules/lib/libemopt.a
 EMELIB = $(EMHOME)/modules/lib/libeme.a $(EMHOME)/lib/em_data.a
 STRLIB = $(EMHOME)/modules/lib/libstring.a
 PRTLIB = $(EMHOME)/modules/lib/libprint.a
+FLTLIB = $(EMHOME)/modules/lib/libflt.a
 EMMESLIB = $(EMHOME)/modules/lib/libem_mes.a
 EMMESOLIB = $(EMHOME)/modules/lib/libem_mesO.a
 EMMESCELIB = $(EMHOME)/modules/lib/libem_mesCE.a
@@ -28,15 +29,15 @@ INPLIB = $(EMHOME)/modules/lib/libinput.a
 ALLOCLIB = $(EMHOME)/modules/lib/liballoc.a
 MALLOC = $(EMHOME)/modules/lib/malloc.o
 LIBS = $(INPLIB) $(EMMESLIB) $(EMKLIB) $(PRTLIB) $(STRLIB) \
-       $(ALLOCLIB) $(MALLOC) $(SYSLIB)
+       $(ALLOCLIB) $(MALLOC) $(SYSLIB) $(FLTLIB)
 ELIBS = $(INPLIB) $(EMMESLIB) $(EMELIB) $(PRTLIB) $(STRLIB) \
-       $(ALLOCLIB) $(MALLOC) $(SYSLIB)
+       $(ALLOCLIB) $(MALLOC) $(SYSLIB) $(FLTLIB)
 OLIBS = $(INPLIB) $(EMMESOLIB) $(EMOLIB) $(EMKLIB) $(PRTLIB) $(STRLIB) \
-       $(ALLOCLIB) $(MALLOC) $(SYSLIB)
+       $(ALLOCLIB) $(MALLOC) $(SYSLIB) $(FLTLIB)
 CELIBS = $(INPLIB) $(EMMESCELIB) $(EMCELIB) $(PRTLIB) $(STRLIB) \
-       $(ALLOCLIB) $(MALLOC) $(SYSLIB)
+       $(ALLOCLIB) $(MALLOC) $(SYSLIB) $(FLTLIB)
 LLIBS = $(INPLIB) $(EMMESLIB) $(PRTLIB) $(STRLIB) \
-       $(ALLOCLIB) $(MALLOC) $(SYSLIB)
+       $(ALLOCLIB) $(MALLOC) $(SYSLIB) $(FLTLIB)
 LIB_INCLUDES = -I$(EMHOME)/modules/h -I$(EMHOME)/modules/pkg
 EM_INCLUDES = -I$(EMHOME)/h
 SYSLLIB = $(EMHOME)/modules/lib/llib-lsystem.ln
@@ -70,7 +71,7 @@ LOBJ =        tokenfile.o declar.o statement.o expression.o program.o Lpars.o ival.o
 
 # Objects of hand-written C files
 CSRC = main.c idf.c declarator.c decspecs.c struct.c \
-       expr.c ch7.c ch7bin.c cstoper.c arith.c \
+       expr.c ch7.c ch7bin.c cstoper.c fltcstoper.c arith.c \
        code.c dumpidf.c error.c field.c\
        tokenname.c LLlex.c LLmessage.c \
        input.c domacro.c replace.c init.c options.c \
@@ -79,7 +80,7 @@ CSRC =        main.c idf.c declarator.c decspecs.c struct.c \
        pragma.c blocks.c dataflow.c Version.c \
        l_lint.c l_states.c l_misc.c l_ev_ord.c l_outdef.c l_comment.c l_dummy.c
 COBJ = main.o idf.o declarator.o decspecs.o struct.o \
-       expr.o ch7.o ch7bin.o cstoper.o arith.o \
+       expr.o ch7.o ch7bin.o cstoper.o fltcstoper.o arith.o \
        code.o dumpidf.o error.o field.o\
        tokenname.o LLlex.o LLmessage.o \
        input.o domacro.o replace.o init.o options.o \
@@ -106,7 +107,7 @@ GSRC =      $(GCSRC)  $(GHSTRSRC)
 # .h files generated by `make hfiles LLfiles'; PLEASE KEEP THIS UP-TO-DATE!
 GHSRC =        botch_free.h dataflow.h debug.h density.h errout.h \
        idfsize.h ifdepth.h inputtype.h lapbuf.h argbuf.h lint.h \
-       nobitfield.h nofloat.h nopp.h noRoption.h nocross.h \
+       nobitfield.h nopp.h nocross.h \
        nparams.h numsize.h parbufsize.h pathlength.h Lpars.h \
        strsize.h target_sizes.h textsize.h use_tmp.h spec_arith.h static.h \
        regcount.h
@@ -290,10 +291,8 @@ main.o: input.h
 main.o: inputtype.h
 main.o: level.h
 main.o: lint.h
-main.o: noRoption.h
 main.o: nobitfield.h
 main.o: nocross.h
-main.o: nofloat.h
 main.o: nopp.h
 main.o: proto.h
 main.o: sizes.h
@@ -319,10 +318,8 @@ idf.o: idfsize.h
 idf.o: label.h
 idf.o: level.h
 idf.o: lint.h
-idf.o: noRoption.h
 idf.o: nobitfield.h
 idf.o: nocross.h
-idf.o: nofloat.h
 idf.o: nopp.h
 idf.o: nparams.h
 idf.o: proto.h
@@ -346,7 +343,6 @@ declarator.o: level.h
 declarator.o: lint.h
 declarator.o: nobitfield.h
 declarator.o: nocross.h
-declarator.o: nofloat.h
 declarator.o: nopp.h
 declarator.o: proto.h
 declarator.o: sizes.h
@@ -361,9 +357,7 @@ decspecs.o: decspecs.h
 decspecs.o: def.h
 decspecs.o: level.h
 decspecs.o: lint.h
-decspecs.o: noRoption.h
 decspecs.o: nobitfield.h
-decspecs.o: nofloat.h
 decspecs.o: spec_arith.h
 decspecs.o: type.h
 struct.o: LLlex.h
@@ -379,10 +373,8 @@ struct.o: file_info.h
 struct.o: idf.h
 struct.o: level.h
 struct.o: lint.h
-struct.o: noRoption.h
 struct.o: nobitfield.h
 struct.o: nocross.h
-struct.o: nofloat.h
 struct.o: nopp.h
 struct.o: proto.h
 struct.o: sizes.h
@@ -394,7 +386,9 @@ struct.o: type.h
 expr.o: LLlex.h
 expr.o: Lpars.h
 expr.o: arith.h
+expr.o: assert.h
 expr.o: botch_free.h
+expr.o: debug.h
 expr.o: declar.h
 expr.o: decspecs.h
 expr.o: def.h
@@ -404,10 +398,8 @@ expr.o: idf.h
 expr.o: label.h
 expr.o: level.h
 expr.o: lint.h
-expr.o: noRoption.h
 expr.o: nobitfield.h
 expr.o: nocross.h
-expr.o: nofloat.h
 expr.o: nopp.h
 expr.o: sizes.h
 expr.o: spec_arith.h
@@ -424,7 +416,6 @@ ch7.o: idf.h
 ch7.o: label.h
 ch7.o: lint.h
 ch7.o: nobitfield.h
-ch7.o: nofloat.h
 ch7.o: nopp.h
 ch7.o: proto.h
 ch7.o: spec_arith.h
@@ -437,9 +428,7 @@ ch7bin.o: expr.h
 ch7bin.o: idf.h
 ch7bin.o: label.h
 ch7bin.o: lint.h
-ch7bin.o: noRoption.h
 ch7bin.o: nobitfield.h
-ch7bin.o: nofloat.h
 ch7bin.o: nopp.h
 ch7bin.o: spec_arith.h
 ch7bin.o: struct.h
@@ -453,24 +442,37 @@ cstoper.o: idf.h
 cstoper.o: label.h
 cstoper.o: nobitfield.h
 cstoper.o: nocross.h
-cstoper.o: nofloat.h
 cstoper.o: nopp.h
 cstoper.o: sizes.h
 cstoper.o: spec_arith.h
 cstoper.o: target_sizes.h
 cstoper.o: type.h
+fltcstoper.o: Lpars.h
+fltcstoper.o: arith.h
+fltcstoper.o: assert.h
+fltcstoper.o: debug.h
+fltcstoper.o: expr.h
+fltcstoper.o: idf.h
+fltcstoper.o: label.h
+fltcstoper.o: nobitfield.h
+fltcstoper.o: nocross.h
+fltcstoper.o: nopp.h
+fltcstoper.o: sizes.h
+fltcstoper.o: spec_arith.h
+fltcstoper.o: target_sizes.h
+fltcstoper.o: type.h
 arith.o: Lpars.h
 arith.o: arith.h
+arith.o: assert.h
+arith.o: debug.h
 arith.o: expr.h
 arith.o: field.h
 arith.o: idf.h
 arith.o: label.h
 arith.o: lint.h
 arith.o: mes.h
-arith.o: noRoption.h
 arith.o: nobitfield.h
 arith.o: nocross.h
-arith.o: nofloat.h
 arith.o: nopp.h
 arith.o: proto.h
 arith.o: sizes.h
@@ -495,10 +497,8 @@ code.o: l_lint.h
 code.o: label.h
 code.o: level.h
 code.o: lint.h
-code.o: noRoption.h
 code.o: nobitfield.h
 code.o: nocross.h
-code.o: nofloat.h
 code.o: nopp.h
 code.o: sizes.h
 code.o: spec_arith.h
@@ -519,7 +519,6 @@ dumpidf.o: idf.h
 dumpidf.o: label.h
 dumpidf.o: lint.h
 dumpidf.o: nobitfield.h
-dumpidf.o: nofloat.h
 dumpidf.o: nopp.h
 dumpidf.o: proto.h
 dumpidf.o: spec_arith.h
@@ -536,7 +535,6 @@ error.o: expr.h
 error.o: file_info.h
 error.o: label.h
 error.o: lint.h
-error.o: nofloat.h
 error.o: nopp.h
 error.o: spec_arith.h
 error.o: tokenname.h
@@ -553,7 +551,6 @@ field.o: label.h
 field.o: lint.h
 field.o: nobitfield.h
 field.o: nocross.h
-field.o: nofloat.h
 field.o: nopp.h
 field.o: sizes.h
 field.o: spec_arith.h
@@ -564,7 +561,6 @@ tokenname.o: Lpars.h
 tokenname.o: arith.h
 tokenname.o: file_info.h
 tokenname.o: idf.h
-tokenname.o: nofloat.h
 tokenname.o: nopp.h
 tokenname.o: spec_arith.h
 tokenname.o: tokenname.h
@@ -582,7 +578,6 @@ LLlex.o: input.h
 LLlex.o: lint.h
 LLlex.o: macro.h
 LLlex.o: nocross.h
-LLlex.o: nofloat.h
 LLlex.o: nopp.h
 LLlex.o: numsize.h
 LLlex.o: sizes.h
@@ -594,7 +589,6 @@ LLmessage.o: Lpars.h
 LLmessage.o: arith.h
 LLmessage.o: file_info.h
 LLmessage.o: idf.h
-LLmessage.o: nofloat.h
 LLmessage.o: nopp.h
 LLmessage.o: spec_arith.h
 input.o: file_info.h
@@ -614,7 +608,6 @@ domacro.o: idfsize.h
 domacro.o: ifdepth.h
 domacro.o: input.h
 domacro.o: macro.h
-domacro.o: nofloat.h
 domacro.o: nopp.h
 domacro.o: nparams.h
 domacro.o: parbufsize.h
@@ -632,7 +625,6 @@ replace.o: idfsize.h
 replace.o: input.h
 replace.o: lapbuf.h
 replace.o: macro.h
-replace.o: nofloat.h
 replace.o: nopp.h
 replace.o: nparams.h
 replace.o: numsize.h
@@ -654,10 +646,8 @@ options.o: idf.h
 options.o: idfsize.h
 options.o: lint.h
 options.o: macro.h
-options.o: noRoption.h
 options.o: nobitfield.h
 options.o: nocross.h
-options.o: nofloat.h
 options.o: nopp.h
 options.o: sizes.h
 options.o: spec_arith.h
@@ -668,7 +658,6 @@ skip.o: arith.h
 skip.o: class.h
 skip.o: file_info.h
 skip.o: input.h
-skip.o: nofloat.h
 skip.o: nopp.h
 skip.o: spec_arith.h
 stack.o: Lpars.h
@@ -680,9 +669,7 @@ stack.o: idf.h
 stack.o: level.h
 stack.o: lint.h
 stack.o: mes.h
-stack.o: noRoption.h
 stack.o: nobitfield.h
-stack.o: nofloat.h
 stack.o: nopp.h
 stack.o: spec_arith.h
 stack.o: stack.h
@@ -698,7 +685,6 @@ type.o: idf.h
 type.o: lint.h
 type.o: nobitfield.h
 type.o: nocross.h
-type.o: nofloat.h
 type.o: nopp.h
 type.o: proto.h
 type.o: sizes.h
@@ -714,7 +700,6 @@ ch7mon.o: idf.h
 ch7mon.o: label.h
 ch7mon.o: lint.h
 ch7mon.o: nobitfield.h
-ch7mon.o: nofloat.h
 ch7mon.o: nopp.h
 ch7mon.o: spec_arith.h
 ch7mon.o: type.h
@@ -725,9 +710,7 @@ label.o: idf.h
 label.o: label.h
 label.o: level.h
 label.o: lint.h
-label.o: noRoption.h
 label.o: nobitfield.h
-label.o: nofloat.h
 label.o: nopp.h
 label.o: spec_arith.h
 label.o: type.h
@@ -748,7 +731,6 @@ eval.o: lint.h
 eval.o: mes.h
 eval.o: nobitfield.h
 eval.o: nocross.h
-eval.o: nofloat.h
 eval.o: nopp.h
 eval.o: sizes.h
 eval.o: spec_arith.h
@@ -766,19 +748,19 @@ switch.o: density.h
 switch.o: expr.h
 switch.o: idf.h
 switch.o: label.h
-switch.o: noRoption.h
 switch.o: nobitfield.h
-switch.o: nofloat.h
+switch.o: nocross.h
 switch.o: nopp.h
+switch.o: sizes.h
 switch.o: spec_arith.h
 switch.o: switch.h
+switch.o: target_sizes.h
 switch.o: type.h
 conversion.o: Lpars.h
 conversion.o: arith.h
 conversion.o: lint.h
 conversion.o: nobitfield.h
 conversion.o: nocross.h
-conversion.o: nofloat.h
 conversion.o: sizes.h
 conversion.o: spec_arith.h
 conversion.o: target_sizes.h
@@ -788,7 +770,6 @@ util.o: align.h
 util.o: def.h
 util.o: lint.h
 util.o: nocross.h
-util.o: nofloat.h
 util.o: regcount.h
 util.o: sizes.h
 util.o: stack.h
@@ -812,7 +793,6 @@ proto.o: level.h
 proto.o: lint.h
 proto.o: nobitfield.h
 proto.o: nocross.h
-proto.o: nofloat.h
 proto.o: nopp.h
 proto.o: nparams.h
 proto.o: proto.h
@@ -834,7 +814,6 @@ pragma.o: idfsize.h
 pragma.o: ifdepth.h
 pragma.o: input.h
 pragma.o: macro.h
-pragma.o: nofloat.h
 pragma.o: nopp.h
 pragma.o: nparams.h
 pragma.o: parbufsize.h
@@ -847,7 +826,6 @@ blocks.o: atw.h
 blocks.o: label.h
 blocks.o: lint.h
 blocks.o: nocross.h
-blocks.o: nofloat.h
 blocks.o: sizes.h
 blocks.o: spec_arith.h
 blocks.o: stack.h
@@ -871,7 +849,6 @@ l_lint.o: label.h
 l_lint.o: level.h
 l_lint.o: lint.h
 l_lint.o: nobitfield.h
-l_lint.o: nofloat.h
 l_lint.o: nopp.h
 l_lint.o: spec_arith.h
 l_lint.o: stack.h
@@ -896,7 +873,6 @@ l_states.o: label.h
 l_states.o: level.h
 l_states.o: lint.h
 l_states.o: nobitfield.h
-l_states.o: nofloat.h
 l_states.o: nopp.h
 l_states.o: spec_arith.h
 l_states.o: stack.h
@@ -915,7 +891,6 @@ l_misc.o: label.h
 l_misc.o: level.h
 l_misc.o: lint.h
 l_misc.o: nobitfield.h
-l_misc.o: nofloat.h
 l_misc.o: nopp.h
 l_misc.o: spec_arith.h
 l_misc.o: stack.h
@@ -937,7 +912,6 @@ l_ev_ord.o: label.h
 l_ev_ord.o: level.h
 l_ev_ord.o: lint.h
 l_ev_ord.o: nobitfield.h
-l_ev_ord.o: nofloat.h
 l_ev_ord.o: nopp.h
 l_ev_ord.o: spec_arith.h
 l_ev_ord.o: stack.h
@@ -962,7 +936,6 @@ l_outdef.o: label.h
 l_outdef.o: level.h
 l_outdef.o: lint.h
 l_outdef.o: nobitfield.h
-l_outdef.o: nofloat.h
 l_outdef.o: nopp.h
 l_outdef.o: spec_arith.h
 l_outdef.o: stack.h
@@ -998,7 +971,6 @@ declar.o: level.h
 declar.o: lint.h
 declar.o: nobitfield.h
 declar.o: nocross.h
-declar.o: nofloat.h
 declar.o: nopp.h
 declar.o: proto.h
 declar.o: sizes.h
@@ -1021,7 +993,6 @@ statement.o: l_state.h
 statement.o: label.h
 statement.o: lint.h
 statement.o: nobitfield.h
-statement.o: nofloat.h
 statement.o: nopp.h
 statement.o: spec_arith.h
 statement.o: stack.h
@@ -1035,9 +1006,7 @@ expression.o: file_info.h
 expression.o: idf.h
 expression.o: label.h
 expression.o: lint.h
-expression.o: noRoption.h
 expression.o: nobitfield.h
-expression.o: nofloat.h
 expression.o: nopp.h
 expression.o: spec_arith.h
 expression.o: type.h
@@ -1055,7 +1024,6 @@ program.o: l_state.h
 program.o: label.h
 program.o: lint.h
 program.o: nobitfield.h
-program.o: nofloat.h
 program.o: nopp.h
 program.o: spec_arith.h
 program.o: type.h
@@ -1075,10 +1043,8 @@ ival.o: l_lint.h
 ival.o: label.h
 ival.o: level.h
 ival.o: lint.h
-ival.o: noRoption.h
 ival.o: nobitfield.h
 ival.o: nocross.h
-ival.o: nofloat.h
 ival.o: nopp.h
 ival.o: proto.h
 ival.o: sizes.h
index 9d012b7..b5d103f 100644 (file)
 #define SZ_WORD                (arith)4
 #define        SZ_INT          (arith)4
 #define        SZ_LONG         (arith)4
-#ifndef NOFLOAT
 #define        SZ_FLOAT        (arith)4
 #define        SZ_DOUBLE       (arith)8
 #define        SZ_LNGDBL       (arith)8        /* for now */
-#endif NOFLOAT
 #define        SZ_POINTER      (arith)4
 
 /* target machine alignment requirements       */
 #define AL_WORD                SZ_WORD
 #define        AL_INT          SZ_WORD
 #define        AL_LONG         SZ_WORD
-#ifndef NOFLOAT
 #define        AL_FLOAT        SZ_WORD
 #define        AL_DOUBLE       SZ_WORD
 #define        AL_LNGDBL       SZ_WORD
-#endif NOFLOAT
 #define        AL_POINTER      SZ_WORD
 #define AL_STRUCT      1
 #define AL_UNION       1
 #define GSTATIC                        /* for large global "static" arrays */
 
 
-!File: nofloat.h
-#undef NOFLOAT         1       /* if NOT defined, floats are implemented */
-
-
-!File: noRoption.h
-#define NOROPTION      1       /* if NOT defined, R option is implemented */
-
-
 !File: nocross.h
 #undef NOCROSS         1       /* if NOT defined, cross compiler */
 
index 470c141..0fc8359 100644 (file)
@@ -5,16 +5,13 @@
 /* $Header$ */
 /*      A L I G N M E N T   D E F I N I T I O N S      */
 
-#include "nofloat.h"
 #include "nocross.h"
 #include "target_sizes.h"
 
 #ifndef NOCROSS
 extern int
        short_align, word_align, int_align, long_align,
-#ifndef NOFLOAT
        float_align, double_align, lngdbl_align,
-#endif NOFLOAT
        pointer_align,
        struct_align, union_align;
 #else NOCROSS
@@ -22,11 +19,9 @@ extern int
 #define word_align     ((int)AL_WORD)
 #define int_align      ((int)AL_INT)
 #define long_align     ((int)AL_LONG)
-#ifndef NOFLOAT
 #define float_align    ((int)AL_FLOAT)
 #define double_align   ((int)AL_DOUBLE)
 #define        lngdbl_align    ((int)AL_LNGDBL)
-#endif NOFLOAT
 #define pointer_align  ((int)AL_POINTER)
 #define struct_align   ((int)AL_STRUCT)
 #define union_align    ((int)AL_UNION)
index dbdf564..955b232 100644 (file)
@@ -13,9 +13,9 @@
 
 #include       <alloc.h>
 #include       "lint.h"
-#include       "nofloat.h"
 #include       "nobitfield.h"
 #include       "idf.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "sizes.h"
 #include       "type.h"
 #include       "Lpars.h"
 #include       "field.h"
 #include       "mes.h"
-#include       "noRoption.h"
+#include       "assert.h"
 
 extern char *symbol2str();
 extern char options[];
 
-arithbalance(e1p, oper, e2p)   /* RM 6.6 */
+arithbalance(e1p, oper, e2p)   /* 3.1.2.5 */
        register struct expr **e1p, **e2p;
        int oper;
 {
@@ -38,15 +38,17 @@ arithbalance(e1p, oper, e2p)        /* RM 6.6 */
                of the arithmetic operator oper.
        */
        register int t1, t2, u1, u2;
+       int shifting = (oper == LEFT || oper == RIGHT
+                       || oper == LEFTAB || oper == RIGHTAB);
 
        t1 = any2arith(e1p, oper);
        t2 = any2arith(e2p, oper);
        /* Now t1 and t2 are either INT, LONG, FLOAT, DOUBLE, or LNGDBL */
 
-#ifndef NOFLOAT
        /*      If any operand has the type long double, the other operand
                is converted to long double.
        */
+       /* ??? t1 == LNGDBL, t2 == DOUBLE */
        if (t1 == LNGDBL) {
                if (t2 != LNGDBL)
                        int2float(e2p, lngdbl_type);
@@ -82,7 +84,6 @@ arithbalance(e1p, oper, e2p)  /* RM 6.6 */
                        int2float(e1p, float_type);
                return;
        }
-#endif NOFLOAT
 
        /* Now they are INT or LONG */
        u1 = (*e1p)->ex_type->tp_unsigned;
@@ -93,7 +94,8 @@ arithbalance(e1p, oper, e2p)  /* RM 6.6 */
        */
        if (t1 == LONG && u1 && (t2 != LONG || !u2))
                t2 = int2int(e2p, ulong_type);
-       else if (t2 == LONG && u2 && (t1 != LONG || !u1))
+       else if (t2 == LONG && u2 && (t1 != LONG || !u1)
+                       && !shifting)   /* ??? */
                t1 = int2int(e1p, ulong_type);
 
        /*      If one operand has type long int and the other has type unsigned
@@ -104,7 +106,7 @@ arithbalance(e1p, oper, e2p)        /* RM 6.6 */
        */
        if (t1 == LONG && t2 == INT && u2)
                t2 = int2int(e2p, (int_size<long_size)? long_type : ulong_type);
-       else if (t2 == LONG && t1 == INT && u1)
+       else if (t2 == LONG && t1 == INT && u1 && !shifting)    /* ??? */
                t1 = int2int(e1p, (int_size<long_size)? long_type : ulong_type);
        if (int_size > long_size) /* sanity check */
                crash("size of int exceeds size of long");
@@ -115,17 +117,17 @@ arithbalance(e1p, oper, e2p)      /* RM 6.6 */
        if (t1 == LONG && t2 != LONG)
                t2 = int2int(e2p, long_type);
        else
-       if (t2 == LONG && t1 != LONG)
+       if (t2 == LONG && t1 != LONG && !shifting)      /* ??? */
                t1 = int2int(e1p, long_type);
 
        /*      If either operand has type unsigned int, the other operand
                is converted to unsigned int.
                Otherwise, both operands have type int.
        */
-       if (u1 && !u2)
+       if (u1 && !u2 && !shifting)
                t2 = int2int(e2p, (t1 == LONG) ? ulong_type : uint_type);
        else
-       if (!u1 && u2)
+       if (!u1 && u2 && !shifting)
                t1 = int2int(e1p, (t2 == LONG) ? ulong_type : uint_type);
 }
 
@@ -168,15 +170,15 @@ ch76pointer(expp, oper, tp)
                        ch7cast(expp, oper, tp);
        }
        else
-       if (    is_integral_type(exp->ex_type)
-#ifndef NOROPTION
-               &&
-               (       !options['R'] /* we don't care */ ||
-                       (oper == EQUAL || oper == NOTEQUAL || oper == ':')
-               )
-#endif NOROPTION
-       )               /* ch 7.7 */
+       if (is_integral_type(exp->ex_type)) {
+               if ((oper != EQUAL && oper != NOTEQUAL && oper != ':')
+                   || !(is_cp_cst(exp) && exp->VL_VALUE == 0)) {
+                       expr_error(exp,"%s on %s and pointer",
+                                       symbol2str(oper),
+                                       symbol2str(exp->ex_type->tp_fund));
+               }
                ch7cast(expp, CAST, tp);
+       }
        else    {
                expr_error(exp, "%s on %s and pointer",
                                symbol2str(oper),
@@ -191,8 +193,8 @@ any2arith(expp, oper)
        register struct expr **expp;
        register int oper;
 {
-       /*      Turns any expression into int_type, long_type or
-               double_type.
+       /*      Turns any expression into int_type, long_type,
+               float_type, double_type or lngdbl_type.
        */
        int fund;
 
@@ -200,41 +202,32 @@ any2arith(expp, oper)
        case CHAR:
        case SHORT:
        case GENERIC:
-               int2int(expp,
-                       (*expp)->ex_type->tp_unsigned ? uint_type : int_type);
+               ASSERT((*expp)->ex_type->tp_size <= int_type->tp_size);
+
+               if ((*expp)->ex_type->tp_unsigned
+                   && (*expp)->ex_type->tp_size == int_type->tp_size) {
+                       int2int(expp, uint_type);
+               } else {
+                       int2int(expp, int_type);
+               }
                break;
        case INT:
        case LONG:
                break;
        case ENUM:
-               /* test the admissibility of the operator */
-               if (    is_test_op(oper) || oper == '=' || oper == PARCOMMA ||
-                       oper == ',' || oper == ':'
-               )       {
-                       /* allowed by K & R */
-               }
-               else
-#ifndef NOROPTION
-               if (!options['R'])      {
-                       /* allowed by us */
-               }
-               else
-                       expr_warning(*expp, "%s on enum", symbol2str(oper));
-#endif NOROPTION
 #ifndef        LINT
                int2int(expp, int_type);
 #endif LINT
                break;
-#ifndef        NOFLOAT
        case FLOAT:
-/*
+/*     only when it is a parameter and the default promotion should
+       occur. Hence this code is moved to any2parameter().
                float2float(expp, double_type);
                break;
 */
        case DOUBLE:
        case LNGDBL:
                break;
-#endif NOFLOAT
 #ifndef NOBITFIELD
        case FIELD:
                field2arith(expp);
@@ -322,7 +315,6 @@ int2int(expp, tp)
        return exp->ex_type->tp_fund;
 }
 
-#ifndef NOFLOAT
 int2float(expp, tp)
        register struct expr **expp;
        struct type *tp;
@@ -331,18 +323,20 @@ int2float(expp, tp)
                converted to the floating type tp.
        */
        register struct expr *exp = *expp;
-       char buf[32];
        
        fp_used = 1;
        if (is_cp_cst(exp)) {
                *expp = new_expr();
                **expp = *exp;
-               sprint(buf+1, "%ld", (long)(exp->VL_VALUE));
-               buf[0] = '-';
-               exp = *expp;
+               /* sprint(buf+1, "%ld", (long)(exp->VL_VALUE));
+               /* buf[0] = '-';
+               */
+               exp = *expp;    /* ??? */
+               
                exp->ex_type = tp;
                exp->ex_class = Float;
-               exp->FL_VALUE = Salloc(buf, (unsigned)strlen(buf)+2) + 1;
+               exp->FL_VALUE = 0 /* Salloc(buf, (unsigned)strlen(buf)+1) */ ;
+               flt_arith2flt(exp->VL_VALUE, &(exp->FL_ARITH));
                exp->FL_DATLAB = 0;
        }
        else    *expp = arith2arith(tp, INT2FLOAT, *expp);
@@ -376,7 +370,6 @@ float2float(expp, tp)
        else
                *expp = arith2arith(tp, FLOAT2FLOAT, *expp);
 }
-#endif NOFLOAT
 
 array2pointer(exp)
        register struct expr *exp;
@@ -384,8 +377,9 @@ array2pointer(exp)
        /*      The expression, which must be an array, is converted
                to a pointer.
        */
-       exp->ex_type = construct_type(POINTER, exp->ex_type->tp_up, 0,
-                                    (arith)0, NO_PROTO);
+       exp->ex_type = construct_type(POINTER, exp->ex_type->tp_up
+                                   , /* exp->ex_type->tp_typequal */ 0
+                                   , (arith)0, NO_PROTO);
 }
 
 function2pointer(exp)
@@ -454,10 +448,9 @@ opnd2logical(expp, oper)
        case LONG:
        case ENUM:
        case POINTER:
-#ifndef NOFLOAT
        case FLOAT:
        case DOUBLE:
-#endif NOFLOAT
+       case LNGDBL:
                break;
        default:
                expr_error(*expp, "%s operand to %s",
@@ -503,13 +496,11 @@ any2opnd(expp, oper)
 {
        if (!*expp)
                return;
-       switch ((*expp)->ex_type->tp_fund)      {       /* RM 7.1 */
+       switch ((*expp)->ex_type->tp_fund)      {
        case CHAR:
        case SHORT:
        case ENUM:
-#ifndef NOFLOAT
-       case FLOAT:
-#endif NOFLOAT
+       /* case FLOAT:  /* not necessary anymore */
                any2arith(expp, oper);
                break;
        case ARRAY:
@@ -533,10 +524,8 @@ any2parameter(expp)
        /*      To handle default argument promotions
        */
        any2opnd(expp, '(');
-#ifndef NOFLOAT
        if ((*expp)->ex_type->tp_fund == FLOAT)
                float2float(expp, double_type);
-#endif NOFLOAT
 }
 
 #ifndef NOBITFIELD
@@ -569,19 +558,13 @@ field2arith(expp)
 }
 #endif NOBITFIELD
 
-#ifndef NOFLOAT
-/*     switch_sign_fp() negates the given floating constant expression
-       The lexical analyser has reserved an extra byte of space in front
-       of the string containing the representation of the floating
-       constant.  This byte contains the '-' character and we have to
-       take care of the first byte the fl_value pointer points to.
-*/
+/*     switch_sign_fp() negates the given floating constant expression,
+ *     and frees the string representing the old value.
+ */
 switch_sign_fp(expr)
        register struct expr *expr;
 {
-       if (*(expr->FL_VALUE) == '-')
-               ++(expr->FL_VALUE);
-       else
-               --(expr->FL_VALUE);
+       flt_umin(&(expr->FL_ARITH));
+       if (expr->FL_VALUE) free(expr->FL_VALUE);
+       expr->FL_VALUE = 0;
 }
-#endif NOFLOAT
index 5ffea6c..6a79be6 100644 (file)
@@ -26,3 +26,7 @@
 #define        arith   long                            /* dummy */
 
 #endif SPECIAL_ARITHMETICS
+
+#define        arith_size      (sizeof(arith))
+#define        arith_sign      ((arith) 1 << (arith_size * 8 - 1))
+#define        max_arith       (~arith_sign)
index 57bd94c..022521b 100644 (file)
@@ -3,13 +3,13 @@
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
 /* $Header$ */
-/*     S E M A N T I C   A N A L Y S I S -- C H A P T E R  7 RM        */
+/*     S E M A N T I C   A N A L Y S I S -- C H A P T E R  3.3         */
 
 #include       "lint.h"
-#include       "nofloat.h"
 #include       "debug.h"
 #include       "nobitfield.h"
 #include       "idf.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "proto.h"
 #include       "type.h"
@@ -23,6 +23,7 @@
 
 extern char options[];
 extern char *symbol2str();
+extern struct type *qualifier_type();
 
 /*     Most expression-handling routines have a pointer to a
        (struct type *) as first parameter. The object under the pointer
@@ -52,15 +53,15 @@ ch7sel(expp, oper, idf)
                                "char c; c->selector"
                        */
                        switch (tp->tp_fund)    {
+                       case POINTER:
+                               break;
                        case INT:
                        case LONG:
-                               /* Allowed by RM 14.1 */
+                               /* An error is given in idf2sdef() */
                                ch7cast(expp, CAST, pa_type);
                                sd = idf2sdef(idf, tp);
                                tp = sd->sd_stype;
                                break;
-                       case POINTER:
-                               break;
                        default:
                                expr_error(exp, "-> applied to %s",
                                        symbol2str(tp->tp_fund));
@@ -69,7 +70,9 @@ ch7sel(expp, oper, idf)
                                return;
                        }
                }
-       } /* oper == ARROW */
+       } else {                /* oper == '.' */
+               /* nothing */
+       }
        exp = *expp;
        switch (tp->tp_fund)    {
        case POINTER:   /* for int *p;  p->next = ...   */
@@ -105,8 +108,10 @@ ch7sel(expp, oper, idf)
                        */
                        exp->VL_VALUE += sd->sd_offset;
                        exp->ex_type = sd->sd_type;
-                       if (exp->ex_type == error_type)
+                       exp->ex_lvalue = exp->ex_type->tp_fund != ARRAY;
+                       if (exp->ex_type == error_type) {
                                exp->ex_flags |= EX_ERROR;
+                       }
                }
                else
                if (exp->ex_class == Oper)      {
@@ -116,13 +121,17 @@ ch7sel(expp, oper, idf)
                                ASSERT(is_cp_cst(op->op_right));
                                op->op_right->VL_VALUE += sd->sd_offset;
                                exp->ex_type = sd->sd_type;
-                               if (exp->ex_type == error_type)
+                               exp->ex_lvalue = exp->ex_type->tp_fund != ARRAY;
+                               if (exp->ex_type == error_type) {
                                        exp->ex_flags |= EX_ERROR;
+                               }
                        }
                        else {
                                exp = new_oper(sd->sd_type, exp, '.',
                                                intexpr(sd->sd_offset, INT));
-                               exp->ex_lvalue = exp->OP_LEFT->ex_lvalue;
+                               exp->ex_lvalue = sd->sd_type->tp_fund != ARRAY;
+                               if (!exp->OP_LEFT->ex_lvalue)
+                                       exp->ex_flags |= EX_ILVALUE;
                        }
                }
        }
@@ -130,11 +139,15 @@ ch7sel(expp, oper, idf)
                exp = new_oper(sd->sd_type,
                        exp, oper, intexpr(sd->sd_offset, INT));
                exp->ex_lvalue = (sd->sd_type->tp_fund != ARRAY);
+               exp->ex_flags &= ~EX_ILVALUE;
        }
        if (sd->sd_type->tp_typequal & TQ_CONST)
                exp->ex_flags |= EX_READONLY;
        if (sd->sd_type->tp_typequal & TQ_VOLATILE)
                exp->ex_flags |= EX_VOLATILE;
+       if (oper == '.' && exp->ex_flags & EX_READONLY)  {
+               exp->ex_type = qualifier_type(exp->ex_type, TQ_CONST);
+       }
        *expp = exp;
 }
 
@@ -191,15 +204,6 @@ ch7cast(expp, oper, tp)
                int i = is_integral_type(tp);
 
                if (oldi && i)  {
-                       if (    oper != CAST
-                       &&      (       tp->tp_fund == ENUM
-                               ||      oldtp->tp_fund == ENUM
-                               )
-                       ) {
-                               expr_warning(*expp,
-                                       "dubious %s on enum",
-                                       symbol2str(oper));
-                       }
 #ifdef LINT
                        if (oper == CAST)
                                (*expp)->ex_type = tp;
@@ -209,13 +213,8 @@ ch7cast(expp, oper, tp)
                        int2int(expp, tp);
 #endif LINT
                }
-#ifndef NOFLOAT
                else
                if (oldi && !i) {
-                       if (oldtp->tp_fund == ENUM && oper != CAST)
-                               expr_warning(*expp,
-                                       "conversion of enum to %s\n",
-                                       symbol2str(tp->tp_fund));
 #ifdef LINT
                        if (oper == CAST)
                                (*expp)->ex_type = tp;
@@ -247,12 +246,6 @@ ch7cast(expp, oper, tp)
                        float2float(expp, tp);
 #endif LINT
                }
-#else NOFLOAT
-               else {
-                       crash("(ch7cast) floats not implemented\n");
-                       /*NOTREACHED*/
-               }
-#endif NOFLOAT
        }
        else
        if (oldtp->tp_fund == POINTER && tp->tp_fund == POINTER)        {
@@ -330,6 +323,9 @@ ch7cast(expp, oper, tp)
                        );
                (*expp)->ex_type = tp;          /* brute force */
        }
+       if (oper == CAST) {
+               (*expp)->ex_flags |= EX_ILVALUE;
+       }
 }
 
 /*     Determine whether two types are equal.
@@ -348,9 +344,10 @@ equal_type(tp, otp)
                return 0;
        if (tp->tp_align != otp->tp_align)
                return 0;
-       if (tp->tp_fund != ARRAY)
+       if (tp->tp_fund != ARRAY /* && tp->tp_fund != STRUCT */ ) {     /* UNION ??? */
                if (tp->tp_size != otp->tp_size)
                        return 0;
+       }
 
        switch (tp->tp_fund) {
 
@@ -359,9 +356,13 @@ equal_type(tp, otp)
                        each parameter in the composite parameter type list
                        is the composite type of the corresponding paramaters.
                */
-               if (tp->tp_proto && otp->tp_proto &&
-                   !equal_proto(tp->tp_proto, otp->tp_proto))
-                       return 0;
+               if (tp->tp_proto && otp->tp_proto) {
+                       if (!equal_proto(tp->tp_proto, otp->tp_proto))
+                               return 0;
+               } else if (tp->tp_proto || otp->tp_proto) {
+                       if (!legal_mixture(tp, otp))
+                               return 0;
+               }
                return equal_type(tp->tp_up, otp->tp_up);
 
        case ARRAY:
@@ -374,6 +375,16 @@ equal_type(tp, otp)
                return equal_type(tp->tp_up, otp->tp_up);
 
        case POINTER:
+               if (equal_type(tp->tp_up, otp->tp_up)) {
+                   if (otp->tp_up->tp_typequal & TQ_CONST) {
+                       if (!(tp->tp_up->tp_typequal & TQ_CONST)) {
+                           strict("illegal use of pointer to const object");
+                       }
+                   }
+                   return 1;
+               }
+               else return 0;
+
        case FIELD:
                return equal_type(tp->tp_up, otp->tp_up);
 
@@ -387,6 +398,78 @@ equal_type(tp, otp)
        }
 }
 
+check_pseudoproto(pl, opl)
+       register struct proto *pl, *opl;
+{
+       int retval = 1;
+
+       if (pl->pl_flag & PL_ELLIPSIS) {
+               error("illegal ellipsis terminator");
+               return 2;
+       }
+       while (pl && opl) {
+           if (!equal_type(pl->pl_type, opl->pl_type)) {
+               if (!(pl->pl_flag & PL_ERRGIVEN)
+                   && !(opl->pl_flag & PL_ERRGIVEN))
+                       error("incorrect type for parameter %s of definition",
+                               opl->pl_idf->id_text);
+               pl->pl_flag |= PL_ERRGIVEN;
+               opl->pl_flag |= PL_ERRGIVEN;
+               retval = 2;
+           }
+           pl = pl->next;
+           opl = opl->next;
+       }
+       if (pl || opl) {
+               error("incorrect number of parameters");
+               retval = 2;
+       }
+       return retval;
+}
+
+legal_mixture(tp, otp)
+       struct type *tp, *otp;
+{
+       register struct proto *pl = tp->tp_proto, *opl = otp->tp_proto;
+       int retval = 1;
+       struct proto *prot;
+       int fund;
+
+       ASSERT( (pl != 0) ^ (opl != 0));
+       if (pl)  {
+               prot = pl;
+       } else  {
+               prot = opl;
+       }
+       if (!opl && otp->tp_pseudoproto) {
+               return check_pseudoproto(tp->tp_proto, otp->tp_pseudoproto);
+       }
+
+       if (prot->pl_flag & PL_ELLIPSIS) {
+               if (!(prot->pl_flag & PL_ERRGIVEN)) {
+                       if (pl)
+                               error("illegal ellipsis terminator");
+                       else    error("ellipsis terminator in previous (prototype) declaration");
+               }
+               prot->pl_flag |= PL_ERRGIVEN;
+               prot = prot->next;
+               return 2;
+       }
+       while (prot) {
+                               /* if (!(prot->pl_flag & PL_ELLIPSIS)) {} */
+               fund = prot->pl_type->tp_fund;
+               if (fund == CHAR || fund == SHORT || fund == FLOAT) {
+                       if (!(prot->pl_flag & PL_ERRGIVEN))
+                           error("illegal %s parameter in %sdeclaration",
+                               symbol2str(fund), (opl ? "previous (prototype) " : "" ));
+                       prot->pl_flag |= PL_ERRGIVEN;
+                       retval = 2;
+               }
+               prot = prot->next;
+       }
+       return retval;
+}
+
 equal_proto(pl, opl)
        register struct proto *pl, *opl;
 {
@@ -397,15 +480,35 @@ equal_proto(pl, opl)
                (a function prototype), the composite type is a function
                prototype with parameter type list.
        */
-       if (pl == 0 || opl == 0) return 0;
+       while ( pl && opl) {
 
-       if (pl->pl_flag != opl->pl_flag)
+           if ((pl->pl_flag & ~PL_ERRGIVEN) != (opl->pl_flag & ~PL_ERRGIVEN))
                return 0;
 
-       if (!equal_type(pl->pl_type, opl->pl_type))
+           if (!equal_type(pl->pl_type, opl->pl_type))
                return 0;
 
-       return equal_proto(pl->next, opl->next);
+           pl = pl->next;
+           opl = opl->next;
+       }
+       return !(pl || opl);
+}
+
+recurconst(tp)
+struct type *tp;
+{
+       register struct sdef *sdf;
+
+       ASSERT(tp);
+       if (!tp) return 0;
+       if (tp->tp_typequal & TQ_CONST) return 1;
+       sdf = tp->tp_sdef;
+       while (sdf) {
+               if (recurconst(sdf->sd_type))
+                       return 1;
+               sdf = sdf->sd_sdef;
+       }
+       return 0;
 }
 
 ch7asgn(expp, oper, expr)
@@ -431,13 +534,17 @@ ch7asgn(expp, oper, expr)
        struct type *tp;
 
        /* We expect an lvalue */
-       if (!exp->ex_lvalue)    {
-               expr_error(exp, "no lvalue in lhs of %s", symbol2str(oper));
-               exp->ex_depth = 99;     /* no direct store/load at EVAL() */
-                       /* what is 99 ??? DG */
+       if (!exp->ex_lvalue) {
+               expr_error(exp, "no lvalue in operand of %s", symbol2str(oper));
+       } else if (exp->ex_flags & EX_ILVALUE)  {
+               strict("incorrect lvalue in operand of %s", symbol2str(oper));
+       } else if (exp->ex_flags & EX_READONLY) {
+               expr_error(exp, "operand of %s is read-only", symbol2str(oper));
+       } else if (fund == STRUCT || fund == UNION) {
+               if (recurconst(exp->ex_type))
+                       expr_error(expr,"operand of %s contains a const-qualified member",
+                                           symbol2str(oper));
        }
-       if (exp->ex_flags & EX_READONLY)
-               strict("lhs of assignment is read-only");
 
        /*      Preserve volatile markers across the tree.
                This is questionable, depending on the way the optimizer
@@ -520,11 +627,9 @@ is_arith_type(tp)
        case INT:
        case LONG:
        case ENUM:
-#ifndef NOFLOAT
        case FLOAT:
        case DOUBLE:
        case LNGDBL:
-#endif NOFLOAT
                return 1;
 #ifndef NOBITFIELD
        case FIELD:
index e43f159..66d3ff6 100644 (file)
@@ -3,20 +3,19 @@
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
 /* $Header$ */
-/* SEMANTIC ANALYSIS (CHAPTER 7RM)  --  BINARY OPERATORS */
+/* SEMANTIC ANALYSIS (CHAPTER 3.3)  --  BINARY OPERATORS */
 
 #include       "botch_free.h"
 #include       <alloc.h>
-#include       "nofloat.h"
 #include       "lint.h"
 #include       "idf.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "type.h"
 #include       "struct.h"
 #include       "label.h"
 #include       "expr.h"
 #include       "Lpars.h"
-#include       "noRoption.h"
 
 extern char options[];
 extern char *symbol2str();
@@ -40,8 +39,8 @@ ch7bin(expp, oper, expr)
        any2opnd(expp, oper);
        any2opnd(&expr, oper);
        switch (oper)   {
-       case '[':                               /* RM 7.1 */
-               /* RM 14.3 states that indexing follows the commutative laws */
+       case '[':                               /* 3.3.2.1 */
+               /* indexing follows the commutative laws */
                switch ((*expp)->ex_type->tp_fund)      {
                case POINTER:
                case ARRAY:
@@ -67,14 +66,10 @@ ch7bin(expp, oper, expr)
                ch7mon('*', expp);
                break;
 
-       case '(':                               /* RM 7.1 */
+       case '(':                               /* 3.3.2.2 */
                if (    (*expp)->ex_type->tp_fund == POINTER &&
                        (*expp)->ex_type->tp_up->tp_fund == FUNCTION
                )       {
-#ifndef NOROPTION
-                       if (options['R'])
-                               warning("function pointer called");
-#endif NOROPTION
                        ch7mon('*', expp);
                }
                if ((*expp)->ex_type->tp_fund != FUNCTION)      {
@@ -82,6 +77,8 @@ ch7bin(expp, oper, expr)
                                symbol2str((*expp)->ex_type->tp_fund));
                        /* leave the expression; it may still serve */
                        free_expression(expr);  /* there go the parameters */
+                       *expp = new_oper(error_type,
+                                       *expp, '(', (struct expr *)0);
                }
                else
                        *expp = new_oper((*expp)->ex_type->tp_up,
@@ -89,7 +86,7 @@ ch7bin(expp, oper, expr)
                (*expp)->ex_flags |= EX_SIDEEFFECTS;
                break;
 
-       case PARCOMMA:                          /* RM 7.1 */
+       case PARCOMMA:                          /* 3.3.2.2 */
                if ((*expp)->ex_type->tp_fund == FUNCTION)
                        function2pointer(*expp);
                *expp = new_oper(expr->ex_type, *expp, PARCOMMA, expr);
@@ -102,7 +99,7 @@ ch7bin(expp, oper, expr)
        case ORAB:
                opnd2integral(expp, oper);
                opnd2integral(&expr, oper);
-               /* Fall through */
+               /* fallthrough */
        case '/':
        case DIVAB:
        case TIMESAB:
@@ -115,7 +112,7 @@ ch7bin(expp, oper, expr)
        case '|':
                opnd2integral(expp, oper);
                opnd2integral(&expr, oper);
-               /* Fall through */
+               /* fallthrough */
        case '*':
                arithbalance(expp, oper, &expr);
                commutative_binop(expp, oper, expr);
@@ -127,7 +124,7 @@ ch7bin(expp, oper, expr)
                        expr = *expp;
                        *expp = etmp;
                }
-               /*FALLTHROUGH*/
+               /* fallthrough */
        case PLUSAB:
        case POSTINCR:
        case PLUSPLUS:
@@ -226,8 +223,9 @@ ch7bin(expp, oper, expr)
                                ch7bin(expp, ',', expr);
                        }
                }
-               else
+               else {
                        *expp = new_oper(int_type, *expp, oper, expr);
+               }
                (*expp)->ex_flags |= EX_LOGICAL;
                break;
 
@@ -310,6 +308,8 @@ mk_binop(expp, oper, expr, commutative)
 
        if (is_cp_cst(expr) && is_cp_cst(ex))
                cstbin(expp, oper, expr);
+       else if (is_fp_cst(expr) && is_fp_cst(ex))
+               fltcstbin(expp, oper, expr);
        else    {
                *expp = (commutative && expr->ex_depth >= ex->ex_depth) ?
                                new_oper(ex->ex_type, expr, oper, ex) :
@@ -320,16 +320,18 @@ mk_binop(expp, oper, expr, commutative)
 pointer_arithmetic(expp1, oper, expp2)
        register struct expr **expp1, **expp2;
 {
+       int typ;
        /*      prepares the integral expression expp2 in order to
                apply it to the pointer expression expp1
        */
-#ifndef NOFLOAT
-       if (any2arith(expp2, oper) == DOUBLE)   {
+       if ((typ = any2arith(expp2, oper)) == FLOAT
+           || typ == DOUBLE
+           || typ == LNGDBL)   {
                expr_error(*expp2,
-                       "illegal combination of float and pointer");
+                       "illegal combination of %s and pointer",
+                       symbol2str(typ));
                erroneous2int(expp2);
        }
-#endif NOFLOAT
        ch7bin( expp2, '*',
                intexpr(size_of_type((*expp1)->ex_type->tp_up, "object"),
                        pa_type->tp_fund)
index 9e1be20..ab3e386 100644 (file)
@@ -3,13 +3,13 @@
  * See the copyright notice in the ACK home directory, in the file "Copyright".
  */
 /* $Header$ */
-/* SEMANTIC ANALYSIS (CHAPTER 7RM) -- MONADIC OPERATORS */
+/* SEMANTIC ANALYSIS (CHAPTER 3.3) -- MONADIC OPERATORS */
 
 #include       "botch_free.h"
 #include       <alloc.h>
-#include       "nofloat.h"
 #include       "nobitfield.h"
 #include       "Lpars.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "type.h"
 #include       "label.h"
@@ -18,7 +18,7 @@
 #include       "def.h"
 
 extern char options[];
-extern long full_mask[/*MAXSIZE*/];    /* cstoper.c */
+extern arith full_mask[/*MAXSIZE*/];   /* cstoper.c */
 char *symbol2str();
 
 ch7mon(oper, expp)
@@ -29,16 +29,20 @@ ch7mon(oper, expp)
        register struct expr *expr;
 
        switch (oper)   {
-       case '*':                       /* RM 7.2 */
+       case '*':                       /* 3.3.3.2 */
                /* no FIELD type allowed        */
                if ((*expp)->ex_type->tp_fund == ARRAY)
                        array2pointer(*expp);
-               if ((*expp)->ex_type->tp_fund != POINTER)       {
-                       expr_error(*expp,
-                               "* applied to non-pointer (%s)",
-                               symbol2str((*expp)->ex_type->tp_fund));
-               }
-               else {
+               if ((*expp)->ex_type->tp_fund != POINTER) {
+                   if ((*expp)->ex_type->tp_fund != FUNCTION) {
+                           expr_error(*expp,
+                                   "* applied to non-pointer (%s)",
+                                   symbol2str((*expp)->ex_type->tp_fund));
+                   } else {
+                           warning("superfluous use of * on function");
+                           /* ignore indirection (yegh) */
+                   }
+               } else {
                        expr = *expp;
                        if (expr->ex_lvalue == 0 && expr->ex_class != String)
                                /* dereference in administration only */
@@ -54,16 +58,17 @@ ch7mon(oper, expp)
                                (*expp)->ex_flags |= EX_READONLY;
                        if ((*expp)->ex_type->tp_typequal & TQ_VOLATILE)
                                (*expp)->ex_flags |= EX_VOLATILE;
+                       (*expp)->ex_flags &= ~EX_ILVALUE;
                }
                break;
        case '&':
                if ((*expp)->ex_type->tp_fund == ARRAY) {
-                       warning("& before array ignored");
+                       expr_warning(*expp, "& before array ignored");
                        array2pointer(*expp);
                }
                else
                if ((*expp)->ex_type->tp_fund == FUNCTION) {
-                       warning("& before function ignored");
+                       expr_warning(*expp, "& before function ignored");
                        function2pointer(*expp);
                }
                else
@@ -74,6 +79,8 @@ ch7mon(oper, expp)
 #endif NOBITFIELD
                if (!(*expp)->ex_lvalue)
                        expr_error(*expp, "& applied to non-lvalue");
+               else if ((*expp)->ex_flags & EX_ILVALUE)
+                       expr_error(*expp, "& applied to illegal lvalue");
                else {
                        /* assume that enums are already filtered out   */
                        if (ISNAME(*expp)) {
@@ -90,28 +97,25 @@ ch7mon(oper, expp)
                                        break;  /* break case '&' */
                                }
                        }
-                       (*expp)->ex_type = pointer_to((*expp)->ex_type);
+                       (*expp)->ex_type = pointer_to((*expp)->ex_type,
+                                               (*expp)->ex_type->tp_typequal);
                        (*expp)->ex_lvalue = 0;
                        (*expp)->ex_flags &= ~EX_READONLY;
                }
                break;
        case '~':
-#ifndef NOFLOAT
        {
                int fund = (*expp)->ex_type->tp_fund;
 
-               if (fund == FLOAT || fund == DOUBLE)    {
-                       expr_error(
-                               *expp,
-                               "~ not allowed on %s operands",
-                               symbol2str(fund)
-                       );
+               if (fund == FLOAT || fund == DOUBLE || fund == LNGDBL)  {
+                       expr_error( *expp,
+                                   "~ not allowed on %s operands",
+                                   symbol2str(fund));
                        erroneous2int(expp);
                        break;
                }
                /* FALLTHROUGH */
        }
-#endif NOFLOAT
        case '-':
                any2arith(expp, oper);
                if (is_cp_cst(*expp))   {
@@ -124,11 +128,9 @@ ch7mon(oper, expp)
                          );
                }
                else
-#ifndef NOFLOAT
                if (is_fp_cst(*expp))
                        switch_sign_fp(*expp);
                else
-#endif NOFLOAT
                        *expp = new_oper((*expp)->ex_type,
                                        NILEXPR, oper, *expp);
                break;
@@ -152,7 +154,7 @@ ch7mon(oper, expp)
                break;
        case SIZEOF:
                if (ISNAME(*expp) && (*expp)->VL_IDF->id_def->df_formal_array)
-                       warning("sizeof formal array %s is sizeof pointer!",
+                       expr_warning(*expp, "sizeof formal array %s is sizeof pointer!",
                                (*expp)->VL_IDF->id_text);
                expr = intexpr((*expp)->ex_class == String ?
                                   (arith)((*expp)->SG_LEN) :
index 682d10a..3291782 100644 (file)
 %iSTGARB
 STSKIP:\r \t\013\f
 STNL:\n
-STCOMP:-!&+<=>|
-STSIMP:%()*,/:;?[]^{}~
+STCOMP:-!&+<=>|*%/^
+STSIMP:(),:;?[]{}~
 STCHAR:'
-STIDF:a-zA-KM-Z_
+STIDF:a-zA-KM-Z_\003
 STELL:L
 STNUM:.0-9
 STSTR:"
 STEOI:\200
+STMSPEC:\004
 %T/* character classes */
 %T#include "class.h"
 %Tchar tkclass[] = {
@@ -44,7 +45,7 @@ STEOI:\200
 %      ISHEX
 %
 %C
-1:a-fA-F
+1:0-9a-fA-F
 %Tchar ishex[] = {
 %p
 %T};
@@ -57,14 +58,6 @@ STEOI:\200
 %p
 %T};
 %
-%      ISSUF
-%
-%C
-1:lLuU
-%Tchar issuf[] = {
-%p
-%T};
-%
 %      ISWSP
 %
 %C
index d57ce26..7377131 100644 (file)
@@ -13,7 +13,7 @@
 #define        class(ch)       (tkclass[ch])
 
 /*     Being the start of a token is, fortunately, a mutual exclusive
-       property, so, although there are less than 16 classes they can be
+       property, so, as there are less than 16 classes they can be
        packed in 4 bits.
 */
 
 #define        STSTR   8       /* the starter of a string                      */
 #define        STNUM   9       /* the starter of a numeric constant            */
 #define        STEOI   10      /* End-Of-Information mark                      */
+#define        STMSPEC 11      /* special class for token expansion            */
+
+#define        NOEXPM  '\003'  /* don't expand the next macro identifier       */
+#define        TOKSEP  '\004'  /* the token separator                          */
 
 /*     But occurring inside a token is not, so we need 1 bit for each
        class.  This is implemented as a collection of tables to speed up
index 5717399..21b0224 100644 (file)
@@ -11,6 +11,7 @@
 #include       <alloc.h>
 #include       "dataflow.h"
 #include       "use_tmp.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "type.h"
 #include       "idf.h"
@@ -28,7 +29,6 @@
 #include       "specials.h"
 #include       "atw.h"
 #include       "assert.h"
-#include       "noRoption.h"
 #include       "file_info.h"
 #ifdef LINT
 #include       "l_lint.h"
@@ -37,9 +37,8 @@
 label lab_count = 1;
 label datlab_count = 1;
 
-#ifndef NOFLOAT
 int fp_used;
-#endif NOFLOAT
+extern arith NewLocal();       /* util.c       */
 
 /* global function info */
 char *func_name;
@@ -109,12 +108,10 @@ end_code()
        /*      end_code() performs the actions to be taken when closing
                the output stream.
        */
-#ifndef NOFLOAT
        if (fp_used) {
                /* floating point used  */
                C_ms_flt();
        }
-#endif NOFLOAT
        def_strings(str_list);
        str_list = 0;
        C_ms_src((int)(LineNumber - 2), FileName);
@@ -204,6 +201,7 @@ begin_proc(ds, idf)         /* to be called when entering a procedure */
                DfaStartFunction(name);
 #endif DATAFLOW
 
+
        /* set global function info */
        func_name = name;
        if (def->df_type->tp_fund != FUNCTION) {
@@ -368,32 +366,31 @@ code_declaration(idf, expr, lvl, sc)
                If there is a storage class indication (EXTERN/STATIC),
                code_declaration() will generate an exa or ina.
                The sc is the actual storage class, as given in the
-               declaration.  This is to allow:
-                       extern int a;
-                       int a = 5;
-               while at the same time forbidding
-                       extern int a = 5;
+               declaration.
        */
        register struct def *def = idf->id_def;
        register arith size = def->df_type->tp_size;
+       int fund = def->df_type->tp_fund;
        int def_sc = def->df_sc;
        
        if (def_sc == TYPEDEF)  /* no code for typedefs         */
                return;
-       if (sc == EXTERN && expr && !is_anon_idf(idf))
-               error("%s is extern; cannot initialize", idf->id_text);
 #ifndef PREPEND_SCOPES
-       if (def->df_type->tp_fund == FUNCTION) {
+       if (fund == FUNCTION) {
                code_scope(idf->id_text, def);
        }
 #endif PREPEND_SCOPES
        if (lvl == L_GLOBAL)    {       /* global variable      */
                /* is this an allocating declaration? */
                if (    (sc == 0 || sc == STATIC)
-                       && def->df_type->tp_fund != FUNCTION
+                       && fund != FUNCTION
                        && size >= 0
                )
                        def->df_alloc = ALLOC_SEEN;
+               if (expr && def_sc == STATIC && sc == EXTERN) {
+                       warning("%s redeclared extern", idf->id_text);
+                       def->df_sc = EXTERN;
+               }
                if (expr) {     /* code only if initialized */
 #ifndef PREPEND_SCOPES
                        code_scope(idf->id_text, def);
@@ -407,7 +404,7 @@ code_declaration(idf, expr, lvl, sc)
                /* STATIC, EXTERN, GLOBAL, IMPLICIT, AUTO or REGISTER */
                switch (def_sc) {
                case STATIC:
-                       if (def->df_type->tp_fund == FUNCTION) {
+                       if (fund == FUNCTION) {
                                /* should produce "inp $function" ??? */
                                break;
                        }
@@ -426,6 +423,9 @@ code_declaration(idf, expr, lvl, sc)
                        }
                        break;
                case EXTERN:
+                       if (expr && !is_anon_idf(idf) && level != L_GLOBAL)
+                               error("cannot initialize extern in block"
+                                               , idf->id_text);
                case GLOBAL:
                case IMPLICIT:
                        /* we are sure there is no expression */
@@ -437,6 +437,11 @@ code_declaration(idf, expr, lvl, sc)
                case REGISTER:
                        if (expr)
                                loc_init(expr, idf);
+                       else if ((fund == ARRAY)
+                                   && (def->df_type->tp_size == (arith)-1)) {
+                               error("size for local %s unknown"
+                                       , idf->id_text);
+                       }
                        break;
                default:
                        crash("bad local storage class");
@@ -455,27 +460,44 @@ loc_init(expr, id)
        */
        register struct expr *e = expr;
        register struct type *tp = id->id_def->df_type;
+       static arith tmpoffset = 0;
+       static arith unknownsize = 0;
        
        ASSERT(id->id_def->df_sc != STATIC);
        switch (tp->tp_fund)    {
        case ARRAY:
+               if (id->id_def->df_type->tp_size == (arith) -1)
+                       unknownsize = 1;
        case STRUCT:
        case UNION:
-               error("automatic %s cannot be initialized in declaration",
-                       symbol2str(tp->tp_fund));
-               free_expression(e);
+               if (!tmpoffset) {       /* first time for this variable */
+                       tmpoffset = id->id_def->df_address;
+                       id->id_def->df_address = data_label();
+                       C_df_dlb((label)id->id_def->df_address);
+               } else {
+                       /* generate a 'loi, sti' sequence. The peephole
+                        * optimizer will optimize this into a 'blm'
+                        * whenever possible.
+                        */
+                       C_lae_dlb((label)id->id_def->df_address, (arith)0);
+                       C_loi(tp->tp_size);
+                       if (unknownsize) {
+                               /* tmpoffset += tp->tp_size; */
+                               unknownsize = 0;
+
+                               tmpoffset = NewLocal(tp->tp_size
+                                                   , tp->tp_align
+                                                   , regtype(tp)
+                                                   , id->id_def->df_sc);
+                       }
+                       C_lal(tmpoffset);
+                       C_sti(tp->tp_size);
+                       id->id_def->df_address = tmpoffset;
+                       tmpoffset = 0;
+               }
                return;
        }
        if (ISCOMMA(e)) {       /* embraced: int i = {12};      */
-#ifndef NOROPTION
-               if (options['R'])       {
-                       if (ISCOMMA(e->OP_LEFT)) /* int i = {{1}} */
-                               expr_error(e, "extra braces not allowed");
-                       else
-                       if (e->OP_RIGHT != 0) /* int i = {1 , 2} */
-                               expr_error(e, "too many initializers");
-               }
-#endif NOROPTION
                while (e)       {
                        loc_init(e->OP_LEFT, id);
                        e = e->OP_RIGHT;
@@ -510,25 +532,17 @@ bss(idf)
 #ifndef        PREPEND_SCOPES
        code_scope(idf->id_text, idf->id_def);
 #endif PREPEND_SCOPES
-       /*      Since bss() is only called if df_alloc is non-zero, and
-               since df_alloc is only non-zero if size >= 0, we have:
-       */
-       /*      but we already gave a warning at the declaration of the
-               array. Besides, the message given here does not apply to
-               voids
-       
-       if (options['R'] && size == 0)
-               warning("actual array of size 0");
-       */
        C_df_dnam(idf->id_text);
        C_bss_cst(ATW(size), (arith)0, 1);
 }
 
-formal_cvt(df)
+formal_cvt(hasproto,df)
+       int hasproto;
        register struct def *df;
 {
        /*      formal_cvt() converts a formal parameter of type char or
-               short from int to that type.
+               short from int to that type. It also converts a formal
+               parameter of type float from a double to a float.
        */
        register struct type *tp = df->df_type;
 
@@ -540,6 +554,12 @@ formal_cvt(df)
                   No, you can't do this on the stack! (CJ)
                */
                StoreLocal(df->df_address, tp->tp_size);
+       } else if (tp->tp_size != double_size
+                   && tp->tp_fund == FLOAT
+                   && !hasproto) {
+               LoadLocal(df->df_address, double_size);
+               conversion(double_type, float_type);
+               StoreLocal(df->df_address, tp->tp_size);
        }
 }
 
index 536d887..b9b6acd 100644 (file)
@@ -8,7 +8,6 @@
 #include       "lint.h"
 #ifndef        LINT
 
-#include       "nofloat.h"
 #include       <em.h>
 #include       "arith.h"
 #include       "type.h"
@@ -17,9 +16,7 @@
 
 #define        T_SIGNED                1
 #define        T_UNSIGNED              2
-#ifndef NOFLOAT
 #define        T_FLOATING              3
-#endif NOFLOAT
 
 /*     conversion() generates the EM code for a conversion between
        the types char, short, int, long, float, double and pointer.
@@ -52,9 +49,7 @@ conversion(from_type, to_type)
                        C_cii();
                        break;
                case T_UNSIGNED:
-#ifndef NOFLOAT
                case T_FLOATING:
-#endif NOOFLOAT
                        if ((int)from_size < (int)word_size) {
                                C_loc(from_size);
                                C_loc(word_size);
@@ -79,14 +74,11 @@ conversion(from_type, to_type)
                case T_UNSIGNED:
                        C_cuu();
                        break;
-#ifndef NOFLOAT
                case T_FLOATING:
                        C_cuf();
                        break;
-#endif NOFLOAT
                }
                break;
-#ifndef NOFLOAT
        case T_FLOATING:
                C_loc(from_size);
                C_loc(to_size);
@@ -102,17 +94,14 @@ conversion(from_type, to_type)
                        break;
                }
                break;
-#endif NOFLOAT
        default:
                crash("(conversion) illegal type conversion");
                /*NOTREACHED*/
        }
        if ((int)(to_type->tp_size) < (int)word_size
-#ifndef NOFLOAT
            && to_cnvtype != T_FLOATING
-#endif NOFLOAT
            ) {
-               extern long full_mask[];
+               extern arith full_mask[];
 
                if (to_cnvtype == T_SIGNED) {
                        C_loc(to_type->tp_size);
@@ -142,12 +131,10 @@ convtype(tp)
        case LONG:
        case ENUM:
                return tp->tp_unsigned ? T_UNSIGNED : T_SIGNED;
-#ifndef NOFLOAT
        case FLOAT:
        case DOUBLE:
        case LNGDBL:
                return T_FLOATING;
-#endif NOFLOAT
        case POINTER:
                return T_UNSIGNED;
        }
index d613edb..b2c185e 100644 (file)
@@ -7,6 +7,7 @@
 
 #include       "target_sizes.h"
 #include       "idf.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "type.h"
 #include       "label.h"
 #include       "Lpars.h"
 #include       "assert.h"
 
-long mach_long_sign;   /* sign bit of the machine long */
-int mach_long_size;    /* size of long on this machine == sizeof(long) */
-long full_mask[MAXSIZE];/* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */
+arith full_mask[MAXSIZE];/* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */
 arith max_int;         /* maximum integer on target machine    */
 arith max_unsigned;    /* maximum unsigned on target machine   */
+extern int ResultKnown;
 
 cstbin(expp, oper, expr)
        register struct expr **expp, *expr;
@@ -39,35 +39,38 @@ cstbin(expp, oper, expr)
                break;
        case '/':
                if (o2 == 0)    {
-                       expr_error(expr, "division by 0");
+                       if (!ResultKnown)
+                               expr_error(expr, "division by 0");
+                       else
+                               expr_warning(expr, "division by 0");
                        break;
                }
                if (uns)        {
                        /*      this is more of a problem than you might
                                think on C compilers which do not have
-                               unsigned long.
+                               unsigned arith (== long (probably)).
                        */
-                       if (o2 & mach_long_sign)        {/* o2 > max_long */
+                       if (o2 & arith_sign)    {/* o2 > max_arith */
                                o1 = ! (o1 >= 0 || o1 < o2);
                                /*      this is the unsigned test
-                                       o1 < o2 for o2 > max_long
+                                       o1 < o2 for o2 > max_arith
                                */
                        }
-                       else    {               /* o2 <= max_long */
-                               long half, bit, hdiv, hrem, rem;
+                       else    {               /* o2 <= max_arith */
+                               arith half, bit, hdiv, hrem, rem;
 
-                               half = (o1 >> 1) & ~mach_long_sign;
+                               half = (o1 >> 1) & ~arith_sign;
                                bit = o1 & 01;
                                /*      now o1 == 2 * half + bit
-                                       and half <= max_long
-                                       and bit <= max_long
+                                       and half <= max_arith
+                                       and bit <= max_arith
                                */
                                hdiv = half / o2;
                                hrem = half % o2;
                                rem = 2 * hrem + bit;
                                o1 = 2 * hdiv + (rem < 0 || rem >= o2);
                                /*      that is the unsigned compare
-                                       rem >= o2 for o2 <= max_long
+                                       rem >= o2 for o2 <= max_arith
                                */
                        }
                }
@@ -76,24 +79,27 @@ cstbin(expp, oper, expr)
                break;
        case '%':
                if (o2 == 0)    {
-                       expr_error(expr, "modulo by 0");
+                       if (!ResultKnown)
+                               expr_error(expr, "modulo by 0");
+                       else
+                               expr_warning(expr, "modulo by 0");
                        break;
                }
                if (uns)        {
-                       if (o2 & mach_long_sign)        {/* o2 > max_long */
+                       if (o2 & arith_sign)    {/* o2 > max_arith */
                                o1 = (o1 >= 0 || o1 < o2) ? o1 : o1 - o2;
                                /*      this is the unsigned test
-                                       o1 < o2 for o2 > max_long
+                                       o1 < o2 for o2 > max_arith
                                */
                        }
-                       else    {               /* o2 <= max_long */
-                               long half, bit, hrem, rem;
+                       else    {               /* o2 <= max_arith */
+                               arith half, bit, hrem, rem;
 
-                               half = (o1 >> 1) & ~mach_long_sign;
+                               half = (o1 >> 1) & ~arith_sign;
                                bit = o1 & 01;
                                /*      now o1 == 2 * half + bit
-                                       and half <= max_long
-                                       and bit <= max_long
+                                       and half <= max_arith
+                                       and bit <= max_arith
                                */
                                hrem = half % o2;
                                rem = 2 * hrem + bit;
@@ -117,7 +123,7 @@ cstbin(expp, oper, expr)
                        break;
                if (uns)        {
                        o1 >>= 1;
-                       o1 &= ~mach_long_sign;
+                       o1 &= ~arith_sign;
                        o1 >>= (o2-1);
                }
                else
@@ -133,9 +139,9 @@ cstbin(expp, oper, expr)
                /* Fall through */
        case '>':
                if (uns)        {
-                       o1 = (o1 & mach_long_sign ?
-                               (o2 & mach_long_sign ? o1 > o2 : 1) :
-                               (o2 & mach_long_sign ? 0 : o1 > o2)
+                       o1 = (o1 & arith_sign ?
+                               (o2 & arith_sign ? o1 > o2 : 1) :
+                               (o2 & arith_sign ? 0 : o1 > o2)
                        );
                }
                else
@@ -151,9 +157,9 @@ cstbin(expp, oper, expr)
                /* Fall through */
        case GREATEREQ:
                if (uns)        {
-                       o1 = (o1 & mach_long_sign ?
-                               (o2 & mach_long_sign ? o1 >= o2 : 1) :
-                               (o2 & mach_long_sign ? 0 : o1 >= o2)
+                       o1 = (o1 & arith_sign ?
+                               (o2 & arith_sign ? o1 >= o2 : 1) :
+                               (o2 & arith_sign ? 0 : o1 >= o2)
                        );
                }
                else
@@ -201,16 +207,18 @@ cut_size(expr)
        }
        if (uns) {
                if (o1 & ~full_mask[size])
+                   if (!ResultKnown)
                        expr_warning(expr,
                                "overflow in unsigned constant expression");
                o1 &= full_mask[size];
        }
        else {
-               int nbits = (int) (mach_long_size - size) * 8;
-               long remainder = o1 & ~full_mask[size];
+               int nbits = (int) (arith_size - size) * 8;
+               arith remainder = o1 & ~full_mask[size];
 
                if (remainder != 0 && remainder != ~full_mask[size])
-                       expr_warning(expr, "overflow in constant expression");
+                   if (!ResultKnown)
+                       expr_warning(expr,"overflow in constant expression");
                o1 <<= nbits;           /* ??? */
                o1 >>= nbits;
        }
@@ -228,10 +236,8 @@ init_cst()
                        fatal("array full_mask too small for this machine");
                full_mask[i] = bt;
        }
-       mach_long_size = i;
-       mach_long_sign = 1L << (mach_long_size * 8 - 1);
-       if ((int)long_size < mach_long_size)
-               fatal("sizeof (long) insufficient on this machine");
+       if ((int)long_size > arith_size)
+               fatal("sizeof (arith) insufficient on this machine");
        max_int = full_mask[(int)int_size] & ~(1L << ((int)int_size * 8 - 1));
        max_unsigned = full_mask[(int)int_size];
 }
index 6395fb4..86ca4b7 100644 (file)
@@ -10,6 +10,7 @@
 #include       <alloc.h>
 #include       "nobitfield.h"
 #include       "debug.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "LLlex.h"
 #include       "label.h"
@@ -32,7 +33,7 @@
 #endif LINT
 }
 
-/* 8 */
+/* 3.5 */
 declaration
        {struct decspecs Ds;}
 :
@@ -49,12 +50,12 @@ declaration
        empty case has already be dealt with in `external_definition'.
        This means that something like:
                unsigned extern int short xx;
-       is perfectly good C.
+       is perfectly legal C.
        
        On top of that, multiple occurrences of storage_class_specifiers,
        unsigned_specifiers and size_specifiers are errors, but a second
        type_specifier should end the decl_specifiers and be treated as
-       the name to be declared (see the thin ice in RM11.1).
+       the name to be declared.
        Such a language is not easily expressed in a grammar; enumeration
        of the permutations is unattractive. We solve the problem by
        having a regular grammar for the "soft" items, handling the single
@@ -86,7 +87,7 @@ decl_specifiers       /* non-empty */ (register struct decspecs *ds;)
        {do_decspecs(ds);}
 ;
 
-/* 8.1 */
+/* 3.5.1 & 3.5.2 (partially) & 3.5.3 (partially) */
 other_specifier(register struct decspecs *ds;)
 :
        [ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
@@ -125,7 +126,7 @@ other_specifier(register struct decspecs *ds;)
        }
 ;
 
-/* 8.2 */
+/* 3.5.2 */
 type_specifier(struct type **tpp;)
        /*      Used in struct/union declarations and in casts; only the
                type is relevant.
@@ -161,7 +162,7 @@ single_type_specifier(register struct decspecs *ds;):
        enum_specifier(&ds->ds_type)
 ;
 
-/* 8.3 */
+/* 3.5 */
 init_declarator_list(struct decspecs *ds;):
        init_declarator(ds)
        [ ',' init_declarator(ds) ]*
@@ -179,6 +180,7 @@ init_declarator(register struct decspecs *ds;)
        declarator(&Dc)
        {
                reject_params(&Dc);
+               def_proto(&Dc);
                declare_idf(ds, &Dc, level);
 #ifdef LINT
                lint_declare_idf(Dc.dc_idf, ds->ds_sc);
@@ -198,18 +200,26 @@ init_declarator(register struct decspecs *ds;)
        }
 ;
 
-/* 8.6: initializer */
+/* 3.5.7: initializer */
 initializer(struct idf *idf; int sc;)
        {
                struct expr *expr = (struct expr *) 0;
-               int globalflag = level == L_GLOBAL ||
-                                (level >= L_LOCAL && sc == STATIC);
+               int fund = idf->id_def->df_type->tp_fund;
+               int autoagg = (level >= L_LOCAL
+                               && sc != STATIC
+                               && ( fund == STRUCT
+                                   || fund == UNION
+                                   || fund == ARRAY));
+               int globalflag = level == L_GLOBAL
+                               || (level >= L_LOCAL && sc == STATIC);
        }
 :
        {       if (idf->id_def->df_type->tp_fund == FUNCTION)  {
                        error("illegal initialization of function");
                        idf->id_def->df_type->tp_fund = ERRONEOUS;
                }
+               if (level == L_FORMAL2)
+                       warning("illegal initialization of formal parameter (ignored)");
        }
        '='
        {
@@ -220,8 +230,12 @@ initializer(struct idf *idf; int sc;)
                        struct expr ex;
                        code_declaration(idf, &ex, level, sc);
                }
+               else if (autoagg)
+                       loc_init((struct expr *) 0, idf);
        }
-       initial_value(globalflag ? &(idf->id_def->df_type) : (struct type **)0,
+       initial_value((globalflag || autoagg) ?
+                               &(idf->id_def->df_type)
+                               : (struct type **)0,
                        &expr)
        {       if (! globalflag) {
                        if (idf->id_def->df_type->tp_fund == FUNCTION)  {
@@ -234,7 +248,9 @@ initializer(struct idf *idf; int sc;)
 #ifdef LINT
                        change_state(idf, SET);
 #endif LINT
-                       code_declaration(idf, expr, level, sc);
+                       if (autoagg)
+                               loc_init((struct expr *) 0, idf);
+                       else    code_declaration(idf, expr, level, sc);
                }
                init_idf(idf);
        }
@@ -247,6 +263,7 @@ initializer(struct idf *idf; int sc;)
        we just include the (formal) parameter list in the declarator
        description list dc.
 */
+/* 3.5.4 */
 declarator(register struct declarator *dc;)
        {       struct formal *fm = NO_PARAMS;
                struct proto *pl = NO_PROTO;
@@ -303,7 +320,7 @@ arrayer(arith *sizep;)
 
 formal_list (struct formal **fmp;)
 :
-       formal(fmp) [ ',' formal(fmp) ]*
+       formal(fmp) [ %persistent ',' formal(fmp) ]*
 ;
 
 formal(struct formal **fmp;)
@@ -404,7 +421,14 @@ struct_or_union_specifier(register struct type **tpp;)
                                (idf->id_struct->tg_busy)--;
                        }
                |
-                       {apply_struct(fund, idf, tpp);}
+                       {
+                         /* a ';' means an empty declaration (probably)
+                          * this means that we have to declare a new
+                          * structure. (yegh)
+                          */
+                         if (DOT == ';') declare_struct(fund, idf, tpp);
+                         else apply_struct(fund, idf, tpp);
+                       }
                        empty
                ]
        ]
@@ -543,12 +567,13 @@ parameter_type_list(struct proto **plp;)
                {       register struct proto *new = new_proto();
 
                        new->next = *plp;
-                       new->pl_flag = ELLIPSIS;
+                       new->pl_flag = PL_ELLIPSIS;
                        *plp = new;
                }
 
        ]?
-       {       if (level == L_PROTO)
+       {       check_for_void(*plp);
+               if (level == L_PROTO)
                        level = save_level;
                else level++;
        }
@@ -558,6 +583,7 @@ parameter_decl_list(struct proto **plp;)
 :
        parameter_decl(plp)
        [ %while (AHEAD != ELLIPSIS)
+         %persistent
                ',' parameter_decl(plp)
        ]*
 ;
@@ -615,11 +641,11 @@ parameter_declarator(register struct declarator *dc;)
                        parameter_type_list(&pl)
                |
                        formal_list(&fm)
-               |
-                       empty
-               ]
+               ]?
                ')'
-               {add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);}
+               {   add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);
+                   reject_params(dc);
+               }
        |
                arrayer(&count)
                {add_decl_unary(dc, ARRAY, 0, count, NO_PARAMS, NO_PROTO);}
@@ -631,7 +657,8 @@ parameter_declarator(register struct declarator *dc;)
 
 primary_parameter_declarator(register struct declarator *dc;)
 :
-[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD))
+[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD)
+                                   && (AHEAD != IDENTIFIER))
        empty
 |
        identifier(&dc->dc_idf)
@@ -645,7 +672,6 @@ pointer(int *qual;)
        '*' type_qualifier_list(qual)
 ;
 
-
 /*     Type qualifiers may come in three flavours:
        volatile, const, const volatile.
        These all have different semantic properties:
@@ -663,12 +689,12 @@ pointer(int *qual;)
                prior knowledge of the implementation, but may
                not be used as a l-value.
 */
+/* 3.5.4 */
 type_qualifier_list(int *qual;)
 :
 [
        [ VOLATILE | CONST ]
        { *qual = (DOT == VOLATILE) ? TQ_VOLATILE : TQ_CONST; }
-
        [
                [ VOLATILE | CONST ]
                {       if (DOT == VOLATILE) {
@@ -690,9 +716,5 @@ type_qualifier_list(int *qual;)
 ]
 ;
 
-
 empty:
 ;
-
-/* 8.8 */
-/* included in the IDENTIFIER/TYPE_IDENTIFIER mechanism */
index d899235..dde0314 100644 (file)
@@ -7,6 +7,7 @@
 
 #include       "botch_free.h"
 #include       <alloc.h>
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "type.h"
 #include       "proto.h"
index c01b661..36e9284 100644 (file)
@@ -5,7 +5,6 @@
 /* $Header$ */
 /*     D E C L A R A T I O N   S P E C I F I E R   C H E C K I N G     */
 
-#include       "nofloat.h"
 #include       "assert.h"
 #include       "Lpars.h"
 #include       "decspecs.h"
@@ -13,7 +12,6 @@
 #include       "type.h"
 #include       "level.h"
 #include       "def.h"
-#include       "noRoption.h"
 
 extern char options[];
 extern int level;
@@ -70,7 +68,7 @@ do_decspecs(ds)
                type and will have to be postponed to declare_idf.
        */
 
-       /* some adjustments as described in RM 8.2 */
+       /* some adjustments as described in 3.5.2. */
        if (tp == 0) {
                ds->ds_notypegiven = 1;
                tp = int_type;
@@ -86,38 +84,24 @@ do_decspecs(ds)
                if (tp == int_type)
                        tp = long_type;
                else
-#ifndef NOFLOAT
                if (tp == double_type)
                        tp = lngdbl_type;
                else
-#endif NOFLOAT
                        error("long with illegal type");
                break;
        }
        if (ds->ds_unsigned == UNSIGNED) {
                switch (tp->tp_fund)    {
                case CHAR:
-#ifndef NOROPTION
-                       if (options['R'])
-                               warning("unsigned char not allowed");
-#endif
                        tp = uchar_type;
                        break;
                case SHORT:
-#ifndef NOROPTION
-                       if (options['R'])
-                               warning("unsigned short not allowed");
-#endif
                        tp = ushort_type;
                        break;
                case INT:
                        tp = uint_type;
                        break;
                case LONG:
-#ifndef NOROPTION
-                       if (options['R'])
-                               warning("unsigned long not allowed");
-#endif
                        tp = ulong_type;
                        break;
                default:
@@ -128,7 +112,7 @@ do_decspecs(ds)
        if (ds->ds_unsigned == SIGNED) {
                switch (tp->tp_fund) {
                case CHAR:
-                       tp = char_type;
+                       tp = schar_type;
                        break;
                case SHORT:
                        tp = short_type;
@@ -172,8 +156,13 @@ qualifier_type(tp, typequal)
                dtp->tp_typequal = typequal;
                dtp->tp_size = tp->tp_size;
                switch (fund) {
-               case POINTER:
                case ARRAY:
+                       if (typequal) {
+                           tp->tp_up = qualifier_type(tp->tp_up, typequal);
+                           dtp->tp_typequal = typequal = 0;
+                       }
+                       /* fallthrough */
+               case POINTER:
                case FUNCTION:
                case STRUCT:
                case UNION:
index 33be293..6da31a7 100644 (file)
@@ -34,20 +34,28 @@ char ifstack[IFDEPTH];      /* if-stack: the content of an entry is */
 int    nestlevel = -1;
 
 struct idf *
-GetIdentifier()
+GetIdentifier(skiponerr)
+       int skiponerr;          /* skip the rest of the line on error */
 {
        /*      returns a pointer to the descriptor of the identifier that is
-               read from the input stream. A null-pointer is returned if
-               the input does not contain an identifier.
+               read from the input stream. When the input doe not contain
+               an identifier, the rest of the line is skipped and a
+               null-pointer is returned.
                The substitution of macros is disabled.
        */
+       int tmp = UnknownIdIsZero;
        int tok;
        struct token tk;
 
-       ReplaceMacros = 0;
+       UnknownIdIsZero = ReplaceMacros = 0;
        tok = GetToken(&tk);
        ReplaceMacros = 1;
-       return tok == IDENTIFIER ? tk.tk_idf : (struct idf *)0;
+       UnknownIdIsZero = tmp;
+       if (tok != IDENTIFIER) {
+               if (skiponerr && tok != EOI) SkipToNewLine(0);
+               return (struct idf *)0;
+       }
+       return tk.tk_idf;
 }
 
 /*     domacro() is the control line interpreter. The '#' has already
@@ -61,9 +69,13 @@ GetIdentifier()
 domacro()
 {
        struct token tk;        /* the token itself                     */
+       int toknum;
 
        EoiForNewline = 1;
-       switch(GetToken(&tk)) {         /* select control line action   */
+       ReplaceMacros = 0;
+       toknum = GetToken(&tk);
+       ReplaceMacros = 1;
+       switch(toknum) {                /* select control line action   */
        case IDENTIFIER:                /* is it a macro keyword?       */
                switch (tk.tk_idf->id_resmac) {
                case K_DEFINE:                          /* "define"     */
@@ -95,7 +107,7 @@ domacro()
                                the arguments.
                        */
                        if (GetToken(&tk) != INTEGER) {
-                               lexerror("#line without linenumber");
+                               error("bad #line syntax");
                                SkipToNewLine(0);
                        }
                        else
@@ -128,8 +140,8 @@ domacro()
        EoiForNewline = 0;
 }
 
-
-skip_block()
+skip_block(to_endif)
+int to_endif;
 {
        /*      skip_block() skips the input from
                1)      a false #if, #ifdef, #ifndef or #elif until the
@@ -142,6 +154,7 @@ skip_block()
        register int ch;
        register int skiplevel = nestlevel; /* current nesting level    */
        struct token tk;
+       int toknum;
 
        NoUnstack++;
        for (;;) {
@@ -153,10 +166,14 @@ skip_block()
                                NoUnstack--;
                                return;
                        }
+                       UnGetChar();
                        SkipToNewLine(0);
                        continue;
                }
-               if (GetToken(&tk) != IDENTIFIER) {
+               ReplaceMacros = 0;
+               toknum = GetToken(&tk);
+               ReplaceMacros = 1;
+               if (toknum != IDENTIFIER) {
                        SkipToNewLine(0);
                        continue;
                }
@@ -166,13 +183,19 @@ skip_block()
                        on the same level.
                */
                switch(tk.tk_idf->id_resmac) {
+               default:
+                       SkipToNewLine(0);
+                       break;
                case K_IF:
                case K_IFDEF:
                case K_IFNDEF:
                        push_if();
+                       SkipToNewLine(0);
                        break;
                case K_ELIF:
-                       if (nestlevel == skiplevel) {
+                       if (ifstack[nestlevel])
+                               lexerror("#elif after #else");
+                       if (!to_endif && nestlevel == skiplevel) {
                                nestlevel--;
                                push_if();
                                if (ifexpr()) {
@@ -180,15 +203,19 @@ skip_block()
                                        return;
                                }
                        }
+                       else SkipToNewLine(0);  /* otherwise done in ifexpr() */
                        break;
                case K_ELSE:
+                       if (ifstack[nestlevel])
+                               lexerror("#else after #else");
                        ++(ifstack[nestlevel]);
-                       if (nestlevel == skiplevel) {
+                       if (!to_endif && nestlevel == skiplevel) {
                                if (SkipToNewLine(1))
-                                       strict("garbage following #endif");
+                                       strict("garbage following #else");
                                NoUnstack--;
                                return;
                        }
+                       else SkipToNewLine(0);
                        break;
                case K_ENDIF:
                        ASSERT(nestlevel > nestlow);
@@ -199,6 +226,7 @@ skip_block()
                                NoUnstack--;
                                return;
                        }
+                       else SkipToNewLine(0);
                        nestlevel--;
                        break;
                }
@@ -241,7 +269,7 @@ do_include()
        if (((tok = GetToken(&tk)) == FILESPECIFIER) || tok == STRING)
                filenm = tk.tk_bts;
        else {
-               lexerror("bad include syntax");
+               error("bad include syntax");
                filenm = (char *)0;
        }
        AccFileSpecifier = 0;
@@ -249,7 +277,7 @@ do_include()
        inctable[0] = WorkingDir;
        if (filenm) {
                if (!InsertFile(filenm, &inctable[tok==FILESPECIFIER],&result)){
-                       fatal("cannot open include file \"%s\"", filenm);
+                       error("cannot open include file \"%s\"", filenm);
                }
                else {
                        WorkingDir = getwdir(result);
@@ -275,9 +303,8 @@ do_define()
        char *get_text();
 
        /* read the #defined macro's name       */
-       if (!(id = GetIdentifier())) {
-               lexerror("#define: illegal macro name");
-               SkipToNewLine(0);
+       if (!(id = GetIdentifier(1))) {
+               lexerror("illegal #define line");
                return;
        }
        /*      there is a formal parameter list if the identifier is
@@ -297,7 +324,8 @@ do_define()
        if (class(ch) == STNL) {
                /*      Treat `#define something' as `#define something ""'
                */
-               repl_text = "";
+               repl_text = Malloc(1);
+               *repl_text = '\0';
                length = 0;
        }
        else {
@@ -318,35 +346,38 @@ push_if()
 
 do_elif()
 {
-       if (nestlevel <= nestlow || (ifstack[nestlevel])) {
+       if (nestlevel <= nestlow) {
                lexerror("#elif without corresponding #if");
                SkipToNewLine(0);
        }
-       else { /* restart at this level as if a #if is detected.  */
+       else {          /* restart at this level as if a #if is detected.  */
+               if (ifstack[nestlevel]) {
+                       lexerror("#elif after #else");
+                       SkipToNewLine(0);
+               }
                nestlevel--;
                push_if();
-               skip_block();
+               skip_block(1);
        }
 }
 
 do_else()
 {
-       struct token tok;
-
        if (SkipToNewLine(1))
                strict("garbage following #else");
-       if (nestlevel <= nestlow || (ifstack[nestlevel]))
+       if (nestlevel <= nestlow)
                lexerror("#else without corresponding #if");
        else {  /* mark this level as else-d */
+               if (ifstack[nestlevel]) {
+                       lexerror("#else after #else");
+               }
                ++(ifstack[nestlevel]);
-               skip_block();
+               skip_block(1);
        }
 }
 
 do_endif()
 {
-       struct token tok;
-
        if (SkipToNewLine(1))
                strict("garbage following #endif");
        if (nestlevel <= nestlow)       {
@@ -359,7 +390,7 @@ do_if()
 {
        push_if();
        if (!ifexpr())  /* a false #if/#elif expression */
-               skip_block();
+               skip_block(0);
 }
 
 do_ifdef(how)
@@ -369,15 +400,15 @@ do_ifdef(how)
        /*      how == 1 : ifdef; how == 0 : ifndef
        */
        push_if();
-       if (!(id = GetIdentifier()))
+       if (!(id = GetIdentifier(1)))
                lexerror("illegal #ifdef construction");
 
        /* The next test is a shorthand for:
                (how && !id->id_macro) || (!how && id->id_macro)
        */
        if (how ^ (id && id->id_macro != 0))
-               skip_block();
-       else
+               skip_block(0);
+       else if (id)
                SkipToNewLine(0);
 }
 
@@ -386,15 +417,20 @@ do_undef()
        register struct idf *id;
 
        /* Forget a macro definition.   */
-       if (id = GetIdentifier()) {
+       if (id = GetIdentifier(1)) {
                if (id->id_macro) { /* forget the macro */
-                       free_macro(id->id_macro);
-                       id->id_macro = (struct macro *) 0;
+                       if (id->id_macro->mc_flag & NOUNDEF) {
+                               lexerror("it is not allowed to undef %s", id->id_text);
+                       } else {
+                               free(id->id_text);
+                               free_macro(id->id_macro);
+                               id->id_macro = (struct macro *) 0;
+                       }
                } /* else: don't complain */
+               SkipToNewLine(0);
        }
        else
                lexerror("illegal #undef construction");
-       SkipToNewLine(0);
 }
 
 do_error()
@@ -488,15 +524,17 @@ macro_def(id, text, nformals, length, flags)
        /*      macro_def() puts the contents and information of a macro
                definition into a structure and stores it into the symbol
                table entry belonging to the name of the macro.
-               A warning is given if the definition overwrites another.
+               An error is given if there was already a definition
        */
        if (newdef) {           /* is there a redefinition?     */
-               if (macroeq(newdef->mc_text, text))
-                       return;
-               lexwarning("redefine \"%s\"", id->id_text);
+               if (newdef->mc_flag & NOUNDEF) {
+                       lexerror("it is not allowed to redefine %s", id->id_text);
+               } else if (!macroeq(newdef->mc_text, text))
+                       lexerror("illegal redefine of \"%s\"", id->id_text);
+               free(text);
+               return;
        }
-       else
-               id->id_macro = newdef = new_macro();
+       id->id_macro = newdef = new_macro();
        newdef->mc_text = text;         /* replacement text     */
        newdef->mc_nps  = nformals;     /* nr of formals        */
        newdef->mc_length = length;     /* length of repl. text */
@@ -553,14 +591,14 @@ get_text(formals, length)
                        register int delim = c;
 
                        do {
-                               /* being careful, as ever */
-                               if (pos+3 >= text_size)
-                                       text = Srealloc(text,
-                                                       text_size += RTEXTSIZE);
-                               text[pos++] = c;
-                               if (c == '\\')
-                                       text[pos++] = GetChar();
-                               c = GetChar();
+                           /* being careful, as ever */
+                           if (pos+3 >= text_size)
+                               text = Srealloc(text,
+                                       (unsigned) (text_size += RTEXTSIZE));
+                           text[pos++] = c;
+                           if (c == '\\')
+                                   text[pos++] = GetChar();
+                           c = GetChar();
                        } while (c != delim && c != EOI && class(c) != STNL);
                        text[pos++] = c;
                        c = GetChar();
@@ -569,7 +607,8 @@ get_text(formals, length)
                if (c == '/') {
                        c = GetChar();
                        if (pos+1 >= text_size)
-                               text = Srealloc(text, text_size += RTEXTSIZE);
+                               text = Srealloc(text,
+                                       (unsigned) (text_size += RTEXTSIZE));
                        if (c == '*') {
                                skipcomment();
                                text[pos++] = ' ';
@@ -593,25 +632,27 @@ get_text(formals, length)
                        } while (in_idf(c));
                        id_buf[--id_size] = '\0';
                        if (n = find_name(id_buf, formals)) {
-                               /* construct the formal parameter mark  */
-                               if (pos+1 >= text_size)
-                                       text = Srealloc(text,
-                                               text_size += RTEXTSIZE);
-                               text[pos++] = FORMALP | (char) n;
+                           /* construct the formal parameter mark      */
+                           if (pos+1 >= text_size)
+                               text = Srealloc(text,
+                                       (unsigned) (text_size += RTEXTSIZE));
+                           text[pos++] = FORMALP | (char) n;
                        }
                        else {
-                               register char *ptr = &id_buf[0];
-
-                               while (pos + id_size >= text_size)
-                                       text = Srealloc(text,
-                                               text_size += RTEXTSIZE);
-                               while (text[pos++] = *ptr++) ;
-                               pos--;
+                           register char *ptr = &id_buf[0];
+
+                           while (pos + id_size >= text_size)
+                               text = Srealloc(text,
+                                       (unsigned) (text_size += RTEXTSIZE));
+                           while (text[pos++] = *ptr++)
+                               /* EMPTY */ ;
+                           pos--;
                        }
                }
                else {
                        if (pos+1 >= text_size)
-                               text = Srealloc(text, text_size += RTEXTSIZE);
+                               text = Srealloc(text,
+                                       (unsigned) (text_size += RTEXTSIZE));
                        text[pos++] = c;
                        c = GetChar();
                }
index cd11ff4..af0c703 100644 (file)
@@ -8,9 +8,10 @@
 #include       "debug.h"
 
 #ifdef DEBUG
-#include       "nofloat.h"
+#include       <alloc.h>
 #include       "nopp.h"
 #include       "nobitfield.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "stack.h"
 #include       "idf.h"
@@ -252,8 +253,8 @@ dump_proto(pl)
        newline();
        while (pl) {
                print("%d: %s", argcnt++,
-                       pl->pl_flag == FORMAL ?
-                       (pl->pl_flag == VOID ? "void" : "formal")
+                       pl->pl_flag & PL_FORMAL ?
+                       (pl->pl_flag & PL_VOID ? "void" : "formal")
                        : "ellipsis");
                newline();
                if (type = pl->pl_type){
@@ -442,9 +443,7 @@ p1_expr(lvl, expr)
                expr->ex_depth,
                expr->ex_class == Value ? "Value" :
                expr->ex_class == String ? "String" :
-#ifndef NOFLOAT
                expr->ex_class == Float ? "Float" :
-#endif NOFLOAT
                expr->ex_class == Oper ? "Oper" :
                expr->ex_class == Type ? "Type" : "UNKNOWN CLASS"
        );
@@ -479,11 +478,13 @@ p1_expr(lvl, expr)
                );
                break;
        }
-#ifndef NOFLOAT
        case Float:
+               if (!expr->FL_VALUE) {
+                       expr->FL_VALUE = Malloc(FLT_STRLEN);
+                       flt_flt2str(&(expr->FL_ARITH), expr->FL_VALUE, FLT_STRLEN);
+               }
                print("%s\n", expr->FL_VALUE);
                break;
-#endif NOFLOAT
        case Oper:
                o = &expr->ex_object.ex_oper;
                print("\n");
index 89517f4..846f23a 100644 (file)
@@ -15,6 +15,7 @@
 #include       "debug.h"
 
 #include       "tokenname.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "label.h"
 #include       "expr.h"
@@ -32,6 +33,7 @@
 #define        ERROR           3
 #define        CRASH           4
 #define        FATAL           5
+#define DO_DEBUG       6
 
 int err_occurred = 0;
 
@@ -93,11 +95,28 @@ strict(va_alist)
 
        va_start(ap);
        {
-               _error(STRICT, FileName, LineNumber, ap);
+               _error(STRICT, dot.tk_file, dot.tk_line, ap);
        }
        va_end(ap);
 }
 
+#ifdef DEBUG
+/*VARARGS*/
+debug(va_alist)
+       va_dcl
+{
+       va_list ap;
+
+       va_start(ap);
+       {
+               _error(DO_DEBUG, dot.tk_file, dot.tk_line, ap);
+               /* _error(DO_DEBUG, NILEXPR, ap);
+               */
+       }
+       va_end(ap);
+}
+#endif DEBUG
+
 /*VARARGS*/
 warning(va_alist)
        va_dcl
@@ -106,7 +125,9 @@ warning(va_alist)
 
        va_start(ap);
        {
-               _error(WARNING, NILEXPR, ap);
+               _error(WARNING, dot.tk_file, dot.tk_line, ap);
+               /* _error(WARNING, NILEXPR, ap);
+               */
        }
        va_end(ap);
 }
@@ -310,12 +331,18 @@ _error(class, fn, ln, ap)
        case FATAL:
                remark = "fatal error --";
                break;
+#ifdef DEBUG
+       case DO_DEBUG:
+               remark = "(debug)";
+               break;
+#endif DEBUG
        default:
                /*NOTREACHED*/;
        }
        
 #ifndef        LINT
-       if (ln == last_ln && fn && last_fn && strcmp(fn, last_fn) == 0) {
+       if (class != DO_DEBUG)  /* ??? DEBUG */
+           if (ln == last_ln && fn && last_fn && strcmp(fn, last_fn) == 0) {
                /* we've seen this place before */
                e_seen++;
                if (e_seen == MAXERR_LINE)
index 3854c5d..0defbfe 100644 (file)
@@ -8,12 +8,13 @@
 #include       "lint.h"
 #ifndef        LINT
 
-#include       "nofloat.h"
 #include       <em.h>
 #include       <em_reg.h>
+#include       <alloc.h>
 #include       "debug.h"
 #include       "nobitfield.h"
 #include       "dataflow.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "type.h"
 #include       "idf.h"
@@ -69,7 +70,7 @@ EVAL(expr, val, code, true_label, false_label)
        int val, code;
        label true_label, false_label;
 {
-       register int gencode = (code == TRUE);
+       register int gencode = (code == TRUE && expr->ex_type->tp_size > 0);
 
        switch (expr->ex_class) {
        case Value:     /* just a simple value  */
@@ -82,18 +83,20 @@ EVAL(expr, val, code, true_label, false_label)
                        C_lae_dlb(expr->VL_LBL, expr->VL_VALUE);
                }
                break;
-#ifndef NOFLOAT
        case Float:     /* a floating constant  */
                if (gencode) {
                        label datlab = data_label();
                        
+                       if (!expr->FL_VALUE) {
+                               expr->FL_VALUE = Malloc(FLT_STRLEN);
+                               flt_flt2str(&(expr->FL_ARITH), expr->FL_VALUE, FLT_STRLEN);
+                       }
                        C_df_dlb(datlab);
                        C_rom_fcon(expr->FL_VALUE, expr->ex_type->tp_size);
                        C_lae_dlb(datlab, (arith)0);
                        C_loi(expr->ex_type->tp_size);
                }
                break;
-#endif NOFLOAT
        case Oper:      /* compound expression  */
        {
                int oper = expr->OP_OPER;
@@ -107,6 +110,7 @@ EVAL(expr, val, code, true_label, false_label)
                }
                if (tp->tp_fund == VOID)
                        gencode = 0;
+
                switch (oper) {
                case '+':
                        /*      We have the following possibilities :
@@ -130,13 +134,11 @@ EVAL(expr, val, code, true_label, false_label)
                                        C_cuu();
                                        C_ads(pointer_size);
                                        break;
-#ifndef NOFLOAT
                                case FLOAT:
                                case DOUBLE:
                                case LNGDBL:
                                        C_adf(tp->tp_size);
                                        break;
-#endif NOFLOAT
                                default:
                                        crash("bad type +");
                                }
@@ -152,13 +154,11 @@ EVAL(expr, val, code, true_label, false_label)
                                        case POINTER:
                                                C_ngi(tp->tp_size);
                                                break;
-#ifndef NOFLOAT
                                        case FLOAT:
                                        case DOUBLE:
                                        case LNGDBL:
                                                C_ngf(tp->tp_size);
                                                break;
-#endif NOFLOAT
                                        default:
                                                CRASH();
                                        }
@@ -192,13 +192,11 @@ EVAL(expr, val, code, true_label, false_label)
                                        C_ads(pointer_size);
                                }
                                break;
-#ifndef NOFLOAT
                        case FLOAT:
                        case DOUBLE:
                        case LNGDBL:
                                C_sbf(tp->tp_size);
                                break;
-#endif NOFLOAT
                        default:
                                crash("bad type -");
                        }
@@ -223,14 +221,12 @@ EVAL(expr, val, code, true_label, false_label)
                                                else
                                                        C_mli(tp->tp_size);
                                                break;
-#ifndef NOFLOAT
                                        case FLOAT:
                                        case DOUBLE:
                                        case LNGDBL:
                                                /*C_mlf(double_size);*/
                                                C_mlf(tp->tp_size);
                                                break;
-#endif NOFLOAT
                                        default:
                                                crash("bad type *");
                                        }
@@ -249,14 +245,12 @@ EVAL(expr, val, code, true_label, false_label)
                                        else
                                                C_dvi(tp->tp_size);
                                        break;
-#ifndef NOFLOAT
                                case FLOAT:
                                case DOUBLE:
                                case LNGDBL:
                                        /*C_dvf(double_size);*/
                                        C_dvf(tp->tp_size);
                                        break;
-#endif NOFLOAT
                                default:
                                        crash("bad type /");
                                }
@@ -309,13 +303,11 @@ EVAL(expr, val, code, true_label, false_label)
                                        else
                                                C_cmi(size);
                                        break;
-#ifndef NOFLOAT
                                case FLOAT:
                                case DOUBLE:
                                case LNGDBL:
                                        C_cmf(size);
                                        break;
-#endif NOFLOAT
                                case POINTER:
                                        C_cmp();
                                        break;
@@ -543,10 +535,6 @@ EVAL(expr, val, code, true_label, false_label)
                        ASSERT(is_cp_cst(right));
                        if (gencode) {
                                C_adp(right->VL_VALUE);
-                               if (val == RVAL && expr->ex_lvalue == 0) {
-                                       load_block(expr->ex_type->tp_size,
-                                               expr->ex_type->tp_align);
-                               }
                        }
                        break;
                case ARROW:
@@ -624,11 +612,9 @@ EVAL(expr, val, code, true_label, false_label)
                                                                true_label);
                        break;
                case INT2INT:
-#ifndef NOFLOAT
                case INT2FLOAT:
                case FLOAT2INT:
                case FLOAT2FLOAT:
-#endif NOFLOAT
                        EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
                        if (gencode)
                                conversion(right->ex_type, left->ex_type);
@@ -640,9 +626,10 @@ EVAL(expr, val, code, true_label, false_label)
                        only its lvalue is evaluated, its rvalue is
                        loaded by the following statements:
                */
-               if (gencode && val == RVAL && expr->ex_lvalue == 1)
+               if (gencode && val == RVAL && expr->ex_lvalue == 1) {
                        load_block(expr->ex_type->tp_size,
                                expr->ex_type->tp_align);
+               }
                break;
        }
        default:
@@ -782,13 +769,12 @@ assop(type, oper)
                        break;
                }
                break;
-#ifndef NOFLOAT
        case FLOAT:
        case DOUBLE:
        case LNGDBL:
                switch (oper) {
                case PLUSAB:
-               case PLUSPLUS:
+               case PLUSPLUS:                  /* ??? etc... */
                case POSTINCR:
                        C_adf(size);
                        break;
@@ -805,7 +791,6 @@ assop(type, oper)
                        break;
                }
                break;
-#endif NOFLOAT
        case POINTER:
                if (oper == MINAB || oper == MINMIN || oper == POSTDECR)
                        C_ngi(size);
@@ -851,7 +836,11 @@ store_val(vl, tp)
                register struct idf *id = vl->vl_data.vl_idf;
                register struct def *df = id->id_def;
 
-               if (df->df_level == L_GLOBAL) {
+               /* if (df->df_level == L_GLOBAL) { /* } ??? re-examine */
+               if (df->df_sc == GLOBAL
+                   || df->df_sc == EXTERN
+                   || df->df_sc == STATIC
+                   || df->df_sc == IMPLICIT) {
                        if (inword)
                                C_ste_dnam(id->id_text, val);
                        else
@@ -956,7 +945,11 @@ load_val(expr, rlval)
                        C_lpi(id->id_text);
                }
                else
-               if (df->df_level == L_GLOBAL) {
+               /* if (df->df_level == L_GLOBAL) { /* } ??? re-examine */
+               if ( df->df_sc == GLOBAL
+                   || df->df_sc == STATIC
+                   || df->df_sc == EXTERN
+                   || df->df_sc == IMPLICIT) {
                        if (rvalue) {
                                if (inword)
                                        C_loe_dnam(id->id_text, val);
@@ -974,7 +967,7 @@ load_val(expr, rlval)
                        }
                }
                else {
-                       ASSERT(df->df_sc != STATIC);
+                       /* ASSERT(df->df_sc != STATIC); */
                        if (rvalue) {
                                if (inword || indword)
                                        LoadLocal(df->df_address + val, size);
index 3e26e16..ae6f986 100644 (file)
@@ -6,10 +6,11 @@
 /* EXPRESSION TREE HANDLING */
 
 #include       "lint.h"
-#include       "nofloat.h"
+#include       "assert.h"
 #include       "botch_free.h"
 #include       <alloc.h>
 #include       "idf.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "def.h"
 #include       "type.h"
 #include       "declar.h"
 #include       "sizes.h"
 #include       "level.h"
-#include       "noRoption.h"
 
 extern char *symbol2str();
 extern char options[];
+extern int InSizeof;
 
 int
 rank_of(oper)
@@ -96,7 +97,6 @@ rank_of(oper)
        /*NOTREACHED*/
 }
 
-#ifndef NOROPTION
 int
 rank_of_expression(ex)
        register struct expr *ex;
@@ -112,15 +112,14 @@ check_conditional(expr, oper, pos_descr)
        register struct expr *expr;
        char *pos_descr;
 {
-       /*      Warn if restricted C is in effect and the expression expr,
-               which occurs at the position pos_descr, is not lighter than
-               the operator oper.
+       /*      Since the grammar is LR and the parser is LL, this kludge
+               here checks if there was a syntax error caused by
+               the priorities in an expression.
        */
-       if (options['R'] && rank_of_expression(expr) >= rank_of(oper))
-               expr_warning(expr, "%s %s is ungrammatical",
+       if (rank_of_expression(expr) >= rank_of(oper))
+               expr_error(expr, "%s %s",
                        symbol2str(expr->OP_OPER), pos_descr);
 }
-#endif
 
 dot2expr(expp)
        struct expr **expp;
@@ -140,11 +139,9 @@ dot2expr(expp)
        case INTEGER:
                int2expr(ex);
                break;
-#ifndef NOFLOAT
        case FLOATING:
                float2expr(ex);
                break;
-#endif NOFLOAT
        default:
                crash("bad conversion to expression");
                /*NOTREACHED*/
@@ -163,9 +160,12 @@ idf2expr(expr)
        register struct def *def = idf->id_def;
        
        if (def == 0)   {
-               if (AHEAD == '(') /* function call, declare name IMPLICITly */
-                       add_def(idf, IMPLICIT, funint_type, level); /* RM 13 */
-               else    {
+               if (AHEAD == '(') {
+                       /* function call, declare name IMPLICITly (3.3.2.2) */
+                       warning("implicit declaration of function %s"
+                               , idf->id_text);
+                       add_def(idf, IMPLICIT, funint_type, level);
+               } else  {
                        if (!is_anon_idf(idf))
                                error("%s undefined", idf->id_text);
                        /* declare idf anyway */
@@ -180,11 +180,13 @@ idf2expr(expr)
        }
        else {
 #ifndef        LINT
-               def->df_used = 1;
+               if (!InSizeof)
+                       def->df_used = 1;
 #endif LINT
                expr->ex_type = def->df_type;
-               if (expr->ex_type == error_type)
+               if (expr->ex_type == error_type) {
                        expr->ex_flags |= EX_ERROR;
+               }
        }
        expr->ex_lvalue =
                (       def->df_type->tp_fund == FUNCTION ||
@@ -215,9 +217,9 @@ idf2expr(expr)
        }
 }
 
-string2expr(expp, typ, str, len)
+string2expr(expp, str, len)
        register struct expr **expp;
-       int typ, len;
+       int len;
        char *str;
 {
        /*      The string in the argument is converted into an expression,
@@ -229,9 +231,7 @@ string2expr(expp, typ, str, len)
        ex->ex_file = dot.tk_file;
        ex->ex_line = dot.tk_line;
        ex->ex_type = string_type;
-/*
-       ex->ex_type = qualifier_type(ex->ex_type, TQ_CONST);
-*/
+       /* ex->ex_type = qualifier_type(ex->ex_type, TQ_CONST); */
        ex->ex_flags |= EX_READONLY;
        ex->ex_lvalue = 0;
        ex->ex_class = String;
@@ -249,7 +249,6 @@ int2expr(expr)
        fill_int_expr(expr, dot.tk_ival, dot.tk_fund);
 }
 
-#ifndef NOFLOAT
 float2expr(expr)
        register struct expr *expr;
 {
@@ -274,9 +273,12 @@ float2expr(expr)
        }
        expr->ex_class = Float;
        expr->FL_VALUE = dot.tk_fval;
+       flt_str2flt(expr->FL_VALUE, &(expr->FL_ARITH));
+       ASSERT(flt_status != FLT_NOFLT);
+       if (flt_status == FLT_OVFL)
+               expr_warning(expr,"internal floating point overflow");
        expr->FL_DATLAB = 0;
 }
-#endif NOFLOAT
 
 struct expr*
 intexpr(ivalue, fund)
@@ -287,7 +289,7 @@ intexpr(ivalue, fund)
                the size indicated by fund.
        */
        register struct expr *expr = new_expr();
-       
+
        expr->ex_file = dot.tk_file;
        expr->ex_line = dot.tk_line;
        fill_int_expr(expr, ivalue, fund);
@@ -324,8 +326,8 @@ fill_int_expr(ex, ivalue, fund)
                /*      We cannot make a test like
                                ivalue <= max_unsigned
                        because, if
-                               sizeof(long) == int_size
-                       holds, max_unsigned may be a negative long in
+                               sizeof(arith) == int_size
+                       holds, max_unsigned may be a negative arith in
                        which case the comparison results in an unexpected
                        answer.
                */
@@ -392,7 +394,8 @@ new_oper(tp, e1, oper, e2)
                
                expr->ex_depth =
                        (e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) + 1;
-               expr->ex_flags = (e1_flags | e2->ex_flags) & ~EX_PARENS;
+               expr->ex_flags = (e1_flags | e2->ex_flags)
+                       & ~(EX_PARENS | EX_READONLY /* ??? | EX_VOLATILE */ );
        }
        op = &expr->ex_object.ex_oper;
        op->op_type = tp;
@@ -425,43 +428,24 @@ chk_cst_expr(expp)
                the others in the various C compilers.  I have tried some
                hypotheses to unify them, but all have failed.
                
-               This routine will give a warning for those operators
-               not allowed by K&R, under the R-option only.  The anomalies
-               are cast, logical operators and the expression comma.
                Special problems (of which there is only one, sizeof in
                Preprocessor #if) have to be dealt with locally
-               
-               Note that according to K&R the negation ! is illegal in
-               constant expressions and is indeed rejected by the
-               Ritchie compiler.
        */
        register struct expr *expr = *expp;
        register int fund = expr->ex_type->tp_fund;
-       register int flags = expr->ex_flags;
        int err = 0;
        
 #ifdef DEBUG
        print_expr("constant_expression", expr);
 #endif DEBUG
-       if (    fund != CHAR && fund != SHORT && fund != INT &&
-               fund != ENUM && fund != LONG
-       )
-               expr_error(expr, "non-numerical constant expression"), err++;
-       else
-       if (!is_ld_cst(expr))
-               expr_error(expr, "expression is not constant"), err++;
-#ifndef NOROPTION
-       if (options['R'])       {
-               if (flags & EX_CAST)
-                       expr_warning(expr, "cast in constant expression");
-               if (flags & EX_LOGICAL)
-                       expr_warning(expr,
-                               "logical operator in constant expression");
-               if (flags & EX_COMMA)
-                       expr_warning(expr,
-                               "expression comma in constant expression");
+       if ( fund != CHAR && fund != SHORT && fund != INT
+           && fund != ENUM && fund != LONG) {
+               expr_error(expr, "non-numerical constant expression");
+               err++;
+       } else if (!is_ld_cst(expr)) {
+               expr_error(expr, "expression is not constant");
+               err++;
        }
-#endif NOROPTION
        if (err)
                erroneous2int(expp);
 }
@@ -501,7 +485,7 @@ is_ld_cst(expr)
 
 int
 is_cp_cst(expr)
-       register struct expr *expr;
+       struct expr *expr;
 {
        /*      An expression is a `compile-time constant' if it is a
                load-time constant, and the idf is not there.
@@ -509,17 +493,31 @@ is_cp_cst(expr)
        return is_ld_cst(expr) && expr->VL_CLASS == Const;
 }
 
-#ifndef NOFLOAT
 int
 is_fp_cst(expr)
-       register struct expr *expr;
+       struct expr *expr;
 {
        /*      An expression is a `floating-point constant' if it consists
                of the float only.
        */
        return expr->ex_class == Float;
 }
-#endif NOFLOAT
+
+int
+is_zero_cst(expr)
+       register struct expr *expr;
+{
+       flt_arith var;
+
+       switch(expr->ex_class) {
+       case Value:
+               return expr->VL_VALUE == 0;
+       case Float:
+               flt_arith2flt((arith) 0, &var);
+               return flt_cmp(&var, &(expr->FL_ARITH)) == 0;
+       }
+       /*NOTREACHED*/
+}
 
 free_expression(expr)
        register struct expr *expr;
@@ -527,6 +525,8 @@ free_expression(expr)
        /*      The expression expr is freed recursively.
        */
        if (expr) {
+               if (expr->ex_class == Float && expr->FL_VALUE)
+                       free(expr->FL_VALUE);
                if (expr->ex_class == Oper)     {
                        free_expression(expr->OP_LEFT);
                        free_expression(expr->OP_RIGHT);
index 16648e0..67fe963 100644 (file)
@@ -9,8 +9,6 @@
        a union of various goodies, we define them first; so be patient.
 */
 
-#include       "nofloat.h"
-
 /* classes of value */
 #define Const  1
 #define Name   2
@@ -31,12 +29,11 @@ struct string       {
        label sg_datlab;        /* global data-label                    */
 };
 
-#ifndef NOFLOAT
 struct floating        {
        char *fl_value;         /* pointer to string repr. the fp const. */
+       flt_arith fl_arith;     /* the value in high precision */
        label fl_datlab;        /* global data_label    */
 };
-#endif NOFLOAT
 
 struct oper    {
        struct type *op_type;   /* resulting type of the operation      */
@@ -48,9 +45,7 @@ struct oper   {
 /* The following constants indicate the class of the expression: */
 #define        Value   0               /* it is a value known at load time */
 #define        String  1               /* it is a string constant  */
-#ifndef NOFLOAT
 #define        Float   2               /* it is a floating point constant      */
-#endif NOFLOAT
 #define        Oper    3               /* it is a run-time expression */
 #define        Type    4               /* only its type is relevant */
 
@@ -66,9 +61,7 @@ struct expr   {
        union   {
                struct value ex_value;
                struct string ex_string;
-#ifndef NOFLOAT
                struct floating ex_float;
-#endif NOFLOAT
                struct oper ex_oper;
        } ex_object;
 };
@@ -82,10 +75,9 @@ struct expr  {
 #define        SG_VALUE        ex_object.ex_string.sg_value
 #define SG_LEN         ex_object.ex_string.sg_len
 #define        SG_DATLAB       ex_object.ex_string.sg_datlab
-#ifndef NOFLOAT
 #define        FL_VALUE        ex_object.ex_float.fl_value
+#define        FL_ARITH        ex_object.ex_float.fl_arith
 #define        FL_DATLAB       ex_object.ex_float.fl_datlab
-#endif NOFLOAT
 #define        OP_TYPE         ex_object.ex_oper.op_type
 #define        OP_LEFT         ex_object.ex_oper.op_left
 #define        OP_OPER         ex_object.ex_oper.op_oper
@@ -94,15 +86,16 @@ struct expr {
 /*     some bits for the ex_flag field, to keep track of various
        interesting properties of an expression.
 */
-#define        EX_SIZEOF       0001            /* contains sizeof operator */
-#define        EX_CAST         0002            /* contains cast */
-#define        EX_LOGICAL      0004            /* contains logical operator */
-#define        EX_COMMA        0010            /* contains expression comma */
-#define        EX_PARENS       0020            /* the top level is parenthesized */
-#define EX_SIDEEFFECTS 0040            /* expression has side effects */
-#define        EX_READONLY     0100            /* read only variabele */
-#define        EX_VOLATILE     0200            /* volatile variabele */
-#define        EX_ERROR        0400            /* the expression is wrong */
+#define        EX_SIZEOF       0x001           /* contains sizeof operator */
+#define        EX_CAST         0x002           /* contains cast */
+#define        EX_LOGICAL      0x004           /* contains logical operator */
+#define        EX_COMMA        0x008           /* contains expression comma */
+#define        EX_PARENS       0x010           /* the top level is parenthesized */
+#define EX_SIDEEFFECTS 0x020           /* expression has side effects */
+#define        EX_READONLY     0x040           /* read only variabele */
+#define        EX_VOLATILE     0x080           /* volatile variabele */
+#define        EX_ILVALUE      0x100           /* an illegal lvalue e.g. f().x */
+#define        EX_ERROR        0x200           /* the expression is wrong */
 
 #define        NILEXPR         ((struct expr *)0)
 
index e341ed6..70dad65 100644 (file)
@@ -8,6 +8,7 @@
 {
 #include       <alloc.h>
 #include       "lint.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "LLlex.h"
 #include       "type.h"
 #include       "label.h"
 #include       "expr.h"
 #include       "code.h"
-#include       "noRoption.h"
 
 extern struct expr *intexpr();
+int InSizeof = 0;      /* inside a sizeof- expression */
+int ResultKnown = 0;   /* result of the expression is already known */
+
+/* Since the grammar in the standard is not LL(n), it is modified so that
+ * it accepts basically the same grammar. Thsi means that there is no 1-1
+ * mapping from the grammar in the standard to the grammar given here.
+ * Such is life.
+ */
 }
 
-/* 7.1 */
+/* 3.3.1 */
 primary(register struct expr **expp;) :
        IDENTIFIER
        {dot2expr(expp);}
@@ -30,14 +38,14 @@ primary(register struct expr **expp;) :
        string(expp)
 |
        '(' expression(expp) ')'
-       {(*expp)->ex_flags |= EX_PARENS;}
+       { (*expp)->ex_flags |= EX_PARENS; }
 ;
 
 
-/*     Character string literals that are adjacent tokens
      are concatenated into a single character string
      literal.
-*/
+/* Character string literals that are adjacent tokens
* are concatenated into a single character string
* literal.
+ */
 string(register struct expr **expp;)
        {       register int i, len;
                register char *str;
@@ -51,12 +59,12 @@ string(register struct expr **expp;)
        }
        [
                STRING
-               {       /*      A pasted string keeps the type of the first
-                               string literal.
-                               The pasting of normal strings and wide
-                               character strings are stated as having an
-                               undefined behaviour.
-                       */
+               {       /* A pasted string keeps the type of the first
+                        * string literal.
+                        * The pasting of normal strings and wide
+                        * character strings are stated as having an
+                        * undefined behaviour.
+                        */
                        if (dot.tk_fund != fund)
                                warning("illegal pasting of string literals");
                        str = Srealloc(str, (unsigned) (--len + dot.tk_len));
@@ -64,43 +72,35 @@ string(register struct expr **expp;)
                                str[len++] = dot.tk_bts[i];
                }
        ]*
-       {string2expr(expp, STRING, str, len);}
+       { string2expr(expp, str, len); }
 ;
 
-secundary(register struct expr **expp;) :
+/* 3.3.2 */
+postfix_expression(register struct expr **expp;)
+       { int oper; 
+         struct expr *e1 = 0;
+         struct idf *idf;
+       }
+:
        primary(expp)
        [
-               index_pack(expp)
+               '[' expression(&e1) ']'
+                       { ch7bin(expp, '[', e1); e1 = 0; }
        |
-               parameter_pack(expp)
+               '(' parameter_list(&e1)? ')'
+                       { ch7bin(expp, '(', e1); call_proto(expp); e1 = 0; }
        |
-               selection(expp)
+               [ '.' | ARROW ]                 { oper = DOT; }
+               identifier(&idf)                { ch7sel(expp, oper, idf); }
        ]*
-;
-
-index_pack(struct expr **expp;)
-       {struct expr *e1;}
-:
-       '[' expression(&e1) ']'
-       {ch7bin(expp, '[', e1);}
-;
-
-parameter_pack(struct expr **expp;)
-       {struct expr *e1 = 0;}
-:
-       '(' parameter_list(&e1)? ')'
-       {       ch7bin(expp, '(', e1);
-               call_proto(expp);
-       }
-;
-
-selection(struct expr **expp;)
-       {int oper; struct idf *idf;}
-:
-       [ '.' | ARROW ]
-       {oper = DOT;}
-       identifier(&idf)
-       {ch7sel(expp, oper, idf);}
+       [
+               [
+                       PLUSPLUS        { oper = POSTINCR; }
+               |
+                       MINMIN          { oper = POSTDECR; }
+               ]
+                   { ch7incr(expp, oper); }
+       ]?
 ;
 
 parameter_list(struct expr **expp;)
@@ -108,28 +108,17 @@ parameter_list(struct expr **expp;)
 :
        assignment_expression(expp)
        {any2opnd(expp, PARCOMMA);}
-       [       ','
+       [ %persistent
+               ','
                assignment_expression(&e1)
                {any2opnd(&e1, PARCOMMA);}
                {ch7bin(expp, PARCOMMA, e1);}
        ]*
 ;
 
-/* 7.2 */
-postfixed(struct expr **expp;)
-       {int oper;}
-:
-       secundary(expp)
-       [
-               postop(&oper)
-               {ch7incr(expp, oper);}
-       |
-               empty
-       ]
-;
-
 %first first_of_type_specifier, type_specifier;
 
+/* 3.3.3 & 3.3.4 */
 unary(register struct expr **expp;)
        {struct type *tp; int oper;}
 :
@@ -139,7 +128,7 @@ unary(register struct expr **expp;)
                (*expp)->ex_flags |= EX_CAST;
        }
 |
-       postfixed(expp)
+       postfix_expression(expp)
 |
        unop(&oper) unary(expp)
        {ch7mon(oper, expp);}
@@ -147,10 +136,14 @@ unary(register struct expr **expp;)
        size_of(expp)
 ;
 
+/* When an identifier is used in a sizeof()-expression, we must stil not
+ * mark it as used.
+ * extern int i;  ....  sizeof(i)  .... need not have a definition for i
+ */
 size_of(register struct expr **expp;)
        {struct type *tp;}
 :
-       SIZEOF
+       SIZEOF { InSizeof++; }  /* handle (sizeof(sizeof(int))) too */
        [%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
                cast(&tp)
                {
@@ -161,13 +154,19 @@ size_of(register struct expr **expp;)
                unary(expp)
                {ch7mon(SIZEOF, expp);}
        ]
+       { InSizeof--; }
 ;
 
-/* 7.3-7.12 */
+/* 3.3.5-3.3.17 */
 /*     The set of operators in C is stratified in 15 levels, with level
-       N being treated in RM 7.N.  In principle each operator is
-       assigned a rank, ranging from 1 to 15.  Such an expression can
-       be parsed by a construct like:
+       N being treated in RM 7.N (although this is not the standard
+       anymore). The standard describes this in phrase-structure-grammar,
+       which we are unable to parse. The description that follows comes
+       from the old C-compiler.
+
+       In principle each operator is assigned a rank, ranging
+       from 1 to 15.  Such an expression can be parsed by a construct
+       like:
                binary_expression(int maxrank;)
                        {int oper;}
                :
@@ -199,48 +198,57 @@ size_of(register struct expr **expp;)
 */
 
 binary_expression(int maxrank; struct expr **expp;)
-       {int oper; struct expr *e1;}
+       {int oper, OldResultKnown; struct expr *e1;}
 :
        unary(expp)
-       [%while (rank_of(DOT) <= maxrank && AHEAD != '=')
-               /*      '?', '=', and ',' are no binops, and the test
-                       for AHEAD != '=' keeps the other assignment
-                       operators out
-               */
+       [%while (rank_of(DOT) <= maxrank )
+               /*      '?', '=', and ',' are no binops
+                */
                binop(&oper)
+               { OldResultKnown = ResultKnown;
+                 if (oper == OR || oper == AND) {
+                         if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
+                                 if (is_zero_cst(*expp)) {
+                                         if (oper == AND) ResultKnown++;
+                                 } else if (oper == OR) ResultKnown++;
+                         }
+                 }
+               }
                binary_expression(rank_of(oper)-1, &e1)
                {
                        ch7bin(expp, oper, e1);
+                       ResultKnown = OldResultKnown;
                }
        ]*
 ;
 
-/* 7.13 */
+/* 3.3.15 */
 conditional_expression(struct expr **expp;)
-/*     There is some unfortunate disagreement about what is allowed
-       between the '?' and the ':' of a conditional_expression.
-       Although the Ritchie compiler does not even allow
-       conditional_expressions there, some other compilers (e.g., VAX)
-       accept a full assignment_expression there, and programs
-       (like, e.g., emacs) rely on it. So we have little choice.
-*/
-       {struct expr *e1 = 0, *e2 = 0;}
+       {struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;}
 :
        /* allow all binary operators */
        binary_expression(rank_of('?') - 1, expp)
        [       '?'
-               expression(&e1)
-               {
-#ifndef NOROPTION
-                       check_conditional(e1, '?', "between ? and :");
-#endif
+               { OldResultKnown = ResultKnown;
+                 if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
+                         ConstExpr++;
+                         if (is_zero_cst(*expp)) ResultKnown++;
+                 }
                }
+               expression(&e1)
                ':'
+               { if (ConstExpr) {
+                       if (OldResultKnown == ResultKnown) ResultKnown++;
+                       else ResultKnown = OldResultKnown;
+                 }
+               }
+               /* should be: conditional_expression(&e2)
+                * but that wouldn't work  with 0 ? 0 : i = 0
+                */
                assignment_expression(&e2)
                {       
-#ifndef NOROPTION
-                       check_conditional(e2, '=', "after :");
-#endif
+                       check_conditional(e2, '=', "not allowed after :");
+                       ResultKnown = OldResultKnown;
                        ch7bin(&e1, ':', e2);
                        opnd2test(expp, '?');
                        ch7bin(expp, '?', e1);
@@ -248,11 +256,10 @@ conditional_expression(struct expr **expp;)
        ]?
 ;
 
-/* 7.14 */
+/* 3.3.16 */
 assignment_expression(struct expr **expp;)
-       {
-               int oper;
-               struct expr *e1 = 0;
+       { int oper;
+         struct expr *e1 = 0;
        }
 :
        conditional_expression(expp)
@@ -265,7 +272,7 @@ assignment_expression(struct expr **expp;)
        ]
 ;
 
-/* 7.15 */
+/* 3.3.17 */
 expression(struct expr **expp;)
        {struct expr *e1;}
 :
@@ -283,12 +290,6 @@ unop(int *oper;) :
        {*oper = DOT;}
 ;
 
-postop(int *oper;):
-       PLUSPLUS {*oper = POSTINCR;}
-|
-       MINMIN {*oper = POSTDECR;}
-;
-
 multop:
        '*' | '/' | '%'
 ;
@@ -321,30 +322,8 @@ binop(int *oper;) :
 ;
 
 asgnop(register int *oper;):
-       '=' {*oper = DOT;}
-|
-       '+' '=' {*oper = PLUSAB;}
-|
-       '-' '=' {*oper = MINAB;}
-|
-       '*' '=' {*oper = TIMESAB;}
-|
-       '/' '=' {*oper = DIVAB;}
-|
-       '%' '=' {*oper = MODAB;}
-|
-       LEFT '=' {*oper = LEFTAB;}
-|
-       RIGHT '=' {*oper = RIGHTAB;}
-|
-       '&' '=' {*oper = ANDAB;}
-|
-       '^' '=' {*oper = XORAB;}
-|
-       '|' '=' {*oper = ORAB;}
-|
-       [ PLUSAB | MINAB | TIMESAB | DIVAB | MODAB | LEFTAB | RIGHTAB
-       | ANDAB | XORAB | ORAB ]
+       [ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB 
+       | LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ]
        { *oper = DOT; }
 
 ;
@@ -357,19 +336,16 @@ constant(struct expr **expp;) :
 ]      {dot2expr(expp);}
 ;
 
-/* 15 */
+/* 3.4 */
 constant_expression (struct expr **expp;) :
-       assignment_expression(expp)
-       {chk_cst_expr(expp);}
+       conditional_expression(expp)
+                           /* was: assignment_expression(expp) */
+       { chk_cst_expr(expp); }
 ;
 
 identifier(struct idf **idfp;) :
-[
-       IDENTIFIER
-|
-       TYPE_IDENTIFIER
+[ IDENTIFIER
+| TYPE_IDENTIFIER
 ]
-       {
-               *idfp = dot.tk_idf;
-       }
+       { *idfp = dot.tk_idf; }
 ;
index 3b94431..b1dc436 100644 (file)
@@ -14,6 +14,7 @@
 #include       <em.h>
 #include       <em_reg.h>
 #include       "debug.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "type.h"
 #include       "idf.h"
index 9ebd895..6f557ab 100644 (file)
@@ -7,7 +7,6 @@
 
 #include       "lint.h"
 #include       <em_reg.h>
-#include       "nofloat.h"
 #include       "debug.h"
 #include       "idfsize.h"
 #include       "botch_free.h"
@@ -31,7 +30,6 @@
 #include       "Lpars.h"
 #include       "assert.h"
 #include       "specials.h"    /* registration of special identifiers  */
-#include       "noRoption.h"
 
 int idfsize = IDFSIZE;
 extern char options[];
@@ -226,24 +224,18 @@ declare_idf(ds, dc, lvl)
                        type = construct_type(POINTER, type, 0, (arith)0,
                                              NO_PROTO);
                        break;
-               case ARRAY:     /* RM 10.1      */
+               case ARRAY:     /* 3.7.1 */
                        type = construct_type(POINTER, type->tp_up, 0, (arith)0,
                                              NO_PROTO);
                        formal_array = 1;
                        break;
-#ifndef NOFLOAT
-               case FLOAT:     /* RM 10.1      */
-                       type = double_type;
-                       break;
-#endif NOFLOAT
+               case FLOAT:
                case CHAR:
                case SHORT:
-                       /*      The RM is not clear about this: we must
-                               convert the parameter from int (they have
-                               been pushed as ints) to the specified type.
-                               The conversion to type int or uint is not
-                               allowed.
-                       */
+                       /* The conversion is done in formal_cvt(). It is
+                        * not done when the type is float and there is a
+                        * prototype.
+                        */
                        break;
                }
        }
@@ -252,29 +244,27 @@ declare_idf(ds, dc, lvl)
        */
        /* update the storage class */
        if (type && type->tp_fund == FUNCTION)  {
-               if (sc == 0 || (ds->ds_sc_given && sc == AUTO)) /* RM 8.1 */
-                       sc = GLOBAL;
-               else
-               if (sc == REGISTER) {
-                       error("function storage class cannot be register");
-                       ds->ds_sc = sc = GLOBAL;
+               if (lvl != L_GLOBAL)  {         /* 3.5.1 */
+                       if (sc == 0)
+                               sc = GLOBAL;
+                       else if (sc != EXTERN && sc != IMPLICIT) {
+                               error("illegal storage class %s for function with block-scope"
+                                       , symbol2str(sc));
+                               ds->ds_sc = sc = GLOBAL;
+                       }
                }
+               else if (sc == 0)
+                       sc = GLOBAL;
        }
        else    /* non-FUNCTION */
                if (sc == 0)
                        sc =    lvl == L_GLOBAL ? GLOBAL
                                : lvl == L_FORMAL1 || lvl == L_FORMAL2 ? FORMAL
                                : AUTO;
-#ifndef NOROPTION
-       if (options['R']) { /* some special K & R tests */
-               /* is it also an enum? */
-               if (idf->id_enum && idf->id_enum->tg_level == level)
-                       warning("%s is also an enum tag", idf->id_text);
-               /* is it a universal typedef? */
-               if (def && def->df_level == L_UNIVERSAL)
-                       warning("redeclaring reserved word %s", idf->id_text);
-       }
-#endif
+
+       /* is it a universal typedef? */
+       if (def && def->df_level == L_UNIVERSAL)
+               warning("redeclaring reserved word %s", idf->id_text);
 
 #ifdef LINT
        if (    def && def->df_level < lvl
@@ -330,6 +320,7 @@ declare_idf(ds, dc, lvl)
                def->df_file = idf->id_file;
                def->df_line = idf->id_line;
        }
+#if    0       /* be more strict in scope (at least for now) */
        else
        if (    lvl >= L_LOCAL &&
                (type->tp_fund == FUNCTION || sc == EXTERN)
@@ -337,16 +328,13 @@ declare_idf(ds, dc, lvl)
                /*      extern declaration inside function is treated the
                        same way as global extern declaration
                */
-#ifndef NOROPTION
-               if (    options['R'] &&
-                       (sc == STATIC && type->tp_fund == FUNCTION)
-               )
+               if (sc == STATIC && type->tp_fund == FUNCTION)
                        if (!is_anon_idf(idf))
                                warning("non-global static function %s",
                                        idf->id_text);
-#endif
                declare_idf(ds, dc, L_GLOBAL);
        }
+#endif
        else    { /* fill in the def block */
                register struct def *newdef = new_def();
 
@@ -376,7 +364,8 @@ declare_idf(ds, dc, lvl)
                        switch (sc)     {
                        case REGISTER:
                        case AUTO:
-                               if (type->tp_size == (arith)-1) {
+                               if (type->tp_size == (arith)-1
+                                       && type->tp_fund != ARRAY) {
                                        error("size of local %s unknown",
                                                idf->id_text);
                                /** type = idf->id_def->df_type = int_type; **/
@@ -423,10 +412,12 @@ global_redecl(idf, new_sc, tp)
                in storage class.
        */
        register struct def *def = idf->id_def;
+       int retval;
 
-       if (!equal_type(tp, def->df_type))
+       if (!(retval = equal_type(tp, def->df_type)))
                error("redeclaration of %s with different type", idf->id_text);
-       else update_proto(tp, def->df_type);
+       else if (retval == 1)
+               update_proto(tp, def->df_type);
        if (tp->tp_fund == ARRAY) {
                /* Multiple array declaration; this may be interesting */
                if (tp->tp_size < 0)    {               /* new decl has [] */
@@ -451,6 +442,7 @@ global_redecl(idf, new_sc, tp)
        */
        if (new_sc == IMPLICIT)
                return;                 /* no new information */
+
        switch (def->df_sc)     {       /* the old storage class */
        case EXTERN:
                switch (new_sc) {       /* the new storage class */
@@ -458,15 +450,8 @@ global_redecl(idf, new_sc, tp)
                case GLOBAL:
                        break;
                case STATIC:
-                       if (def->df_initialized)        {
-                               error("cannot redeclare %s to static",
-                                       idf->id_text);
-                       }
-                       else    {
-                               warning("%s redeclared to static",
-                                               idf->id_text);
-                       }
-                       def->df_sc = new_sc;
+                       warning("redeclaration of %s to static ignored"
+                                               , idf->id_text);
                        break;
                default:
                        crash("bad storage class");
@@ -481,17 +466,8 @@ global_redecl(idf, new_sc, tp)
                case GLOBAL:
                        break;
                case STATIC:
-                       if (def->df_initialized)
-                               error("cannot redeclare %s to static",
-                                       idf->id_text);
-                       else    {
-#ifndef NOROPTION
-                               if (options['R'])
-                                       warning("%s redeclared to static",
-                                               idf->id_text);
-#endif
-                               def->df_sc = STATIC;
-                       }
+                       warning("redeclaration of %s to static ignored"
+                                               , idf->id_text);
                        break;
                default:
                        crash("bad storage class");
@@ -500,21 +476,13 @@ global_redecl(idf, new_sc, tp)
                break;
        case STATIC:
                switch (new_sc) {       /* the new storage class */
-               case EXTERN:
-                       if (def->df_initialized)
-                               error("cannot redeclare %s to extern",
-                                       idf->id_text);
-                       else    {
-                               warning("%s redeclared to extern",
-                                       idf->id_text);
-                               def->df_sc = EXTERN;
-                       }
-                       break;
                case GLOBAL:
+                       warning("%s redeclared extern", idf->id_text);
+                       def->df_sc = new_sc;
+                       break;
+               case EXTERN:                    /* complain at definition */
+                       break;
                case STATIC:
-                       if (def->df_type->tp_fund != FUNCTION)
-                               warning("%s was already static",
-                                       idf->id_text);
                        break;
                default:
                        crash("bad storage class");
@@ -528,11 +496,6 @@ global_redecl(idf, new_sc, tp)
                        def->df_sc = new_sc;
                        break;
                case STATIC:
-#ifndef NOROPTION
-                       if (options['R'])
-                               warning("%s was implicitly declared as extern",
-                                       idf->id_text);
-#endif
                        def->df_sc = new_sc;
                        break;
                default:
@@ -568,18 +531,16 @@ good_formal(def, idf)
 }
 
 declare_params(dc)
-       register struct declarator *dc;
+       struct declarator *dc;
 {
        /*      Declares the formal parameters if they exist.
        */
        register struct formal *fm = dc->dc_formal;
-       
+
        while (fm)      {
                declare_parameter(fm->fm_idf);
                fm = fm->next;
        }
-       free_formals(dc->dc_formal);
-       dc->dc_formal = 0;
 }
 
 init_idf(idf)
@@ -617,7 +578,76 @@ declare_enum(tp, idf, l)
        idf->id_def->df_address = l;
 }
 
-declare_formals(fp)
+check_formals(idf, dc)
+       struct idf *idf;
+       struct declarator *dc;
+{
+       register struct formal *fm = dc->dc_formal;
+       register struct proto *pl = idf->id_def->df_type->tp_proto;
+       register struct decl_unary *du = dc->dc_decl_unary;
+
+       if (!du) {      /* error or typdef'ed function */
+               error("illegal definition of %s", idf->id_text);
+               return;
+       }
+
+       while (du && du->du_fund != FUNCTION)
+               du = du->next;
+       ASSERT(du);
+       if (du->du_proto) return;
+
+       warning("'%s' old-fashioned function definition", dc->dc_idf->id_text);
+
+       if (pl) {
+               if (pl->pl_flag & PL_ELLIPSIS) {
+                   if (!(du->du_proto) && !(pl->pl_flag & PL_ERRGIVEN))
+                       error("ellipsis terminator in previous declaration");
+                   pl = pl->next;
+               }
+               else if (pl->pl_flag & PL_VOID) {
+                   pl = pl->next;                      /* should be 0 */
+               }
+               while(fm && pl) {
+                   if (!equal_type(promoted_type(fm->fm_idf->id_def->df_type)
+                                       , pl->pl_type)) {
+                       if (!(pl->pl_flag & PL_ERRGIVEN))
+                           error("incorrect type for parameter %s"
+                                               , fm->fm_idf->id_text);
+                       pl->pl_flag |= PL_ERRGIVEN;
+                   }
+                   fm = fm->next;
+                   pl = pl->next;
+               }
+               if (pl || fm) {
+                       error("incorrect number of parameters");
+               }
+       } else {                        /* make a pseudo-prototype */
+               register struct proto *lpl;
+
+               while (fm) {
+                       if (pl == 0) pl = lpl = new_proto();
+                       else {
+                               lpl->next = new_proto();
+                               lpl = lpl->next;
+                       }
+                       lpl->pl_flag = PL_FORMAL;
+                       lpl->pl_idf = fm->fm_idf;
+                       lpl->pl_type =
+                                   promoted_type(fm->fm_idf->id_def->df_type);
+                       fm = fm->next;
+               }
+               if (pl == 0) {          /* make func(void) */
+                       pl = new_proto();
+                       pl->pl_flag = PL_VOID;
+               }
+               idf->id_def->df_type->tp_pseudoproto = pl;
+       }
+       free_formals(dc->dc_formal);
+       dc->dc_formal = 0;
+}
+
+declare_formals(idf, fp)
+       struct idf *idf;
        arith *fp;
 {
        /*      Declares those formals as int that haven't been declared
@@ -628,6 +658,7 @@ declare_formals(fp)
        register struct stack_entry *se = stack_level_of(L_FORMAL1)->sl_entry;
        arith f_offset = (arith)0;
        register int nparams = 0;
+       int hasproto = idf->id_def->df_type->tp_proto != 0;
 
 #ifdef DEBUG
        if (options['t'])
@@ -636,13 +667,22 @@ declare_formals(fp)
        while (se)      {
                register struct def *def = se->se_idf->id_def;
                
+               /* this stacklevel may also contain tags. ignore them */
+               if (!def || def->df_level < L_FORMAL1 ) {
+                       se = se->next;
+                       continue;
+               }
+
                def->df_address = f_offset;
                /*      the alignment convention for parameters is: align on
                        word boundaries, i.e. take care that the following
                        parameter starts on a new word boundary.
                */
                f_offset = align(f_offset + def->df_type->tp_size, (int) word_size);
-               formal_cvt(def); /* cvt int to char or short, if necessary */
+               /* cvt int to char or short and double to float, if necessary
+                */
+               formal_cvt(hasproto, def);
+
                se = se->next;
                def->df_level = L_FORMAL2;      /* CJ */
                RegisterAccount(def->df_address, def->df_type->tp_size,
@@ -662,11 +702,10 @@ regtype(tp)
        case INT:
        case LONG:
                return reg_any;
-#ifndef NOFLOAT
        case FLOAT:
        case DOUBLE:
+       case LNGDBL:
                return reg_float;
-#endif NOFLOAT
        case POINTER:
                return reg_pointer;
        }
index f6f1106..640d933 100644 (file)
@@ -40,7 +40,6 @@ struct idf    {
        struct sdef *id_sdef;   /* selector tags                        */
        struct tag *id_struct;  /* struct and union tags                */
        struct tag *id_enum;    /* enum tags                            */
-       int id_proto;           /* non-zero don't complain about proto  */
        int id_special;         /* special action needed at occurrence  */
 };
 
index 2e77ca1..9476ed4 100644 (file)
@@ -74,22 +74,22 @@ init_pp()
        /* __DATE__ */
        sprintf(dbuf, "\"%.3s %.2d %d\"", months[tp->tm_mon],
                        tp->tm_mday, tp->tm_year+1900);
-       macro_def(str2idf("__DATE__"), dbuf, -1, 12, NOFLAG);
+       macro_def(str2idf("__DATE__"), dbuf, -1, strlen(dbuf), NOUNDEF);
 
        /* __TIME__ */
        sprintf(tbuf, "\"%.2d:%.2d:%.2d\"", tp->tm_hour, tp->tm_min, tp->tm_sec);
-       macro_def(str2idf("__TIME__"), tbuf, -1, 10, NOFLAG);
+       macro_def(str2idf("__TIME__"), tbuf, -1, strlen(tbuf), NOUNDEF);
 
        /* __LINE__     */
-       macro_def(str2idf("__LINE__"), "0", -1, 1, FUNC);
+       macro_def(str2idf("__LINE__"), "0", -1, 1, NOUNDEF | FUNC);
 
        /* __FILE__     */
-       macro_def(str2idf("__FILE__"), "", -1, 1, FUNC);
+       macro_def(str2idf("__FILE__"), "", -1, 1, NOUNDEF | FUNC);
 
        /* __STDC__ */
-       macro_def(str2idf("__STDC__"), "1", -1, 1, NOFLAG);
+       macro_def(str2idf("__STDC__"), "1", -1, 1, NOUNDEF);
 
        /* defined(??) */
-       macro_def(str2idf("defined"), "", 1, 1, FUNC);
+       macro_def(str2idf("defined"), "", 1, 1, NOUNDEF | FUNC);
 }
 #endif NOPP
index afe2f64..6e917e4 100644 (file)
@@ -34,7 +34,7 @@ getwdir(fn)
                return "";
        if (p) {
                *p = '\0';
-               fn = Salloc(fn, p - &fn[0] + 1);
+               fn = Salloc(fn,(unsigned) (p - &fn[0] + 1));
                *p = '/';
                return fn;
        }
@@ -43,9 +43,13 @@ getwdir(fn)
 #endif NOPP
 
 int    NoUnstack;
+int    InputLevel;
+#if 0
+#endif
 
 AtEoIT()
 {
+       InputLevel--;
        unstackrepl();
        return 0;
 }
index 43e11d4..47d7207 100644 (file)
@@ -9,7 +9,7 @@
 
 /*     Note: The following macro only garuantees one PushBack.
 */
-#define UnGetChar()    ChPushBack(LexSave)
+#define UnGetChar()    ((LexSave != EOI) ? ChPushBack(LexSave) : 0)
 
 extern int LexSave;    /* last character read by GetChar               */
 extern         int GetChar();  /* character input, with trigraph parsing       */
index b385db2..96a0516 100644 (file)
@@ -7,12 +7,12 @@
 
 {
 #include       "lint.h"
-#include       "nofloat.h"
 #include       <em.h>
 #include       "debug.h"
 #include       <alloc.h>
 #include       <assert.h>
 #include       "nobitfield.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "label.h"
 #include       "expr.h"
@@ -27,7 +27,6 @@
 #include       "level.h"
 #include       "def.h"
 #include       "LLlex.h"
-#include       "noRoption.h"
 #include       "estack.h"
 #ifdef LINT
 #include       "l_lint.h"
@@ -45,13 +44,15 @@ struct sdef *gen_align_to_next();
 struct e_stack *p_stack;
 }
 
-/*     initial_value recursively guides the initialisation expression.
-       Upto now, the initialisation of a union is not allowed!
-*/
-/* 7 */
+/* initial_value recursively guides the initialisation expression.
+ */
+/* 3.5 */
+{ static int pack_level; }
+
 initial_value(register struct type **tpp; register struct expr **expp;) :
-       { if (tpp) gen_tpcheck(tpp, 0); }
+       { if (tpp) gen_tpcheck(tpp); }
 [
+               { if (pack_level == 0) gen_error = 0; }
        assignment_expression(expp)
                {
 #ifdef LINT
@@ -71,7 +72,6 @@ initial_value(register struct type **tpp; register struct expr **expp;) :
 ;
 
 initial_value_pack(struct type **tpp; struct expr **expp;)
-       { static int pack_level; }
 :
        '{'
                        { if (pack_level == 0) gen_error = 0; pack_level++; }
@@ -108,7 +108,7 @@ initial_value_list(register struct type **tpp; struct expr **expp;)
 ;
 
 {
-gen_tpcheck(tpp, union_allowed)
+gen_tpcheck(tpp)
        struct type **tpp;
 {
        register struct type *tp;
@@ -418,24 +418,14 @@ pad(tpx)
        register struct type *tp = tpx;
        register arith sz = tp->tp_size;
 
-       gen_tpcheck(&tpx, 1);
+       gen_tpcheck(&tpx);
        if (gen_error) return;
-       switch (tp->tp_fund) {
-       case UNION:
-#ifndef NOROPTION
-               if (options['R']) {
-                       warning("initialisation of unions not allowed");
-               }
-#endif
-               break;
 #ifndef NOBITFIELD
-       case FIELD:
+       if (tp->tp_fund == FIELD) {
                put_bf(tp, (arith)0);
                return;
-#endif NOBITFIELD
-               default:
-                       break;
        }
+#endif NOBITFIELD
 
        while (sz >= word_size) {
                C_con_cst((arith) 0);
@@ -498,16 +488,21 @@ check_ival(expp, tp)
                        C_con_dlb(expr->VL_LBL, expr->VL_VALUE);
                }
                break;
-#ifndef NOFLOAT
        case FLOAT:
        case DOUBLE:
+       case LNGDBL:
                ch7cast(expp, '=', tp);
                expr = *expp;
 #ifdef DEBUG
                print_expr("init-expr after cast", expr);
 #endif DEBUG
-               if (expr->ex_class == Float)
+               if (expr->ex_class == Float) {
+                       if (!expr->FL_VALUE) {
+                               expr->FL_VALUE = Malloc(FLT_STRLEN);
+                               flt_flt2str(&(expr->FL_ARITH), expr->FL_VALUE, FLT_STRLEN);
+                       }
                        C_con_fcon(expr->FL_VALUE, expr->ex_type->tp_size);
+               }
 #ifdef NOTDEF
 
 Coercion from int to float is now always done compile time.
@@ -529,7 +524,6 @@ and also to prevent runtime coercions for compile-time constants.
                else
                        illegal_init_cst(expr);
                break;
-#endif NOFLOAT
 
 #ifndef NOBITFIELD
        case FIELD:
@@ -562,13 +556,13 @@ ch_array(tpp, ex)
        struct expr *ex;
 {
        register struct type *tp = *tpp;
-       register arith length = ex->SG_LEN;
-       char *s;
+       register int length = ex->SG_LEN, i;
+       register char *to, *from, *s;
 
        ASSERT(ex->ex_class == String);
        if (tp->tp_size == (arith)-1) {
                /* set the dimension    */
-               tp = *tpp = construct_type(ARRAY, tp->tp_up, 0, length, NO_PROTO);
+               tp = *tpp = construct_type(ARRAY, tp->tp_up, 0, (arith)length, NO_PROTO);
        }
        else {
                arith dim = tp->tp_size / tp->tp_up->tp_size;
@@ -580,10 +574,14 @@ ch_array(tpp, ex)
        }
        /* throw out the characters of the already prepared string      */
        s = Malloc((unsigned) (length));
-       clear(s, (int) (length));
-       strncpy(s, ex->SG_VALUE, (int) length);
+       clear(s, length);
+       i = length <= ex->SG_LEN ? length : ex->SG_LEN;
+       to = s; from = ex->SG_VALUE;
+       while(--i >= 0) {
+               *to++ = *from++;
+       }
        free(ex->SG_VALUE);
-       str_cst(s, (int) (length));
+       str_cst(s, length);
        free(s);
 }
 
@@ -651,7 +649,7 @@ zero_bytes(sd)
        */
        register int n = sd->sd_sdef->sd_offset - sd->sd_offset -
                size_of_type(sd->sd_type, "struct member");
-       register int count = n;
+       int count = n;
 
        while (n-- > 0)
                con_nullbyte();
index c0cfe4c..5cdda08 100644 (file)
@@ -12,6 +12,7 @@
 #include       <alloc.h>       /* for st_free */
 #include       "interface.h"
 #include       "assert.h"
+#include       <flt_arith.h>
 #include       "arith.h"       /* definition arith */
 #include       "label.h"       /* definition label */
 #include       "expr.h"
@@ -23,7 +24,6 @@
 #include       "stack.h"
 #include       "type.h"
 #include       "level.h"
-#include       "nofloat.h"
 #include       "l_lint.h"
 #include       "l_state.h"
 
index b591e11..e2629df 100644 (file)
@@ -13,6 +13,7 @@
 #include       "debug.h"
 #include       "interface.h"
 #include       "assert.h"
+#include       <flt_arith.h>
 #include       "arith.h"       /* definition arith */
 #include       "label.h"       /* definition label */
 #include       "expr.h"
@@ -24,7 +25,6 @@
 #include       "stack.h"
 #include       "type.h"
 #include       "level.h"
-#include       "nofloat.h"
 #include       "l_lint.h"
 #include       "l_state.h"
 #include       "l_outdef.h"
index 1384c5f..9f67044 100644 (file)
@@ -11,6 +11,7 @@
 
 #include       <alloc.h>       /* for st_free */
 #include       "interface.h"
+#include       <flt_arith.h>
 #include       "arith.h"       /* definition arith */
 #include       "label.h"       /* definition label */
 #include       "expr.h"
@@ -22,7 +23,6 @@
 #include       "stack.h"
 #include       "type.h"
 #include       "level.h"
-#include       "nofloat.h"
 #include       "l_state.h"
 
 extern char *symbol2str();
@@ -140,7 +140,8 @@ lint_new_oper(expr)
                break;
 
        case '~':
-               if (r_fund == ENUM || r_fund == FLOAT || r_fund == DOUBLE)
+               if (r_fund == ENUM || r_fund == FLOAT || r_fund == DOUBLE
+                                           /* ??? ||  r_fund == LNGDBL */ )
                        warning("~ on %s", symbol2str(r_fund));
                break;
 
@@ -285,6 +286,7 @@ numsize(fund)
        case LONG:      return 4;
        case FLOAT:     return 5;
        case DOUBLE:    return 6;
+       case LNGDBL:    return 7;
        default:        return 0;
        }
 }
@@ -300,8 +302,8 @@ lint_ptr_conv(from, to)
 {
 /* X -> X ok                   -- this includes struct -> struct, of any size
  * X -> CHAR ok
- * DOUBLE -> X ok
- * FLOAT -> LONG -> INT -> SHORT  ok
+ * LNGDBL -> X ok
+ * DOUBLE -> FLOAT -> LONG -> INT -> SHORT  ok
  */
        if (from == to)
                return;
@@ -309,10 +311,18 @@ lint_ptr_conv(from, to)
        if (to == CHAR)
                return;
 
-       if (from == DOUBLE)
+       if (from == LNGDBL)
                return;
 
        switch (from) {
+       case DOUBLE:
+               switch(to) {
+               case FLOAT:
+               case INT:
+               case SHORT:
+                       return;
+               }
+               break;
        case FLOAT:
                switch (to) {
                case LONG:
index ef31a1a..a01cb06 100644 (file)
@@ -11,6 +11,7 @@
 
 #include       <alloc.h>
 #include       "interface.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "assert.h"
 #include       "type.h"
@@ -442,6 +443,7 @@ outargtype(tp)
        case LONG:
        case FLOAT:
        case DOUBLE:
+       case LNGDBL:
        case VOID:
        case ERRONEOUS:
                if (tp->tp_unsigned)
index ad47b97..0c4fb90 100644 (file)
@@ -13,6 +13,7 @@
 #include       "interface.h"
 #include       "assert.h"
 #include       "debug.h"
+#include       <flt_arith.h>
 #include       "arith.h"       /* definition arith */
 #include       "label.h"       /* definition label */
 #include       "expr.h"
@@ -24,7 +25,6 @@
 #include       "stack.h"
 #include       "type.h"
 #include       "level.h"
-#include       "nofloat.h"
 #include       "l_lint.h"
 #include       "l_brace.h"
 #include       "l_state.h"
index 984a433..112bd33 100644 (file)
@@ -12,7 +12,6 @@
 #include       "arith.h"
 #include       "def.h"
 #include       "type.h"
-#include       "noRoption.h"
 
 extern char options[];
 
@@ -33,25 +32,10 @@ enter_label(idf, defining)
                                                                idf->id_text);
                }
                else    {               /* there may still be room for it */
-#ifndef NOROPTION
-                       if (options['R'] && def->df_sc == TYPEDEF)
-                               warning("label %s is also a typedef",
-                                       idf->id_text);
-#endif
-                       
                        if (def->df_level == level)     /* but alas, no */
                                error("%s is not a label", idf->id_text);
                        else    {
-                               register int lvl = def->df_level + 1;
-                               
-#ifndef NOROPTION
-                               if (options['R'] && def->df_level > L_LOCAL)
-                                       warning("label %s is not function-wide",
-                                                               idf->id_text);
-#endif
-                               if (lvl < L_LOCAL)
-                                       lvl = L_LOCAL;
-                               add_def(idf, LABEL, label_type, lvl);
+                               add_def(idf, LABEL, label_type, L_LOCAL);
                        }
                }
        }
index 39476d6..fa8fb7d 100644 (file)
@@ -12,8 +12,9 @@
        these flags can be set simultaneously.
 */
 #define NOFLAG         0               /* no special flags     */
-#define        FUNC            01              /* function attached    */
-#define NOREPLACE      02              /* don't replace        */
+#define        FUNC            0x1             /* function attached    */
+#define        NOUNDEF         0x2             /* special macro */
+#define NOREPLACE      0x4             /* prevent recursion */
 
 #define        FORMALP 0200    /* mask for creating macro formal parameter     */
 
index 660770a..e940aaf 100644 (file)
@@ -6,7 +6,6 @@
 /* MAIN PROGRAM */
 
 #include       "lint.h"
-#include       "nofloat.h"
 #include       <system.h>
 #include       "nopp.h"
 #include       "target_sizes.h"
@@ -25,7 +24,6 @@
 #include       "LLlex.h"
 #include       <alloc.h>
 #include       "specials.h"
-#include       "noRoption.h"
 #include       "nocross.h"
 #include       "sizes.h"
 #include       "align.h"
@@ -55,11 +53,9 @@ arith
        dword_size = (2 * SZ_WORD),
        int_size = SZ_INT,
        long_size = SZ_LONG,
-#ifndef NOFLOAT
        float_size = SZ_FLOAT,
        double_size = SZ_DOUBLE,
        lngdbl_size = SZ_LNGDBL,
-#endif NOFLOAT
        pointer_size = SZ_POINTER;
 
 int
@@ -67,11 +63,9 @@ int
        word_align = AL_WORD,
        int_align = AL_INT,
        long_align = AL_LONG,
-#ifndef NOFLOAT
        float_align = AL_FLOAT,
        double_align = AL_DOUBLE,
        lngdbl_align = AL_LNGDBL,
-#endif NOFLOAT
        pointer_align = AL_POINTER,
        struct_align = AL_STRUCT,
        union_align = AL_UNION;
@@ -113,7 +107,7 @@ main(argc, argv)
        {
                char *par = &argv[1][1];
 
-               do_option(par, 1);
+               do_option(par);
                argc--, argv++;
        }
 #ifdef LINT
@@ -240,7 +234,7 @@ init()
                transparent to the user.
        */
        gen_type = standard_type(GENERIC, 0, 1, (arith)1);
-       char_type = standard_type(CHAR, 0, 1, (arith)1);
+       schar_type = standard_type(CHAR, 0, 1, (arith)1);
        uchar_type = standard_type(CHAR, UNSIGNED, 1, (arith)1);
 
        short_type = standard_type(SHORT, 0, short_align, short_size);
@@ -259,11 +253,9 @@ init()
        long_type = standard_type(LONG, 0, long_align, long_size);
        ulong_type = standard_type(LONG, UNSIGNED, long_align, long_size);
 
-#ifndef NOFLOAT
        float_type = standard_type(FLOAT, 0, float_align, float_size);
        double_type = standard_type(DOUBLE, 0, double_align, double_size);
        lngdbl_type = standard_type(LNGDBL, 0, lngdbl_align, lngdbl_size);
-#endif NOFLOAT
        void_type = standard_type(VOID, 0, 1, (arith)0);
        label_type = standard_type(LABEL, 0, 0, (arith)0);
        error_type = standard_type(ERRONEOUS, 0, 1, (arith)1);
@@ -292,17 +284,15 @@ init()
        if ((int)short_size > (int)int_size || (int)int_size > (int)long_size)
                fatal("sizes of short/int/long decreasing");
 
-       /* Build a type for function returning int, RM 13 */
+       /* Build a type for function returning int (3.3.2.2) */
        funint_type = construct_type(FUNCTION, int_type, 0, (arith)0, NO_PROTO);
-       string_type = construct_type(POINTER, char_type, 0, (arith)0, NO_PROTO);
+       string_type = construct_type(POINTER, schar_type, 0, (arith)0, NO_PROTO);
 
        /* Define the standard type identifiers. */
-       add_def(str2idf("char"), TYPEDEF, char_type, L_UNIVERSAL);
+       add_def(str2idf("char"), TYPEDEF, schar_type, L_UNIVERSAL);
        add_def(str2idf("int"), TYPEDEF, int_type, L_UNIVERSAL);
-#ifndef NOFLOAT
        add_def(str2idf("float"), TYPEDEF, float_type, L_UNIVERSAL);
        add_def(str2idf("double"), TYPEDEF, double_type, L_UNIVERSAL);
-#endif NOFLOAT
        add_def(str2idf("void"), TYPEDEF, void_type, L_UNIVERSAL);
        stack_level();
 }
@@ -372,17 +362,16 @@ preprocess()
                        char sbuf[1024];        /* a transient buffer */
                        char *bts2str();
 
-                       print("\"%s\" ", bts2str(dot.tk_bts, dot.tk_len, sbuf));
+                       print("\"%s\" ", bts2str(dot.tk_bts, dot.tk_len -
+                       1, sbuf));
                        break;
                }
                case INTEGER:
                        print("%ld ", dot.tk_ival);
                        break;
-#ifndef NOFLOAT
                case FLOATING:
                        print("%s ", dot.tk_fval);
                        break;
-#endif NOFLOAT
                case EOI:
                case EOF:
                        return;
index c96cef6..548d42d 100644 (file)
@@ -8,7 +8,6 @@
 #include       "lint.h"
 #include       "botch_free.h"
 #include       <alloc.h>
-#include       "nofloat.h"
 #include       "nopp.h"
 #include       "idfsize.h"
 #include       "nobitfield.h"
@@ -20,7 +19,6 @@
 #include       "align.h"
 #include       "use_tmp.h"
 #include       "dataflow.h"
-#include       "noRoption.h"
 
 #ifndef NOPP
 extern char **inctable;
@@ -86,14 +84,6 @@ next_option:                 /* to allow combined one-char options */
                goto next_option;
 #endif LINT
 
-       case 'R':                       /* strict version */
-#ifndef        NOROPTION
-               options[opt] = 1;
-#else  NOROPTION
-               warning("-R option not implemented");
-#endif NOROPTION
-               goto next_option;
-
 #ifdef ___XXX___
 deleted, is now a debug-flag
        case 'C' :      /* E option + comment output            */
@@ -284,28 +274,22 @@ deleted, is now a debug-flag
                                        long_align = algn;
                                break;
                        case 'f':       /* float        */
-#ifndef NOFLOAT
                                if (sz != (arith)0)
                                        float_size = sz;
                                if (algn != 0)
                                        float_align = algn;
-#endif NOFLOAT
                                break;
                        case 'd':       /* double       */
-#ifndef NOFLOAT
                                if (sz != (arith)0)
                                        double_size = sz;
                                if (algn != 0)
                                        double_align = algn;
-#endif NOFLOAT
                                break;
                        case 'x':       /* long double  */
-#ifndef NOFLOAT
                                if (sz != (arith)0)
                                        lngdbl_size = sz;
                                if (algn != 0)
                                        lngdbl_align = algn;
-#endif NOFLOAT
                                break;
                        case 'p':       /* pointer      */
                                if (sz != (arith)0)
index 83edebb..e350c4c 100644 (file)
@@ -38,15 +38,13 @@ struct pkey {
 
 extern struct idf *GetIdentifier();
 
-
 do_pragma()
 {
        register struct pkey *pkp;
        register struct idf *id;
        struct token tk;
-       int flag;
 
-       if ((id = GetIdentifier()) != (struct idf *)0) {
+       if ((id = GetIdentifier(1)) != (struct idf *)0) {
                /*      Lineair search - why bother ?
                */
                for (pkp = &pragmas[0]; pkp->pk_key != P_UNKNOWN; pkp++)
@@ -67,8 +65,8 @@ do_pragma()
                        strict("unimplemented pragma directive");
                        break;
                }
+               SkipToNewLine(0);
        }
-       SkipToNewLine(0);
-
+       else strict("unrecognized pragma line");
 }
 #endif
index fbee3bc..adbeef4 100644 (file)
@@ -47,6 +47,7 @@
 {
 #include       "lint.h"
 #include       "nopp.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "LLlex.h"
 #include       "idf.h"
@@ -86,10 +87,10 @@ control_if_expression
                }
 ;
 
-/* 10 */
+/* 3.7 */
 program:
        [%persistent external_definition]*
-       {unstack_world();}
+       { unstack_world(); }
 ;
 
 /*     A C identifier definition is remarkable in that it formulates
@@ -176,29 +177,28 @@ non_function(register struct decspecs *ds; register struct declarator *dc;)
        ';'
 ;
 
-/* 10.1 */
+/* 3.7.1 */
 function(struct decspecs *ds; struct declarator *dc;)
        {
                arith fbytes;
+               register struct idf *idf = dc->dc_idf;
        }
 :
-       {       register struct idf *idf = dc->dc_idf;
+       {
 #ifdef LINT
                lint_start_function();
 #endif LINT
                init_idf(idf);
                stack_level();          /* L_FORMAL1 declarations */
-               if (dc->dc_formal)
-                       strict("'%s' old-fashioned function declaration",
-                               idf->id_text);
                declare_params(dc);
                begin_proc(ds, idf);    /* sets global function info */
                stack_level();          /* L_FORMAL2 declarations */
-               declare_protos(idf, dc);
+               declare_protos(dc);
        }
        declaration*
        {
-               declare_formals(&fbytes);
+               check_formals(idf, dc);         /* check style-mixtures */
+               declare_formals(idf, &fbytes);
 #ifdef LINT
                lint_formals();
 #endif LINT
index e3b8626..a078a2d 100644 (file)
@@ -13,6 +13,7 @@
 #include       <alloc.h>
 #include       "Lpars.h"
 #include       "level.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "align.h"
 #include       "stack.h"
 
 extern char options[];
 
+check_for_void(pl)
+       register struct proto *pl;
+{
+       register int errcnt = 0;
+
+       if (!pl) return;
+       if ((pl->pl_flag & PL_VOID) && !(pl->next)) return;
+
+       while (pl) {
+               if (pl->pl_flag & PL_VOID) {
+                       if (!errcnt && !(pl->pl_flag & PL_ERRGIVEN))
+                               error("illegal use of void in argument list");
+                       pl->pl_flag |= PL_ERRGIVEN;
+                       errcnt++;
+               }
+               pl = pl->next;
+       }
+}
+
 add_proto(pl, ds, dc, level)
        struct proto *pl;
        struct decspecs *ds;
@@ -50,7 +70,7 @@ add_proto(pl, ds, dc, level)
 
        ASSERT(ds->ds_type != (struct type *)0);
 
-       pl->pl_flag = FORMAL;
+       pl->pl_flag = PL_FORMAL;
        if ((idf = dc->dc_idf) != (struct idf *)0)
                def = idf->id_def;
        type = declare_type(ds->ds_type, dc);
@@ -58,9 +78,9 @@ add_proto(pl, ds, dc, level)
                extern char *symbol2str();
                error("unknown %s-type", symbol2str(type->tp_fund));
        } else if (type->tp_size == 0) {
-               pl->pl_flag = VOID;
                if (idf != (struct idf *)0)
-                       strict("illegal use of void in argument list");
+                       error("illegal use of void in argument list");
+               else pl->pl_flag = PL_VOID;
        }
 
        /*      Perform some special conversions for parameters.
@@ -70,7 +90,7 @@ add_proto(pl, ds, dc, level)
                        remove_proto_idfs(type->tp_proto);
                type = construct_type(POINTER, type, 0, (arith) 0, NO_PROTO);
        } else if (type->tp_fund == ARRAY) {
-               type = construct_type(POINTER, type, 0, (arith) 0, NO_PROTO);
+               type = construct_type(POINTER, type->tp_up, 0, (arith) 0, NO_PROTO);
                formal_array = 1;
        }
 
@@ -84,7 +104,7 @@ add_proto(pl, ds, dc, level)
        sc = (ds->ds_sc_given && ds->ds_sc != REGISTER) ?
                                0 : sc == 0 ? FORMAL : REGISTER;
 
-       if (def && (def->df_level == level || def->df_level < L_PROTO)) {
+       if (def && (def->df_level == level /* || def->df_level < L_PROTO */ )) {
                /* redeclaration at the same level */
                error("parameter %s redeclared", idf->id_text);
        } else if (idf != (struct idf *)0) {
@@ -111,6 +131,8 @@ add_proto(pl, ds, dc, level)
                        ...
                                { int func(int a, int b);
                                ...
+                               }
+                       }
 
                        The idf's a and b declared in the prototype declaration
                        do not go at any level, they are simply ignored.
@@ -118,6 +140,7 @@ add_proto(pl, ds, dc, level)
 
                        f(int a, int b) {
                        ...
+                       }
 
                        They should go at level L_FORMAL2. But at this stage
                        we don't know whether we have a prototype or function
@@ -131,8 +154,25 @@ add_proto(pl, ds, dc, level)
        pl->pl_type = type;
 }
 
-declare_protos(idf, dc)
-       register struct idf *idf;
+struct tag *
+gettag(tp, idpp)
+struct type *tp;
+struct idf **idpp;
+{
+       struct tag *tg;
+
+       while (tp->tp_up) tp = tp->tp_up;
+       *idpp = tp->tp_idf;
+       switch(tp->tp_fund) {
+       case ENUM: tg = tp->tp_idf->id_enum; break;
+       case UNION:
+       case STRUCT: tg = tp->tp_idf->id_struct; break;
+       default: return (struct tag *)0;
+       }
+       return tg;
+}
+
+declare_protos(dc)
        register struct declarator *dc;
 {
        /*      At this points we know that the idf's in protolist are formal
@@ -153,12 +193,17 @@ declare_protos(idf, dc)
                du = du->next;
        pl = du ? du->du_proto : NO_PROTO;
        if (pl) {
+#if    0 /* the id_proto member is deleted (???) */
                idf->id_proto = 0;
+#endif /* 0 */
                do {
+                       struct tag *tg;
+                       struct idf *idp = 0;
+
                        type = pl->pl_type;
 
                        /* `...' only for type checking */
-                       if (pl->pl_flag == ELLIPSIS) {
+                       if (pl->pl_flag & PL_ELLIPSIS) {
                                pl = pl->next;
                                continue;
                        }
@@ -181,6 +226,12 @@ declare_protos(idf, dc)
                        def->df_level = L_FORMAL2;
                        stack_idf(pl->pl_idf, stl);
                        pl = pl->next;
+
+                       tg = gettag(type, &idp);
+                       if (tg && tg->tg_level <= L_PROTO) {
+                               tg->tg_level = L_FORMAL2;
+                               stack_idf(idp, stl);
+                       }
                } while (pl);
        }
 #ifdef DEBUG
@@ -265,6 +316,50 @@ free_proto_list(pl)
        }
 }
 
+/* struct/union and enum tags can be declared inside prototypes
+ * remove them from the symbol-table
+ */
+remove_proto_tag(tp)
+struct type *tp;
+{
+       struct idf *ident;
+       struct tag *tg, *otg = 0;
+
+       while(tp->tp_up) tp = tp->tp_up;
+
+       ident = tp->tp_idf;
+       switch(tp->tp_fund) {
+       case ENUM: tg = ident->id_enum; break;
+       case UNION:
+       case STRUCT: tg = ident->id_struct; break;
+       default: return;
+       }
+       while (tg && tg->tg_type != tp) {
+               otg = tg;
+               tg = tg->next;
+       }
+       if (tg ->tg_level > L_PROTO) return;
+
+#ifdef DEBUG
+       if (options['t'])
+               print("Removing idf %s from list\n",
+                       ident->id_text);
+#endif
+
+       if (!otg) {
+               switch(tp->tp_fund) {
+               case ENUM: ident->id_enum = tg->next; break;
+               case UNION:
+               case STRUCT: ident->id_struct = tg->next; break;
+               }
+               free_tag(tg);
+       }
+       else {
+               otg->next = tg->next;
+               free_tag(tg);
+       }
+}
+
 remove_proto_idfs(pl)
        register struct proto *pl;
 {
@@ -283,15 +378,19 @@ remove_proto_idfs(pl)
 #endif
                        /*      Remove all the definitions made within
                                a prototype.
+                               ??? is this really necessary (Hans)
+                               wasn't this done before in the declaration
                        */
-                       if (pl->pl_flag == FORMAL) {
+#if 0
+                       if (pl->pl_flag & PL_FORMAL) {
                                register struct type *tp = pl->pl_type;
 
                                while (tp && tp->tp_fund != FUNCTION)
                                        tp = tp->tp_up;
                                if (tp)
-                                       remove_proto_idfs(tp->tp_proto);
+                                   debug("remove_proto_idfs(tp->tp_proto)");
                        }
+#endif
                        def = pl->pl_idf->id_def;
                        if (def && def->df_level <= L_PROTO){
                                pl->pl_idf->id_def = def->next;
@@ -299,6 +398,9 @@ remove_proto_idfs(pl)
                        }
                        pl->pl_idf = (struct idf *) 0;
                }
+               if (pl->pl_type) {
+                       remove_proto_tag(pl->pl_type);
+               }
                pl = pl->next;
        }
 }
@@ -316,7 +418,7 @@ call_proto(expp)
        register struct expr *left = (*expp)->OP_LEFT;
        register struct expr *right = (*expp)->OP_RIGHT;
        register struct proto *pl = NO_PROTO;
-       static struct proto ellipsis = { 0, 0, 0, ELLIPSIS };
+       static struct proto ellipsis = { 0, 0, 0, PL_ELLIPSIS };
 
        if (left != NILEXPR) {  /* in case of an error */
                register struct type *tp = left->ex_type;
@@ -333,18 +435,6 @@ call_proto(expp)
                struct expr **estack[NPARAMS];
                struct proto *pstack[NPARAMS];
 
-               if (pl == NO_PROTO) {
-                       register struct idf *idf;
-
-                       if (left->ex_class != Value || left->VL_CLASS != Name) {
-                               strict("no prototype supplied");
-                       }
-                       else if (! (idf = left->VL_IDF)->id_proto) {
-                               strict("'%s' no prototype supplied", idf->id_text);
-                               idf->id_proto++;
-                       }
-               }
-
                /* stack up the parameter expressions */
                while (ex->ex_class == Oper && ex->OP_OPER == PARCOMMA) {
                        if (ecnt == STDC_NPARAMS)
@@ -362,7 +452,7 @@ call_proto(expp)
                /*      Declarations like int f(void) do not expect any
                        parameters.
                */
-               if (pl && pl->pl_flag == VOID) {
+               if (pl && pl->pl_flag & PL_VOID) {
                        strict("no parameters expected");
                        pl = NO_PROTO;
                }
@@ -391,17 +481,17 @@ call_proto(expp)
                                error("more parameters than specified in prototype");
                                break;
                        }
-                       else if (pstack[pcnt]->pl_flag != ELLIPSIS) {
+                       else if (!(pstack[pcnt]->pl_flag & PL_ELLIPSIS)) {
                                ch7cast(estack[ecnt],CASTAB,pstack[pcnt]->pl_type);
                                pcnt--;
                        } else
                                any2parameter(estack[ecnt]);
                }
-               if (pcnt >= 0 && pstack[0]->pl_flag != ELLIPSIS)
+               if (pcnt >= 0 && !(pstack[0]->pl_flag & PL_ELLIPSIS))
                        error("less parameters than specified in prototype");
 
        } else {
-               if (pl && pl->pl_flag != VOID)
+               if (pl && !(pl->pl_flag & PL_VOID))
                        error("less parameters than specified in prototype");
        }
 }
index 614a5c9..946c780 100644 (file)
@@ -9,9 +9,14 @@ struct proto {
        struct proto *next;
        struct type *pl_type;   /* parameter type */
        struct idf *pl_idf;     /* parameter identifier */
-       short pl_flag;          /* ELLIPSIS or FORMAL */
+       short pl_flag;          /* see define's */
 };
 
-#define NO_PROTO       ((struct proto *)0)
+#define        NO_PROTO        ((struct proto *)0)
+
+#define        PL_VOID         0x01
+#define        PL_FORMAL       0x02
+#define        PL_ELLIPSIS     0x04
+#define        PL_ERRGIVEN     0x08
 
 /* ALLOCDEF "proto" 10 */
index f907db7..11aa83b 100644 (file)
@@ -27,7 +27,9 @@
 #include       "argbuf.h"
 #include       "replace.h"
 
-struct repl    *ReplaceList;   /* list of currently active macros */
+extern struct idf *GetIdentifier();
+extern int InputLevel;
+struct repl *ReplaceList;      /* list of currently active macros */
 
 int
 replace(idf)
@@ -38,15 +40,23 @@ replace(idf)
                higher interface to the real thing: expand_macro().
        */
        struct repl *repl;
-       int size;
        
+       if (!(idf->id_macro)) return 0;
+       if (idf->id_macro->mc_flag & NOREPLACE){
+               return 0;
+       }
        repl = new_repl();
        repl->r_ptr = repl->r_text;
        repl->r_args = new_args();
-       if (!expand_macro(repl, idf, (struct idf *)0))
+       repl->r_idf = idf;
+/* repl->r_level = InputLevel; /* ?? temporary */
+       if (!expand_macro(repl, idf)) {
                return 0;
-       free_args(repl->r_args);
+       }
+       InputLevel++;
        InsertText(repl->r_text, repl->r_ptr - repl->r_text);
+       repl->r_level = InputLevel;
+       idf->id_macro->mc_flag |= NOREPLACE;
        repl->next = ReplaceList;
        ReplaceList = repl;
        return 1;
@@ -54,24 +64,33 @@ replace(idf)
 
 unstackrepl()
 {
-       struct repl *repl = ReplaceList;
+       Unstacked++;
+}
 
-#ifdef PERSONAL_TOUCH
-       if (repl == NO_REPL) {
-               print("Leendert, you don't understand the principle yet\n");
-               return;
+EnableMacros()
+{
+       register struct repl *r = ReplaceList, *prev = 0;
+
+       ASSERT(Unstacked > 0);
+       while(r) {
+               struct repl *nxt = r->next;
+
+               if (r->r_level > InputLevel) {
+                       r->r_idf->id_macro->mc_flag &= ~NOREPLACE;
+                       if (!prev) ReplaceList = nxt;
+                       else prev->next = nxt;
+                       free_args(r->r_args);
+                       free_repl(r);
+               }
+               else prev = r;
+               r = nxt;
        }
-#else
-       ASSERT(repl != NO_REPL);
-#endif
-       ReplaceList = repl->next;
-       free_repl(repl);
+       Unstacked = 0;
 }
 
-expand_macro(repl, idf, previdf)
+expand_macro(repl, idf)
        register struct repl *repl;
        register struct idf *idf;
-       struct idf *previdf;
 {
        /*      expand_macro() does the actual macro replacement.
                "idf" is a description of the identifier which
@@ -85,6 +104,10 @@ expand_macro(repl, idf, previdf)
                ment list associated with "idf" is expanded.
                expand_macro() returns 1 if the replacement succeeded
                and 0 if some error occurred.
+
+               A special case is "defined". This acts as a unary operator
+               on a single, unexpanded identifier, which may be surrounded
+               by parenthesis. The function expand_defined handles this.
        */
        register struct macro *mac = idf->id_macro;
        struct args *args = repl->r_args;
@@ -94,44 +117,37 @@ expand_macro(repl, idf, previdf)
                if (mac->mc_flag & FUNC) {
                        /* the following assertion won't compile:
                        ASSERT(!strcmp("defined", idf->id_text));
+                       expand the assert macro by hand (??? dirty, temporary)
                        */
+#ifdef DEBUG
+                       if (strcmp("defined", idf->id_text))
+                               crash("in %s, %u: assertion %s failed",
+                                       __FILE__, __LINE__ - 2, 
+                                       "strcmp(\"defined\", idf->id_text)");
+#endif
                        if (!AccDefined) return 0;
+                       expand_defined(repl);
+                       return 1;
                }
 
                ch = GetChar();
                ch = skipspaces(ch,1);
                if (ch != '(') {        /* no replacement if no () */
-                       /*      This is obscure. See the examples for the replace
-                               algorithm in section 3`.8.3.5.
+                       /*      This is obscure. See the examples for the
+                               replace algorithm in section 3`.8.3.5.
                        lexwarning("macro %s needs arguments", idf->id_text);
                        */
                        UnGetChar();
                        return 0;
                } else
-                       getactuals(args, idf);
+                       getactuals(repl, idf);
 
-               if (mac->mc_flag & FUNC) {
-                       struct idf *param = str2idf(args->a_rawbuf);
-
-                       *repl->r_ptr++ = param->id_macro ? '1' : '0';
-                       *repl->r_ptr = '\0';
-                       return 1;
-               }
        }
 
        if (mac->mc_flag & FUNC) /* this macro leads to special action */
                macro_func(idf);
 
-       if (mac->mc_nps == -1) {
-               register int size = mac->mc_length;
-               register char *text = mac->mc_text;
-
-               ASSERT((repl->r_ptr+size) < &(repl->r_text[LAPBUF]));
-               while (size-- > 0)
-                       *repl->r_ptr++ = *text++;
-               *repl->r_ptr = '\0';
-       } else
-               macro2buffer(repl, idf, args);
+       macro2buffer(repl, idf, args);
 
        /*      According to the ANSI definition:
 
@@ -143,23 +159,56 @@ expand_macro(repl, idf, previdf)
                character based, we have a problem.
                For now: just insert a space after all tokens,
                until ANSI fixes this flaw.
+               ^^^^^^^^^^^^^^^^^^^^^^^^^^      tsk tsk tsk
        */
-       *repl->r_ptr++ = ' ';
+       if (*repl->r_ptr != TOKSEP) *repl->r_ptr++ = TOKSEP;
        *repl->r_ptr = '\0';
 
-       if (idf != previdf)
-               maccount(repl, idf);
        return 1;
 }
 
-getactuals(args, idf)
-       register struct args *args;
+expand_defined(repl)
+       register struct repl *repl;
+{
+       register int ch = GetChar();
+       struct idf *id;
+       int parens = 0;
+
+       ch = skipspaces(ch, 0);
+
+       if (ch == '(') {
+               parens++;
+               ch = GetChar();
+               ch = skipspaces(ch, 0);
+       }
+       if ((class(ch) != STIDF) && (class(ch) != STELL)) {
+               error("identifier missing");
+               if (parens && ch != ')') error(") missing");
+               if (!parens || ch != ')') UnGetChar();
+               *repl->r_ptr++ = '0';
+               *repl->r_ptr = '\0';
+               return;
+       }
+       UnGetChar();
+       id = GetIdentifier(0);
+       ASSERT(id || class(ch) == STELL);
+       ch = GetChar();
+       ch = skipspaces(ch, 0);
+       if (parens && ch != ')') error(") missing");
+       if (!parens || ch != ')') UnGetChar();
+       *repl->r_ptr++ = (id && id->id_macro) ? '1' : '0';
+       *repl->r_ptr = '\0';
+}
+
+getactuals(repl, idf)
+       struct repl* repl;
        register struct idf *idf;
 {
        /*      Get the actual parameters from the input stream.
                The hard part is done by actual(), only comma's and
                other syntactic trivialities are checked here.
        */
+       register struct args *args = repl->r_args;
        register int nps = idf->id_macro->mc_nps;
        register int argcnt;
        register int ch;
@@ -169,12 +218,12 @@ getactuals(args, idf)
        args->a_rawvec[0] = args->a_rawptr = &args->a_rawbuf[0];
        if ((ch = GetChar()) != ')') {
                PushBack();
-               while ((ch = actual(args, idf)) != ')' ) {
+               while ((ch = actual(repl)) != ')' ) {
                        if (ch != ',') {
                                lexerror("illegal macro call");
                                return;
                        }
-                       stash(args, '\0');
+                       stash(repl, '\0', 1);
                        ++argcnt;
                        args->a_expvec[argcnt] = args->a_expptr;
                        args->a_rawvec[argcnt] = args->a_rawptr;
@@ -183,30 +232,73 @@ getactuals(args, idf)
                        if (argcnt >= NPARAMS)
                                fatal("argument vector overflow");
                }
-               stash(args, '\0');
+               stash(repl, '\0', 1);
                ++argcnt;
        }
        if (argcnt < nps)
                lexerror("too few macro arguments");
-       if (argcnt > nps)
+       else if (argcnt > nps)
                lexerror("too many macro arguments");
 }
 
+saveraw(repl)
+struct repl *repl;
+{
+       register struct repl *nrepl = ReplaceList;
+       register struct args *ap = nrepl->r_args;
+       struct args *args = repl->r_args;
+       register char *p;
+
+       /* stash identifier name */
+       for (p = nrepl->r_idf->id_text; *p != '\0'; p++)
+               *args->a_rawptr++ = *p;
+
+       /*      The following code deals with expanded function
+               like macro calls. It makes the following code
+               work:
+
+                       #define def(a,b)        x(a,b)
+                       #define glue(a,b)       a ## b
+
+                       glue(abc,def(a,b))
+                       
+               Results in:
+
+                       abcdef(a,b);
+       */
+       if (ap->a_rawvec[0]) {
+               /* stash arguments */
+               register int i;
+
+               *args->a_rawptr++ = '(';
+               for (i = 0; ap->a_rawvec[i] != (char *)0; i++) {
+                       for (p = ap->a_rawvec[i]; *p != '\0'; p++)
+                               *args->a_rawptr++ = *p;
+                       *args->a_rawptr++ = ',';
+               }
+               *(args->a_rawptr-1) = ')';      /* delete last ',' */
+       }
+}
+
 int
-actual(args, idf)
-       register struct args *args;
-       register struct idf *idf;
+actual(repl)
+       struct repl *repl;
 {
        /*      This routine deals with the scanning of an actual parameter.
-               It keeps in account the openning and clossing brackets,
+               It keeps in account the opening and closing brackets,
                preprocessor numbers, strings and character constants.
        */
        register int ch;
-       register int level = 0;
+       register int level = 0, nostashraw = 0;
 
        while (1) {
                ch = GetChar();
 
+               if (Unstacked) {
+                       nostashraw -= Unstacked;
+                       if (nostashraw < 0) nostashraw = 0;
+                       EnableMacros();
+               }
                if (class(ch) == STIDF || class(ch) == STELL) {
                        /*      Scan a preprocessor identifier token. If the
                                token is a macro, it is expanded first.
@@ -217,7 +309,12 @@ actual(args, idf)
                        register int pos = -1;
                        register int hash;
                        extern int idfsize;
-                       int size;
+                       int NoExpandMacro;
+
+                       if (ch == NOEXPM) {
+                               NoExpandMacro= 1;
+                               ch = GetChar();
+                       } else NoExpandMacro = 0;
 
                        hash = STARTHASH();
                        do {
@@ -235,47 +332,62 @@ actual(args, idf)
                                replacement list, it's expanded.
                        */
                        idef = idf_hashed(buf, p - buf, hash);
-                       if (idef->id_macro)     /* expand macro identifier */
-                               expand_actual(args, idef, idf);
-                       else
+                       if (NoExpandMacro || !replace(idef)) {
+                               if ((idef->id_macro
+                                   && (idef->id_macro->mc_flag & NOREPLACE))
+                                   || NoExpandMacro)
+                                       stash(repl, NOEXPM, !nostashraw);
                                for (p = buf; *p != '\0'; p++)
-                                       stash(args, *p);
-               } else if (class(ch) == STNUM || class(ch) == '.') {
-                       /*      preprocessor number token. No this is no joke,
-                               the commitee decided (in all it's wisdom) that
-                               a preprocessing number has the following regular
-                               expression:
-                                       [0-9"."]{[0-9"."a-zA-Z_]|{[Ee][+-]}}*
+                                       stash(repl, *p, !nostashraw);
+                       } else {
+                               if (!nostashraw) saveraw(repl);
+                               nostashraw++;
+                       }
+               } else if (class(ch) == STNUM) {
+                       /*      a preprocessing number has the following
+                               regular expression:
+                                   [0-9|"."[0-9]]{[0-9"."a-zA-Z_]|{[Ee][+-]}}*
                        */
-                       do {
-                               stash(args, ch);
+                       stash(repl, ch, !nostashraw);
+                       if (ch == '.') {
+                               ch = GetChar();
+                               if (class(ch) != STNUM) {
+                                       UnGetChar();
+                                       continue;
+                               }
+                               else stash(repl, ch, !nostashraw);
+                       }
+                       ch = GetChar();
+                       while (in_idf(ch) || ch == '.') {
+                               stash(repl, ch, !nostashraw);
                                if ((ch = GetChar()) == 'e' || ch == 'E') {
+                                       stash(repl, ch, !nostashraw);
                                        ch = GetChar();
                                        if (ch == '+' || ch == '-') {
-                                               stash(args, ch);
+                                               stash(repl, ch, !nostashraw);
                                                ch = GetChar();
                                        }
                                }
-                       } while (class(ch) == STNUM || class(ch) == STIDF ||
-                                class(ch) == STELL || ch == '.');
+                       }
                        UnGetChar();
                } else if (ch == '(' || ch == '[' || ch == '{') {
                        /* a comma may occur within these constructions */
                        level++;
-                       stash(args, ch);
+                       stash(repl, ch, !nostashraw);
                } else if (ch == ')' || ch == ']' || ch == '}') {
                        level--;
                        /* clossing parenthesis of macro call */
                        if (ch == ')' && level < 0)
                                return ')';
-                       stash(args, ch);
+                       stash(repl, ch, !nostashraw);
                } else if (ch == ',') {
                        if (level <= 0) { /* comma separator for next argument */
                                if (level)
                                        lexerror("unbalanced parenthesis");
-                               return ',';
+                               if (!nostashraw)
+                                       return ',';     /* ??? */
                        }
-                       stash(args, ch);
+                       stash(repl, ch, !nostashraw);
                } else if (ch == '\n') {
                        /* newlines are accepted as white spaces */
                        LineNumber++;
@@ -294,16 +406,20 @@ actual(args, idf)
                        */
                        if (ch == '#')
                                domacro();
+                       else if (ch == EOI) {
+                               lexerror("unterminated macro call");
+                               return ')';
+                       }
                        UnGetChar();
-                       stash(args, ' ');
+                       stash(repl, ' ', !nostashraw);
                } else if (ch == '/') {
                        /* comments are treated as one white space token */
-                       if ((ch = GetChar()) == '*') {
+                       if ((ch = GetChar()) == '*' && !InputLevel) {
                                skipcomment();
-                               stash(args, ' ');
+                               stash(repl, ' ', !nostashraw);
                        } else {
                                UnGetChar();
-                               stash(args, '/');
+                               stash(repl, '/', !nostashraw);
                        }
                } else if (ch == '\'' || ch == '"') {
                        /*      Strings are considered as ONE token, thus no
@@ -311,129 +427,28 @@ actual(args, idf)
                        */
                        register int match = ch;
 
-                       stash(args, ch);
+                       stash(repl, ch, !nostashraw);
                        while ((ch = GetChar()) != EOI) {
                                if (ch == match)
                                        break;
                                if (ch == '\\') {
-                                       stash(args, ch);
+                                       stash(repl, ch, !nostashraw);
                                        ch = GetChar();
                                } else if (ch == '\n') {
                                        lexerror("newline in string");
                                        LineNumber++;
-                                       stash(args, match);
+                                       stash(repl, match, !nostashraw);
                                        break;
                                }
-                               stash(args, ch);
+                               stash(repl, ch, !nostashraw);
                        }
                        if (ch != match) {
                                lexerror("unterminated macro call");
                                return ')';
                        }
-                       stash(args, ch);
+                       stash(repl, ch, !nostashraw);
                } else
-                       stash(args, ch);
-       }
-}
-
-expand_actual(args, idef, idf)
-       register struct args *args;
-       register struct idf *idf, *idef;
-{
-       struct repl *nrepl = new_repl();
-       register char *p;
-
-       nrepl->r_args = new_args();
-       nrepl->r_ptr = nrepl->r_text;
-       if (expand_macro(nrepl, idef, idf)) {
-               register struct args *ap = nrepl->r_args;
-
-               for (p = nrepl->r_text; p < nrepl->r_ptr; p++)
-                       *args->a_expptr++ = *p;
-
-               /* stash idef name */
-               for (p = idef->id_text; *p != '\0'; p++)
-                       *args->a_rawptr++ = *p;
-
-               /*      The following code deals with expanded function
-                       like macro calls. It makes the following code
-                       work:
-
-                               #define def(a,b)        x(a,b)
-                               #define glue(a,b)       a ## b
-
-                               glue(abc,def(a,b))
-                               
-                       Results in:
-
-                               abcdef(a,b);
-               */
-               if (ap->a_rawvec[0]) {
-                       /* stash arguments */
-                       register int i;
-
-                       *args->a_rawptr++ = '(';
-                       for (i = 0; ap->a_rawvec[i] != (char *)0; i++) {
-                               for (p = ap->a_rawvec[i]; *p != '\0'; p++)
-                                       *args->a_rawptr++ = *p;
-                               *args->a_rawptr++ = ',';
-                       }
-                       *--args->a_rawptr = ')';
-                       ++args->a_rawptr;       /* one too far */
-               }
-       } else  /* something happened during the macro expansion */
-               for (p = idef->id_text; *p != '\0'; p++)
-                       stash(args, *p);
-       free_args(nrepl->r_args);
-       free_repl(nrepl);
-}
-
-maccount(repl, idf)
-       register struct repl *repl;
-       register struct idf *idf;
-{
-       /*      To prevent re-expansion of already expanded macro's we count
-               the occurrences of the currently expanded macro name in the
-               replacement list. This is mainly to prevent recursion as in:
-
-                       #define f(a)    f(2 * (a))
-                       f(y+1);
-
-               This results in:
-
-                       f(2*(y+1));
-
-               When reading the inserted text we decrement the count of a
-               macro name until it's zero. Then we start expanding it again.
-       */
-       register char *text = repl->r_text;
-       register int pos = -1;
-       extern int idfsize;
-
-       while (*text != '\0') {
-               if (*text == '\'' || *text == '"') {
-                       register int delim;
-
-                       for (delim = *text++; *text != delim; text++)
-                               if (*text == '\\')
-                                       text++;
-                       text++;
-               } else
-               if (class(*text) == STIDF || class(*text) == STELL) {
-                       char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1];
-                       register char *p = buf;
-
-                       do {
-                               if (++pos < idfsize)
-                                       *p++ = *text;
-                               text++;
-                       } while (in_idf(*text));
-                       *p++ = '\0';
-
-                       if (!strcmp(idf->id_text, buf))
-                               idf->id_macro->mc_count++;
-               } else
-                       text++;
+                       stash(repl, ch, !nostashraw);
        }
 }
 
@@ -459,7 +474,7 @@ macro_func(idef)
                break;
        case 'L':                       /* __LINE__     */
                mac->mc_text = long2str((long)LineNumber, 10);
-               mac->mc_length = 1;
+               mac->mc_length = strlen(mac->mc_text);
                break;
        default:
                crash("(macro_func)");
@@ -499,98 +514,124 @@ macro2buffer(repl, idf, args)
                smarter should be done (but even a DFA is O(|s|)).
        */
        register char *ptr = idf->id_macro->mc_text;
+       register char *tmpptr;
+       int err = 0;
        char *stringify();
 
        while (*ptr) {
-               ASSERT(repl->r_ptr < &(repl->r_text[LAPBUF]));
-               if (*ptr == '\'' || *ptr == '"') {
-                       register int delim = *ptr;
-
-                       do {
-                               *repl->r_ptr++ = *ptr;
-                               if (*ptr == '\\')
-                                       *repl->r_ptr++ = *++ptr;
-                               if (*ptr == '\0') {
-                                       lexerror("unterminated string");
-                                       *repl->r_ptr = '\0';
-                                       return;
-                               }
-                               ptr++;
-                       } while (*ptr != delim || *ptr == '\0');
-                       *repl->r_ptr++ = *ptr++;
-               } else if (*ptr == '#') {
-                       if (*++ptr == '#') {
-                               /* ## - paste operator */
-                               ptr++;
-
-                               /* trim the actual replacement list */
-                               --repl->r_ptr;
-                               while (is_wsp(*repl->r_ptr) &&
-                                      repl->r_ptr >= repl->r_text)
-                                       --repl->r_ptr;
-
-                               /*      ## occurred at the beginning of the
-                                       replacement list.
-                               */
-                               if (repl->r_ptr == repl->r_text)
-                                       goto paste;
-                               ++repl->r_ptr;
-
-                               /* skip space in macro replacement list */
-                               while ((*ptr & FORMALP) == 0 && is_wsp(*ptr))
-                                       ptr++;
-
-                               /*      ## occurred at the end of the
-                                       replacement list.
-                               */
-                               if (*ptr & FORMALP) {
-                                       register int n = *ptr++ & 0177;
-                                       register char *p;
-                                       
-                                       ASSERT(n != 0);
-                                       p = args->a_rawvec[n-1];
-                                       while (is_wsp(*p))
-                                               p++;
-                                       while (*p)
-                                               *repl->r_ptr++ = *p++;
-                               } else if (*ptr == '\0')
-                                       goto paste;
-                       } else
-                               ptr = stringify(repl, ptr, args);
-               } else if (*ptr & FORMALP) {
-                       /* insert actual parameter */
+           ASSERT(repl->r_ptr < &(repl->r_text[LAPBUF]));
+           if (*ptr == '\'' || *ptr == '"') {
+               register int delim = *ptr;
+
+               do {
+                   *repl->r_ptr++ = *ptr;
+                   if (*ptr == '\\')
+                           *repl->r_ptr++ = *++ptr;
+                   if (*ptr == '\0') {
+                           lexerror("unterminated string");
+                           *repl->r_ptr = '\0';
+                           return;
+                   }
+                   ptr++;
+               } while (*ptr != delim || *ptr == '\0');
+               *repl->r_ptr++ = *ptr++;
+           } else if (*ptr == '#') {
+               if (*++ptr == '#') {
+                       /* ## - paste operator */
+                   ptr++;
+
+                       /* trim the actual replacement list */
+                   --repl->r_ptr;
+                   while (is_wsp(*repl->r_ptr)
+                               && repl->r_ptr >= repl->r_text)
+                           --repl->r_ptr;
+
+                   /*  ## occurred at the beginning of the
+                           replacement list.
+                   */
+                   if (repl->r_ptr == repl->r_text
+                               && is_wsp(*repl->r_ptr)) {
+                           err = 1;
+                           break;
+                   }
+
+                   while(*repl->r_ptr == TOKSEP
+                               && repl->r_ptr >= repl->r_text)
+                           --repl->r_ptr;
+
+                   tmpptr = repl->r_ptr;
+                   ++repl->r_ptr;
+
+                   /* skip space in macro replacement list */
+                   while ((*ptr & FORMALP) == 0 && is_wsp(*ptr))
+                           ptr++;
+
+                   /*  ## occurred at the end of the replacement list.
+                   */
+                   if (*ptr & FORMALP) {
                        register int n = *ptr++ & 0177;
-                       register char *p, *q;
-                       
-                       ASSERT(n != 0);
-
-                       /*      This is VERY dirty, we look ahead for the
-                               ## operater. If it's found we use the raw
-                               argument buffer instead of the expanded
-                               one.
-                       */
-                       for (p = ptr; (*p & FORMALP) == 0 && is_wsp(*p); p++)
-                               /* VOID */;
-                       if (*p == '#' && p[1] == '#')
-                               q = args->a_rawvec[n-1];
-                       else
-                               q = args->a_expvec[n-1];
+                       register char *p;
 
-                       while (*q)
-                               *repl->r_ptr++ = *q++;
-
-                       *repl->r_ptr++ = ' ';
+                       ASSERT(n > 0);
+                       p = args->a_rawvec[n-1];
+                       if (p) {        /* else macro argument missing */
+                           while (is_wsp(*p))
+                               p++;
+                           if (*p == NOEXPM) p++;
+                           while (*p)
+                               *repl->r_ptr++ = *p++;
+                       }
+                       if (in_idf(*tmpptr + 1)) {
+                               while (in_idf(*tmpptr)
+                                           && tmpptr >= repl->r_text)
+                                       tmpptr--;
+                               if (*tmpptr == NOEXPM) *tmpptr = TOKSEP;
+                       }
+                   } else if (*ptr == '\0') {
+                           err = 1;
+                           break;
+                   } else {
+                           if (in_idf(*ptr)) {
+                               while (in_idf(*tmpptr)
+                                           && tmpptr >= repl->r_text)
+                                       tmpptr--;
+                               if (*tmpptr == NOEXPM) *tmpptr = TOKSEP;
+                           }
+                   }
                } else
-                       *repl->r_ptr++ = *ptr++;
+                   ptr = stringify(repl, ptr, args);
+           } else if (*ptr & FORMALP) {
+               /* insert actual parameter */
+               register int n = *ptr++ & 0177;
+               register char *p, *q;
+                       
+               ASSERT(n > 0);
+
+               /*      This is VERY dirty, we look ahead for the
+                       ## operater. If it's found we use the raw
+                       argument buffer instead of the expanded
+                       one.
+               */
+               for (p = ptr; (*p & FORMALP) == 0 && is_wsp(*p); p++)
+                               /* EMPTY */;
+               if (*p == '#' && p[1] == '#')
+                       q = args->a_rawvec[n-1];
+               else
+                       q = args->a_expvec[n-1];
+
+               p = repl->r_ptr;
+               if (q)                  /* else macro argument missing */
+                   while (*q)
+                       *repl->r_ptr++ = *q++;
+
+               if (*repl->r_ptr != TOKSEP)
+                       *repl->r_ptr++ = TOKSEP;
+           } else
+               *repl->r_ptr++ = *ptr++;
        }
        *repl->r_ptr = '\0';
-       return;
-
-paste:
-       /*      Sorry, i know this looks a bit like
-               a unix device driver code.
-       */
-       lexerror("illegal use of the ## operator");
+       if (err)
+               lexerror("illegal use of the ## operator");
        return;
 }
 
@@ -625,7 +666,7 @@ stringify(repl, ptr, args)
                register char *p;
                
                ASSERT(n != 0);
-               p = args->a_expvec[n-1];
+               p = args->a_rawvec[n-1];
                *repl->r_ptr++ = '"';
                while (*p) {
                        if (is_wsp(*p)) {
@@ -645,7 +686,8 @@ stringify(repl, ptr, args)
                        backslash = *p == '\\';
                        if (*p == '"' || (delim && *p == '\\'))
                                *repl->r_ptr++ = '\\';
-                       *repl->r_ptr++ = *p++;
+                       if (*p == TOKSEP || *p == NOEXPM) p++;
+                       else *repl->r_ptr++ = *p++;
                }
 
                /* trim spaces in the replacement list */
@@ -658,20 +700,23 @@ stringify(repl, ptr, args)
        return ptr;
 }
 
-stash(args, ch)
-       register struct args *args;
+stash(repl, ch, stashraw)
+       struct repl *repl;
        register int ch;
+       int stashraw;
 {
        /*      Stash characters into the macro expansion buffer.
        */
+       register struct args *args = repl->r_args;
+
        if (args->a_expptr >= &(args->a_expbuf[ARGBUF]))
                fatal("macro argument buffer overflow");
        *args->a_expptr++ = ch;
 
-       if (args->a_rawptr >= &(args->a_rawbuf[ARGBUF]))
-               fatal("raw macro argument buffer overflow");
-       *args->a_rawptr++ = ch;
-
-                       
+       if (stashraw) {
+               if (args->a_rawptr >= &(args->a_rawbuf[ARGBUF]))
+                       fatal("raw macro argument buffer overflow");
+               *args->a_rawptr++ = ch;
+       }
 }
 #endif NOPP
index f4eccae..e740cd7 100644 (file)
@@ -1,8 +1,10 @@
 struct repl {
        struct  repl *next;
+       struct  idf *r_idf;             /* name of the macro */
        struct  args *r_args;           /* replacement parameters */
-       char    r_text[LAPBUF];         /* replacement text */
+       int     r_level;                /* level of insertion */
        char    *r_ptr;                 /* replacement text pointer */
+       char    r_text[LAPBUF];         /* replacement text */
 };
 
 /* ALLOCDEF "repl" 4 */
index 6e89228..d5b259e 100644 (file)
@@ -166,7 +166,7 @@ copyact(ch1, ch2, lvl)
                case '/':
                        LoadChar(ch);
 
-                       if (ch == '*')  {       /* skip comment */
+                       if (ch == '*' && !InputLevel)   {       /* skip comment */
                                skipcomment();
                                continue;
                        }
index 7508a27..0a608c8 100644 (file)
@@ -5,16 +5,13 @@
 /* $Header$ */
 /* VARIOUS TARGET MACHINE SIZE DESCRIPTORS */
 
-#include "nofloat.h"
 #include "nocross.h"
 #include "target_sizes.h"
 
 #ifndef NOCROSS
 extern arith
        short_size, word_size, dword_size, int_size, long_size,
-#ifndef NOFLOAT
        float_size, double_size, lngdbl_size,
-#endif NOFLOAT
        pointer_size;
 #else NOCROSS
 #define short_size     (SZ_SHORT)
@@ -22,11 +19,9 @@ extern arith
 #define dword_size     (2*SZ_WORD)
 #define int_size       (SZ_INT)
 #define long_size      (SZ_LONG)
-#ifndef NOFLOAT
 #define float_size     (SZ_FLOAT)
 #define double_size    (SZ_DOUBLE)
 #define        lngdbl_size     (SZ_LNGDBL)
-#endif NOFLOAT
 #define pointer_size   (SZ_POINTER)
 #endif NOCROSS
 
index 36ca38c..94fdd3b 100644 (file)
@@ -12,6 +12,8 @@
 #include       "input.h"
 
 #ifndef NOPP
+extern int InputLevel;
+
 int
 skipspaces(ch, skipnl)
        register int ch;
@@ -19,12 +21,19 @@ skipspaces(ch, skipnl)
        /*      skipspaces() skips any white space and returns the first
                non-space character.
        */
+       register int nlseen = 0;
+
        for (;;) {
                while (class(ch) == STSKIP)
                        ch = GetChar();
                if (skipnl && class(ch) == STNL) {
                        ch = GetChar();
-                       ++LineNumber;
+                       LineNumber++;
+                       nlseen++;
+                       continue;
+               }
+               if (ch == TOKSEP && InputLevel) {
+                       ch = GetChar();
                        continue;
                }
 
@@ -32,7 +41,7 @@ skipspaces(ch, skipnl)
 
                if (ch == '/') {
                        ch = GetChar();
-                       if (ch == '*') {
+                       if (ch == '*' && !InputLevel) {
                                skipcomment();
                                ch = GetChar();
                        }
@@ -41,7 +50,10 @@ skipspaces(ch, skipnl)
                                return '/';
                        }
                }
-               else
+               else if(nlseen && ch == '#') {
+                       domacro();
+                       ch = GetChar();
+               } else
                        return ch;
        }
 }
@@ -53,10 +65,9 @@ SkipToNewLine(garbage)
        register int ch;
        register int pstrict = 0;
 
-       UnGetChar();
        while ((ch = GetChar()) != '\n') {
                if (ch == '/') {
-                       if ((ch = GetChar()) == '*') {
+                       if ((ch = GetChar()) == '*' && !InputLevel) {
                                skipcomment();
                                continue;
                        }
index 3be2dec..b7d5b70 100644 (file)
@@ -6,7 +6,6 @@
 /*     S T A C K / U N S T A C K  R O U T I N E S      */
 
 #include       "lint.h"
-#include       "nofloat.h"
 #include       <system.h>
 #include       <em.h>
 #include       "debug.h"
@@ -21,7 +20,6 @@
 #include       "struct.h"
 #include       "level.h"
 #include       "mes.h"
-#include       "noRoption.h"
 
 /* #include    <em_reg.h> */
 
@@ -84,8 +82,9 @@ stack_level_of(lvl)
                return local_level;
        stl = &UniversalLevel;
                
-       while (stl->sl_level != lvl)
+       while (stl->sl_level != lvl) {
                stl = stl->sl_next;
+       }
        return stl;
 }
 
@@ -214,25 +213,18 @@ unstack_world()
                        def->df_sc = EXTERN;
                */
                
-               if (    def->df_sc == STATIC
-                       && def->df_type->tp_fund == FUNCTION
-                       && !def->df_initialized
-               )       {
+               if (def->df_sc == STATIC
+                   && def->df_type->tp_fund == FUNCTION
+                   && !def->df_initialized) {
                        /* orphaned static function */
-#ifndef NOROPTION
-                       if (options['R'])
-                               warning("static function %s never defined, %s",
-                                       idf->id_text,
-                                       "changed to extern"
-                               );
-#endif
+                       warning("static function %s never defined, %s"
+                                   , idf->id_text
+                                   , "changed to extern");
                        def->df_sc = EXTERN;
                }
                
-               if (
-                       def->df_alloc == ALLOC_SEEN &&
-                       !def->df_initialized
-               )       {
+               if (def->df_alloc == ALLOC_SEEN
+                   && !def->df_initialized) {
                        /* space must be allocated */
                        bss(idf);
                        if (def->df_sc != STATIC)
index b105260..03f4bc6 100644 (file)
@@ -12,6 +12,7 @@
 #include       "debug.h"
 #include       "botch_free.h"
 
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "LLlex.h"
 #include       "type.h"
 extern int level;
 }
 
-/*     Each statement construction is stacked in order to trace a
      statement to such a construction. Example: a case statement should
      be recognized as a piece of the most enclosing switch statement.
-*/
+/* Each statement construction is stacked in order to trace a
* statement to such a construction. Example: a case statement should
* be recognized as a piece of the most enclosing switch statement.
+ */
 
-/* 9 */
+/* 3.6 */
 statement
        {
 #ifdef LINT
@@ -104,9 +105,9 @@ expression_statement
                }
 ;
 
+/* 3.6.1 (partially) */
 label
-       {       struct idf *idf;
-       }
+       { struct idf *idf; }
 :
        identifier(&idf)
        {
@@ -125,6 +126,7 @@ label
        }
 ;
 
+/* 3.6.4.1 */
 if_statement
        {
                struct expr *expr;
@@ -186,6 +188,7 @@ if_statement
        ]
 ;
 
+/* 3.6.5.3 */
 while_statement
        {
                struct expr *expr;
@@ -233,6 +236,7 @@ while_statement
                }
 ;
 
+/* 3.6.5.2 */
 do_statement
        {       struct expr *expr;
                label l_break = text_label();
@@ -279,6 +283,7 @@ do_statement
                }
 ;
 
+/* 3.6.5.3 */
 for_statement
        {       struct expr *e_init = 0, *e_test = 0, *e_incr = 0;
                label l_break = text_label();
@@ -350,6 +355,7 @@ for_statement
                }
 ;
 
+/* 3.6.4.2 */
 switch_statement
        {
                struct expr *expr;
@@ -375,6 +381,7 @@ switch_statement
                }
 ;
 
+/* 3.6.1 (partially) */
 case_statement
        {
                struct expr *expr;
@@ -393,6 +400,7 @@ case_statement
        statement
 ;
 
+/* 3.6.1 (partially) */
 default_statement
 :
        DEFAULT
@@ -406,6 +414,7 @@ default_statement
        statement
 ;
 
+/* 3.6.6.4 */
 return_statement
        {       struct expr *expr = 0;
        }
@@ -436,6 +445,7 @@ return_statement
        ';'
 ;
 
+/* 3.6.6.1 (partially) */
 jump
        {       struct idf *idf;
        }
@@ -452,6 +462,7 @@ jump
                }
 ;
 
+/* 3.6.2 */
 compound_statement:
        '{'
                {
index ad0cc42..048fa98 100644 (file)
@@ -23,7 +23,6 @@
 #include       "level.h"
 #include       "assert.h"
 #include       "sizes.h"
-#include       "noRoption.h"
 
 /*     Type of previous selector declared with a field width specified,
        if any.  If a selector is declared with no field with it is set to 0.
@@ -78,14 +77,6 @@ add_sel(stp, tp, idf, sdefpp, szp, fd)       /* this is horrible */
        register struct sdef *newsdef;
        int lvl = tg->tg_level;
        
-#ifndef NOROPTION
-       if (options['R'] && !is_anon_idf(idf))  {
-               /* a K & R test */
-               if (idf->id_struct && idf->id_struct->tg_level == level)
-                       warning("%s is also a struct/union tag", idf->id_text);
-       }
-#endif
-
        if (stp->tp_fund == STRUCT)     {
 #ifndef NOBITFIELD
                if (fd == 0)    {       /* no field width specified     */
@@ -105,24 +96,11 @@ add_sel(stp, tp, idf, sdefpp, szp, fd)     /* this is horrible */
 #endif NOBITFIELD
        }
        else    {       /* (stp->tp_fund == UNION)              */
-               if (fd) {
-                       error("fields not allowed in unions");
-                       free_field(fd);
-                       fd = 0;
-               }
+               if (fd) offset = add_field(szp, fd, &tp, idf, stp);
                offset = (arith)0;
        }
        
        check_selector(idf, stp);
-#ifndef NOROPTION
-       if (options['R'])       {
-               if (    sdef && sdef->sd_level == lvl &&
-                       ( sdef->sd_offset != offset ||
-                         !equal_type(sdef->sd_type, tp))
-               )                               /* RM 8.5 */
-                       warning("selector %s redeclared", idf->id_text);
-       }
-#endif
 
        newsdef = new_sdef();
        newsdef->sd_sdef = (struct sdef *) 0;
@@ -159,7 +137,10 @@ add_sel(stp, tp, idf, sdefpp, szp, fd)     /* this is horrible */
                stp->tp_align = lcm(stp->tp_align, tp->tp_align);
        }
        else
-       if (stp->tp_fund == UNION)      {
+       if (stp->tp_fund == UNION && fd == 0)   {
+               /*      Note: the case that a bitfield is declared is
+                       handled by add_field() !
+               */
                arith sel_size = size_of_type(tp, "member");
 
                if (*szp < sel_size)
@@ -198,47 +179,29 @@ declare_struct(fund, idf, tpp)
        register struct tag **tgp;
        register struct tag *tg;
 
+
        if (!idf)
                idf = gen_idf();
        tgp = (fund == ENUM ? &idf->id_enum : &idf->id_struct);
-       
-#ifndef NOROPTION
-       if (options['R'] && !is_anon_idf(idf))  {
-               /* a K & R test */
-               if (    fund != ENUM &&
-                       idf->id_sdef && idf->id_sdef->sd_level == level
-               )       {
-                       warning("%s is also a selector", idf->id_text);
-               }
-               if (    fund == ENUM &&
-                       idf->id_def && idf->id_def->df_level == level
-               )       {
-                       warning("%s is also a variable", idf->id_text);
-               }
-       }
-#endif
-       
        tg = *tgp;
-       if (tg && tg->tg_type->tp_size < 0 && tg->tg_type->tp_fund == fund) {
-               /*      An unfinished declaration has preceded it, possibly on
-                       an earlier level.  We just fill in the answer.
-               */
+       if (tg
+           && tg->tg_type->tp_size < 0
+           && tg->tg_type->tp_fund == fund
+           && tg->tg_level == level) {
+               /*      An unfinished declaration has preceded it.
+                       We just fill in the answer.
+                */
                if (tg->tg_busy) {
                        error("recursive declaration of struct/union %s",
                                idf->id_text);
                        declare_struct(fund, gen_idf(), tpp);
                }
                else {
-#ifndef NOROPTION
-                       if (options['R'] && tg->tg_level != level)
-                               warning("%s declares %s in different range",
-                                       idf->id_text, symbol2str(fund));
-#endif
+                       /* hint: if (level <= L_PROTO) */
                        *tpp = tg->tg_type;
                }
        }
-       else
-       if (tg && tg->tg_level == level)        {
+       else if (tg && tg->tg_level == level && tg->tg_type->tp_size >= 0)      {
                /*      There is an already defined struct/union of this name
                        on our level!
                */
@@ -307,15 +270,7 @@ idf2sdef(idf, tp)
        /* Tp not met; any unique identification will do. */
        if (sdef = idf->id_sdef)        {
                /* There is an identification */
-               if (uniq_selector(sdef))        {
-                       /* and it is unique, so we accept */
-                       warning("selector %s applied to alien type",
-                                       idf->id_text);
-               }
-               else    {
-                       /* it is ambiguous */
-                       error("ambiguous use of selector %s", idf->id_text);
-               }
+               error("illegal use of selector %s", idf->id_text);
                return sdef;
        }
        
@@ -328,6 +283,7 @@ idf2sdef(idf, tp)
        return sdef;
 }
 
+#if    0
 int
 uniq_selector(idf_sdef)
        register struct sdef *idf_sdef;
@@ -352,6 +308,7 @@ uniq_selector(idf_sdef)
        }
        return 1;
 }
+#endif
 
 #ifndef NOBITFIELD
 arith
@@ -365,8 +322,7 @@ add_field(szp, fd, fdtpp, idf, stp)
        /*      The address where this selector is put is returned. If the
                selector with specified width does not fit in the word, or
                an explicit alignment is given, a new address is needed.
-               Note that the fields are packed into machine words (according
-               to the RM.)
+               Note that the fields are packed into machine words.
        */
        long bits_in_type = word_size * 8;
        static int field_offset = (arith)0;
@@ -392,9 +348,10 @@ add_field(szp, fd, fdtpp, idf, stp)
        switch ((*fdtpp)->tp_fund)      {
        case CHAR:
        case SHORT:
-       case INT:
        case ENUM:
        case LONG:
+               strict("non-portable field type");
+       case INT:
                /* right type; size OK? */
                if ((*fdtpp)->tp_size > word_size) {
                        error("bit field type %s does not fit in a word",
@@ -461,6 +418,8 @@ add_field(szp, fd, fdtpp, idf, stp)
        else                    /* adjust the field at the left         */
                fd->fd_shift = bits_in_type - bits_declared;
        
+       if (stp->tp_fund == UNION) bits_declared = (arith)0;
+
        return field_offset;
 }
 #endif NOBITFIELD
index 859766c..39beb9d 100644 (file)
@@ -5,7 +5,6 @@
 /* $Header$ */
 /*     S W I T C H - S T A T E M E N T  A D M I N I S T R A T I O N    */
 
-#include       "nofloat.h"
 #include       <em.h>
 #include       "debug.h"
 #include       "botch_free.h"
 #include       "Lpars.h"
 #include       "idf.h"
 #include       "label.h"
+#include       <flt_arith.h>
 #include       "arith.h"
 #include       "switch.h"
 #include       "code.h"
 #include       "assert.h"
 #include       "expr.h"
 #include       "type.h"
-#include       "noRoption.h"
+#include       "sizes.h"
 
 extern char options[];
 
@@ -39,9 +39,10 @@ compact(nr, low, up)
 static struct switch_hdr *switch_stack = 0;
 
 /* (EB 86.05.20) The following rules hold for switch statements:
-       - the expression E in "switch(E)" is cast to 'int' (RM 9.7)
-       - the expression E in "case E:" must be 'int' (RM 9.7)
-       - the values in the CSA/CSB tables are words (EM 7.4)
+       - the expression E in "switch(E)" shall have integral type (3.6.4.2)
+       - the expression E in "case E:" is converted to the promoted type
+                                       of the controlling expression
+       - the values in the CSA/CSB tables are words (EM 7.4) (??? JvE)
        For simplicity, we suppose int_size == word_size.
 */
 
@@ -54,22 +55,21 @@ code_startswitch(expp)
        register label l_table = text_label();
        register label l_break = text_label();
        register struct switch_hdr *sh = new_switch_hdr();
-       int fund = any2arith(expp, SWITCH);     /* INT, LONG or DOUBLE */
+       int fund = any2arith(expp, SWITCH);
+                                   /* INT, LONG, FLOAT, DOUBLE or LNGDBL */
        
        switch (fund) {
        case LONG:
-#ifndef NOROPTION
-               if (options['R'])
-                       warning("long in switch (cast to int)");
-#endif
+               if (long_size > int_size)
+                       warning("can't switch on longs (cast to int)");
                int2int(expp, int_type);
                break;
-#ifndef NOFLOAT
+       case FLOAT:
        case DOUBLE:
-               error("float/double in switch");
+       case LNGDBL:
+               error("floating point type in switch");
                erroneous2int(expp);
                break;
-#endif NOFLOAT
        }
        stack_stmt(l_break, NO_LABEL);
        sh->sh_break = l_break;
index 7d39783..f1cada9 100644 (file)
@@ -5,7 +5,6 @@
 /* $Header$ */
 /*     T Y P E   D E F I N I T I O N   M E C H A N I S M        */
 
-#include       "nofloat.h"
 #include       "nobitfield.h"
 #include       "botch_free.h"
 #include       <alloc.h>
@@ -28,14 +27,12 @@ extern struct type *field_of();
        line parameters.
 */
 struct type
-       *char_type, *uchar_type,
+       *schar_type, *uchar_type,
        *short_type, *ushort_type,
        *word_type, *uword_type,
        *int_type, *uint_type,
        *long_type, *ulong_type,
-#ifndef NOFLOAT
        *float_type, *double_type, *lngdbl_type,
-#endif NOFLOAT
        *void_type, *gen_type, *label_type,
        *string_type, *funint_type, *error_type;
 
@@ -56,6 +53,19 @@ create_type(fund)
        return ntp;
 }
 
+struct type *
+promoted_type(tp)
+struct type *tp;
+{
+       if (tp->tp_fund == CHAR || tp->tp_fund == SHORT) {
+               if (tp->tp_unsigned == UNSIGNED && tp->tp_size == int_size)
+                       return uint_type;
+               else return int_type;
+       } else if (tp->tp_fund == FLOAT)
+               return double_type;
+       else return tp;
+}
+
 struct type *
 construct_type(fund, tp, qual, count, pl)
        register struct type *tp;
@@ -123,8 +133,19 @@ function_of(tp, pl, qual)
        register struct type *dtp = tp->tp_function;
 
        /* look for a type with the right qualifier */
+#if 0
+/* the code doesn't work in the following case:
+       int func();
+       int func(int a, int b) { return q(a); }
+   because updating the type works inside the data-structures for that type
+   thus, a new type is created for very function. This may change in the
+   future, when declarations with empty parameter lists become obsolete.
+*/
        while (dtp && (dtp->tp_typequal != qual || dtp->tp_proto != pl))
                dtp = dtp->next;
+#else
+       dtp = 0;
+#endif
 
        if (!dtp)       {
                dtp = create_type(FUNCTION);
index b437901..deaa2f0 100644 (file)
@@ -5,7 +5,6 @@
 /* $Header$ */
 /* TYPE DESCRIPTOR */
 
-#include       "nofloat.h"
 #include       "nobitfield.h"
 
 struct type    {
@@ -23,6 +22,7 @@ struct type   {
        struct type *tp_pointer;/* to POINTER */
        struct type *tp_array;  /* to ARRAY */
        struct proto *tp_proto; /* prototype list */
+       struct proto *tp_pseudoproto;   /* pseudo prototype list */
        struct type *tp_function;/* to FUNCTION */
 };
 
@@ -30,26 +30,24 @@ struct type {
 /*     Type qualifiers. Note: TQ_VOLATILE and TQ_CONST can be
        'ored' to specify: extern const volatile int a;
 */
-#define        TQ_VOLATILE     01
-#define        TQ_CONST        02
+#define        TQ_VOLATILE     0x01
+#define        TQ_CONST        0x02
 
 extern struct type
        *create_type(), *standard_type(), *construct_type(), *pointer_to(),
-       *array_of(), *function_of();
+       *array_of(), *function_of(), *promoted_type();
 
 #ifndef NOBITFIELD
 extern struct type *field_of();
 #endif NOBITFIELD
 
 extern struct type
-       *char_type, *uchar_type,
+       *schar_type, *uchar_type,
        *short_type, *ushort_type,
        *word_type, *uword_type,
        *int_type, *uint_type,
        *long_type, *ulong_type,
-#ifndef NOFLOAT
        *float_type, *double_type, *lngdbl_type,
-#endif NOFLOAT
        *void_type, *gen_type, *label_type,
        *string_type, *funint_type, *error_type;