common.c

     
   1  //! @file common.c
   2  //! @author J. Marcel van der Veer
   3  //
   4  //! @section Copyright
   5  //
   6  // This file is part of VIF - vintage FORTRAN compiler.
   7  // Copyright 2020-2024 J. Marcel van der Veer <algol68g@xs4all.nl>.
   8  //
   9  //! @section License
  10  //
  11  // This program is free software; you can redistribute it and/or modify it 
  12  // under the terms of the GNU General Public License as published by the 
  13  // Free Software Foundation; either version 3 of the License, or 
  14  // (at your option) any later version.
  15  //
  16  // This program is distributed in the hope that it will be useful, but 
  17  // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  18  // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
  19  // more details. You should have received a copy of the GNU General Public 
  20  // License along with this program. If not, see <http://www.gnu.org/licenses/>.
  21  
  22  //! @section Synopsis
  23  //!
  24  //! Compiler COMMON statements.
  25  
  26  #include <vif.h>
  27  
  28  void merge_commons (void)
  29  {
  30    int_4 k, g;
  31    for (k = 0; k < nlocals; k++) {
  32      IDENT *idf = &locals[k];
  33      int_4 found = FALSE;
  34      if (idf->common > 0 && idf->common != EXTERN) {
  35        for (g = 0; g < nglobals && !found; g++) {
  36          IDENT *idg = &globals[g];
  37          if (idf->common == idg->common && EQUAL (CID (idf), CID (idg))) {
  38            int_4 same = TRUE;
  39            found = TRUE;
  40            same &= (idf->mode.type == idg->mode.type);
  41            same &= (idf->mode.len == idg->mode.len);
  42            same &= (idf->mode.dim == idg->mode.dim);
  43            if (same) {
  44              int_4 n;
  45              for (n = 0; n < idf->mode.dim; n++) {
  46                same &= (EQUAL (idf->lwb[n], idg->lwb[n]));
  47                same &= (EQUAL (idf->upb[n], idg->upb[n]));
  48              }
  49            }
  50            if (!same) {
  51              ERROR (601, "common block consistency", CID (idg));
  52            }
  53          }
  54        }
  55        if (!found) {
  56          if (nglobals >= MAX_IDENTS) {
  57            ERROR (602, "too many common identifiers", NULL);
  58            return;
  59          }
  60  // Copy-paste into global name space.
  61          IDENT *idn = &globals[nglobals++];
  62          memcpy (idn, idf, sizeof (IDENT));
  63        }
  64      }
  65    }
  66  }
  67  
  68  void common (void)
  69  {
  70    int_4 cblck = LOCAL, rc;
  71    rc = scan (NULL);
  72    if (!TOKEN ("/")) {
  73      cblck = add_block ("_common");
  74    }
  75    while (WITHIN) {
  76      if (TOKEN (",")) {
  77        rc = scan (NULL);
  78        if (!WITHIN) {
  79          SYNTAX (603, "common block");
  80        }
  81      } else if (TOKEN ("/")) {
  82        rc = scan (NULL);
  83        if (rc != WORD) {
  84          SYNTAX (604, "common block name");
  85        } else {
  86          cblck = add_block (curlex);
  87        }
  88        rc = scan ("/");
  89        rc = scan (NULL);
  90      } else if (rc == WORD) {
  91        MODE mode;
  92        IDENT *idf = void_decl (curlex, &mode);
  93        if (idf != NULL) {
  94          idf->common = cblck;
  95        }
  96        rc = scan (NULL);
  97        if (TOKEN ("(") && idf != NULL) {
  98          if (idf->mode.dim != 0) {
  99            ERROR (605, "already dimensioned", CID (idf));
 100          }
 101          get_dims (idf, 1);
 102          rc = scan (NULL);
 103        }
 104      } else {
 105        SYNTAX (606, "common block");
 106        rc = scan (NULL);
 107      }
 108    }
 109  }
 110  
 111  void get_common (void)
 112  {
 113    int_4 go_on = TRUE;
 114    while (go_on) {
 115      SAVE_POS;
 116      int_4 rc = scan (NULL);
 117      if (rc == DECLAR) {
 118        skip_card ();
 119      } else if (TOKEN ("implicit")) {
 120        skip_card ();
 121      } else if (TOKEN ("save")) {
 122        skip_card ();
 123      } else if (TOKEN ("automatic")) {
 124        skip_card ();
 125      } else if (TOKEN ("parameter")) {
 126        skip_card ();
 127      } else if (TOKEN ("common")) {
 128        common ();
 129        skip_card ();
 130      } else if (TOKEN ("dimension")) {
 131        skip_card ();
 132      } else if (TOKEN ("equivalence")) {
 133        skip_card ();
 134      } else if (TOKEN ("external")) {
 135        skip_card ();
 136      } else if (TOKEN ("intrinsic")) {
 137        skip_card ();
 138      } else if (TOKEN ("data")) {
 139        skip_card ();
 140      } else if (strlen (curlex) > 0) {
 141  // Backspace and done.
 142        RESTORE_POS;
 143        go_on = FALSE;
 144      }
 145    }
 146  }
     


© 2002-2024 J.M. van der Veer (jmvdveer@xs4all.nl)