stage3/constant_folding.cc
changeset 640 ffa02cf2b335
parent 621 e3616f6b6959
child 643 1cc0e1ca2aad
equal deleted inserted replaced
624:c2546c6e0cfa 640:ffa02cf2b335
    29  * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
    29  * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
    30  *
    30  *
    31  */
    31  */
    32 
    32 
    33 
    33 
       
    34 
       
    35 /* TODO: 
       
    36  *         - Add support for comparison (= and !=) of enumeration literals!
       
    37  *              We will need to add another const_value entry to the symbol_c, containing the 
       
    38  *              possible enumeration value of the enum constant!
       
    39  *              Doing this will allow us to more easily implement a constant_propagation_c later on!
       
    40  *
       
    41  *         - Add support for comparison (= and !=) of the exact same variable
       
    42  *                (e.g. if (int_v = int_v) then ...)
       
    43  */
    34 
    44 
    35 
    45 
    36 
    46 
    37 /* Do constant folding...
    47 /* Do constant folding...
    38  *
    48  *
   213    *  that may be added to the standard library in the future).
   223    *  that may be added to the standard library in the future).
   214    * We actually create several of each, and let the compiler choose which is the correct one,
   224    * We actually create several of each, and let the compiler choose which is the correct one,
   215    * by having it resolve the call to the overloaded function. For the C++ compiler to be able
   225    * by having it resolve the call to the overloaded function. For the C++ compiler to be able
   216    * to resolve this ambiguity, we need to add a dummy parameter to each function!
   226    * to resolve this ambiguity, we need to add a dummy parameter to each function!
   217    *
   227    *
   218    * TODO: support platforms in which int64_t is mapped onto int !! Is this really needed?
   228    * TODO: support platforms (where the compiler will run) in which int64_t is mapped onto int !!
       
   229    *       Is this really needed?
       
   230    *       Currently, when trying to compile matiec on sych a platform, the C++ compiler will not
       
   231    *       find any apropriate matiec_strtoint64() to call, so matiec will not be able to be compiled.
       
   232    *       If you need this, you are welcome to fix it yourself...
   219    */
   233    */
   220 static  int64_t matiec_strtoint64 (         long      int *dummy, const char *nptr, char **endptr, int base) {return strtol  (nptr, endptr, base);}
   234 static  int64_t matiec_strtoint64 (         long      int *dummy, const char *nptr, char **endptr, int base) {return strtol  (nptr, endptr, base);}
   221 static  int64_t matiec_strtoint64 (         long long int *dummy, const char *nptr, char **endptr, int base) {return strtoll (nptr, endptr, base);}
   235 static  int64_t matiec_strtoint64 (         long long int *dummy, const char *nptr, char **endptr, int base) {return strtoll (nptr, endptr, base);}
   222   
   236   
   223 static uint64_t matiec_strtouint64(unsigned long      int *dummy, const char *nptr, char **endptr, int base) {return strtoul (nptr, endptr, base);}
   237 static uint64_t matiec_strtouint64(unsigned long      int *dummy, const char *nptr, char **endptr, int base) {return strtoul (nptr, endptr, base);}
   542 
   556 
   543 
   557 
   544 /* unary negation (multiply by -1) */
   558 /* unary negation (multiply by -1) */
   545 static void *handle_neg(symbol_c *symbol, symbol_c *oper) {
   559 static void *handle_neg(symbol_c *symbol, symbol_c *oper) {
   546 	DO_UNARY_OPER( int64, -, oper);	CHECK_OVERFLOW_int64_NEG(symbol, oper);
   560 	DO_UNARY_OPER( int64, -, oper);	CHECK_OVERFLOW_int64_NEG(symbol, oper);
       
   561 	/*
       
   562 	 * NOTE : The syntax:   uint_v := -<INT_MIN>  may occur inside a neg_expression_c, but would always
       
   563 	 *        result in a data type error (in-> INT, out -> UINT). So, although we could handle it here, 
       
   564 	 *        it is not really necessary as it will later be caught by the data type checking classes.
       
   565 	 */
   547 	DO_UNARY_OPER(real64, -, oper);	CHECK_OVERFLOW_real64(symbol);
   566 	DO_UNARY_OPER(real64, -, oper);	CHECK_OVERFLOW_real64(symbol);
   548 	return NULL;
   567 	return NULL;
   549 }
   568 }
   550 
   569 
   551 
   570 
   753 	 */
   772 	 */
   754 	// if (INT64_MIN == -INT64_MAX - 1) // We do not really need to check that the platform uses two's complement
   773 	// if (INT64_MIN == -INT64_MAX - 1) // We do not really need to check that the platform uses two's complement
   755 	if (VALID_CVALUE(uint64, symbol->exp) && (GET_CVALUE(uint64, symbol->exp) == (uint64_t)INT64_MAX+1)) {
   774 	if (VALID_CVALUE(uint64, symbol->exp) && (GET_CVALUE(uint64, symbol->exp) == (uint64_t)INT64_MAX+1)) {
   756 		SET_CVALUE(int64, symbol, INT64_MIN);
   775 		SET_CVALUE(int64, symbol, INT64_MIN);
   757 	}
   776 	}
       
   777 	/* NOTE 3: The standard allows considers the following strange syntax correct:
       
   778 	 *            int_v = ----------42;
       
   779 	 *         However, it will be parsed as multiple neg_expression_c, with a single final neg_integer_c.
       
   780 	 *         So, when parsing a neg_integer_c, we are guaranteed to always have a positive value in symbol->exp
       
   781 	 *         --> Conclusion: 
       
   782 	 *         We do not need to handle the situation where we are negating the INT_MIN value, whose
       
   783 	 *         result can only be stored inside an UINT (remember that INT_MIN is < 0 !!).
       
   784 	 *
       
   785 	 * NOTE 4: The syntax:   uint_v := -<INT_MIN>  may occur inside a neg_expression_c, but would always
       
   786 	 *         result in a data type error. So, although we could handle it here, it is not really
       
   787 	 *         necessary as it will later be caught by the data type checking classes.
       
   788 	 */
   758 	return NULL;
   789 	return NULL;
   759 }
   790 }
   760 
   791 
   761 
   792 
   762 void *constant_folding_c::visit(binary_integer_c *symbol) {
   793 void *constant_folding_c::visit(binary_integer_c *symbol) {