stage3/constant_folding.cc
author Manuele Conti <conti.ma@alice.it>
Tue, 12 Jun 2012 22:32:09 +0200
changeset 587 1ecf916cc397
parent 579 983a3b743085
child 588 3d72d09bd40f
permissions -rw-r--r--
Fix extract_integer_value.
Now we handle signed and unsigned in different mode.
(Thanks to Andreas)
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     1
/*
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     2
 *  matiec - a compiler for the programming languages defined in IEC 61131-3
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     3
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     4
 *  Copyright (C) 2003-2011  Mario de Sousa (msousa@fe.up.pt)
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     5
 *  Copyright (C) 2012       Manuele Conti (conti.ma@alice.it)
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     6
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     7
 *  This program is free software: you can redistribute it and/or modify
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     8
 *  it under the terms of the GNU General Public License as published by
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
     9
 *  the Free Software Foundation, either version 3 of the License, or
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    10
 *  (at your option) any later version.
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    11
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    12
 *  This program is distributed in the hope that it will be useful,
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    15
 *  GNU General Public License for more details.
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    16
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    17
 *  You should have received a copy of the GNU General Public License
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    18
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    19
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    20
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    21
 * This code is made available on the understanding that it will not be
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    22
 * used in safety-critical situations without a full and competent review.
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    23
 */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    24
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    25
/*
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    26
 * An IEC 61131-3 compiler.
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    27
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    28
 * Based on the
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    29
 * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    30
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    31
 */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    32
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    33
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
    34
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
    35
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
    36
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    37
/* Do constant folding...
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    38
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    39
 * I.e., Determine the value of all expressions in which only constant values (i.e. literals) are used.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    40
 * The (constant) result of each operation is stored (annotated) in the respective operation symbol 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    41
 * (e.g.: add_expression_c) in the abstract syntax tree,
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    42
 *
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    43
 * For example:
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    44
 *       2 + 3         -> the constant value '5'    is stored in the add_expression_c symbol.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    45
 *       22.2 - 5.0    -> the constant value '17.2' is stored in the add_expression_c symbol.
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
    46
 *       etc...
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    47
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    48
 *
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
    49
 * NOTE 1 
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
    50
 *      Some operations and constants can have multiple data types. For example,
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    51
 *        1 AND 0
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    52
 *      may be either a BOOL, BYTE, WORD or LWORD.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    53
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    54
 *      The same happens with 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    55
 *        1 + 2
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    56
 *      which may be signed (e.g. INT) or unsigned (UINT)
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    57
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    58
 *      For the above reason, instead of storing a single constant value, we actually store 4:
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    59
 *        - bool
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    60
 *        - uint64
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    61
 *        -  int64
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    62
 *        - real64
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    63
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    64
 *      Additionally, since the result of an operation may result in an overflow, we actually
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    65
 *      store the result inside a struct (defined in absyntax.hh)
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    66
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    67
 *             ** During stage 3 (semantic analysis/checking) we will be doing constant folding.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    68
 *              * That algorithm will anotate the abstract syntax tree with the result of operations
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    69
 *              * on literals (i.e. 44 + 55 will store the result 99).
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    70
 *              * Since the same source code (e.g. 1 + 0) may actually be a BOOL or an ANY_INT,
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    71
 *              * or an ANY_BIT, we need to handle all possibilities, and determine the result of the
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    72
 *              * operation assuming each type.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    73
 *              * For this reason, we have one entry for each possible type, with some expressions
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    74
 *              * having more than one entry filled in!
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    75
 *              **
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    76
 *             typedef enum { cs_undefined,   // not defined --> const_value is not valid!
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    77
 *                            cs_const_value, // const value is valid
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    78
 *                            cs_overflow     // result produced overflow or underflow --> const_value is not valid!
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    79
 *                          } const_status_t;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    80
 *    
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    81
 *             typedef struct {
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    82
 *                 const_status_t status;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    83
 *                 real64_t       value; 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    84
 *             } const_value_real64_t;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    85
 *             const_value_real64_t *const_value_real64; // when NULL --> UNDEFINED
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    86
 *             
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    87
 *             typedef struct {
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    88
 *                 const_status_t status;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    89
 *                 int64_t        value; 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    90
 *             } const_value_int64_t;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    91
 *             const_value_int64_t *const_value_int64; // when NULL --> UNDEFINED
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    92
 *             
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    93
 *             typedef struct {
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    94
 *                 const_status_t status;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    95
 *                 uint64_t       value; 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    96
 *             } const_value_uint64_t;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    97
 *             const_value_uint64_t *const_value_uint64; // when NULL --> UNDEFINED
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    98
 *             
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
    99
 *             typedef struct {
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   100
 *                 const_status_t status;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   101
 *                 bool           value; 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   102
 *             } const_value_bool_t;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   103
 *             const_value_bool_t *const_value_bool; // when NULL --> UNDEFINED
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   104
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   105
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   106
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   107
 * NOTE 2 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   108
 *    This file does not print out any error messages!
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   109
 *    We cannot really print out error messages when we find an overflow. Since each operation
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   110
 *    (symbol in the absract syntax tree for that operation) will have up to 4 constant results,
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   111
 *    it may happen that some of them overflow, while other do not.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   112
 *    We must wait for data type checking to determine the exact data type of each expression
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   113
 *    before we can decide whether or not we should print out an overflow error message.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   114
 *
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   115
 *    For this reason, this visitor merely annotates the abstract syntax tree, and leaves the
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   116
 *    actuall printing of errors for the print_datatype_errors_c class!
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   117
 */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   118
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   119
#include "constant_folding.hh"
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   120
#include <limits>
579
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   121
#include <math.h> /* required for pow function, and HUGE_VAL, HUGE_VALF, HUGE_VALL */
565
8acbddf75333 Fix a few bugs of previous commit.
Mario de Sousa <msousa@fe.up.pt>
parents: 564
diff changeset
   122
