stage3/constant_folding.cc
author Mario de Sousa <msousa@fe.up.pt>
Wed, 18 Jul 2012 16:56:36 +0100
changeset 604 2989051a0a64
parent 603 a45a62dd6df9
child 607 be9ba3531afb
permissions -rw-r--r--
Fixing includes to define INTxx_MAX etc...
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
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   124
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   125
#include <string.h>  /* required for strlen() */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   126
// #include <stdlib.h>  /* required for atoi() */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   127
#include <errno.h>   /* required for errno */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   128
604
2989051a0a64 Fixing includes to define INTxx_MAX etc...
Mario de Sousa <msousa@fe.up.pt>
parents: 603
diff changeset
   129
#include <../main.hh>         /* 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
   130
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   131
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   132
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   133
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
   134
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
   135
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   136
#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
   137
#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
   138
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   139
#define STAGE3_ERROR(error_level, symbol1, symbol2, ...) {                                                                  \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   140
  if (current_display_error_level >= error_level) {                                                                         \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   141
    fprintf(stderr, "%s:%d-%d..%d-%d: error: ",                                                                             \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   142
            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
   143
                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   144
    fprintf(stderr, __VA_ARGS__);                                                                                           \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   145
    fprintf(stderr, "\n");                                                                                                  \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   146
    error_count++;                                                                                                     \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   147
  }                                                                                                                         \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   148
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   149
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   150
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   151
#define STAGE3_WARNING(symbol1, symbol2, ...) {                                                                             \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   152
    fprintf(stderr, "%s:%d-%d..%d-%d: warning: ",                                                                           \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   153
            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
   154
                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   155
    fprintf(stderr, __VA_ARGS__);                                                                                           \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   156
    fprintf(stderr, "\n");                                                                                                  \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   157
    warning_found = true;                                                                                                   \
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   158
}
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
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   161
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
   162
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   163
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   164
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   165
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   166
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   167
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   168
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   169
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   170
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   171
#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
   172
 (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
   173
 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
   174
 (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
   175
603
a45a62dd6df9 Add remove_from_candidate_datatype_list method using constant_folding results.
Manuele Conti <conti.ma@alice.it>
parents: 602
diff changeset
   176
#define SET_CVALUE(dtype, symbol, new_value)  ((symbol)->const_value_##dtype->value) = new_value; ((symbol)->const_value_##dtype->status) = symbol_c::cs_const_value;
a45a62dd6df9 Add remove_from_candidate_datatype_list method using constant_folding results.
Manuele Conti <conti.ma@alice.it>
parents: 602
diff changeset
   177
#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value_##dtype->value)
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   178
#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
   179
    /* 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
   180
#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
   181
#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
   182
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   183
#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
   184
	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
   185
		NEW_CVALUE(otype, symbol);                                                                             \
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   186
		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
   187
	}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   188
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   189
#define DO_UNARY_OPER(dtype, oper, arg)\
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   190
	if (VALID_CVALUE(dtype, arg)) {                                                                                \
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   191
		NEW_CVALUE(dtype, symbol);                                                                             \
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   192
		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
   193
	}
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   194
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   195
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   196
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   197
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   198
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   199
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   200
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   201
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   202
/***            convert string to numerical value                    ***/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   203
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   204
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   205
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   206
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   207
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   208
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   209
  /* To allow the compiler to be portable, we cannot assume that int64_t is mapped onto long long int,
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   210
   * so we cannot call strtoll() and strtoull() in extract_int64() and extract_uint64().
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   211
   *
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   212
   * So, we create our own strtouint64() and strtoint64() functions.
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   213
   * (We actually call them matiec_strtoint64() so they will not clash with any function
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   214
   *  that may be added to the standard library in the future).
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   215
   * We actually create several of each, and let the compiler choose which is the correct one,
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   216
   * by having it resolve the call to the overloaded function. For the C++ compiler to be able
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   217
   * to resolve this ambiguity, we need to add a dummy parameter to each function!
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   218
   *
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   219
   * TODO: support platforms in which int64_t is mapped onto int !! Is this really needed?
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   220
   */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   221
static  int64_t matiec_strtoint64 (         long      int *dummy, const char *nptr, char **endptr, int base) {return strtol  (nptr, endptr, base);}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   222
static  int64_t matiec_strtoint64 (         long long int *dummy, const char *nptr, char **endptr, int base) {return strtoll (nptr, endptr, base);}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   223
  
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   224
static uint64_t matiec_strtouint64(unsigned long      int *dummy, const char *nptr, char **endptr, int base) {return strtoul (nptr, endptr, base);}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   225
static uint64_t matiec_strtouint64(unsigned long long int *dummy, const char *nptr, char **endptr, int base) {return strtoull(nptr, endptr, base);}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   226
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   227
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   228
/* extract the value of an integer from an integer_c object !! */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   229
/* NOTE: it must ignore underscores! */
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   230
/* NOTE: To follow the basic structure used throughout the compiler's code, we should really be
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   231
 * writing this as a visitor_c (and do away with the dynamic casts!), but since we only have 3 distinct 
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   232
 * symbol class types to handle, it is probably easier to read if we write it as a standard function... 
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   233
 */
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   234
int64_t extract_int64_value(symbol_c *sym, bool *overflow) {
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   235
  int64_t      ret;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   236
  std::string  str = "";
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   237
  char        *endptr;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   238
  const char  *value;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   239
  int          base;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   240
  integer_c         *integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   241
  hex_integer_c     *hex_integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   242
  octal_integer_c   *octal_integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   243
  binary_integer_c  *binary_integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   244
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   245
   if       ((integer        = dynamic_cast<integer_c *>(sym))        != NULL) {value = integer       ->value + 0; base = 10;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   246
   else  if ((hex_integer    = dynamic_cast<hex_integer_c *>(sym))    != NULL) {value = hex_integer   ->value + 3; base = 16;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   247
   else  if ((octal_integer  = dynamic_cast<octal_integer_c *>(sym))  != NULL) {value = octal_integer ->value + 2; base =  8;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   248
   else  if ((binary_integer = dynamic_cast<binary_integer_c *>(sym)) != NULL) {value = binary_integer->value + 2; base =  2;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   249
   else  ERROR;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   250
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   251
  for(unsigned int i = 0; i < strlen(value); i++)
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   252
    if (value[i] != '_')  str += value[i];
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   253
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   254
  errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   255
  ret = matiec_strtoint64((int64_t *)NULL, str.c_str(), &endptr, base);
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   256
  if (overflow != NULL)
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   257
    *overflow = (errno == ERANGE);
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   258
  if (((errno != 0) && (errno != ERANGE)) || (*endptr != '\0'))
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   259
    ERROR;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   260
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   261
  return ret;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   262
}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   263
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   264
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   265
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   266
uint64_t extract_uint64_value(symbol_c *sym, bool *overflow) {
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   267
  uint64_t     ret;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   268
  std::string  str = "";
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   269
  char        *endptr;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   270
  const char  *value;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   271
  int          base;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   272
  integer_c         *integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   273
  hex_integer_c     *hex_integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   274
  octal_integer_c   *octal_integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   275
  binary_integer_c  *binary_integer;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   276
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   277
   if       ((integer        = dynamic_cast<integer_c *>(sym))        != NULL) {value = integer       ->value + 0; base = 10;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   278
   else  if ((hex_integer    = dynamic_cast<hex_integer_c *>(sym))    != NULL) {value = hex_integer   ->value + 3; base = 16;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   279
   else  if ((octal_integer  = dynamic_cast<octal_integer_c *>(sym))  != NULL) {value = octal_integer ->value + 2; base =  8;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   280
   else  if ((binary_integer = dynamic_cast<binary_integer_c *>(sym)) != NULL) {value = binary_integer->value + 2; base =  2;}
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   281
   else  ERROR;
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   282
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   283
  for(unsigned int i = 0; i < strlen(value); i++)
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   284
    if (value[i] != '_')  str += value[i];
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   285
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   286
  errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   287
  ret = matiec_strtouint64((uint64_t *)NULL, str.c_str(), &endptr, base);
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   288
  if (overflow != NULL)
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   289
    *overflow = (errno == ERANGE);
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   290
  if (((errno != 0) && (errno != ERANGE)) || (*endptr != '\0'))
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   291
    ERROR;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   292
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   293
  return ret;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   294
}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   295
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   296
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   297
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   298
/* extract the value of a real from an real_c object !! */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   299
/* NOTE: it must ignore underscores! */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   300
/* From iec_bison.yy
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   301
 *  real:
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   302
 *   real_token		{$$ = new real_c($1, locloc(@$));}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   303
 * | fixed_point_token	{$$ = new real_c($1, locloc(@$));}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   304
 *
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   305
 * From iec_flex.ll
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   306
 * {real}			{yylval.ID=strdup(yytext); return real_token;}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   307
 * {fixed_point}		{yylval.ID=strdup(yytext); return fixed_point_token;}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   308
 *
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   309
 * real		{integer}\.{integer}{exponent}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   310
 * fixed_point		{integer}\.{integer}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   311
 * exponent        [Ee]([+-]?){integer}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   312
 * integer         {digit}((_?{digit})*)
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   313
 */
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   314
real64_t extract_real_value(symbol_c *sym, bool *overflow) {
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   315
  std::string str = "";
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   316
  real_c *real_sym;
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   317
  char   *endptr;
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   318
  real64_t ret;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   319
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   320
  if ((real_sym = dynamic_cast<real_c *>(sym)) == NULL) ERROR;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   321
  for(unsigned int i = 0; i < strlen(real_sym->value); i++)
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   322
    if (real_sym->value[i] != '_') str += real_sym->value[i];
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   323
    
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   324
  errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   325
  #if    (real64_t  == float)
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   326
    ret = strtof(str.c_str(),  &endptr);
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   327
  #elif  (real64_t  == double)
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   328
    ret = strtod(str.c_str(),  &endptr);
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   329
  #elif  (real64_t  == long_double)
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   330
    ret = strtold(str.c_str(), &endptr);
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   331
  #else 
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   332
    #error Could not determine which data type is being used for real64_t (defined in absyntax.hh). Aborting!
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   333
  #endif
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   334
  if (overflow != NULL)
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   335
    *overflow = (errno == ERANGE);
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   336
  if (((errno != 0) && (errno != ERANGE)) || (*endptr != '\0'))
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   337
    ERROR;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   338
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   339
  return ret;
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   340
}
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   341
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   342
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   343
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   344
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   345
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   346
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   347
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   348
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   349
/***        Functions to check for overflow situation                ***/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   350
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   351
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   352
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   353
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   354
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   355
/* NOTE:
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   356
 *   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
   357
 *   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
   358
 *   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
   359
 */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   360
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   361
/* 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
   362
 *       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
   363
 *
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   364
 *       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
   365
 */
572
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
/* 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
   368
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
   369
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   370
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   371
	/* 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
   372
	// 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
   373
	/* 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
   374
	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
   375
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   376
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   377
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   378
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   379
/* 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
   380
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
   381
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   382
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   383
	/* 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
   384
	// 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
   385
	/* Test by pre-condition: if b > a => overflow! */
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   386
	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
   387
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   388
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   389
572
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
/* 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
   392
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
   393
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   394
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   395
	/* 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
   396
	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
   397
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   398
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   399
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   400
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   401
/* 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
   402
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
   403
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   404
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   405
	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
   406
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   407
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   408
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   409
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   410
/* 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
   411
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
   412
	if (!VALID_CVALUE(uint64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   413
		return;
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   414
	/* 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
   415
	if (false) 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   416
		SET_OVFLOW(uint64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   417
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   418
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   419
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   420
/* 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
   421
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
   422
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   423
		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
   424
	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
   425
	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
   426
	/* 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
   427
	if (((b > 0) && (a > (INT64_MAX - b)))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   428
	 || ((b < 0) && (a < (INT64_MIN - b))))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   429
		SET_OVFLOW(int64, res);
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   430
}
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   431
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   432
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   433
/* 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
   434
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
   435
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   436
		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
   437
	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
   438
	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
   439
	/* 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
   440
	if (((b > 0) && (a < (INT64_MIN + b)))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   441
	 || ((b < 0) && (a > (INT64_MAX + b))))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   442
		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
   443
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   444
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   445
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   446
/* 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
   447
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
   448
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   449
		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
   450
	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
   451
	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
   452
	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
   453
	    || ( (a > 0) && !(b > 0) &&             (b < (INT64_MIN / a))) 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   454
	    || (!(a > 0) &&  (b > 0) &&             (a < (INT64_MIN / b))) 
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   455
	    || (!(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
   456
		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
   457
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   458
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   459
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   460
/* 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
   461
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
   462
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   463
		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
   464
	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
   465
	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
   466
	if ((b == 0) || ((a == INT64_MIN) && (b == -1)))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   467
		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
   468
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   469
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   470
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   471
/* 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
   472
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
   473
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   474
		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
   475
	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
   476
	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
   477
	/* 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
   478
	 *  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
   479
	 *
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   480
	 * 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
   481
	 * 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
   482
	 *
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   483
	 * 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
   484
	 */
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   485
	if ((a == INT64_MIN) && (b == -1))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   486
		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
   487
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   488
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   489
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   490
/* 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
   491
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
   492
	if (!VALID_CVALUE(int64, res))
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   493
		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
   494
	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
   495
	if (a == INT64_MIN)
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   496
		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
   497
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   498
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   499
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   500
579
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   501
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
   502
	if (!VALID_CVALUE(real64, res_ptr))
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   503
		return;
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   504
	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
   505
	/* 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
   506
	/* 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
   507
	 * "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
   508
	 *  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
   509
	 * 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
   510
	 */
983a3b743085 Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents: 578
diff changeset
   511
	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
   512
		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
   513
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   514
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   515
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   516
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   517
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   518
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   519
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   520
596
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   521
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   522
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   523
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   524
/***        The constant_folding_c                                   ***/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   525
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   526
/***********************************************************************/
4efb11e44065 Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents: 592
diff changeset
   527
/***********************************************************************/
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   528
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   529
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   530
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   531
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   532
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   533
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   534
constant_folding_c::constant_folding_c(symbol_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   535
    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
   536
    warning_found = false;
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   537
    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
   538
    
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
   539
    /* 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
   540
    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
   541
    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
   542
        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
   543
                                                   "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
   544
                                                   "(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
   545
                                                   "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
   546
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   547
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
   548
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   549
constant_folding_c::~constant_folding_c(void) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   550
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   551
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
   552
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   553
int constant_folding_c::get_error_count() {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   554
	return error_count;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   555
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   556
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   557
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   558
/*********************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   559
/* B 1.2 - Constants */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   560
/*********************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   561
/******************************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   562
/* B 1.2.1 - Numeric Literals */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   563
/******************************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   564
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
   565
	bool overflow;
8368ec909825 Fix extract_real (thanks Manuele), and add check for overflow.
Mario de Sousa <msousa@fe.up.pt>
parents: 575
diff changeset
   566
	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
   567
	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
   568
	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
   569
}
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   570
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   571
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   572
void *constant_folding_c::visit(integer_c *symbol) {
587
1ecf916cc397 Fix extract_integer_value.
Manuele Conti <conti.ma@alice.it>
parents: 579
diff changeset
   573
	bool overflow;
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   574
	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
588
3d72d09bd40f Add missing set overflow flag.
Manuele Conti <conti.ma@alice.it>
parents: 587
diff changeset
   575
	if (overflow) SET_OVFLOW(int64, symbol);
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   576
	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
588
3d72d09bd40f Add missing set overflow flag.
Manuele Conti <conti.ma@alice.it>
parents: 587
diff changeset
   577
	if (overflow) SET_OVFLOW(uint64, symbol);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   578
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   579
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   580
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
   581
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   582
void *constant_folding_c::visit(neg_real_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   583
	symbol->exp->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   584
	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
   585
	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
   586
	return NULL;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   587
}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   588
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   589
/* | '-' integer	{$$ = new neg_integer_c($2, locloc(@$));} */
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   590
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
   591
	symbol->exp->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   592
	DO_UNARY_OPER(int64, -, symbol->exp);
574
d291a942899b Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents: 573
diff changeset
   593
	CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp);
590
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   594
	/* NOTE 1: INT64_MIN = -(INT64_MAX + 1)   ---> assuming two's complement representation!!!
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   595
	 * NOTE 2: if the user happens to want INT_MIN, that value will first be parsed as a positive integer, before being negated here.
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   596
	 * However, the positive value cannot be stored inside an int64! So, in this case, we will get the value from the uint64 cvalue.
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   597
	 */
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   598
	// if (INT64_MIN == -INT64_MAX - 1) // We do not really need to check that the platform uses two's complement
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   599
	if (VALID_CVALUE(uint64, symbol->exp) && (GET_CVALUE(uint64, symbol->exp) == -INT64_MIN)) { // How do we stop the compiler from complaining about a comparison between int and unsigned int?
590
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   600
		NEW_CVALUE(int64, symbol); // in principle, if the above condition is true, then no new cvalue was created by DO_UNARY_OPER(). Not that it would be a problem to create a new one!
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   601
		SET_CVALUE(int64, symbol, INT64_MIN);
649667749171 Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents: 588
diff changeset
   602
	}
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   603
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   604
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   605
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
   606
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   607
void *constant_folding_c::visit(binary_integer_c *symbol) {
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   608
	bool overflow;
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   609
	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   610
	if (overflow) SET_OVFLOW(int64, symbol);
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   611
	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   612
	if (overflow) SET_OVFLOW(uint64, symbol);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   613
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   614
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   615
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
   616
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   617
void *constant_folding_c::visit(octal_integer_c *symbol) {
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   618
	bool overflow;
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   619
	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   620
	if (overflow) SET_OVFLOW(int64, symbol);
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   621
	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   622
	if (overflow) SET_OVFLOW(uint64, symbol);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   623
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   624
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   625
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
   626
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   627
void *constant_folding_c::visit(hex_integer_c *symbol) {
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   628
	bool overflow;
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   629
	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   630
	if (overflow) SET_OVFLOW(int64, symbol);
601
683ae5444237 fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 600
diff changeset
   631
	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
600
f5d4e9f91513 determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents: 596
diff changeset
   632
	if (overflow) SET_OVFLOW(uint64, symbol);
569
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   633
	return NULL;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   634
}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   635
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   636
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   637
/*
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   638
integer_literal:
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   639
  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
   640
| 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
   641
| 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
   642
| 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
   643
*/
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   644
// SYM_REF2(integer_literal_c, type, value)
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   645
void *constant_folding_c::visit(integer_literal_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   646
	symbol->value->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   647
	DO_UNARY_OPER( int64, /* none */, symbol->value);
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   648
	DO_UNARY_OPER(uint64, /* none */, symbol->value);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   649
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   650
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   651
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
   652
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   653
void *constant_folding_c::visit(real_literal_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   654
	symbol->value->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   655
	DO_UNARY_OPER(real64, /* none */, symbol->value);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   656
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   657
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   658
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
   659
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   660
void *constant_folding_c::visit(bit_string_literal_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   661
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   662
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   663
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
   664
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   665
void *constant_folding_c::visit(boolean_literal_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   666
	symbol->value->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   667
	DO_UNARY_OPER(bool, /* none */, symbol->value);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   668
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   669
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   670
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
   671
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   672
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
   673
	NEW_CVALUE(bool, symbol);	SET_CVALUE(bool, symbol, true);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   674
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   675
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   676
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
   677
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   678
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
   679
	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
   680
	return NULL;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   681
}
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
   682
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   683
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   684
/***************************************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   685
/* B.3 - Language ST (Structured Text) */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   686
/***************************************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   687
/***********************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   688
/* B 3.1 - Expressions */
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   689
/***********************/
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   690
void *constant_folding_c::visit(or_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   691
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   692
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   693
	DO_BINARY_OPER(  bool, ||, bool);
602
456add88d64c fix typo.
Mario de Sousa <msousa@fe.up.pt>
parents: 601
diff changeset
   694
	DO_BINARY_OPER(uint64, | , uint64);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   695
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   696
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   697
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
   698
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   699
void *constant_folding_c::visit(xor_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   700
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   701
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   702
	DO_BINARY_OPER(  bool, ^, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   703
	DO_BINARY_OPER(uint64, ^, uint64);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   704
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   705
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   706
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
   707
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   708
void *constant_folding_c::visit(and_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   709
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   710
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   711
	DO_BINARY_OPER(  bool, &&, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   712
	DO_BINARY_OPER(uint64, & , uint64);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   713
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   714
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   715
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
   716
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   717
void *constant_folding_c::visit(equ_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   718
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   719
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   720
	DO_BINARY_OPER(  bool, ==, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   721
	DO_BINARY_OPER(uint64, ==, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   722
	DO_BINARY_OPER( int64, ==, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   723
	DO_BINARY_OPER(real64, ==, bool);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   724
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   725
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   726
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
   727
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   728
void *constant_folding_c::visit(notequ_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   729
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   730
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   731
	DO_BINARY_OPER(  bool, !=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   732
	DO_BINARY_OPER(uint64, !=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   733
	DO_BINARY_OPER( int64, !=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   734
	DO_BINARY_OPER(real64, !=, bool);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   735
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   736
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   737
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
   738
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   739
void *constant_folding_c::visit(lt_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   740
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   741
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   742
	DO_BINARY_OPER(  bool, <, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   743
	DO_BINARY_OPER(uint64, <, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   744
	DO_BINARY_OPER( int64, <, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   745
	DO_BINARY_OPER(real64, <, bool);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   746
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   747
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   748
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
   749
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   750
void *constant_folding_c::visit(gt_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   751
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   752
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   753
	DO_BINARY_OPER(  bool, >, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   754
	DO_BINARY_OPER(uint64, >, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   755
	DO_BINARY_OPER( int64, >, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   756
	DO_BINARY_OPER(real64, >, bool);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   757
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   758
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   759
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
   760
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   761
void *constant_folding_c::visit(le_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   762
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   763
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   764
	DO_BINARY_OPER(  bool, <=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   765
	DO_BINARY_OPER(uint64, <=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   766
	DO_BINARY_OPER( int64, <=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   767
	DO_BINARY_OPER(real64, <=, bool);
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   768
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   769
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   770
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
   771
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   772
void *constant_folding_c::visit(ge_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   773
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   774
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   775
	DO_BINARY_OPER(  bool, >=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   776
	DO_BINARY_OPER(uint64, >=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   777
	DO_BINARY_OPER( int64, >=, bool);
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   778
	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
   779
	return NULL;
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   780
}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   781
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   782
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   783
void *constant_folding_c::visit(add_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   784
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   785
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   786
	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
   787
	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
   788
	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
   789
	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
   790
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   791
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   792
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   793
void *constant_folding_c::visit(sub_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   794
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   795
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   796
	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
   797
	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
   798
	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
   799
	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
   800
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   801
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   802
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   803
void *constant_folding_c::visit(mul_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   804
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   805
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   806
	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
   807
	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
   808
	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
   809
	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
   810
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   811
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   812
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   813
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   814
void *constant_folding_c::visit(div_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   815
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   816
	symbol->r_exp->accept(*this);
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   817
	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
   818
	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
   819
	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
   820
	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
   821
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   822
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   823
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   824
void *constant_folding_c::visit(mod_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   825
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   826
	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
   827
	/* 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
   828
	 *  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
   829
	 *
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   830
	 * 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
   831
	 * 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
   832
	 */
577
f578f14cb97f Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents: 576
diff changeset
   833
	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
   834
	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
   835
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   836
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   837
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
   838
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   839
void *constant_folding_c::visit(power_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   840
	symbol->l_exp->accept(*this);
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   841
	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
   842
	/* 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
   843
	 *       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
   844
	 *       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
   845
	 */
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   846
	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
   847
		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
   848
		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
   849
	}
0d1ab9e78574 Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents: 568
diff changeset
   850
	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
   851
		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
   852
		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
   853
	}
572
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   854
	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
   855
	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
   856
}
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   857
c353bc67bf91 Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents: 570
diff changeset
   858
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   859
void *constant_folding_c::visit(neg_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   860
	symbol->exp->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   861
	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
   862
	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
   863
	return NULL;
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   864
}
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   865
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
   866
e5deeb6d4d2f create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents: 566
diff changeset
   867
564
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   868
void *constant_folding_c::visit(not_expression_c *symbol) {
dabffc3086dc Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff changeset
   869
	symbol->exp->accept(*this);
575
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   870
	DO_UNARY_OPER(  bool, !, symbol->exp);
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   871
	DO_UNARY_OPER(uint64, ~, symbol->exp);
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   872
	return NULL;
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   873
}
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   874
a1b63f776535 cleaning up the code...
Mario de Sousa <msousa@fe.up.pt>
parents: 574
diff changeset
   875