# HG changeset patch # User Manuele Conti # Date 1338916649 -7200 # Node ID dabffc3086dce81eb0209e96dbc06b14ebb50d36 # Parent 61410284a9b46b2b3e437af2eaa39f5b1f6882a7 Start constant_folding class. diff -r 61410284a9b4 -r dabffc3086dc absyntax/absyntax.cc --- a/absyntax/absyntax.cc Tue Jun 05 11:10:12 2012 +0200 +++ b/absyntax/absyntax.cc Tue Jun 05 19:17:29 2012 +0200 @@ -62,6 +62,10 @@ this->last_column = last_column; this->last_order = last_order; this->datatype = NULL; + this->const_value_real = NULL; + this->const_value_integer = NULL; + this->const_value_uinteger = NULL; + this->const_value_bool = NULL; } diff -r 61410284a9b4 -r dabffc3086dc absyntax/absyntax.hh --- a/absyntax/absyntax.hh Tue Jun 05 11:10:12 2012 +0200 +++ b/absyntax/absyntax.hh Tue Jun 05 19:17:29 2012 +0200 @@ -48,9 +48,10 @@ #include // required for NULL #include +#include /* Forward declaration of the visitor interface - * dclared in the visitor.hh file + * declared in the visitor.hh file * We cannot include the visitor.hh file, as it will * include this same file first, as it too requires references * to the abstract syntax classes defined here. @@ -61,7 +62,6 @@ class symbol_c; // forward declaration - /* The base class of all symbols */ class symbol_c { @@ -83,7 +83,12 @@ * If it points to an object of type invalid_type_name_c, it means it is invalid. * Otherwise, it points to an object of the apropriate data type (e.g. int_type_name_c, bool_type_name_c, ...) */ - symbol_c *datatype; + symbol_c *datatype; + + double *const_value_real; + int64_t *const_value_integer; + uint64_t *const_value_uinteger; + bool *const_value_bool; public: @@ -302,6 +307,4 @@ #undef SYM_REF5 #undef SYM_REF6 - - #endif /* _ABSYNTAX_HH */ diff -r 61410284a9b4 -r dabffc3086dc absyntax_utils/absyntax_utils.cc --- a/absyntax_utils/absyntax_utils.cc Tue Jun 05 11:10:12 2012 +0200 +++ b/absyntax_utils/absyntax_utils.cc Tue Jun 05 19:17:29 2012 +0200 @@ -52,6 +52,7 @@ #include #include /* required for strlen() */ #include /* required for atoi() */ +#include /* required for errno */ #include "../util/symtable.hh" #include "../util/dsymtable.hh" @@ -115,6 +116,22 @@ return atoll(str.c_str()); } +uint64_t extract_hex_value(symbol_c *sym) { + std::string str = ""; + char *endptr; + hex_integer_c * hex_integer; + uint64_t ret; + + if ((hex_integer = dynamic_cast(sym)) == NULL) ERROR; + for(unsigned int i = 3; i < strlen(hex_integer->value); i++) + if (hex_integer->value[i] != '_') str += hex_integer->value[i]; + errno = 0; /* To distinguish success/failure after call */ + ret = strtol(str.c_str(), &endptr, 16); + if (errno != 0) ERROR; + + return ret; +} + /***********************************************************************/ diff -r 61410284a9b4 -r dabffc3086dc absyntax_utils/absyntax_utils.hh --- a/absyntax_utils/absyntax_utils.hh Tue Jun 05 11:10:12 2012 +0200 +++ b/absyntax_utils/absyntax_utils.hh Tue Jun 05 19:17:29 2012 +0200 @@ -57,6 +57,8 @@ /* extract the value of an integer from an integer_c object !! */ long long extract_integer_value(symbol_c *integer); + +uint64_t extract_hex_value(symbol_c *sym); /* A symbol table with all globally declared functions... */ extern function_declaration_c null_symbol1; diff -r 61410284a9b4 -r dabffc3086dc stage3/Makefile.am --- a/stage3/Makefile.am Tue Jun 05 11:10:12 2012 +0200 +++ b/stage3/Makefile.am Tue Jun 05 19:17:29 2012 +0200 @@ -10,5 +10,6 @@ print_datatypes_error.cc \ datatype_functions.cc \ lvalue_check.cc \ - array_range_check.cc + array_range_check.cc \ + constant_folding.cc diff -r 61410284a9b4 -r dabffc3086dc stage3/constant_folding.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage3/constant_folding.cc Tue Jun 05 19:17:29 2012 +0200 @@ -0,0 +1,494 @@ +/* + * matiec - a compiler for the programming languages defined in IEC 61131-3 + * + * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt) + * Copyright (C) 2012 Manuele Conti (conti.ma@alice.it) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * + * This code is made available on the understanding that it will not be + * used in safety-critical situations without a full and competent review. + */ + +/* + * An IEC 61131-3 compiler. + * + * Based on the + * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) + * + */ + + +/* Determine the value of an ST expression. + * Filling in all symbols the correct value. + * + * For example: + * 2 + 3 -> returns constant_value_integer = 5 + * 22.2 - 5.0 -> returns constant_value_real = 17.2 + * etc... + */ + +#include "constant_folding.hh" +#include +#include +#include /* required for pow function */ + +#define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order) ? (symbol1) : (symbol2)) +#define LAST_(symbol1, symbol2) (((symbol1)->last_order > (symbol2)->last_order) ? (symbol1) : (symbol2)) + +#define STAGE3_ERROR(error_level, symbol1, symbol2, ...) { \ + if (current_display_error_level >= error_level) { \ + fprintf(stderr, "%s:%d-%d..%d-%d: error: ", \ + FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\ + LAST_(symbol1,symbol2) ->last_line, LAST_(symbol1,symbol2) ->last_column);\ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + error_count++; \ + } \ +} + + +#define STAGE3_WARNING(symbol1, symbol2, ...) { \ + fprintf(stderr, "%s:%d-%d..%d-%d: warning: ", \ + FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\ + LAST_(symbol1,symbol2) ->last_line, LAST_(symbol1,symbol2) ->last_column);\ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + warning_found = true; \ +} + + + +#define DO_OPER(dtype)\ + (NULL != symbol->r_exp->const_value_##dtype ) && \ + (NULL != symbol->l_exp->const_value_##dtype ) + + +#define CHECK_OVERFLOW_SUM(a, b, type)\ + ((((std::numeric_limits< type >::max() - a) < (b)) ? 1 : 0) || \ + (((std::numeric_limits< type >::min() + a) > (b)) ? 1 : 0)) + +#define CHECK_OVERFLOW_SUB(a, b, type)\ + ((((std::numeric_limits< type >::max() - a) < (-b)) ? 1 : 0) || \ + (((std::numeric_limits< type >::min() + a) > (-b)) ? 1 : 0)) + + + + + +constant_folding_c::constant_folding_c(symbol_c *symbol) { + error_count = 0; + current_display_error_level = 0; +} + +constant_folding_c::~constant_folding_c(void) { +} + +int constant_folding_c::get_error_count() { + return error_count; +} + + +/*********************/ +/* B 1.2 - Constants */ +/*********************/ +/******************************/ +/* B 1.2.1 - Numeric Literals */ +/******************************/ +void *constant_folding_c::visit(real_c *symbol) { + double *real_value; + + real_value = (double *)malloc(sizeof(double)); + sscanf(symbol->value, "%lf", real_value); + symbol->const_value_real = real_value; + + return NULL; +} + +void *constant_folding_c::visit(integer_c *symbol) { + int64_t *integer_value; + + integer_value = (int64_t *)malloc(sizeof(int64_t)); + *integer_value = extract_integer_value(symbol); + symbol->const_value_integer = integer_value; + + return NULL; +} + +void *constant_folding_c::visit(neg_real_c *symbol) { + double *real_value; + + real_value = (double *)malloc(sizeof(double)); + symbol->exp->accept(*this); + if (NULL == symbol->exp->const_value_real) + ERROR; + *real_value = - *(symbol->exp->const_value_real); + symbol->const_value_real = real_value; + + return NULL; +} + +void *constant_folding_c::visit(neg_integer_c *symbol) { + int64_t *integer_value; + + integer_value = (int64_t *)malloc(sizeof(int64_t)); + *integer_value = extract_integer_value(symbol); + symbol->const_value_integer = integer_value; + + return NULL; +} + +void *constant_folding_c::visit(binary_integer_c *symbol) { + + return NULL; +} + +void *constant_folding_c::visit(octal_integer_c *symbol) { + + return NULL; +} + +void *constant_folding_c::visit(hex_integer_c *symbol) { + int64_t *integer_value; + + integer_value = (int64_t *)malloc(sizeof(int64_t)); + *integer_value = extract_hex_value(symbol); + + return NULL; +} + +void *constant_folding_c::visit(integer_literal_c *symbol) { + int64_t *integer_value; + + symbol->value->accept(*this); + if (NULL == symbol->value->const_value_integer) ERROR; + *(symbol->const_value_integer) = *(symbol->value->const_value_integer); + integer_value = (int64_t *)malloc(sizeof(int64_t)); + + return NULL; +} + +void *constant_folding_c::visit(real_literal_c *symbol) { + double *real_value; + + real_value = (double *)malloc(sizeof(double)); + symbol->value->accept(*this); + if (NULL == symbol->value->const_value_real) + ERROR; + *real_value = *(symbol->value->const_value_real); + symbol->const_value_real = real_value; + + return NULL; +} + +void *constant_folding_c::visit(bit_string_literal_c *symbol) { + + return NULL; +} + +void *constant_folding_c::visit(boolean_literal_c *symbol) { + symbol->value->accept(*this); + if (NULL == symbol->value->const_value_bool) ERROR; + symbol->const_value_bool = (bool *)malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->value->const_value_bool); + + return NULL; +} + +void *constant_folding_c::visit(boolean_true_c *symbol) { + symbol->const_value_bool = (bool *)malloc(sizeof(bool)); + *(symbol->const_value_bool) = true; + + return NULL; +} + +void *constant_folding_c::visit(boolean_false_c *symbol) { + symbol->const_value_bool = (bool *)malloc(sizeof(bool)); + *(symbol->const_value_bool) = false; + + return NULL; +} + +/***************************************/ +/* B.3 - Language ST (Structured Text) */ +/***************************************/ +/***********************/ +/* B 3.1 - Expressions */ +/***********************/ +void *constant_folding_c::visit(or_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(bool)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_bool) || *(symbol->r_exp->const_value_bool); + } + if (DO_OPER(integer)) { + symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); + *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) | *(symbol->r_exp->const_value_integer); + } + + return NULL; +} + +void *constant_folding_c::visit(xor_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(integer)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) ^ *(symbol->r_exp->const_value_integer); + } + + return NULL; +} + +void *constant_folding_c::visit(and_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(bool)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_bool) && *(symbol->r_exp->const_value_bool); + } + if (DO_OPER(integer)) { + symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) & *(symbol->r_exp->const_value_integer); + } + + return NULL; +} + +void *constant_folding_c::visit(equ_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(bool)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_bool) == *(symbol->r_exp->const_value_bool); + } + if (DO_OPER(integer)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) == *(symbol->r_exp->const_value_integer); + } + if (DO_OPER(real)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) == *(symbol->r_exp->const_value_real); + } + + return NULL; +} + +void *constant_folding_c::visit(notequ_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(bool)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_bool) != *(symbol->r_exp->const_value_bool); + } + if (DO_OPER(integer)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) != *(symbol->r_exp->const_value_integer); + } + if (DO_OPER(real)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) != *(symbol->r_exp->const_value_real); + } + + return NULL; +} + +void *constant_folding_c::visit(lt_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(integer)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) < *(symbol->r_exp->const_value_integer); + } + if (DO_OPER(real)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) < *(symbol->r_exp->const_value_real); + } + + return NULL; +} + +void *constant_folding_c::visit(gt_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(integer)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) > *(symbol->r_exp->const_value_integer); + } + if (DO_OPER(real)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) > *(symbol->r_exp->const_value_real); + } + + return NULL; +} + +void *constant_folding_c::visit(le_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(integer)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) <= *(symbol->r_exp->const_value_integer); + } + if (DO_OPER(real)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) <= *(symbol->r_exp->const_value_real); + } + + return NULL; +} + +void *constant_folding_c::visit(ge_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(integer)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) >= *(symbol->r_exp->const_value_integer); + } + if (DO_OPER(real)) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) >= *(symbol->r_exp->const_value_real); + } + + return NULL; +} + +void *constant_folding_c::visit(add_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(integer)) { + if (CHECK_OVERFLOW_SUM(*(symbol->l_exp->const_value_integer), *(symbol->r_exp->const_value_integer), int64_t)) + STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); + symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); + *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) + *(symbol->r_exp->const_value_integer); + } + if (DO_OPER(real)) { + if (CHECK_OVERFLOW_SUM(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_real), double)) + STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); + symbol->const_value_real = (double*) malloc(sizeof(double)); + *(symbol->const_value_real) = *(symbol->l_exp->const_value_real) + *(symbol->r_exp->const_value_real); + } + + return NULL; +} + +void *constant_folding_c::visit(sub_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(integer)) { + if (CHECK_OVERFLOW_SUB(*(symbol->l_exp->const_value_integer), *(symbol->r_exp->const_value_integer), int64_t)) + STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); + symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); + *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) - *(symbol->r_exp->const_value_integer); + } + if (DO_OPER(real)) { + if (CHECK_OVERFLOW_SUB(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_real), double)) + STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); + symbol->const_value_real = (double*) malloc(sizeof(double)); + *(symbol->const_value_real) = *(symbol->l_exp->const_value_real) - *(symbol->r_exp->const_value_real); + } + + return NULL; +} + +void *constant_folding_c::visit(mul_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(integer)) { + symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); + if ((*(symbol->l_exp->const_value_integer) == 0) || + (*(symbol->r_exp->const_value_integer) == 0)) { + *(symbol->const_value_integer) = 0; + return NULL; + } + + *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) * *(symbol->r_exp->const_value_integer); + } + if (DO_OPER(real)) { + symbol->const_value_real = (double*) malloc(sizeof(double)); + *(symbol->const_value_real) = *(symbol->l_exp->const_value_real) * *(symbol->r_exp->const_value_real); + } + + return NULL; +} + +void *constant_folding_c::visit(div_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(integer)) { + if (*(symbol->r_exp->const_value_integer) == 0) + STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression."); + symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); + *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) / *(symbol->r_exp->const_value_integer); + } + if (DO_OPER(real)) { + if (*(symbol->r_exp->const_value_real) == 0) + STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression."); + symbol->const_value_real = (double*) malloc(sizeof(double)); + *(symbol->const_value_real) = *(symbol->l_exp->const_value_real) / *(symbol->r_exp->const_value_real); + } + + return NULL; +} + +void *constant_folding_c::visit(mod_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if (DO_OPER(integer)) { + if (*(symbol->r_exp->const_value_integer) == 0) + STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression."); + symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); + *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) % *(symbol->r_exp->const_value_integer); + } + + return NULL; +} + +void *constant_folding_c::visit(power_expression_c *symbol) { + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if ((NULL != symbol->l_exp->const_value_real) && (NULL != symbol->r_exp->const_value_integer)) { + symbol->const_value_real = (double*) malloc(sizeof(double)); + *(symbol->const_value_real) = pow(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_integer)); + } + + return NULL; +} +void *constant_folding_c::visit(neg_expression_c *symbol) { + symbol->exp->accept(*this); + if (NULL != symbol->exp->const_value_integer) { + symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); + *(symbol->const_value_integer) = - *(symbol->exp->const_value_integer); + } + if (NULL != symbol->exp->const_value_real) { + symbol->const_value_real = (double*) malloc(sizeof(double)); + *(symbol->const_value_real) = - *(symbol->exp->const_value_real); + } + return NULL; +} + +void *constant_folding_c::visit(not_expression_c *symbol) { + symbol->exp->accept(*this); + if (NULL != symbol->exp->const_value_bool) { + symbol->const_value_bool = (bool*) malloc(sizeof(bool)); + *(symbol->const_value_bool) = !*(symbol->exp->const_value_bool); + } + + return NULL; +} + + + diff -r 61410284a9b4 -r dabffc3086dc stage3/constant_folding.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stage3/constant_folding.hh Tue Jun 05 19:17:29 2012 +0200 @@ -0,0 +1,103 @@ +/* + * matiec - a compiler for the programming languages defined in IEC 61131-3 + * + * Copyright (C) 2009-2012 Mario de Sousa (msousa@fe.up.pt) + * Copyright (C) 2012 Manuele Conti (conti.ma@alice.it) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * + * This code is made available on the understanding that it will not be + * used in safety-critical situations without a full and competent review. + */ + +/* + * An IEC 61131-3 compiler. + * + * Based on the + * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) + * + */ + +/* Determine the data type of an constant expression. + * A reference to the relevant type definition is returned. + * + * For example: + * 2 + 3 -> returns reference + * 22.2 - 5 -> returns reference + * etc... + */ + +#include +#include "../absyntax_utils/absyntax_utils.hh" + + + +class constant_folding_c : public iterator_visitor_c { + search_varfb_instance_type_c *search_varfb_instance_type; + search_base_type_c search_base_type; + int error_count; + int current_display_error_level; + +public: + constant_folding_c(symbol_c *symbol = NULL); + virtual ~constant_folding_c(void); + int get_error_count(); + +private: + /*********************/ + /* B 1.2 - Constants */ + /*********************/ + /******************************/ + /* B 1.2.1 - Numeric Literals */ + /******************************/ + void *visit(real_c *symbol); + void *visit(integer_c *symbol); + void *visit(neg_real_c *symbol); + void *visit(neg_integer_c *symbol); + void *visit(binary_integer_c *symbol); + void *visit(octal_integer_c *symbol); + void *visit(hex_integer_c *symbol); + void *visit(integer_literal_c *symbol); + void *visit(real_literal_c *symbol); + void *visit(bit_string_literal_c *symbol); + void *visit(boolean_literal_c *symbol); + void *visit(boolean_true_c *symbol); + void *visit(boolean_false_c *symbol); + + /***************************************/ + /* B.3 - Language ST (Structured Text) */ + /***************************************/ + /***********************/ + /* B 3.1 - Expressions */ + /***********************/ + void *visit(or_expression_c *symbol); + void *visit(xor_expression_c *symbol); + void *visit(and_expression_c *symbol); + void *visit(equ_expression_c *symbol); + void *visit(notequ_expression_c *symbol); + void *visit(lt_expression_c *symbol); + void *visit(gt_expression_c *symbol); + void *visit(le_expression_c *symbol); + void *visit(ge_expression_c *symbol); + void *visit(add_expression_c *symbol); + void *visit(sub_expression_c *symbol); + void *visit(mul_expression_c *symbol); + void *visit(div_expression_c *symbol); + void *visit(mod_expression_c *symbol); + void *visit(power_expression_c *symbol); + void *visit(neg_expression_c *symbol); + void *visit(not_expression_c *symbol); +}; + diff -r 61410284a9b4 -r dabffc3086dc stage3/stage3.cc --- a/stage3/stage3.cc Tue Jun 05 11:10:12 2012 +0200 +++ b/stage3/stage3.cc Tue Jun 05 19:17:29 2012 +0200 @@ -40,12 +40,18 @@ #include "print_datatypes_error.hh" #include "lvalue_check.hh" #include "array_range_check.hh" +#include "constant_folding.hh" +static int constant_check(symbol_c *tree_root){ + constant_folding_c constant_folding(tree_root); + tree_root->accept(constant_folding); + return constant_folding.get_error_count(); +} static int flow_control_analysis(symbol_c *tree_root){ - flow_control_analysis_c flow_control_analysis(tree_root); - tree_root->accept(flow_control_analysis); - return 0; + flow_control_analysis_c flow_control_analysis(tree_root); + tree_root->accept(flow_control_analysis); + return 0; } @@ -81,6 +87,7 @@ int stage3(symbol_c *tree_root){ int error_count = 0; + error_count += constant_check(tree_root); error_count += flow_control_analysis(tree_root); error_count += type_safety(tree_root); error_count += lvalue_check(tree_root);