assign.c

     1  //! @file assign.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-2025 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  //! Compile assignments.
    25  
    26  #include <vif.h>
    27  
    28  void assign (EXPR * reg)
    29  {
    30  #define ASSIGN_ERROR(s) {\
    31      NEW_RECORD (str);\
    32      _srecordf (str, "%s = %s", qtype (&(lhs.mode)), qtype (&(rhs.mode)));\
    33      ERROR (101, (s), str);\
    34      return;\
    35    }
    36    int_4 rc;
    37    EXPR lhs, rhs;
    38    memset (&lhs, 0, sizeof (lhs));
    39    memset (&rhs, 0, sizeof (rhs));
    40    lhs_factor = TRUE;
    41    factor (&lhs);
    42    lhs_factor = FALSE;
    43    if (lhs.variant != EXPR_VAR && lhs.variant != EXPR_SLICE && lhs.variant != EXPR_SUBSTR) {
    44      ERROR (102, "invalid lhs in assignment", lhs.str);
    45      skip_card (FALSE);
    46      return;
    47    }
    48    if (lhs.variant == EXPR_VAR) {
    49      IDENT *idf = impl_decl (lhs.str, NO_MODE);
    50      if (idf != NO_IDENT && IS_ROW (idf->mode)) {
    51        ERROR (103, "cannot assign to dimensioned variable", curlex);
    52        skip_card (FALSE);
    53        return;
    54      }
    55    }
    56    rc = scan (EXPECT_NONE);
    57    if (TOKEN ("=")) {
    58      rc = scan (EXPECT_NONE);
    59      exprio (&rhs, 1, TRUE);
    60      (void) fold_expr (&rhs, rhs.mode.type);
    61      rc = scan (EXPECT_NONE);
    62    } else {
    63      EXPECT (104, "=");
    64    }
    65  // Assign.
    66    if (lhs.mode.type == CHARACTER && rhs.mode.type == CHARACTER) {
    67      // character*n = character*m; m <= n
    68      if (lhs.variant == EXPR_SUBSTR) {
    69        _srecordf (reg->str, "bufrep (%s, %s)", lhs.str, rhs.str);
    70      } else if (lhs.mode.len == 0) {
    71        _srecordf (reg->str, "strcpy (%s, %s)", lhs.str, rhs.str);
    72      } else {
    73        _srecordf (reg->str, "bufcpy (%s, %s, %d)", lhs.str, rhs.str, lhs.mode.len);
    74      }
    75    } else if (rhs.variant == EXPR_CONST && rhs.mode.type == INTEGER && lhs.mode.type == INTEGER) {
    76  // INTEGER length denotations overlap.
    77      factor_integer_number (&rhs, rhs.str);
    78      if (rhs.mode.len > lhs.mode.len) {
    79        MODE_ERROR (105, qtype (&(rhs.mode)), qtype (&(lhs.mode)));
    80      } 
    81      _srecordf (reg->str, "%s = %s", lhs.str, rhs.str);
    82    } else if (lhs.mode.type == rhs.mode.type && lhs.mode.len == rhs.mode.len) {
    83      if (strcmp (lhs.str, rhs.str) == 0) {
    84        _srecordf (reg->str, "/* %s = %s */", lhs.str, rhs.str);
    85      } else {
    86        _srecordf (reg->str, "%s = %s", lhs.str, rhs.str);
    87      }
    88    } else {
    89      EXPR new = (EXPR) {.mode = lhs.mode};
    90      if (!coerce (&new, &rhs)) {
    91        MODE_ERROR (106, qtype (&(rhs.mode)), qtype (&(lhs.mode)));
    92      }  
    93      _srecordf (reg->str, "%s = %s", lhs.str, new.str);
    94    }
    95    skip_card (TRUE);
    96    (void) rc;
    97  }


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