#include <stdlib.h> /* required for malloc() */
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   123
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   124
#define __STDC_LIMIT_MACROS /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   125
#include <stdint.h>         /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */
579
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   126
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   127
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   128
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   129
#ifndef   UINT64_MAX 
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   130
  #define UINT64_MAX (std::numeric_limits< uint64_t >::max())
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   131
#endif
579
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   132
#ifndef    INT64_MAX 
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   133
  #define  INT64_MAX (std::numeric_limits<  int64_t >::max())
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   134
#endif
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   135
#ifndef    INT64_MIN
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   136
  #define  INT64_MIN (std::numeric_limits<  int64_t >::min()) 
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   137
#endif
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   138
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   139
#if    (real64_t  == float)
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   140
  #define HUGE_VAL64  HUGE_VALF
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   141
#elif  (real64_t  == double)
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   142
  #define HUGE_VAL64  HUGE_VAL
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   143
#elif  (real64_t  == long_double)
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   144
  #define HUGE_VAL64  HUGE_VALL
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   145
#else 
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   146
  #error Could not determine which data type is being used for real64_t (defined in absyntax.hh). Aborting!
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   147
#endif
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   148
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   149
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   150
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   151
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   152
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   153
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   154
568
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   155
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   156
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   157
#define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   158
#define  LAST_(symbol1, symbol2) (((symbol1)->last_order  > (symbol2)->last_order)    ? (symbol1) : (symbol2))
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   159
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   160
#define STAGE3_ERROR(error_level, symbol1, symbol2, ...) {                                                                  \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   161
  if (current_display_error_level >= error_level) {                                                                         \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   162
    fprintf(stderr, "%s:%d-%d..%d-%d: error: ",                                                                             \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   163
            FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   164
                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   165
    fprintf(stderr, __VA_ARGS__);                                                                                           \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   166
    fprintf(stderr, "\n");                                                                                                  \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   167
    error_count++;                                                                                                     \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   168
  }                                                                                                                         \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   169
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   170
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   171
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   172
#define STAGE3_WARNING(symbol1, symbol2, ...) {                                                                             \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   173
    fprintf(stderr, "%s:%d-%d..%d-%d: warning: ",                                                                           \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   174
            FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   175
                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   176
    fprintf(stderr, __VA_ARGS__);                                                                                           \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   177
    fprintf(stderr, "\n");                                                                                                  \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   178
    warning_found = true;                                                                                                   \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   179
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   180
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   181
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   182
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   183
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   184
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   185
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   186
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   187
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   188
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   189
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   190
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   191
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   192
#define NEW_CVALUE(dtype, symbol) \
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   193
 (symbol->const_value_##dtype) = new(symbol_c::const_value_##dtype##_t); \
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   194
 if ((symbol->const_value_##dtype) == NULL) ERROR; \
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   195
 (symbol->const_value_##dtype)->status = symbol_c::cs_undefined;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   196
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   197
#define SET_CVALUE(dtype, symbol, new_value)  ((symbol)->const_value_##dtype->value) = new_value; ((symbol)->const_value_##dtype->status) = symbol_c::cs_const_value;  
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   198
#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value_##dtype->value) 
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   199
#define SET_OVFLOW(dtype, symbol)             ((symbol)->const_value_##dtype->status) = symbol_c::cs_overflow
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   200
    /* The following test is correct in the presence of a NULL pointer, as the logical evaluation will be suspended as soon as the first condition is false! */
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   201
#define VALID_CVALUE(dtype, symbol)           ((NULL != (symbol)->const_value_##dtype) && (symbol_c::cs_const_value == (symbol)->const_value_##dtype->status))
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   202
#define ISZERO_CVALUE(dtype, symbol)          ((VALID_CVALUE(dtype, symbol)) && (GET_CVALUE(dtype, symbol) == 0))
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   203
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   204
#define DO_BINARY_OPER(dtype, oper, otype)\
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   205
	if (VALID_CVALUE(dtype, symbol->r_exp) && VALID_CVALUE(dtype, symbol->l_exp)) {                                \
578
70c0456affca small bug fix.
Mario de Sousa <msousa@fe.up.pt>
parents: 577
diff changeset
   206
		NEW_CVALUE(otype, symbol);                                                                             \
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   207
		SET_CVALUE(otype, symbol, GET_CVALUE(dtype, symbol->l_exp) oper GET_CVALUE(dtype, symbol->r_exp));     \
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   208
	}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   209
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   210
#define DO_UNARY_OPER(dtype, oper, arg)\
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   211
	if (VALID_CVALUE(dtype, arg)) {                                                                                \
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   212
		NEW_CVALUE(dtype, symbol);                                                                             \
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   213
		SET_CVALUE(dtype, symbol, oper GET_CVALUE(dtype, arg));                                                \
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   214
	}
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   215
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   216
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   217
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   218
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   219
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   220
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   221
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   222
/* NOTE:
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   223
 *   Most of the conditions to detect overflows on signed and unsigned integer operations were adapted from
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   224
 *   https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow?showComments=false
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   225
 *   https://www.securecoding.cert.org/confluence/display/seccode/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   226
 */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   227
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   228
/* NOTE: If at all possible, all overflow tests are done by pre-condition tests, i.e. tests that 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   229
 *       can be run _before_ the operation is executed, and therefore without accessing the result!
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   230
 *
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   231
 *       The exception is for real/floating point values, that simply test if the result is NaN (not a number).
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   232
 */
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   233
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   234
/* res = a + b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   235
static void CHECK_OVERFLOW_uint64_SUM(symbol_c *res, symbol_c *a, symbol_c *b) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   236
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   237
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   238
	/* Test by post-condition: If sum is smaller than either operand => overflow! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   239
	// if (GET_CVALUE(uint64, res) < GET_CVALUE(uint64, a))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   240
	/* Test by pre-condition: If (UINT64_MAX - a) < b => overflow! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   241
	if ((UINT64_MAX - GET_CVALUE(uint64, a)) < GET_CVALUE(uint64, b))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   242
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   243
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   244
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   245
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   246
/* res = a - b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   247
static void CHECK_OVERFLOW_uint64_SUB(symbol_c *res, symbol_c *a, symbol_c *b) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   248
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   249
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   250
	/* Test by post-condition: If diference is larger than a => overflow! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   251
	// if (GET_CVALUE(uint64, res) > GET_CVALUE(uint64, a))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   252
	/* Test by pre-condition: if b > a => overflow! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   253
	if (GET_CVALUE(uint64, b) > GET_CVALUE(uint64, a))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   254
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   255
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   256
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   257
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   258
/* res = a * b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   259
static void CHECK_OVERFLOW_uint64_MUL(symbol_c *res, symbol_c *a, symbol_c *b) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   260
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   261
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   262
	/* Test by pre-condition: If (UINT64_MAX / a) < b => overflow! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   263
	if ((UINT64_MAX / GET_CVALUE(uint64, a)) < GET_CVALUE(uint64, b))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   264
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   265
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   266
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   267
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   268
/* res = a / b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   269
static void CHECK_OVERFLOW_uint64_DIV(symbol_c *res, symbol_c *a, symbol_c *b) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   270
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   271
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   272
	if (GET_CVALUE(uint64, b) == 0) /* division by zero! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   273
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   274
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   275
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   276
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   277
/* res = a MOD b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   278
static void CHECK_OVERFLOW_uint64_MOD(symbol_c *res, symbol_c *a, symbol_c *b) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   279
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   280
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   281
	/* no overflow condition exists, including division by zero, which IEC 61131-3 considers legal for MOD operation! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   282
	if (false) 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   283
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   284
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   285
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   286
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   287
/* res = a + b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   288
static void CHECK_OVERFLOW_int64_SUM(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   289
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   290
		return;
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   291
	int64_t a = GET_CVALUE(int64, a_ptr);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   292
	int64_t b = GET_CVALUE(int64, b_ptr);
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   293
	/* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   294
	if (((b > 0) && (a > (INT64_MAX - b)))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   295
	 || ((b < 0) && (a < (INT64_MIN - b))))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   296
		SET_OVFLOW(int64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   297
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   298
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   299
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   300
/* res = a - b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   301
static void CHECK_OVERFLOW_int64_SUB(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   302
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   303
		return;
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   304
	int64_t a = GET_CVALUE(int64, a_ptr);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   305
	int64_t b = GET_CVALUE(int64, b_ptr);
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   306
	/* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   307
	if (((b > 0) && (a < (INT64_MIN + b)))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   308
	 || ((b < 0) && (a > (INT64_MAX + b))))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   309
		SET_OVFLOW(int64, res);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   310
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   311
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   312
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   313
/* res = a * b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   314
static void CHECK_OVERFLOW_int64_MUL(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   315
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   316
		return;
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   317
	int64_t a = GET_CVALUE(int64, a_ptr);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   318
	int64_t b = GET_CVALUE(int64, b_ptr);
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   319
	if (   ( (a > 0) &&  (b > 0) &&             (a > (INT64_MAX / b))) 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   320
	    || ( (a > 0) && !(b > 0) &&             (b < (INT64_MIN / a))) 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   321
	    || (!(a > 0) &&  (b > 0) &&             (a < (INT64_MIN / b))) 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   322
	    || (!(a > 0) && !(b > 0) && (a != 0) && (b < (INT64_MAX / a))))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   323
		SET_OVFLOW(int64, res);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   324
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   325
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   326
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   327
/* res = a / b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   328
static void CHECK_OVERFLOW_int64_DIV(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   329
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   330
		return;
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   331
	int64_t a = GET_CVALUE(int64, a_ptr);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   332
	int64_t b = GET_CVALUE(int64, b_ptr);
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   333
	if ((b == 0) || ((a == INT64_MIN) && (b == -1)))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   334
		SET_OVFLOW(int64, res);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   335
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   336
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   337
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   338
/* res = a MOD b */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   339
static void CHECK_OVERFLOW_int64_MOD(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   340
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   341
		return;
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   342
	int64_t a = GET_CVALUE(int64, a_ptr);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   343
	int64_t b = GET_CVALUE(int64, b_ptr);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   344
	/* IEC 61131-3 standard says IN1 MOD IN2 must be equivalent to
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   345
	 *  IF (IN2 = 0) THEN OUT:=0 ; ELSE OUT:=IN1 - (IN1/IN2)*IN2 ; END_IF
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   346
	 *
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   347
	 * Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division,
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   348
	 * so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!!
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   349
	 *
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   350
	 * On the other hand, division by 0 is OK!!
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   351
	 */
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   352
	if ((a == INT64_MIN) && (b == -1))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   353
		SET_OVFLOW(int64, res);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   354
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   355
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   356
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   357
/* res = - a */
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   358
static void CHECK_OVERFLOW_int64_NEG(symbol_c *res, symbol_c *a_ptr) {
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   359
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   360
		return;
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   361
	int64_t a = GET_CVALUE(int64, a_ptr);
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   362
	if (a == INT64_MIN)
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   363
		SET_OVFLOW(int64, res);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   364
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   365
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   366
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   367
579
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   368
static void CHECK_OVERFLOW_real64(symbol_c *res_ptr) {
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   369
	if (!VALID_CVALUE(real64, res_ptr))
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   370
		return;
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   371
	real64_t res = GET_CVALUE(real64, res_ptr);
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   372
	/* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   373
	/* The IEC 61131-3 clearly states in section '2.5.1.5.2 Numerical functions':
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   374
	 * "It is an error if the result of evaluation of one of these [numerical] functions exceeds the range of values
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   375
	 *  specified for the data type of the function output, or if division by zero is attempted."
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   376
	 * For this reason, any operation that has as a result a positive or negative inifinity, is also an error!
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   377
	 */
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   378
	if ((isnan(res)) || (res == HUGE_VAL64) || (res == -HUGE_VAL64))
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   379
		SET_OVFLOW(real64, res_ptr);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   380
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   381
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   382
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   383
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   384
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   385
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   386
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   387
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   388
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   389
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   390
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   391
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   392
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   393
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   394
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   395
constant_folding_c::constant_folding_c(symbol_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   396
    error_count = 0;
568
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   397
    warning_found = false;
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   398
    current_display_error_level = 0;
568
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   399
    
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   400
    /* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   401
    symbol_c null_symbol;
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   402
    if (! (std::numeric_limits<real64_t>::is_iec559) )
579
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   403
        STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 60559 floating point numbers. "
568
5f79478142d7 make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents: 567
diff changeset
   404
                                                   "Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals "
579
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   405
                                                   "(i.e. constant folding) may themselves be erroneous, although are most probably correct."
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   406
                                                   "However, more likely is the possible existance of overflow/underflow errors that are not detected.");
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   407
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   408
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   409
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   410
constant_folding_c::~constant_folding_c(void) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   411
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   412
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   413
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   414
int constant_folding_c::get_error_count() {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   415
	return error_count;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   416
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   417
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   418
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   419
/*********************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   420
/* B 1.2 - Constants */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   421
/*********************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   422
/******************************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   423
/* B 1.2.1 - Numeric Literals */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   424
/******************************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   425
void *constant_folding_c::visit(real_c *symbol) {
576
8368ec909825 Fix extract_real (thanks Manuele), and add check for overflow.
Mario de Sousa <msousa@fe.up.pt>
parents: 575
diff changeset
   426
	bool overflow;
8368ec909825 Fix extract_real (thanks Manuele), and add check for overflow.
Mario de Sousa <msousa@fe.up.pt>
parents: 575
diff changeset
   427
	NEW_CVALUE(real64, symbol);	SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow));
8368ec909825 Fix extract_real (thanks Manuele), and add check for overflow.
Mario de Sousa <msousa@fe.up.pt>
parents: 575
diff changeset
   428
	if (overflow) SET_OVFLOW(real64, symbol);
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   429
	return NULL;
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   430
}
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   431
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   432
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   433
void *constant_folding_c::visit(integer_c *symbol) {
587
1ecf916cc397 Fix extract_integer_value.
Manuele Conti <conti.ma@alice.it>
parents: 579
diff changeset
   434
	bool overflow;
1ecf916cc397 Fix extract_integer_value.
Manuele Conti <conti.ma@alice.it>
parents: 579
diff changeset
   435
	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value(symbol, &overflow));
1ecf916cc397 Fix extract_integer_value.
Manuele Conti <conti.ma@alice.it>
parents: 579
diff changeset
   436
	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   437
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   438
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   439
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   440
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   441
void *constant_folding_c::visit(neg_real_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   442
	symbol->exp->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   443
	DO_UNARY_OPER(real64, -, symbol->exp);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   444
	CHECK_OVERFLOW_real64(symbol);
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   445
	return NULL;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   446
}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   447
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   448
/* | '-' integer	{$$ = new neg_integer_c($2, locloc(@$));} */
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   449
void *constant_folding_c::visit(neg_integer_c *symbol) {
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   450
	symbol->exp->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   451
	DO_UNARY_OPER(int64, -, symbol->exp);
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   452
	CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   453
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   454
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   455
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   456
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   457
void *constant_folding_c::visit(binary_integer_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   458
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   459
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   460
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   461
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   462
void *constant_folding_c::visit(octal_integer_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   463
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   464
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   465
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   466
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   467
void *constant_folding_c::visit(hex_integer_c *symbol) {
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   468
	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_hex_value(symbol));
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   469
	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_hex_value(symbol));
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   470
	return NULL;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   471
}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   472
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   473
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   474
/*
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   475
integer_literal:
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   476
  integer_type_name '#' signed_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   477
| integer_type_name '#' binary_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   478
| integer_type_name '#' octal_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   479
| integer_type_name '#' hex_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   480
*/
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   481
// SYM_REF2(integer_literal_c, type, value)
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   482
void *constant_folding_c::visit(integer_literal_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   483
	symbol->value->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   484
	DO_UNARY_OPER( int64, /* none */, symbol->value);
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   485
	DO_UNARY_OPER(uint64, /* none */, symbol->value);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   486
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   487
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   488
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   489
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   490
void *constant_folding_c::visit(real_literal_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   491
	symbol->value->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   492
	DO_UNARY_OPER(real64, /* none */, symbol->value);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   493
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   494
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   495
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   496
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   497
void *constant_folding_c::visit(bit_string_literal_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   498
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   499
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   500
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   501
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   502
void *constant_folding_c::visit(boolean_literal_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   503
	symbol->value->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   504
	DO_UNARY_OPER(bool, /* none */, symbol->value);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   505
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   506
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   507
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   508
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   509
void *constant_folding_c::visit(boolean_true_c *symbol) {
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   510
	NEW_CVALUE(bool, symbol);	SET_CVALUE(bool, symbol, true);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   511
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   512
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   513
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   514
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   515
void *constant_folding_c::visit(boolean_false_c *symbol) {
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   516
	NEW_CVALUE(bool, symbol);	SET_CVALUE(bool, symbol, false);
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   517
	return NULL;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   518
}
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   519
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   520
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   521
/***************************************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   522
/* B.3 - Language ST (Structured Text) */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   523
/***************************************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   524
/***********************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   525
/* B 3.1 - Expressions */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   526
/***********************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   527
void *constant_folding_c::visit(or_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   528
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   529
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   530
	DO_BINARY_OPER(  bool, ||, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   531
	DO_BINARY_OPER(uint64, | , bool);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   532
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   533
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   534
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   535
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   536
void *constant_folding_c::visit(xor_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   537
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   538
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   539
	DO_BINARY_OPER(  bool, ^, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   540
	DO_BINARY_OPER(uint64, ^, uint64);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   541
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   542
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   543
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   544
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   545
void *constant_folding_c::visit(and_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   546
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   547
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   548
	DO_BINARY_OPER(  bool, &&, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   549
	DO_BINARY_OPER(uint64, & , uint64);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   550
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   551
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   552
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   553
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   554
void *constant_folding_c::visit(equ_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   555
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   556
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   557
	DO_BINARY_OPER(  bool, ==, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   558
	DO_BINARY_OPER(uint64, ==, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   559
	DO_BINARY_OPER( int64, ==, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   560
	DO_BINARY_OPER(real64, ==, bool);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   561
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   562
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   563
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   564
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   565
void *constant_folding_c::visit(notequ_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   566
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   567
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   568
	DO_BINARY_OPER(  bool, !=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   569
	DO_BINARY_OPER(uint64, !=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   570
	DO_BINARY_OPER( int64, !=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   571
	DO_BINARY_OPER(real64, !=, bool);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   572
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   573
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   574
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   575
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   576
void *constant_folding_c::visit(lt_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   577
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   578
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   579
	DO_BINARY_OPER(  bool, <, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   580
	DO_BINARY_OPER(uint64, <, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   581
	DO_BINARY_OPER( int64, <, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   582
	DO_BINARY_OPER(real64, <, bool);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   583
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   584
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   585
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   586
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   587
void *constant_folding_c::visit(gt_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   588
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   589
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   590
	DO_BINARY_OPER(  bool, >, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   591
	DO_BINARY_OPER(uint64, >, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   592
	DO_BINARY_OPER( int64, >, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   593
	DO_BINARY_OPER(real64, >, bool);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   594
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   595
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   596
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   597
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   598
void *constant_folding_c::visit(le_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   599
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   600
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   601
	DO_BINARY_OPER(  bool, <=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   602
	DO_BINARY_OPER(uint64, <=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   603
	DO_BINARY_OPER( int64, <=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   604
	DO_BINARY_OPER(real64, <=, bool);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   605
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   606
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   607
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   608
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   609
void *constant_folding_c::visit(ge_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   610
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   611
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   612
	DO_BINARY_OPER(  bool, >=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   613
	DO_BINARY_OPER(uint64, >=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   614
	DO_BINARY_OPER( int64, >=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   615
	DO_BINARY_OPER(real64, >=, bool);
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   616
	return NULL;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   617
}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   618
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   619
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   620
void *constant_folding_c::visit(add_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   621
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   622
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   623
	DO_BINARY_OPER(uint64, +, uint64);   CHECK_OVERFLOW_uint64_SUM(symbol, symbol->l_exp, symbol->r_exp);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   624
	DO_BINARY_OPER( int64, +,  int64);   CHECK_OVERFLOW_int64_SUM (symbol, symbol->l_exp, symbol->r_exp);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   625
	DO_BINARY_OPER(real64, +, real64);   CHECK_OVERFLOW_real64    (symbol);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   626
	return NULL;
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   627
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   628
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   629
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   630
void *constant_folding_c::visit(sub_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   631
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   632
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   633
	DO_BINARY_OPER(uint64, -, uint64);   CHECK_OVERFLOW_uint64_SUB(symbol, symbol->l_exp, symbol->r_exp);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   634
	DO_BINARY_OPER( int64, -,  int64);   CHECK_OVERFLOW_int64_SUB (symbol, symbol->l_exp, symbol->r_exp);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   635
	DO_BINARY_OPER(real64, -, real64);   CHECK_OVERFLOW_real64    (symbol);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   636
	return NULL;
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   637
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   638
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   639
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   640
void *constant_folding_c::visit(mul_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   641
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   642
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   643
	DO_BINARY_OPER(uint64, *, uint64);   CHECK_OVERFLOW_uint64_MUL(symbol, symbol->l_exp, symbol->r_exp);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   644
	DO_BINARY_OPER( int64, *,  int64);   CHECK_OVERFLOW_int64_MUL (symbol, symbol->l_exp, symbol->r_exp);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   645
	DO_BINARY_OPER(real64, *, real64);   CHECK_OVERFLOW_real64    (symbol);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   646
	return NULL;
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   647
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   648
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   649
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   650
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   651
void *constant_folding_c::visit(div_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   652
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   653
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   654
	if (ISZERO_CVALUE(uint64, symbol->r_exp))  {NEW_CVALUE(uint64, symbol); SET_OVFLOW(uint64, symbol);} else {DO_BINARY_OPER(uint64, /, uint64); CHECK_OVERFLOW_uint64_DIV(symbol, symbol->l_exp, symbol->r_exp);};
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   655
	if (ISZERO_CVALUE( int64, symbol->r_exp))  {NEW_CVALUE( int64, symbol); SET_OVFLOW( int64, symbol);} else {DO_BINARY_OPER( int64, /,  int64); CHECK_OVERFLOW_int64_DIV(symbol, symbol->l_exp, symbol->r_exp);};
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   656
	if (ISZERO_CVALUE(real64, symbol->r_exp))  {NEW_CVALUE(real64, symbol); SET_OVFLOW(real64, symbol);} else {DO_BINARY_OPER(real64, /, real64); CHECK_OVERFLOW_real64(symbol);};
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   657
	return NULL;
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   658
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   659
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   660
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   661
void *constant_folding_c::visit(mod_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   662
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   663
	symbol->r_exp->accept(*this);
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   664
	/* IEC 61131-3 standard says IN1 MOD IN2 must be equivalent to
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   665
	 *  IF (IN2 = 0) THEN OUT:=0 ; ELSE OUT:=IN1 - (IN1/IN2)*IN2 ; END_IF
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   666
	 *
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   667
	 * Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division,
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   668
	 * so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!!
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   669
	 */
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   670
	if (ISZERO_CVALUE(uint64, symbol->r_exp))  {NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, 0);} else {DO_BINARY_OPER(uint64, %, uint64); CHECK_OVERFLOW_uint64_MOD(symbol, symbol->l_exp, symbol->r_exp);};
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   671
	if (ISZERO_CVALUE( int64, symbol->r_exp))  {NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, 0);} else {DO_BINARY_OPER( int64, %,  int64); CHECK_OVERFLOW_int64_MOD(symbol, symbol->l_exp, symbol->r_exp);};
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   672
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   673
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   674
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   675
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   676
void *constant_folding_c::visit(power_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   677
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   678
	symbol->r_exp->accept(*this);
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   679
	/* NOTE: If the const_value in symbol->r_exp is within the limits of both int64 and uint64, then we do both operations.
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   680
	 *       That is OK, as the result should be identicial (we do create an unnecessary CVALUE variable, but who cares?).
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   681
	 *       If only one is valid, then that is the oper we will do!
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   682
	 */
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   683
	if (VALID_CVALUE(real64, symbol->l_exp) && VALID_CVALUE( int64, symbol->r_exp)) {
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   684
		NEW_CVALUE(real64, symbol);
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   685
		SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, symbol->l_exp), GET_CVALUE( int64, symbol->r_exp)));
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   686
	}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   687
	if (VALID_CVALUE(real64, symbol->l_exp) && VALID_CVALUE(uint64, symbol->r_exp)) {
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   688
		NEW_CVALUE(real64, symbol);
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   689
		SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, symbol->l_exp), GET_CVALUE(uint64, symbol->r_exp)));
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   690
	}
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   691
	CHECK_OVERFLOW_real64(symbol);
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   692
	return NULL;
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   693
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   694
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   695
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   696
void *constant_folding_c::visit(neg_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   697
	symbol->exp->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   698
	DO_UNARY_OPER( int64, -, symbol->exp);	CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp);
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   699
	DO_UNARY_OPER(real64, -, symbol->exp);	CHECK_OVERFLOW_real64(symbol);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   700
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   701
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   702
567
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   703
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   704
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   705
void *constant_folding_c::visit(not_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   706
	symbol->exp->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   707
	DO_UNARY_OPER(  bool, !, symbol->exp);
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   708
	DO_UNARY_OPER(uint64, ~, symbol->exp);
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   709
	return NULL;
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   710
}
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   711
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   712