stage3/constant_folding.cc
changeset 984 634269b0f104
parent 983 ead554e12195
child 985 837c6532a9b8
equal deleted inserted replaced
983:ead554e12195 984:634269b0f104
   589 /***        Functions to execute operations on the const values      ***/
   589 /***        Functions to execute operations on the const values      ***/
   590 /***********************************************************************/
   590 /***********************************************************************/
   591 /***********************************************************************/
   591 /***********************************************************************/
   592 /***********************************************************************/
   592 /***********************************************************************/
   593 
   593 
       
   594 
   594 /* static void *handle_cmp(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2, OPERATION) */
   595 /* static void *handle_cmp(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2, OPERATION) */
   595 #define handle_cmp(symbol, oper1, oper2, operation) {               \
   596 #define handle_cmp(symbol, oper1, oper2, operation) {               \
   596 	if ((NULL == oper1) || (NULL == oper2)) return NULL;        \
   597 	if ((NULL == oper1) || (NULL == oper2)) return NULL;        \
   597 	DO_BINARY_OPER(  bool, operation, bool, oper1, oper2);     \
   598 	DO_BINARY_OPER(  bool, operation, bool, oper1, oper2);     \
   598 	DO_BINARY_OPER(uint64, operation, bool, oper1, oper2);     \
   599 	DO_BINARY_OPER(uint64, operation, bool, oper1, oper2);     \
   722 		SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, oper1), GET_CVALUE(uint64, oper2)));
   723 		SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, oper1), GET_CVALUE(uint64, oper2)));
   723 	CHECK_OVERFLOW_real64(symbol);
   724 	CHECK_OVERFLOW_real64(symbol);
   724 	return NULL;
   725 	return NULL;
   725 }
   726 }
   726 
   727 
   727 static constant_folding_c::map_values_t inner_left_join_values(constant_folding_c::map_values_t m1, constant_folding_c::map_values_t m2) {
   728 
   728 	constant_folding_c::map_values_t::const_iterator itr;
   729 /***********************************************************************/
   729 	constant_folding_c::map_values_t ret;
   730 /***********************************************************************/
       
   731 /***********************************************************************/
       
   732 /***        Helper functions for handling IL instruction lists.      ***/
       
   733 /***********************************************************************/
       
   734 /***********************************************************************/
       
   735 /***********************************************************************/
       
   736 
       
   737 
       
   738 /* If the cvalues of all the prev_il_intructions have the same VALID value, then set the local cvalue to that value, otherwise, set it to NONCONST! */
       
   739 #define intersect_prev_CVALUE_(dtype, symbol) {                                                                   \
       
   740 	symbol->const_value._##dtype = symbol->prev_il_instruction[0]->const_value._##dtype;                      \
       
   741 	for (unsigned int i = 1; i < symbol->prev_il_instruction.size(); i++) {                                   \
       
   742 		if (!ISEQUAL_CVALUE(dtype, symbol, symbol->prev_il_instruction[i]))                               \
       
   743 			{SET_NONCONST(dtype, symbol); break;}                                                     \
       
   744 	}                                                                                                         \
       
   745 }
       
   746 
       
   747 static void intersect_prev_cvalues(il_instruction_c *symbol) {
       
   748 	if (symbol->prev_il_instruction.empty())
       
   749 		return;
       
   750 	intersect_prev_CVALUE_(real64, symbol);
       
   751 	intersect_prev_CVALUE_(uint64, symbol);
       
   752 	intersect_prev_CVALUE_( int64, symbol);
       
   753 	intersect_prev_CVALUE_(  bool, symbol);
       
   754 }
       
   755 
       
   756 
       
   757 
       
   758 /***********************************************************************/
       
   759 /***********************************************************************/
       
   760 /***********************************************************************/
       
   761 /***        The constant_folding_c                                   ***/
       
   762 /***********************************************************************/
       
   763 /***********************************************************************/
       
   764 /***********************************************************************/
       
   765 
       
   766 
       
   767 constant_folding_c::constant_folding_c(symbol_c *symbol) {
       
   768     error_count = 0;
       
   769     warning_found = false;
       
   770     current_display_error_level = 0;
       
   771     il_operand = NULL;
       
   772     prev_il_instruction = NULL;
       
   773     
       
   774     /* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */
       
   775     symbol_c null_symbol;
       
   776     if (! (std::numeric_limits<real64_t>::is_iec559) )
       
   777         STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 60559 floating point numbers. "
       
   778                                                    "Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals "
       
   779                                                    "(i.e. constant folding) may themselves be erroneous, although are most probably correct."
       
   780                                                    "However, more likely is the possible existance of overflow/underflow errors that are not detected.");
       
   781 }
       
   782 
       
   783 
       
   784 constant_folding_c::~constant_folding_c(void) {
       
   785 }
       
   786 
       
   787 
       
   788 int constant_folding_c::get_error_count() {
       
   789 	return error_count;
       
   790 }
       
   791 
       
   792 
       
   793 
       
   794 /*********************/
       
   795 /* B 1.2 - Constants */
       
   796 /*********************/
       
   797 /******************************/
       
   798 /* B 1.2.1 - Numeric Literals */
       
   799 /******************************/
       
   800 void *constant_folding_c::visit(real_c *symbol) {
       
   801 	bool overflow;
       
   802 	SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow));
       
   803 	if (overflow) SET_OVFLOW(real64, symbol);
       
   804 	return NULL;
       
   805 }
       
   806 
       
   807 
       
   808 void *constant_folding_c::visit(integer_c *symbol) {
       
   809 	bool overflow;
       
   810 	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
       
   811 	if (overflow) SET_OVFLOW(int64, symbol);
       
   812 	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
       
   813 	if (overflow) SET_OVFLOW(uint64, symbol);
       
   814 	return NULL;
       
   815 }
       
   816 
       
   817 
       
   818 void *constant_folding_c::visit(neg_real_c *symbol) {
       
   819 	symbol->exp->accept(*this);
       
   820 	DO_UNARY_OPER(real64, -, symbol->exp); CHECK_OVERFLOW_real64(symbol);
       
   821 	if (IS_OVFLOW(real64, symbol->exp)) SET_OVFLOW(real64, symbol);
       
   822 	return NULL;
       
   823 }
       
   824 
       
   825 
       
   826 
       
   827 /* | '-' integer	{$$ = new neg_integer_c($2, locloc(@$));} */
       
   828 void *constant_folding_c::visit(neg_integer_c *symbol) {
       
   829 	symbol->exp->accept(*this);
       
   830 	/* Note that due to syntax restrictions, the value of symbol->exp will always be positive. 
       
   831 	 * However, the following code does not depend on that restriction.
       
   832 	 */
       
   833 	/* The remainder of the code (for example, data type checking) considers the neg_integer_c as a leaf of the
       
   834 	 * abstract syntax tree, and therefore simply ignores the values of neg_integer_c->exp.
       
   835 	 * For this reason only, and in only this situation, we must guarantee that any 'overflow' situation in 
       
   836 	 * the cvalue of neg_integer_c->exp is also reflected back to this neg_integer_c symbol.
       
   837 	 * For the rest of the code we do NOT do this, as it would gurantee that a single overflow deep inside
       
   838 	 * an expression would imply that the expression itself would also be set to 'overflow' condition.
       
   839 	 * This in turn would then have the compiler produce a whole load of error messages where they are not wanted!
       
   840 	 */
       
   841 	DO_UNARY_OPER(uint64, -, symbol->exp); CHECK_OVERFLOW_uint64_NEG(symbol, symbol->exp);  /* handle the uintv := -0 situation */
       
   842 	if (IS_OVFLOW(uint64, symbol->exp)) SET_OVFLOW(uint64, symbol);
       
   843 	DO_UNARY_OPER( int64, -, symbol->exp); CHECK_OVERFLOW_int64_NEG (symbol, symbol->exp);
       
   844 	if (IS_OVFLOW( int64, symbol->exp)) SET_OVFLOW( int64, symbol);
       
   845 	/* NOTE 1: INT64_MIN = -(INT64_MAX + 1)   ---> assuming two's complement representation!!!
       
   846 	 * NOTE 2: if the user happens to want INT_MIN, that value will first be parsed as a positive integer, before being negated here.
       
   847 	 * However, the positive value cannot be stored inside an int64! So, in this case, we will get the value from the uint64 cvalue.
       
   848 	 *
       
   849 	 * This same situation is usually considered an overflow (check handle_neg() function). However, here we have a special
       
   850 	 * situation. If we do not allow this, then the user would never the able to use the following code:
       
   851 	 *  VAR v : LINT; END_VAR
       
   852 	 *    v := -9223372036854775809 ; (* - |INT64_MIN| == INT64_MIN *)
       
   853 	 */
       
   854 	// if (INT64_MIN == -INT64_MAX - 1) // We do not really need to check that the platform uses two's complement
       
   855 	if (VALID_CVALUE(uint64, symbol->exp) && (GET_CVALUE(uint64, symbol->exp) == (uint64_t)INT64_MAX+1)) {
       
   856 		SET_CVALUE(int64, symbol, INT64_MIN);
       
   857 	}
       
   858 	return NULL;
       
   859 }
       
   860 
       
   861 
       
   862 void *constant_folding_c::visit(binary_integer_c *symbol) {
       
   863 	bool overflow;
       
   864 	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
       
   865 	if (overflow) SET_OVFLOW(int64, symbol);
       
   866 	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
       
   867 	if (overflow) SET_OVFLOW(uint64, symbol);
       
   868 	return NULL;
       
   869 }
       
   870 
       
   871 
       
   872 void *constant_folding_c::visit(octal_integer_c *symbol) {
       
   873 	bool overflow;
       
   874 	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
       
   875 	if (overflow) SET_OVFLOW(int64, symbol);
       
   876 	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
       
   877 	if (overflow) SET_OVFLOW(uint64, symbol);
       
   878 	return NULL;
       
   879 }
       
   880 
       
   881 
       
   882 void *constant_folding_c::visit(hex_integer_c *symbol) {
       
   883 	bool overflow;
       
   884 	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
       
   885 	if (overflow) SET_OVFLOW(int64, symbol);
       
   886 	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
       
   887 	if (overflow) SET_OVFLOW(uint64, symbol);
       
   888 	return NULL;
       
   889 }
       
   890 
       
   891 
       
   892 /*
       
   893 integer_literal:
       
   894   integer_type_name '#' signed_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
       
   895 | integer_type_name '#' binary_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
       
   896 | integer_type_name '#' octal_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
       
   897 | integer_type_name '#' hex_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
       
   898 */
       
   899 // SYM_REF2(integer_literal_c, type, value)
       
   900 void *constant_folding_c::visit(integer_literal_c *symbol) {
       
   901 	symbol->value->accept(*this);
       
   902 	DO_UNARY_OPER( int64, /* none */, symbol->value);
       
   903 	DO_UNARY_OPER(uint64, /* none */, symbol->value);
       
   904 	return NULL;
       
   905 }
       
   906 
       
   907 
       
   908 void *constant_folding_c::visit(real_literal_c *symbol) {
       
   909 	symbol->value->accept(*this);
       
   910 	DO_UNARY_OPER(real64, /* none */, symbol->value);
       
   911 	return NULL;
       
   912 }
       
   913 
       
   914 
       
   915 void *constant_folding_c::visit(bit_string_literal_c *symbol) {
       
   916 	return NULL;
       
   917 }
       
   918 
       
   919 
       
   920 void *constant_folding_c::visit(boolean_literal_c *symbol) {
       
   921 	symbol->value->accept(*this);
       
   922 	DO_UNARY_OPER(bool, /* none */, symbol->value);
       
   923 	return NULL;
       
   924 }
       
   925 
       
   926 
       
   927 void *constant_folding_c::visit(boolean_true_c *symbol) {
       
   928 	SET_CVALUE(bool, symbol, true);
       
   929 	return NULL;
       
   930 }
       
   931 
       
   932 
       
   933 void *constant_folding_c::visit(boolean_false_c *symbol) {
       
   934 	SET_CVALUE(bool, symbol, false);
       
   935 	return NULL;
       
   936 }
       
   937 
       
   938 /************************/
       
   939 /* B 1.2.3.1 - Duration */
       
   940 /********* **************/
       
   941 void *constant_folding_c::visit(fixed_point_c *symbol) {
       
   942 	bool overflow;
       
   943 	SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow));
       
   944 	if (overflow) SET_OVFLOW(real64, symbol);
       
   945 	return NULL;
       
   946 }
       
   947 
       
   948 
       
   949 
       
   950 /****************************************/
       
   951 /* B.2 - Language IL (Instruction List) */
       
   952 /****************************************/
       
   953 /***********************************/
       
   954 /* B 2.1 Instructions and Operands */
       
   955 /***********************************/
       
   956 /* Not needed, since we inherit from iterator_visitor_c */
       
   957 /*| instruction_list il_instruction */
       
   958 // SYM_LIST(instruction_list_c)
       
   959 // void *constant_folding_c::visit(instruction_list_c *symbol) {}
       
   960 
       
   961 /* | label ':' [il_incomplete_instruction] eol_list */
       
   962 // SYM_REF2(il_instruction_c, label, il_instruction)
       
   963 // void *visit(instruction_list_c *symbol);
       
   964 void *constant_folding_c::visit(il_instruction_c *symbol) {
       
   965 	if (NULL == symbol->il_instruction) {
       
   966 		/* This empty/null il_instruction does not change the value of the current/default IL variable.
       
   967 		 * So it inherits the candidate_datatypes from it's previous IL instructions!
       
   968 		 */
       
   969 		intersect_prev_cvalues(symbol);
       
   970 	} else {
       
   971 		il_instruction_c fake_prev_il_instruction = *symbol;
       
   972 		intersect_prev_cvalues(&fake_prev_il_instruction);
       
   973 
       
   974 		if (symbol->prev_il_instruction.size() == 0)  prev_il_instruction = NULL;
       
   975 		else                                          prev_il_instruction = &fake_prev_il_instruction;
       
   976 		symbol->il_instruction->accept(*this);
       
   977 		prev_il_instruction = NULL;
       
   978 
       
   979 		/* This object has (inherits) the same cvalues as the il_instruction */
       
   980 		symbol->const_value = symbol->il_instruction->const_value;
       
   981 	}
       
   982 
       
   983 	return NULL;
       
   984 }
       
   985 
       
   986 
       
   987 void *constant_folding_c::visit(il_simple_operation_c *symbol) {
       
   988 	/* determine the cvalue of the operand */
       
   989 	if (NULL != symbol->il_operand) {
       
   990 		symbol->il_operand->accept(*this);
       
   991 	}
       
   992 	/* determine the cvalue resulting from executing the il_operator... */
       
   993 	il_operand = symbol->il_operand;
       
   994 	symbol->il_simple_operator->accept(*this);
       
   995 	il_operand = NULL;
       
   996 	/* This object has (inherits) the same cvalues as the il_instruction */
       
   997 	symbol->const_value = symbol->il_simple_operator->const_value;
       
   998 	return NULL;
       
   999 }
       
  1000 
       
  1001 
       
  1002 /* TODO: handle function invocations... */
       
  1003 /* | function_name [il_operand_list] */
       
  1004 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */
       
  1005 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
       
  1006 // void *constant_folding_c::visit(il_function_call_c *symbol) {}
       
  1007 
       
  1008 
       
  1009 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
       
  1010 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
       
  1011 void *constant_folding_c::visit(il_expression_c *symbol) {
       
  1012   symbol_c *prev_il_instruction_backup = prev_il_instruction;
       
  1013   
       
  1014   /* Stage2 will insert an artificial (and equivalent) LD <il_operand> to the simple_instr_list if necessary. We can therefore ignore the 'il_operand' entry! */
       
  1015   // if (NULL != symbol->il_operand)
       
  1016   //   symbol->il_operand->accept(*this);
       
  1017 
       
  1018   if(symbol->simple_instr_list != NULL)
       
  1019     symbol->simple_instr_list->accept(*this);
       
  1020 
       
  1021   /* Now do the operation,  */
       
  1022   il_operand = symbol->simple_instr_list;
       
  1023   prev_il_instruction = prev_il_instruction_backup;
       
  1024   symbol->il_expr_operator->accept(*this);
       
  1025   il_operand = NULL;
       
  1026   
       
  1027   /* This object has (inherits) the same cvalues as the il_instruction */
       
  1028   symbol->const_value = symbol->il_expr_operator->const_value;
       
  1029   
       
  1030   /* Since stage2 will insert an artificial (and equivalent) LD <il_operand> to the simple_instr_list when an 'il_operand' exists, we know
       
  1031    * that if (symbol->il_operand != NULL), then the first IL instruction in the simple_instr_list will be the equivalent and artificial
       
  1032    * 'LD <il_operand>' IL instruction.
       
  1033    * Just to be cosistent, we will copy the constant info back into the il_operand, even though this should not be necessary!
       
  1034    */
       
  1035   if ((NULL != symbol->il_operand) && ((NULL == symbol->simple_instr_list) || (0 == ((list_c *)symbol->simple_instr_list)->n))) ERROR; // stage2 is not behaving as we expect it to!
       
  1036   if  (NULL != symbol->il_operand)
       
  1037     symbol->il_operand->const_value = ((list_c *)symbol->simple_instr_list)->elements[0]->const_value;
       
  1038 
       
  1039   return NULL;
       
  1040 }
       
  1041 
       
  1042 
       
  1043 
       
  1044 void *constant_folding_c::visit(il_jump_operation_c *symbol) {
       
  1045   /* recursive call to fill const values... */
       
  1046   il_operand = NULL;
       
  1047   symbol->il_jump_operator->accept(*this);
       
  1048   il_operand = NULL;
       
  1049   /* This object has (inherits) the same cvalues as the il_jump_operator */
       
  1050   symbol->const_value = symbol->il_jump_operator->const_value;
       
  1051   return NULL;
       
  1052 }
       
  1053 
       
  1054 
       
  1055 
       
  1056 /* FB calls leave the value in the accumulator unchanged */
       
  1057 /*   il_call_operator prev_declared_fb_name
       
  1058  * | il_call_operator prev_declared_fb_name '(' ')'
       
  1059  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
       
  1060  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
       
  1061  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
       
  1062  */
       
  1063 /* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */
       
  1064 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
       
  1065 void *constant_folding_c::visit(il_fb_call_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1066 
       
  1067 
       
  1068 /* TODO: handle function invocations... */
       
  1069 /* | function_name '(' eol_list [il_param_list] ')' */
       
  1070 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */
       
  1071 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;)
       
  1072 // void *constant_folding_c::visit(il_formal_funct_call_c *symbol) {return NULL;}
       
  1073 
       
  1074 
       
  1075 
       
  1076 /* Not needed, since we inherit from iterator_visitor_c */
       
  1077 //  void *constant_folding_c::visit(il_operand_list_c *symbol);
       
  1078 
       
  1079 
       
  1080 
       
  1081 /* | simple_instr_list il_simple_instruction */
       
  1082 /* This object is referenced by il_expression_c objects */
       
  1083 void *constant_folding_c::visit(simple_instr_list_c *symbol) {
       
  1084   if (symbol->n <= 0)
       
  1085     return NULL;  /* List is empty! Nothing to do. */
       
  1086     
       
  1087   for(int i = 0; i < symbol->n; i++)
       
  1088     symbol->elements[i]->accept(*this);
       
  1089 
       
  1090   /* This object has (inherits) the same cvalues as the il_jump_operator */
       
  1091   symbol->const_value = symbol->elements[symbol->n-1]->const_value;
       
  1092   return NULL;
       
  1093 }
       
  1094 
       
  1095 
       
  1096 
       
  1097 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
       
  1098 void *constant_folding_c::visit(il_simple_instruction_c *symbol) {
       
  1099   if (symbol->prev_il_instruction.size() > 1) ERROR; /* There should be no labeled insructions inside an IL expression! */
       
  1100   if (symbol->prev_il_instruction.size() == 0)  prev_il_instruction = NULL;
       
  1101   else                                          prev_il_instruction = symbol->prev_il_instruction[0];
       
  1102   symbol->il_simple_instruction->accept(*this);
       
  1103   prev_il_instruction = NULL;
       
  1104 
       
  1105   /* This object has (inherits) the same cvalues as the il_jump_operator */
       
  1106   symbol->const_value = symbol->il_simple_instruction->const_value;
       
  1107   return NULL;
       
  1108 }
       
  1109 
       
  1110 
       
  1111 /*
       
  1112     void *visit(il_param_list_c *symbol);
       
  1113     void *visit(il_param_assignment_c *symbol);
       
  1114     void *visit(il_param_out_assignment_c *symbol);
       
  1115 */
       
  1116 
       
  1117 
       
  1118 /*******************/
       
  1119 /* B 2.2 Operators */
       
  1120 /*******************/
       
  1121 void *constant_folding_c::visit(   LD_operator_c *symbol) {return handle_move(symbol, il_operand);}
       
  1122 void *constant_folding_c::visit(  LDN_operator_c *symbol) {return handle_not (symbol, il_operand);}
       
  1123 
       
  1124 /* NOTE: we are implementing a constant folding algorithm, not a constant propagation algorithm.
       
  1125  *       For the constant propagation algorithm, the correct implementation of ST(N)_operator_c would be...
       
  1126  */
       
  1127 //void *constant_folding_c::visit(   ST_operator_c *symbol) {return handle_move(il_operand, symbol);}
       
  1128 //void *constant_folding_c::visit(  STN_operator_c *symbol) {return handle_not (il_operand, symbol);}
       
  1129 void *constant_folding_c::visit(   ST_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1130 void *constant_folding_c::visit(  STN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1131 
       
  1132 /* NOTE: the standard allows syntax in which the NOT operator is followed by an optional <il_operand>
       
  1133  *              NOT [<il_operand>]
       
  1134  *       However, it does not define the semantic of the NOT operation when the <il_operand> is specified.
       
  1135  *       We therefore consider it an error if an il_operand is specified! This error will be caught elsewhere!
       
  1136  */
       
  1137 void *constant_folding_c::visit(  NOT_operator_c *symbol) {return handle_not(symbol, prev_il_instruction);}
       
  1138 
       
  1139 /* NOTE: Since we are only implementing a constant folding algorithm, and not a constant propagation algorithm,
       
  1140  *       the following IL instructions do not change/set the value of the il_operand!
       
  1141  */
       
  1142 void *constant_folding_c::visit(    S_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1143 void *constant_folding_c::visit(    R_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1144 
       
  1145 /* FB calls leave the value in the accumulator unchanged */
       
  1146 void *constant_folding_c::visit(   S1_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1147 void *constant_folding_c::visit(   R1_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1148 void *constant_folding_c::visit(  CLK_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1149 void *constant_folding_c::visit(   CU_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1150 void *constant_folding_c::visit(   CD_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1151 void *constant_folding_c::visit(   PV_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1152 void *constant_folding_c::visit(   IN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1153 void *constant_folding_c::visit(   PT_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1154 
       
  1155 void *constant_folding_c::visit(  AND_operator_c *symbol) {return handle_and (symbol, prev_il_instruction, il_operand);}
       
  1156 void *constant_folding_c::visit(   OR_operator_c *symbol) {return handle_or  (symbol, prev_il_instruction, il_operand);}
       
  1157 void *constant_folding_c::visit(  XOR_operator_c *symbol) {return handle_xor (symbol, prev_il_instruction, il_operand);}
       
  1158 void *constant_folding_c::visit( ANDN_operator_c *symbol) {       handle_and (symbol, prev_il_instruction, il_operand); return handle_not(symbol, symbol);}
       
  1159 void *constant_folding_c::visit(  ORN_operator_c *symbol) {       handle_or  (symbol, prev_il_instruction, il_operand); return handle_not(symbol, symbol);}
       
  1160 void *constant_folding_c::visit( XORN_operator_c *symbol) {       handle_xor (symbol, prev_il_instruction, il_operand); return handle_not(symbol, symbol);}
       
  1161 
       
  1162 void *constant_folding_c::visit(  ADD_operator_c *symbol) {return handle_add (symbol, prev_il_instruction, il_operand);}
       
  1163 void *constant_folding_c::visit(  SUB_operator_c *symbol) {return handle_sub (symbol, prev_il_instruction, il_operand);}
       
  1164 void *constant_folding_c::visit(  MUL_operator_c *symbol) {return handle_mul (symbol, prev_il_instruction, il_operand);}
       
  1165 void *constant_folding_c::visit(  DIV_operator_c *symbol) {return handle_div (symbol, prev_il_instruction, il_operand);}
       
  1166 void *constant_folding_c::visit(  MOD_operator_c *symbol) {return handle_mod (symbol, prev_il_instruction, il_operand);}
       
  1167 
       
  1168 void *constant_folding_c::visit(   GT_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, > );}
       
  1169 void *constant_folding_c::visit(   GE_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, >=);}
       
  1170 void *constant_folding_c::visit(   EQ_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, ==);}
       
  1171 void *constant_folding_c::visit(   LT_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, < );}
       
  1172 void *constant_folding_c::visit(   LE_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, <=);}
       
  1173 void *constant_folding_c::visit(   NE_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, !=);}
       
  1174 
       
  1175 void *constant_folding_c::visit(  CAL_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1176 void *constant_folding_c::visit(  RET_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1177 void *constant_folding_c::visit(  JMP_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1178 void *constant_folding_c::visit( CALC_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1179 void *constant_folding_c::visit(CALCN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1180 void *constant_folding_c::visit( RETC_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1181 void *constant_folding_c::visit(RETCN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1182 void *constant_folding_c::visit( JMPC_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1183 void *constant_folding_c::visit(JMPCN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1184 
       
  1185 
       
  1186 
       
  1187 
       
  1188 /***************************************/
       
  1189 /* B.3 - Language ST (Structured Text) */
       
  1190 /***************************************/
       
  1191 /***********************/
       
  1192 /* B 3.1 - Expressions */
       
  1193 /***********************/
       
  1194 void *constant_folding_c::visit(    or_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_or (symbol, symbol->l_exp, symbol->r_exp);}
       
  1195 void *constant_folding_c::visit(   xor_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_xor(symbol, symbol->l_exp, symbol->r_exp);}
       
  1196 void *constant_folding_c::visit(   and_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_and(symbol, symbol->l_exp, symbol->r_exp);}
       
  1197 
       
  1198 void *constant_folding_c::visit(   equ_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, ==);}
       
  1199 void *constant_folding_c::visit(notequ_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, !=);}
       
  1200 void *constant_folding_c::visit(    lt_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, < );}
       
  1201 void *constant_folding_c::visit(    gt_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, > );}
       
  1202 void *constant_folding_c::visit(    le_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, <=);}
       
  1203 void *constant_folding_c::visit(    ge_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, >=);}
       
  1204 
       
  1205 void *constant_folding_c::visit(   add_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_add(symbol, symbol->l_exp, symbol->r_exp);}
       
  1206 void *constant_folding_c::visit(   sub_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_sub(symbol, symbol->l_exp, symbol->r_exp);}
       
  1207 void *constant_folding_c::visit(   mul_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_mul(symbol, symbol->l_exp, symbol->r_exp);}
       
  1208 void *constant_folding_c::visit(   div_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_div(symbol, symbol->l_exp, symbol->r_exp);}
       
  1209 void *constant_folding_c::visit(   mod_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_mod(symbol, symbol->l_exp, symbol->r_exp);}
       
  1210 void *constant_folding_c::visit( power_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_pow(symbol, symbol->l_exp, symbol->r_exp);}
       
  1211 
       
  1212 void *constant_folding_c::visit(   neg_expression_c *symbol) {symbol->  exp->accept(*this); return handle_neg(symbol, symbol->exp);}
       
  1213 void *constant_folding_c::visit(   not_expression_c *symbol) {symbol->  exp->accept(*this); return handle_not(symbol, symbol->exp);}
       
  1214 
       
  1215 
       
  1216 
       
  1217 
       
  1218 
       
  1219 
       
  1220 
       
  1221 
       
  1222 
       
  1223 
       
  1224 
       
  1225 /***********************************************************************/
       
  1226 /***********************************************************************/
       
  1227 /***********************************************************************/
       
  1228 /***        The constant_propagation_c                               ***/
       
  1229 /***********************************************************************/
       
  1230 /***********************************************************************/
       
  1231 /***********************************************************************/
       
  1232 
       
  1233 
       
  1234 constant_propagation_c::constant_propagation_c(symbol_c *symbol)
       
  1235   : constant_folding_c(symbol) {
       
  1236     current_resource = NULL;
       
  1237     current_configuration = NULL;
       
  1238     fixed_init_value_ = false;
       
  1239     function_pou_ = false;
       
  1240 }
       
  1241 
       
  1242 
       
  1243 constant_propagation_c::~constant_propagation_c(void) {}
       
  1244 
       
  1245 
       
  1246 static constant_propagation_c::map_values_t inner_left_join_values(constant_propagation_c::map_values_t m1, constant_propagation_c::map_values_t m2) {
       
  1247 	constant_propagation_c::map_values_t::const_iterator itr;
       
  1248 	constant_propagation_c::map_values_t ret;
   730 
  1249 
   731 	itr = m1.begin();
  1250 	itr = m1.begin();
   732 	for ( ; itr != m1.end(); ++itr) {
  1251 	for ( ; itr != m1.end(); ++itr) {
   733 		std::string name = itr->first;
  1252 		std::string name = itr->first;
   734 		const_value_c value;
  1253 		const_value_c value;
   745 		ret[name] = value;
  1264 		ret[name] = value;
   746 	}
  1265 	}
   747 
  1266 
   748 	return ret;
  1267 	return ret;
   749 }
  1268 }
   750 
       
   751 /***********************************************************************/
       
   752 /***********************************************************************/
       
   753 /***********************************************************************/
       
   754 /***        Helper functions for handling IL instruction lists.      ***/
       
   755 /***********************************************************************/
       
   756 /***********************************************************************/
       
   757 /***********************************************************************/
       
   758 
       
   759 
       
   760 /* If the cvalues of all the prev_il_intructions have the same VALID value, then set the local cvalue to that value, otherwise, set it to NONCONST! */
       
   761 #define intersect_prev_CVALUE_(dtype, symbol) {                                                                   \
       
   762 	symbol->const_value._##dtype = symbol->prev_il_instruction[0]->const_value._##dtype;                      \
       
   763 	for (unsigned int i = 1; i < symbol->prev_il_instruction.size(); i++) {                                   \
       
   764 		if (!ISEQUAL_CVALUE(dtype, symbol, symbol->prev_il_instruction[i]))                               \
       
   765 			{SET_NONCONST(dtype, symbol); break;}                                                     \
       
   766 	}                                                                                                         \
       
   767 }
       
   768 
       
   769 static void intersect_prev_cvalues(il_instruction_c *symbol) {
       
   770 	if (symbol->prev_il_instruction.empty())
       
   771 		return;
       
   772 	intersect_prev_CVALUE_(real64, symbol);
       
   773 	intersect_prev_CVALUE_(uint64, symbol);
       
   774 	intersect_prev_CVALUE_( int64, symbol);
       
   775 	intersect_prev_CVALUE_(  bool, symbol);
       
   776 }
       
   777 
       
   778 
       
   779 
       
   780 /***********************************************************************/
       
   781 /***********************************************************************/
       
   782 /***********************************************************************/
       
   783 /***        The constant_folding_c                                   ***/
       
   784 /***********************************************************************/
       
   785 /***********************************************************************/
       
   786 /***********************************************************************/
       
   787 
       
   788 #if 0
       
   789 // not currently needed, so comment it out!...
       
   790 // returns true if both symbols have the same value in all the cvalues
       
   791 bool constant_folding_c::is_equal_cvalue(symbol_c *symbol_1, symbol_c *symbol_2) {
       
   792 	if (VALID_CVALUE  (real64, symbol_1) != VALID_CVALUE  (real64, symbol_2)) return false;
       
   793 	if (VALID_CVALUE  (uint64, symbol_1) != VALID_CVALUE  (uint64, symbol_2)) return false;
       
   794 	if (VALID_CVALUE  ( int64, symbol_1) != VALID_CVALUE  ( int64, symbol_2)) return false;
       
   795 	if (VALID_CVALUE  (  bool, symbol_1) != VALID_CVALUE  (  bool, symbol_2)) return false;
       
   796 	if (VALID_CVALUE  (real64, symbol_1) && !ISEQUAL_CVALUE(real64, symbol_1, symbol_2)) return false;
       
   797 	if (VALID_CVALUE  (uint64, symbol_1) && !ISEQUAL_CVALUE(uint64, symbol_1, symbol_2)) return false;
       
   798 	if (VALID_CVALUE  ( int64, symbol_1) && !ISEQUAL_CVALUE( int64, symbol_1, symbol_2)) return false;
       
   799 	if (VALID_CVALUE  (  bool, symbol_1) && !ISEQUAL_CVALUE(  bool, symbol_1, symbol_2)) return false;
       
   800 	return true;
       
   801 }
       
   802 #endif
       
   803 
       
   804 
       
   805 
       
   806 constant_folding_c::constant_folding_c(symbol_c *symbol) {
       
   807     current_resource = NULL;
       
   808     current_configuration = NULL;
       
   809     fixed_init_value_ = false;
       
   810     function_pou_ = false;
       
   811     error_count = 0;
       
   812     warning_found = false;
       
   813     current_display_error_level = 0;
       
   814     il_operand = NULL;
       
   815     search_varfb_instance_type = NULL;
       
   816     prev_il_instruction = NULL;
       
   817     
       
   818     /* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */
       
   819     symbol_c null_symbol;
       
   820     if (! (std::numeric_limits<real64_t>::is_iec559) )
       
   821         STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 60559 floating point numbers. "
       
   822                                                    "Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals "
       
   823                                                    "(i.e. constant folding) may themselves be erroneous, although are most probably correct."
       
   824                                                    "However, more likely is the possible existance of overflow/underflow errors that are not detected.");
       
   825 }
       
   826 
       
   827 
       
   828 constant_folding_c::~constant_folding_c(void) {
       
   829 }
       
   830 
       
   831 
       
   832 int constant_folding_c::get_error_count() {
       
   833 	return error_count;
       
   834 }
       
   835 
       
   836 
  1269 
   837 /***************************/
  1270 /***************************/
   838 /* B 0 - Programming Model */
  1271 /* B 0 - Programming Model */
   839 /***************************/
  1272 /***************************/
   840 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1273 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
   917    *       - After analysing all the configurations, we analyse all the other POUs that have
  1350    *       - After analysing all the configurations, we analyse all the other POUs that have
   918    *         not yet been called (because they are not instantiated directly from within
  1351    *         not yet been called (because they are not instantiated directly from within
   919    *         any configuration - e.g. functions, and most FBs!).
  1352    *         any configuration - e.g. functions, and most FBs!).
   920    *       It is for this reason (3) why we have the two loops on the following code!
  1353    *       It is for this reason (3) why we have the two loops on the following code!
   921    */
  1354    */
   922 void *constant_folding_c::visit(library_c *symbol) {
  1355 void *constant_propagation_c::visit(library_c *symbol) {
   923   int i;
  1356   int i;
   924   
  1357   
   925   for (i = 0; i < symbol->n; i++) {
  1358   for (i = 0; i < symbol->n; i++) {
   926     // first analyse the configurations
  1359     // first analyse the configurations
   927     if (NULL != dynamic_cast<configuration_declaration_c *>(symbol->elements[i]))
  1360     if (NULL != dynamic_cast<configuration_declaration_c *>(symbol->elements[i]))
   939   }
  1372   }
   940   
  1373   
   941   return NULL;
  1374   return NULL;
   942 }
  1375 }
   943 
  1376 
   944 /*********************/
       
   945 /* B 1.2 - Constants */
       
   946 /*********************/
       
   947 /******************************/
       
   948 /* B 1.2.1 - Numeric Literals */
       
   949 /******************************/
       
   950 void *constant_folding_c::visit(real_c *symbol) {
       
   951 	bool overflow;
       
   952 	SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow));
       
   953 	if (overflow) SET_OVFLOW(real64, symbol);
       
   954 	return NULL;
       
   955 }
       
   956 
       
   957 
       
   958 void *constant_folding_c::visit(integer_c *symbol) {
       
   959 	bool overflow;
       
   960 	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
       
   961 	if (overflow) SET_OVFLOW(int64, symbol);
       
   962 	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
       
   963 	if (overflow) SET_OVFLOW(uint64, symbol);
       
   964 	return NULL;
       
   965 }
       
   966 
       
   967 
       
   968 void *constant_folding_c::visit(neg_real_c *symbol) {
       
   969 	symbol->exp->accept(*this);
       
   970 	DO_UNARY_OPER(real64, -, symbol->exp); CHECK_OVERFLOW_real64(symbol);
       
   971 	if (IS_OVFLOW(real64, symbol->exp)) SET_OVFLOW(real64, symbol);
       
   972 	return NULL;
       
   973 }
       
   974 
       
   975 
       
   976 
       
   977 /* | '-' integer	{$$ = new neg_integer_c($2, locloc(@$));} */
       
   978 void *constant_folding_c::visit(neg_integer_c *symbol) {
       
   979 	symbol->exp->accept(*this);
       
   980 	/* Note that due to syntax restrictions, the value of symbol->exp will always be positive. 
       
   981 	 * However, the following code does not depend on that restriction.
       
   982 	 */
       
   983 	/* The remainder of the code (for example, data type checking) considers the neg_integer_c as a leaf of the
       
   984 	 * abstract syntax tree, and therefore simply ignores the values of neg_integer_c->exp.
       
   985 	 * For this reason only, and in only this situation, we must guarantee that any 'overflow' situation in 
       
   986 	 * the cvalue of neg_integer_c->exp is also reflected back to this neg_integer_c symbol.
       
   987 	 * For the rest of the code we do NOT do this, as it would gurantee that a single overflow deep inside
       
   988 	 * an expression would imply that the expression itself would also be set to 'overflow' condition.
       
   989 	 * This in turn would then have the compiler produce a whole load of error messages where they are not wanted!
       
   990 	 */
       
   991 	DO_UNARY_OPER(uint64, -, symbol->exp); CHECK_OVERFLOW_uint64_NEG(symbol, symbol->exp);  /* handle the uintv := -0 situation */
       
   992 	if (IS_OVFLOW(uint64, symbol->exp)) SET_OVFLOW(uint64, symbol);
       
   993 	DO_UNARY_OPER( int64, -, symbol->exp); CHECK_OVERFLOW_int64_NEG (symbol, symbol->exp);
       
   994 	if (IS_OVFLOW( int64, symbol->exp)) SET_OVFLOW( int64, symbol);
       
   995 	/* NOTE 1: INT64_MIN = -(INT64_MAX + 1)   ---> assuming two's complement representation!!!
       
   996 	 * NOTE 2: if the user happens to want INT_MIN, that value will first be parsed as a positive integer, before being negated here.
       
   997 	 * However, the positive value cannot be stored inside an int64! So, in this case, we will get the value from the uint64 cvalue.
       
   998 	 *
       
   999 	 * This same situation is usually considered an overflow (check handle_neg() function). However, here we have a special
       
  1000 	 * situation. If we do not allow this, then the user would never the able to use the following code:
       
  1001 	 *  VAR v : LINT; END_VAR
       
  1002 	 *    v := -9223372036854775809 ; (* - |INT64_MIN| == INT64_MIN *)
       
  1003 	 */
       
  1004 	// if (INT64_MIN == -INT64_MAX - 1) // We do not really need to check that the platform uses two's complement
       
  1005 	if (VALID_CVALUE(uint64, symbol->exp) && (GET_CVALUE(uint64, symbol->exp) == (uint64_t)INT64_MAX+1)) {
       
  1006 		SET_CVALUE(int64, symbol, INT64_MIN);
       
  1007 	}
       
  1008 	return NULL;
       
  1009 }
       
  1010 
       
  1011 
       
  1012 void *constant_folding_c::visit(binary_integer_c *symbol) {
       
  1013 	bool overflow;
       
  1014 	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
       
  1015 	if (overflow) SET_OVFLOW(int64, symbol);
       
  1016 	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
       
  1017 	if (overflow) SET_OVFLOW(uint64, symbol);
       
  1018 	return NULL;
       
  1019 }
       
  1020 
       
  1021 
       
  1022 void *constant_folding_c::visit(octal_integer_c *symbol) {
       
  1023 	bool overflow;
       
  1024 	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
       
  1025 	if (overflow) SET_OVFLOW(int64, symbol);
       
  1026 	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
       
  1027 	if (overflow) SET_OVFLOW(uint64, symbol);
       
  1028 	return NULL;
       
  1029 }
       
  1030 
       
  1031 
       
  1032 void *constant_folding_c::visit(hex_integer_c *symbol) {
       
  1033 	bool overflow;
       
  1034 	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
       
  1035 	if (overflow) SET_OVFLOW(int64, symbol);
       
  1036 	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
       
  1037 	if (overflow) SET_OVFLOW(uint64, symbol);
       
  1038 	return NULL;
       
  1039 }
       
  1040 
       
  1041 
       
  1042 /*
       
  1043 integer_literal:
       
  1044   integer_type_name '#' signed_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
       
  1045 | integer_type_name '#' binary_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
       
  1046 | integer_type_name '#' octal_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
       
  1047 | integer_type_name '#' hex_integer	{$$ = new integer_literal_c($1, $3, locloc(@$));}
       
  1048 */
       
  1049 // SYM_REF2(integer_literal_c, type, value)
       
  1050 void *constant_folding_c::visit(integer_literal_c *symbol) {
       
  1051 	symbol->value->accept(*this);
       
  1052 	DO_UNARY_OPER( int64, /* none */, symbol->value);
       
  1053 	DO_UNARY_OPER(uint64, /* none */, symbol->value);
       
  1054 	return NULL;
       
  1055 }
       
  1056 
       
  1057 
       
  1058 void *constant_folding_c::visit(real_literal_c *symbol) {
       
  1059 	symbol->value->accept(*this);
       
  1060 	DO_UNARY_OPER(real64, /* none */, symbol->value);
       
  1061 	return NULL;
       
  1062 }
       
  1063 
       
  1064 
       
  1065 void *constant_folding_c::visit(bit_string_literal_c *symbol) {
       
  1066 	return NULL;
       
  1067 }
       
  1068 
       
  1069 
       
  1070 void *constant_folding_c::visit(boolean_literal_c *symbol) {
       
  1071 	symbol->value->accept(*this);
       
  1072 	DO_UNARY_OPER(bool, /* none */, symbol->value);
       
  1073 	return NULL;
       
  1074 }
       
  1075 
       
  1076 
       
  1077 void *constant_folding_c::visit(boolean_true_c *symbol) {
       
  1078 	SET_CVALUE(bool, symbol, true);
       
  1079 	return NULL;
       
  1080 }
       
  1081 
       
  1082 
       
  1083 void *constant_folding_c::visit(boolean_false_c *symbol) {
       
  1084 	SET_CVALUE(bool, symbol, false);
       
  1085 	return NULL;
       
  1086 }
       
  1087 
       
  1088 /************************/
       
  1089 /* B 1.2.3.1 - Duration */
       
  1090 /********* **************/
       
  1091 void *constant_folding_c::visit(fixed_point_c *symbol) {
       
  1092 	bool overflow;
       
  1093 	SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow));
       
  1094 	if (overflow) SET_OVFLOW(real64, symbol);
       
  1095 	return NULL;
       
  1096 }
       
  1097 
  1377 
  1098 /*********************/
  1378 /*********************/
  1099 /* B 1.4 - Variables */
  1379 /* B 1.4 - Variables */
  1100 /*********************/
  1380 /*********************/
  1101 #if DO_CONSTANT_PROPAGATION__
  1381 #if DO_CONSTANT_PROPAGATION__
  1102 void *constant_folding_c::visit(symbolic_variable_c *symbol) {
  1382 void *constant_propagation_c::visit(symbolic_variable_c *symbol) {
  1103 	std::string varName = get_var_name_c::get_name(symbol->var_name)->value;
  1383 	std::string varName = get_var_name_c::get_name(symbol->var_name)->value;
  1104 	if (values.count(varName) > 0) 
  1384 	if (values.count(varName) > 0) 
  1105 		symbol->const_value = values[varName];
  1385 		symbol->const_value = values[varName];
  1106 	return NULL;
  1386 	return NULL;
  1107 }
  1387 }
  1108 #endif  // DO_CONSTANT_PROPAGATION__
  1388 #endif  // DO_CONSTANT_PROPAGATION__
  1109 
  1389 
  1110 void *constant_folding_c::visit(symbolic_constant_c *symbol) {
  1390 void *constant_propagation_c::visit(symbolic_constant_c *symbol) {
  1111 	std::string varName = get_var_name_c::get_name(symbol->var_name)->value;
  1391 	std::string varName = get_var_name_c::get_name(symbol->var_name)->value;
  1112 	if (values.count(varName) > 0) 
  1392 	if (values.count(varName) > 0) 
  1113 		symbol->const_value = values[varName];
  1393 		symbol->const_value = values[varName];
  1114 	return NULL;
  1394 	return NULL;
  1115 }
  1395 }
  1117 
  1397 
  1118 /******************************************/
  1398 /******************************************/
  1119 /* B 1.4.3 - Declaration & Initialisation */
  1399 /* B 1.4.3 - Declaration & Initialisation */
  1120 /******************************************/
  1400 /******************************************/
  1121   
  1401   
  1122 void *constant_folding_c::handle_var_decl(symbol_c *var_list, bool fixed_init_value) {
  1402 void *constant_propagation_c::handle_var_decl(symbol_c *var_list, bool fixed_init_value) {
  1123   fixed_init_value_ = fixed_init_value;
  1403   fixed_init_value_ = fixed_init_value;
  1124   var_list->accept(*this); 
  1404   var_list->accept(*this); 
  1125   fixed_init_value_ = false; 
  1405   fixed_init_value_ = false; 
  1126   return NULL;
  1406   return NULL;
  1127 }
  1407 }
  1128 
  1408 
  1129 void *constant_folding_c::handle_var_list_decl(symbol_c *var_list, symbol_c *type_decl) {
  1409 void *constant_propagation_c::handle_var_list_decl(symbol_c *var_list, symbol_c *type_decl) {
  1130   type_decl->accept(*this);  // Do constant folding of the initial value, and literals in subranges! (we will probably be doing this multiple times for the same init value, but this is safe as the cvalue is idem-potent)
  1410   type_decl->accept(*this);  // Do constant folding of the initial value, and literals in subranges! (we will probably be doing this multiple times for the same init value, but this is safe as the cvalue is idem-potent)
  1131   symbol_c *init_value = type_initial_value_c::get(type_decl);  
  1411   symbol_c *init_value = type_initial_value_c::get(type_decl);  
  1132   if (NULL == init_value)   {return NULL;} // this is probably a FB datatype, for which no initial value exists! Do nothing and return.
  1412   if (NULL == init_value)   {return NULL;} // this is probably a FB datatype, for which no initial value exists! Do nothing and return.
  1133   init_value->accept(*this); // necessary when handling default initial values, that were not constant folded in the call type_decl->accept(*this)
  1413   init_value->accept(*this); // necessary when handling default initial values, that were not constant folded in the call type_decl->accept(*this)
  1134   
  1414   
  1151 }
  1431 }
  1152 
  1432 
  1153 //SYM_REF0(constant_option_c)     // Not needed!
  1433 //SYM_REF0(constant_option_c)     // Not needed!
  1154 //SYM_REF0(retain_option_c)       // Not needed!
  1434 //SYM_REF0(retain_option_c)       // Not needed!
  1155 //SYM_REF0(non_retain_option_c)   // Not needed!
  1435 //SYM_REF0(non_retain_option_c)   // Not needed!
  1156 bool constant_folding_c::is_constant(symbol_c *option) {return (NULL != dynamic_cast<constant_option_c *>(option));}
  1436 bool constant_propagation_c::is_constant(symbol_c *option) {return (NULL != dynamic_cast<constant_option_c *>(option));}
  1157 bool constant_folding_c::is_retain  (symbol_c *option) {return (NULL != dynamic_cast<  retain_option_c *>(option));}
  1437 bool constant_propagation_c::is_retain  (symbol_c *option) {return (NULL != dynamic_cast<  retain_option_c *>(option));}
  1158 
  1438 
  1159 /* | var1_list ',' variable_name */
  1439 /* | var1_list ',' variable_name */
  1160 //SYM_LIST(var1_list_c)           // Not needed!
  1440 //SYM_LIST(var1_list_c)           // Not needed!
  1161 
  1441 
  1162 /* spec_init is one of the following...
  1442 /* spec_init is one of the following...
  1163  *    simple_spec_init_c *
  1443  *    simple_spec_init_c *
  1164  *    subrange_spec_init_c *
  1444  *    subrange_spec_init_c *
  1165  *    enumerated_spec_init_c *
  1445  *    enumerated_spec_init_c *
  1166  */
  1446  */
  1167 // SYM_REF2(var1_init_decl_c, var1_list, spec_init)
  1447 // SYM_REF2(var1_init_decl_c, var1_list, spec_init)
  1168 void *constant_folding_c::visit(var1_init_decl_c *symbol) {return handle_var_list_decl(symbol->var1_list, symbol->spec_init);}
  1448 void *constant_propagation_c::visit(var1_init_decl_c *symbol) {return handle_var_list_decl(symbol->var1_list, symbol->spec_init);}
  1169 
  1449 
  1170 /* | [var1_list ','] variable_name integer '..' */
  1450 /* | [var1_list ','] variable_name integer '..' */
  1171 /* NOTE: This is an extension to the standard!!! */
  1451 /* NOTE: This is an extension to the standard!!! */
  1172 //SYM_REF2(extensible_input_parameter_c, var_name, first_index)          // Not needed!
  1452 //SYM_REF2(extensible_input_parameter_c, var_name, first_index)          // Not needed!
  1173 
  1453 
  1186 /* VAR_INPUT [option] input_declaration_list END_VAR */
  1466 /* VAR_INPUT [option] input_declaration_list END_VAR */
  1187 /* option -> the RETAIN/NON_RETAIN/<NULL> directive... */
  1467 /* option -> the RETAIN/NON_RETAIN/<NULL> directive... */
  1188 //SYM_REF3(input_declarations_c, option, input_declaration_list, method) // Not needed since we inherit from iterator_visitor_c!
  1468 //SYM_REF3(input_declarations_c, option, input_declaration_list, method) // Not needed since we inherit from iterator_visitor_c!
  1189 // NOTE: Input variables can take any initial value, so we can not set the const_value annotation => we set fixed_init_value to false !!!
  1469 // NOTE: Input variables can take any initial value, so we can not set the const_value annotation => we set fixed_init_value to false !!!
  1190 //       We must still visit it iteratively, to set the const_value of all literals in the type declarations.
  1470 //       We must still visit it iteratively, to set the const_value of all literals in the type declarations.
  1191 void *constant_folding_c::visit(input_declarations_c *symbol) {return handle_var_decl(symbol->input_declaration_list, false);}
  1471 void *constant_propagation_c::visit(input_declarations_c *symbol) {return handle_var_decl(symbol->input_declaration_list, false);}
  1192 
  1472 
  1193 /* helper symbol for input_declarations */
  1473 /* helper symbol for input_declarations */
  1194 //SYM_LIST(input_declaration_list_c)                                     // Not needed!
  1474 //SYM_LIST(input_declaration_list_c)                                     // Not needed!
  1195 
  1475 
  1196 /* VAR_OUTPUT [RETAIN | NON_RETAIN] var_init_decl_list END_VAR */
  1476 /* VAR_OUTPUT [RETAIN | NON_RETAIN] var_init_decl_list END_VAR */
  1197 /* option -> may be NULL ! */
  1477 /* option -> may be NULL ! */
  1198 //SYM_REF3(output_declarations_c, option, var_init_decl_list, method) 
  1478 //SYM_REF3(output_declarations_c, option, var_init_decl_list, method) 
  1199 void *constant_folding_c::visit(output_declarations_c *symbol) {return handle_var_decl(symbol->var_init_decl_list, !is_retain(symbol->option) && function_pou_);}
  1479 void *constant_propagation_c::visit(output_declarations_c *symbol) {return handle_var_decl(symbol->var_init_decl_list, !is_retain(symbol->option) && function_pou_);}
  1200 
  1480 
  1201 /*  VAR_IN_OUT var_declaration_list END_VAR */
  1481 /*  VAR_IN_OUT var_declaration_list END_VAR */
  1202 //SYM_REF1(input_output_declarations_c, var_declaration_list)
  1482 //SYM_REF1(input_output_declarations_c, var_declaration_list)
  1203 // NOTE: Input variables can take any initial value, so we can not set the const_value annotation => we set fixed_init_value to false !!!
  1483 // NOTE: Input variables can take any initial value, so we can not set the const_value annotation => we set fixed_init_value to false !!!
  1204 //       We must still visit it iteratively, to set the const_value of all literals in the type declarations.
  1484 //       We must still visit it iteratively, to set the const_value of all literals in the type declarations.
  1205 void *constant_folding_c::visit(input_output_declarations_c *symbol) {return handle_var_decl(symbol->var_declaration_list, false);}
  1485 void *constant_propagation_c::visit(input_output_declarations_c *symbol) {return handle_var_decl(symbol->var_declaration_list, false);}
  1206 
  1486 
  1207 /* helper symbol for input_output_declarations */
  1487 /* helper symbol for input_output_declarations */
  1208 /* var_declaration_list var_declaration ';' */
  1488 /* var_declaration_list var_declaration ';' */
  1209 //SYM_LIST(var_declaration_list_c)                                       // Not needed since we inherit from iterator_visitor_c!
  1489 //SYM_LIST(var_declaration_list_c)                                       // Not needed since we inherit from iterator_visitor_c!
  1210 
  1490 
  1215 //SYM_REF2(structured_var_declaration_c, var1_list, structure_type_name) // We do not yet handle structures!
  1495 //SYM_REF2(structured_var_declaration_c, var1_list, structure_type_name) // We do not yet handle structures!
  1216 
  1496 
  1217 /* VAR [CONSTANT] var_init_decl_list END_VAR */
  1497 /* VAR [CONSTANT] var_init_decl_list END_VAR */
  1218 /* option -> may be NULL ! */
  1498 /* option -> may be NULL ! */
  1219 //SYM_REF2(var_declarations_c, option, var_init_decl_list)
  1499 //SYM_REF2(var_declarations_c, option, var_init_decl_list)
  1220 void *constant_folding_c::visit(var_declarations_c *symbol) {return handle_var_decl(symbol->var_init_decl_list, false);}
  1500 void *constant_propagation_c::visit(var_declarations_c *symbol) {return handle_var_decl(symbol->var_init_decl_list, false);}
  1221 
  1501 
  1222 /*  VAR RETAIN var_init_decl_list END_VAR */
  1502 /*  VAR RETAIN var_init_decl_list END_VAR */
  1223 //SYM_REF1(retentive_var_declarations_c, var_init_decl_list)             // Not needed since we inherit from iterator_visitor_c!
  1503 //SYM_REF1(retentive_var_declarations_c, var_init_decl_list)             // Not needed since we inherit from iterator_visitor_c!
  1224 // NOTE: Retentive variables can take any initial value, so we can not set the const_value annotation => we set fixed_init_value to false !!!
  1504 // NOTE: Retentive variables can take any initial value, so we can not set the const_value annotation => we set fixed_init_value to false !!!
  1225 //       We must still visit it iteratively, to set the const_value of all literals in the type declarations.
  1505 //       We must still visit it iteratively, to set the const_value of all literals in the type declarations.
  1226 void *constant_folding_c::visit(retentive_var_declarations_c *symbol) {return handle_var_decl(symbol->var_init_decl_list, false);}
  1506 void *constant_propagation_c::visit(retentive_var_declarations_c *symbol) {return handle_var_decl(symbol->var_init_decl_list, false);}
  1227 
  1507 
  1228 #if 0  
  1508 #if 0  
  1229 // TODO
  1509 // TODO
  1230 /*  VAR [CONSTANT|RETAIN|NON_RETAIN] located_var_decl_list END_VAR */
  1510 /*  VAR [CONSTANT|RETAIN|NON_RETAIN] located_var_decl_list END_VAR */
  1231 /* option -> may be NULL ! */
  1511 /* option -> may be NULL ! */
  1239 #endif
  1519 #endif
  1240 
  1520 
  1241 /*| VAR_EXTERNAL [CONSTANT] external_declaration_list END_VAR */
  1521 /*| VAR_EXTERNAL [CONSTANT] external_declaration_list END_VAR */
  1242 /* option -> may be NULL ! */
  1522 /* option -> may be NULL ! */
  1243 // SYM_REF2(external_var_declarations_c, option, external_declaration_list)
  1523 // SYM_REF2(external_var_declarations_c, option, external_declaration_list)
  1244 void *constant_folding_c::visit(external_var_declarations_c *symbol) {return handle_var_decl(symbol->external_declaration_list, is_constant(symbol->option));}
  1524 void *constant_propagation_c::visit(external_var_declarations_c *symbol) {return handle_var_decl(symbol->external_declaration_list, is_constant(symbol->option));}
  1245 
  1525 
  1246 /* helper symbol for external_var_declarations */
  1526 /* helper symbol for external_var_declarations */
  1247 /*| external_declaration_list external_declaration';' */
  1527 /*| external_declaration_list external_declaration';' */
  1248 // SYM_LIST(external_declaration_list_c)
  1528 // SYM_LIST(external_declaration_list_c)
  1249 // void *constant_folding_c::visit(external_declaration_list_c *symbol) {} // Not needed: we inherit from iterator_c
  1529 // void *constant_propagation_c::visit(external_declaration_list_c *symbol) {} // Not needed: we inherit from iterator_c
  1250 
  1530 
  1251 /*  global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */
  1531 /*  global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */
  1252 //SYM_REF2(external_declaration_c, global_var_name, specification)
  1532 //SYM_REF2(external_declaration_c, global_var_name, specification)
  1253 void *constant_folding_c::visit(external_declaration_c *symbol) {
  1533 void *constant_propagation_c::visit(external_declaration_c *symbol) {
  1254   // The syntax does not allow VAR_EXTERN to be initialized. We must get the initial value from the corresponding VAR_GLOBAL declaration
  1534   // The syntax does not allow VAR_EXTERN to be initialized. We must get the initial value from the corresponding VAR_GLOBAL declaration
  1255   /* However, we only do this is if the visit() method for the Program/FB in which this VAR_EXTERN is found was called from the visit(configurtion/resource) visitor!
  1535   /* However, we only do this is if the visit() method for the Program/FB in which this VAR_EXTERN is found was called from the visit(configurtion/resource) visitor!
  1256    * When we are called from the visit(library_c) visitor, we do not have the required information to do this!
  1536    * When we are called from the visit(library_c) visitor, we do not have the required information to do this!
  1257    */ 
  1537    */ 
  1258   if (NULL != current_configuration) {
  1538   if (NULL != current_configuration) {
  1291 
  1571 
  1292 /* NOTE that the constant folding of GLOBAL variables is already handled by handle_var_extern_global_pair, which 
  1572 /* NOTE that the constant folding of GLOBAL variables is already handled by handle_var_extern_global_pair, which 
  1293  * is called from declaration_check_c,
  1573  * is called from declaration_check_c,
  1294  * This is done like this because we need to know the pairing of external<->global variables to get the cvalue
  1574  * This is done like this because we need to know the pairing of external<->global variables to get the cvalue
  1295  * from the global variable. Since the external<->global pairing information is available in the declaration_check_c,
  1575  * from the global variable. Since the external<->global pairing information is available in the declaration_check_c,
  1296  * we have that class call the constant_folding_c::handle_var_extern_global_pair(), which will actually do the 
  1576  * we have that class call the constant_propagation_c::handle_var_extern_global_pair(), which will actually do the 
  1297  * constant folding of the global and the external variable declarations!
  1577  * constant folding of the global and the external variable declarations!
  1298  */
  1578  */
  1299 /* NOTE: The constant propagation portion of this algorithm must still be done here!!
  1579 /* NOTE: The constant propagation portion of this algorithm must still be done here!!
  1300  * Even though the constant folding of GLOBAL variables are already handled by handle_var_extern_global_pair(),
  1580  * Even though the constant folding of GLOBAL variables are already handled by handle_var_extern_global_pair(),
  1301  * we must still visit them here, since when doing constant propagation of a Configuration or a Resource we need the
  1581  * we must still visit them here, since when doing constant propagation of a Configuration or a Resource we need the
  1310 /* Note that calling handle_var_decl() will result in doing constant folding of literals (of datatype initial values)
  1590 /* Note that calling handle_var_decl() will result in doing constant folding of literals (of datatype initial values)
  1311  * that were already constant folded by the method handle_var_extern_global_pair()
  1591  * that were already constant folded by the method handle_var_extern_global_pair()
  1312  * Nevertheless, since constant folding is idem-potent, it is simpler to just call handle_var_decl() instead
  1592  * Nevertheless, since constant folding is idem-potent, it is simpler to just call handle_var_decl() instead
  1313  * of writing some code specific for this situation!
  1593  * of writing some code specific for this situation!
  1314  */
  1594  */
  1315 void *constant_folding_c::visit(global_var_declarations_c *symbol) {return handle_var_decl(symbol->global_var_decl_list, is_constant(symbol->option));}
  1595 void *constant_propagation_c::visit(global_var_declarations_c *symbol) {return handle_var_decl(symbol->global_var_decl_list, is_constant(symbol->option));}
  1316 
  1596 
  1317 
  1597 
  1318 /* helper symbol for global_var_declarations */
  1598 /* helper symbol for global_var_declarations */
  1319 /*| global_var_decl_list global_var_decl ';' */
  1599 /*| global_var_decl_list global_var_decl ';' */
  1320 // SYM_LIST(global_var_decl_list_c)
  1600 // SYM_LIST(global_var_decl_list_c)
  1321 // void *constant_folding_c::visit(global_var_decl_list_c *symbol) {} // Not needed: we inherit from iterator_c
  1601 // void *constant_propagation_c::visit(global_var_decl_list_c *symbol) {} // Not needed: we inherit from iterator_c
  1322 
  1602 
  1323 /*| global_var_spec ':' [located_var_spec_init|function_block_type_name] */
  1603 /*| global_var_spec ':' [located_var_spec_init|function_block_type_name] */
  1324 /* type_specification ->may be NULL ! */
  1604 /* type_specification ->may be NULL ! */
  1325 //SYM_REF2(global_var_decl_c, global_var_spec, type_specification)
  1605 //SYM_REF2(global_var_decl_c, global_var_spec, type_specification)
  1326 void *constant_folding_c::visit(global_var_decl_c *symbol) {
  1606 void *constant_propagation_c::visit(global_var_decl_c *symbol) {
  1327   /* global_var_spec may be either a global_var_spec_c or a global_var_list_c.
  1607   /* global_var_spec may be either a global_var_spec_c or a global_var_list_c.
  1328    * Since we already have a nice method that handles var lists (handle_var_list_decl() )
  1608    * Since we already have a nice method that handles var lists (handle_var_list_decl() )
  1329    * if it is a global_var_spec_c we will create a temporary list so we can call that method!
  1609    * if it is a global_var_spec_c we will create a temporary list so we can call that method!
  1330    */
  1610    */
  1331   global_var_spec_c *var_spec = dynamic_cast<global_var_spec_c *>(symbol->global_var_spec);
  1611   global_var_spec_c *var_spec = dynamic_cast<global_var_spec_c *>(symbol->global_var_spec);
  1392 /***********************/
  1672 /***********************/
  1393 /* B 1.5.1 - Functions */
  1673 /* B 1.5.1 - Functions */
  1394 /***********************/
  1674 /***********************/
  1395 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1675 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1396 //SYM_REF4(function_declaration_c, derived_function_name, type_name, var_declarations_list, function_body, enumvalue_symtable_t enumvalue_symtable;)
  1676 //SYM_REF4(function_declaration_c, derived_function_name, type_name, var_declarations_list, function_body, enumvalue_symtable_t enumvalue_symtable;)
  1397 void *constant_folding_c::visit(function_declaration_c *symbol) {
  1677 void *constant_propagation_c::visit(function_declaration_c *symbol) {
  1398 	values.clear(); /* Clear global map */
  1678 	values.clear(); /* Clear global map */
  1399 	/* Add initial value of all declared variables into Values map. */
  1679 	/* Add initial value of all declared variables into Values map. */
  1400 	function_pou_ = true;
  1680 	function_pou_ = true;
  1401 	symbol->var_declarations_list->accept(*this);
  1681 	symbol->var_declarations_list->accept(*this);
  1402 	function_pou_ = false;
  1682 	function_pou_ = false;
  1413 // SYM_LIST(var_declarations_list_c) // Not needed since we inherit from iterator_c
  1693 // SYM_LIST(var_declarations_list_c) // Not needed since we inherit from iterator_c
  1414 
  1694 
  1415 /* option -> storage method, CONSTANT or <null> */
  1695 /* option -> storage method, CONSTANT or <null> */
  1416 // SYM_REF2(function_var_decls_c, option, decl_list)
  1696 // SYM_REF2(function_var_decls_c, option, decl_list)
  1417 // NOTE: function_var_decls_c is only used inside Functions, so it is safe to call with fixed_init_value_ = true 
  1697 // NOTE: function_var_decls_c is only used inside Functions, so it is safe to call with fixed_init_value_ = true 
  1418 void *constant_folding_c::visit(function_var_decls_c *symbol) {return handle_var_decl(symbol->decl_list, true);}
  1698 void *constant_propagation_c::visit(function_var_decls_c *symbol) {return handle_var_decl(symbol->decl_list, true);}
  1419 
  1699 
  1420 /* intermediate helper symbol for function_var_decls */
  1700 /* intermediate helper symbol for function_var_decls */
  1421 // SYM_LIST(var2_init_decl_list_c) // Not needed since we inherit from iterator_c
  1701 // SYM_LIST(var2_init_decl_list_c) // Not needed since we inherit from iterator_c
  1422 
  1702 
  1423 
  1703 
  1425 /* B 1.5.2 - Function Blocks */
  1705 /* B 1.5.2 - Function Blocks */
  1426 /*****************************/
  1706 /*****************************/
  1427 /*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
  1707 /*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
  1428 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1708 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1429 //SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body, enumvalue_symtable_t enumvalue_symtable;)
  1709 //SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body, enumvalue_symtable_t enumvalue_symtable;)
  1430 void *constant_folding_c::visit(function_block_declaration_c *symbol) {
  1710 void *constant_propagation_c::visit(function_block_declaration_c *symbol) {
  1431 	values.clear(); /* Clear global map */
  1711 	values.clear(); /* Clear global map */
  1432 	/* Add initial value of all declared variables into Values map. */
  1712 	/* Add initial value of all declared variables into Values map. */
  1433 	function_pou_ = false;
  1713 	function_pou_ = false;
  1434 	symbol->var_declarations->accept(*this);
  1714 	symbol->var_declarations->accept(*this);
  1435 	symbol->fblock_body->accept(*this);
  1715 	symbol->fblock_body->accept(*this);
  1436 	return NULL;
  1716 	return NULL;
  1437 }
  1717 }
  1438 
  1718 
  1439 /*  VAR_TEMP temp_var_decl_list END_VAR */
  1719 /*  VAR_TEMP temp_var_decl_list END_VAR */
  1440 // SYM_REF1(temp_var_decls_c, var_decl_list)
  1720 // SYM_REF1(temp_var_decls_c, var_decl_list)
  1441 void *constant_folding_c::visit(temp_var_decls_c *symbol) {return handle_var_decl(symbol->var_decl_list, true);}
  1721 void *constant_propagation_c::visit(temp_var_decls_c *symbol) {return handle_var_decl(symbol->var_decl_list, true);}
  1442 
  1722 
  1443 /* intermediate helper symbol for temp_var_decls */
  1723 /* intermediate helper symbol for temp_var_decls */
  1444 // SYM_LIST(temp_var_decls_list_c)
  1724 // SYM_LIST(temp_var_decls_list_c)
  1445 
  1725 
  1446 /*  VAR NON_RETAIN var_init_decl_list END_VAR */
  1726 /*  VAR NON_RETAIN var_init_decl_list END_VAR */
  1447 // SYM_REF1(non_retentive_var_decls_c, var_decl_list)
  1727 // SYM_REF1(non_retentive_var_decls_c, var_decl_list)
  1448 // NOTE: non_retentive_var_decls_c is only used inside FBs and Programs, so it is safe to call with fixed_init_value_ = false 
  1728 // NOTE: non_retentive_var_decls_c is only used inside FBs and Programs, so it is safe to call with fixed_init_value_ = false 
  1449 void *constant_folding_c::visit(non_retentive_var_decls_c *symbol) {return handle_var_decl(symbol->var_decl_list, false);}
  1729 void *constant_propagation_c::visit(non_retentive_var_decls_c *symbol) {return handle_var_decl(symbol->var_decl_list, false);}
  1450 
  1730 
  1451 
  1731 
  1452 /**********************/
  1732 /**********************/
  1453 /* B 1.5.3 - Programs */
  1733 /* B 1.5.3 - Programs */
  1454 /**********************/
  1734 /**********************/
  1455 /*  PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
  1735 /*  PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
  1456 //SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body, enumvalue_symtable_t enumvalue_symtable;)
  1736 //SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body, enumvalue_symtable_t enumvalue_symtable;)
  1457 void *constant_folding_c::visit(program_declaration_c *symbol) {
  1737 void *constant_propagation_c::visit(program_declaration_c *symbol) {
  1458 	values.clear(); /* Clear global map */
  1738 	values.clear(); /* Clear global map */
  1459 	/* Add initial value of all declared variables into Values map. */
  1739 	/* Add initial value of all declared variables into Values map. */
  1460 	function_pou_ = false;
  1740 	function_pou_ = false;
  1461 	symbol->var_declarations->accept(*this);
  1741 	symbol->var_declarations->accept(*this);
  1462 	symbol->function_block_body->accept(*this);
  1742 	symbol->function_block_body->accept(*this);
  1477 END_CONFIGURATION
  1757 END_CONFIGURATION
  1478 */
  1758 */
  1479 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1759 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1480 // SYM_REF5(configuration_declaration_c, configuration_name, global_var_declarations, resource_declarations, access_declarations, instance_specific_initializations, 
  1760 // SYM_REF5(configuration_declaration_c, configuration_name, global_var_declarations, resource_declarations, access_declarations, instance_specific_initializations, 
  1481 //          enumvalue_symtable_t enumvalue_symtable; localvar_symbmap_t localvar_symbmap; localvar_symbvec_t localvar_symbvec;)
  1761 //          enumvalue_symtable_t enumvalue_symtable; localvar_symbmap_t localvar_symbmap; localvar_symbvec_t localvar_symbvec;)
  1482 void *constant_folding_c::visit(configuration_declaration_c *symbol) {
  1762 void *constant_propagation_c::visit(configuration_declaration_c *symbol) {
  1483 	values.clear(); /* Clear global map */
  1763 	values.clear(); /* Clear global map */
  1484 
  1764 
  1485 	/* Add initial value of all declared variables into Values map. */
  1765 	/* Add initial value of all declared variables into Values map. */
  1486 	function_pou_ = false;
  1766 	function_pou_ = false;
  1487 	current_configuration = symbol;
  1767 	current_configuration = symbol;
  1501 END_RESOURCE
  1781 END_RESOURCE
  1502 */
  1782 */
  1503 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1783 /* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
  1504 // SYM_REF4(resource_declaration_c, resource_name, resource_type_name, global_var_declarations, resource_declaration, 
  1784 // SYM_REF4(resource_declaration_c, resource_name, resource_type_name, global_var_declarations, resource_declaration, 
  1505 //          enumvalue_symtable_t enumvalue_symtable; localvar_symbmap_t localvar_symbmap; localvar_symbvec_t localvar_symbvec;)
  1785 //          enumvalue_symtable_t enumvalue_symtable; localvar_symbmap_t localvar_symbmap; localvar_symbvec_t localvar_symbvec;)
  1506 void *constant_folding_c::visit(resource_declaration_c *symbol) {
  1786 void *constant_propagation_c::visit(resource_declaration_c *symbol) {
  1507 	values.push(); /* Create inner scope */
  1787 	values.push(); /* Create inner scope */
  1508 
  1788 
  1509 	/* Add initial value of all declared variables into Values map. */
  1789 	/* Add initial value of all declared variables into Values map. */
  1510 	function_pou_ = false;
  1790 	function_pou_ = false;
  1511 	symbol->global_var_declarations->accept(*this);
  1791 	symbol->global_var_declarations->accept(*this);
  1544 
  1824 
  1545 /*  PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] */
  1825 /*  PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] */
  1546 /* NOTE: The parameter 'called_prog_declaration'is used to pass data between stage 3 and stage4 */
  1826 /* NOTE: The parameter 'called_prog_declaration'is used to pass data between stage 3 and stage4 */
  1547 // SYM_REF5(program_configuration_c, retain_option, program_name, task_name, program_type_name, prog_conf_elements,
  1827 // SYM_REF5(program_configuration_c, retain_option, program_name, task_name, program_type_name, prog_conf_elements,
  1548 //          symbol_c *called_prog_declaration;)
  1828 //          symbol_c *called_prog_declaration;)
  1549 void *constant_folding_c::visit(program_configuration_c *symbol) {
  1829 void *constant_propagation_c::visit(program_configuration_c *symbol) {
  1550 	/* find the declaration (i.e. the datatype) of the program being instantiated */
  1830 	/* find the declaration (i.e. the datatype) of the program being instantiated */
  1551 	// NOTE: we do not use symbol->datatype so this cost propagation algorithm will not depend on the fill/narrow datatypes algorithm!
  1831 	// NOTE: we do not use symbol->datatype so this cost propagation algorithm will not depend on the fill/narrow datatypes algorithm!
  1552 	program_type_symtable_t::iterator itr = program_type_symtable.find(symbol->program_type_name);
  1832 	program_type_symtable_t::iterator itr = program_type_symtable.find(symbol->program_type_name);
  1553 	if (itr == program_type_symtable.end()) ERROR; // syntax parsing should not allow this!
  1833 	if (itr == program_type_symtable.end()) ERROR; // syntax parsing should not allow this!
  1554 	program_declaration_c *prog_type = itr->second;
  1834 	program_declaration_c *prog_type = itr->second;
  1564 /* prog_conf_elements ',' prog_conf_element */
  1844 /* prog_conf_elements ',' prog_conf_element */
  1565 // SYM_LIST(prog_conf_elements_c)
  1845 // SYM_LIST(prog_conf_elements_c)
  1566 
  1846 
  1567 /*  fb_name WITH task_name */
  1847 /*  fb_name WITH task_name */
  1568 // SYM_REF2(fb_task_c, fb_name, task_name)
  1848 // SYM_REF2(fb_task_c, fb_name, task_name)
  1569 void *constant_folding_c::visit(fb_task_c *symbol) {
  1849 void *constant_propagation_c::visit(fb_task_c *symbol) {
  1570 	/* find the declaration (i.e. the datatype) of the FB being instantiated */
  1850 	/* find the declaration (i.e. the datatype) of the FB being instantiated */
  1571 	// NOTE: we do not use symbol->datatype so this cost propagation algorithm will not depend on the fill/narrow datatypes algorithm!
  1851 	// NOTE: we do not use symbol->datatype so this cost propagation algorithm will not depend on the fill/narrow datatypes algorithm!
  1572 	symbol_c *fb_type_name = NULL;
  1852 	symbol_c *fb_type_name = NULL;
  1573 	
  1853 	
  1574 	if ((NULL == fb_type_name) && (NULL != current_configuration)) {
  1854 	if ((NULL == fb_type_name) && (NULL != current_configuration)) {
  1608 // SYM_REF2(fb_initialization_c, function_block_type_name, structure_initialization)
  1888 // SYM_REF2(fb_initialization_c, function_block_type_name, structure_initialization)
  1609 
  1889 
  1610 
  1890 
  1611 
  1891 
  1612 
  1892 
  1613 /****************************************/
       
  1614 /* B.2 - Language IL (Instruction List) */
       
  1615 /****************************************/
       
  1616 /***********************************/
       
  1617 /* B 2.1 Instructions and Operands */
       
  1618 /***********************************/
       
  1619 /* Not needed, since we inherit from iterator_visitor_c */
       
  1620 /*| instruction_list il_instruction */
       
  1621 // SYM_LIST(instruction_list_c)
       
  1622 // void *constant_folding_c::visit(instruction_list_c *symbol) {}
       
  1623 
       
  1624 /* | label ':' [il_incomplete_instruction] eol_list */
       
  1625 // SYM_REF2(il_instruction_c, label, il_instruction)
       
  1626 // void *visit(instruction_list_c *symbol);
       
  1627 void *constant_folding_c::visit(il_instruction_c *symbol) {
       
  1628 	if (NULL == symbol->il_instruction) {
       
  1629 		/* This empty/null il_instruction does not change the value of the current/default IL variable.
       
  1630 		 * So it inherits the candidate_datatypes from it's previous IL instructions!
       
  1631 		 */
       
  1632 		intersect_prev_cvalues(symbol);
       
  1633 	} else {
       
  1634 		il_instruction_c fake_prev_il_instruction = *symbol;
       
  1635 		intersect_prev_cvalues(&fake_prev_il_instruction);
       
  1636 
       
  1637 		if (symbol->prev_il_instruction.size() == 0)  prev_il_instruction = NULL;
       
  1638 		else                                          prev_il_instruction = &fake_prev_il_instruction;
       
  1639 		symbol->il_instruction->accept(*this);
       
  1640 		prev_il_instruction = NULL;
       
  1641 
       
  1642 		/* This object has (inherits) the same cvalues as the il_instruction */
       
  1643 		symbol->const_value = symbol->il_instruction->const_value;
       
  1644 	}
       
  1645 
       
  1646 	return NULL;
       
  1647 }
       
  1648 
       
  1649 
       
  1650 void *constant_folding_c::visit(il_simple_operation_c *symbol) {
       
  1651 	/* determine the cvalue of the operand */
       
  1652 	if (NULL != symbol->il_operand) {
       
  1653 		symbol->il_operand->accept(*this);
       
  1654 	}
       
  1655 	/* determine the cvalue resulting from executing the il_operator... */
       
  1656 	il_operand = symbol->il_operand;
       
  1657 	symbol->il_simple_operator->accept(*this);
       
  1658 	il_operand = NULL;
       
  1659 	/* This object has (inherits) the same cvalues as the il_instruction */
       
  1660 	symbol->const_value = symbol->il_simple_operator->const_value;
       
  1661 	return NULL;
       
  1662 }
       
  1663 
       
  1664 
       
  1665 /* TODO: handle function invocations... */
       
  1666 /* | function_name [il_operand_list] */
       
  1667 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */
       
  1668 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
       
  1669 // void *constant_folding_c::visit(il_function_call_c *symbol) {}
       
  1670 
       
  1671 
       
  1672 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
       
  1673 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
       
  1674 void *constant_folding_c::visit(il_expression_c *symbol) {
       
  1675   symbol_c *prev_il_instruction_backup = prev_il_instruction;
       
  1676   
       
  1677   /* Stage2 will insert an artificial (and equivalent) LD <il_operand> to the simple_instr_list if necessary. We can therefore ignore the 'il_operand' entry! */
       
  1678   // if (NULL != symbol->il_operand)
       
  1679   //   symbol->il_operand->accept(*this);
       
  1680 
       
  1681   if(symbol->simple_instr_list != NULL)
       
  1682     symbol->simple_instr_list->accept(*this);
       
  1683 
       
  1684   /* Now do the operation,  */
       
  1685   il_operand = symbol->simple_instr_list;
       
  1686   prev_il_instruction = prev_il_instruction_backup;
       
  1687   symbol->il_expr_operator->accept(*this);
       
  1688   il_operand = NULL;
       
  1689   
       
  1690   /* This object has (inherits) the same cvalues as the il_instruction */
       
  1691   symbol->const_value = symbol->il_expr_operator->const_value;
       
  1692   
       
  1693   /* Since stage2 will insert an artificial (and equivalent) LD <il_operand> to the simple_instr_list when an 'il_operand' exists, we know
       
  1694    * that if (symbol->il_operand != NULL), then the first IL instruction in the simple_instr_list will be the equivalent and artificial
       
  1695    * 'LD <il_operand>' IL instruction.
       
  1696    * Just to be cosistent, we will copy the constant info back into the il_operand, even though this should not be necessary!
       
  1697    */
       
  1698   if ((NULL != symbol->il_operand) && ((NULL == symbol->simple_instr_list) || (0 == ((list_c *)symbol->simple_instr_list)->n))) ERROR; // stage2 is not behaving as we expect it to!
       
  1699   if  (NULL != symbol->il_operand)
       
  1700     symbol->il_operand->const_value = ((list_c *)symbol->simple_instr_list)->elements[0]->const_value;
       
  1701 
       
  1702   return NULL;
       
  1703 }
       
  1704 
       
  1705 
       
  1706 
       
  1707 void *constant_folding_c::visit(il_jump_operation_c *symbol) {
       
  1708   /* recursive call to fill const values... */
       
  1709   il_operand = NULL;
       
  1710   symbol->il_jump_operator->accept(*this);
       
  1711   il_operand = NULL;
       
  1712   /* This object has (inherits) the same cvalues as the il_jump_operator */
       
  1713   symbol->const_value = symbol->il_jump_operator->const_value;
       
  1714   return NULL;
       
  1715 }
       
  1716 
       
  1717 
       
  1718 
       
  1719 /* FB calls leave the value in the accumulator unchanged */
       
  1720 /*   il_call_operator prev_declared_fb_name
       
  1721  * | il_call_operator prev_declared_fb_name '(' ')'
       
  1722  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
       
  1723  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
       
  1724  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
       
  1725  */
       
  1726 /* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */
       
  1727 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
       
  1728 void *constant_folding_c::visit(il_fb_call_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1729 
       
  1730 
       
  1731 /* TODO: handle function invocations... */
       
  1732 /* | function_name '(' eol_list [il_param_list] ')' */
       
  1733 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */
       
  1734 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;)
       
  1735 // void *constant_folding_c::visit(il_formal_funct_call_c *symbol) {return NULL;}
       
  1736 
       
  1737 
       
  1738 
       
  1739 /* Not needed, since we inherit from iterator_visitor_c */
       
  1740 //  void *constant_folding_c::visit(il_operand_list_c *symbol);
       
  1741 
       
  1742 
       
  1743 
       
  1744 /* | simple_instr_list il_simple_instruction */
       
  1745 /* This object is referenced by il_expression_c objects */
       
  1746 void *constant_folding_c::visit(simple_instr_list_c *symbol) {
       
  1747   if (symbol->n <= 0)
       
  1748     return NULL;  /* List is empty! Nothing to do. */
       
  1749     
       
  1750   for(int i = 0; i < symbol->n; i++)
       
  1751     symbol->elements[i]->accept(*this);
       
  1752 
       
  1753   /* This object has (inherits) the same cvalues as the il_jump_operator */
       
  1754   symbol->const_value = symbol->elements[symbol->n-1]->const_value;
       
  1755   return NULL;
       
  1756 }
       
  1757 
       
  1758 
       
  1759 
       
  1760 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
       
  1761 void *constant_folding_c::visit(il_simple_instruction_c *symbol) {
       
  1762   if (symbol->prev_il_instruction.size() > 1) ERROR; /* There should be no labeled insructions inside an IL expression! */
       
  1763   if (symbol->prev_il_instruction.size() == 0)  prev_il_instruction = NULL;
       
  1764   else                                          prev_il_instruction = symbol->prev_il_instruction[0];
       
  1765   symbol->il_simple_instruction->accept(*this);
       
  1766   prev_il_instruction = NULL;
       
  1767 
       
  1768   /* This object has (inherits) the same cvalues as the il_jump_operator */
       
  1769   symbol->const_value = symbol->il_simple_instruction->const_value;
       
  1770   return NULL;
       
  1771 }
       
  1772 
       
  1773 
       
  1774 /*
       
  1775     void *visit(il_param_list_c *symbol);
       
  1776     void *visit(il_param_assignment_c *symbol);
       
  1777     void *visit(il_param_out_assignment_c *symbol);
       
  1778 */
       
  1779 
       
  1780 
       
  1781 /*******************/
       
  1782 /* B 2.2 Operators */
       
  1783 /*******************/
       
  1784 void *constant_folding_c::visit(   LD_operator_c *symbol) {return handle_move(symbol, il_operand);}
       
  1785 void *constant_folding_c::visit(  LDN_operator_c *symbol) {return handle_not (symbol, il_operand);}
       
  1786 
       
  1787 /* NOTE: we are implementing a constant folding algorithm, not a constant propagation algorithm.
       
  1788  *       For the constant propagation algorithm, the correct implementation of ST(N)_operator_c would be...
       
  1789  */
       
  1790 //void *constant_folding_c::visit(   ST_operator_c *symbol) {return handle_move(il_operand, symbol);}
       
  1791 //void *constant_folding_c::visit(  STN_operator_c *symbol) {return handle_not (il_operand, symbol);}
       
  1792 void *constant_folding_c::visit(   ST_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1793 void *constant_folding_c::visit(  STN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1794 
       
  1795 /* NOTE: the standard allows syntax in which the NOT operator is followed by an optional <il_operand>
       
  1796  *              NOT [<il_operand>]
       
  1797  *       However, it does not define the semantic of the NOT operation when the <il_operand> is specified.
       
  1798  *       We therefore consider it an error if an il_operand is specified! This error will be caught elsewhere!
       
  1799  */
       
  1800 void *constant_folding_c::visit(  NOT_operator_c *symbol) {return handle_not(symbol, prev_il_instruction);}
       
  1801 
       
  1802 /* NOTE: Since we are only implementing a constant folding algorithm, and not a constant propagation algorithm,
       
  1803  *       the following IL instructions do not change/set the value of the il_operand!
       
  1804  */
       
  1805 void *constant_folding_c::visit(    S_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1806 void *constant_folding_c::visit(    R_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1807 
       
  1808 /* FB calls leave the value in the accumulator unchanged */
       
  1809 void *constant_folding_c::visit(   S1_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1810 void *constant_folding_c::visit(   R1_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1811 void *constant_folding_c::visit(  CLK_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1812 void *constant_folding_c::visit(   CU_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1813 void *constant_folding_c::visit(   CD_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1814 void *constant_folding_c::visit(   PV_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1815 void *constant_folding_c::visit(   IN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1816 void *constant_folding_c::visit(   PT_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1817 
       
  1818 void *constant_folding_c::visit(  AND_operator_c *symbol) {return handle_and (symbol, prev_il_instruction, il_operand);}
       
  1819 void *constant_folding_c::visit(   OR_operator_c *symbol) {return handle_or  (symbol, prev_il_instruction, il_operand);}
       
  1820 void *constant_folding_c::visit(  XOR_operator_c *symbol) {return handle_xor (symbol, prev_il_instruction, il_operand);}
       
  1821 void *constant_folding_c::visit( ANDN_operator_c *symbol) {       handle_and (symbol, prev_il_instruction, il_operand); return handle_not(symbol, symbol);}
       
  1822 void *constant_folding_c::visit(  ORN_operator_c *symbol) {       handle_or  (symbol, prev_il_instruction, il_operand); return handle_not(symbol, symbol);}
       
  1823 void *constant_folding_c::visit( XORN_operator_c *symbol) {       handle_xor (symbol, prev_il_instruction, il_operand); return handle_not(symbol, symbol);}
       
  1824 
       
  1825 void *constant_folding_c::visit(  ADD_operator_c *symbol) {return handle_add (symbol, prev_il_instruction, il_operand);}
       
  1826 void *constant_folding_c::visit(  SUB_operator_c *symbol) {return handle_sub (symbol, prev_il_instruction, il_operand);}
       
  1827 void *constant_folding_c::visit(  MUL_operator_c *symbol) {return handle_mul (symbol, prev_il_instruction, il_operand);}
       
  1828 void *constant_folding_c::visit(  DIV_operator_c *symbol) {return handle_div (symbol, prev_il_instruction, il_operand);}
       
  1829 void *constant_folding_c::visit(  MOD_operator_c *symbol) {return handle_mod (symbol, prev_il_instruction, il_operand);}
       
  1830 
       
  1831 void *constant_folding_c::visit(   GT_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, > );}
       
  1832 void *constant_folding_c::visit(   GE_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, >=);}
       
  1833 void *constant_folding_c::visit(   EQ_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, ==);}
       
  1834 void *constant_folding_c::visit(   LT_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, < );}
       
  1835 void *constant_folding_c::visit(   LE_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, <=);}
       
  1836 void *constant_folding_c::visit(   NE_operator_c *symbol) {       handle_cmp (symbol, prev_il_instruction, il_operand, !=);}
       
  1837 
       
  1838 void *constant_folding_c::visit(  CAL_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1839 void *constant_folding_c::visit(  RET_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1840 void *constant_folding_c::visit(  JMP_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1841 void *constant_folding_c::visit( CALC_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1842 void *constant_folding_c::visit(CALCN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1843 void *constant_folding_c::visit( RETC_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1844 void *constant_folding_c::visit(RETCN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1845 void *constant_folding_c::visit( JMPC_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1846 void *constant_folding_c::visit(JMPCN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);}
       
  1847 
       
  1848 
       
  1849 
       
  1850 
  1893 
  1851 /***************************************/
  1894 /***************************************/
  1852 /* B.3 - Language ST (Structured Text) */
  1895 /* B.3 - Language ST (Structured Text) */
  1853 /***************************************/
  1896 /***************************************/
  1854 /***********************/
  1897 /***********************/
  1855 /* B 3.1 - Expressions */
  1898 /* B 3.1 - Expressions */
  1856 /***********************/
  1899 /***********************/
  1857 void *constant_folding_c::visit(    or_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_or (symbol, symbol->l_exp, symbol->r_exp);}
  1900 #if DO_CONSTANT_PROPAGATION__
  1858 void *constant_folding_c::visit(   xor_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_xor(symbol, symbol->l_exp, symbol->r_exp);}
       
  1859 void *constant_folding_c::visit(   and_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_and(symbol, symbol->l_exp, symbol->r_exp);}
       
  1860 
       
  1861 void *constant_folding_c::visit(   equ_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, ==);}
       
  1862 void *constant_folding_c::visit(notequ_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, !=);}
       
  1863 void *constant_folding_c::visit(    lt_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, < );}
       
  1864 void *constant_folding_c::visit(    gt_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, > );}
       
  1865 void *constant_folding_c::visit(    le_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, <=);}
       
  1866 void *constant_folding_c::visit(    ge_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this);        handle_cmp (symbol, symbol->l_exp, symbol->r_exp, >=);}
       
  1867 
       
  1868 void *constant_folding_c::visit(   add_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_add(symbol, symbol->l_exp, symbol->r_exp);}
       
  1869 void *constant_folding_c::visit(   sub_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_sub(symbol, symbol->l_exp, symbol->r_exp);}
       
  1870 void *constant_folding_c::visit(   mul_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_mul(symbol, symbol->l_exp, symbol->r_exp);}
       
  1871 void *constant_folding_c::visit(   div_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_div(symbol, symbol->l_exp, symbol->r_exp);}
       
  1872 void *constant_folding_c::visit(   mod_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_mod(symbol, symbol->l_exp, symbol->r_exp);}
       
  1873 void *constant_folding_c::visit( power_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_pow(symbol, symbol->l_exp, symbol->r_exp);}
       
  1874 
       
  1875 void *constant_folding_c::visit(   neg_expression_c *symbol) {symbol->  exp->accept(*this); return handle_neg(symbol, symbol->exp);}
       
  1876 void *constant_folding_c::visit(   not_expression_c *symbol) {symbol->  exp->accept(*this); return handle_not(symbol, symbol->exp);}
       
  1877 
       
  1878 /* TODO: handle function invocations... */
  1901 /* TODO: handle function invocations... */
  1879 // void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) {}
  1902 // void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) {}
  1880 
  1903 
  1881 
  1904 
  1882 
       
  1883 #if DO_CONSTANT_PROPAGATION__
       
  1884 /*********************************/
  1905 /*********************************/
  1885 /* B 3.2.1 Assignment Statements */
  1906 /* B 3.2.1 Assignment Statements */
  1886 /*********************************/
  1907 /*********************************/
  1887 void *constant_folding_c::visit(assignment_statement_c *symbol) {
  1908 void *constant_propagation_c::visit(assignment_statement_c *symbol) {
  1888 	std::string varName;
  1909 	std::string varName;
  1889 
  1910 
  1890 	symbol->r_exp->accept(*this);
  1911 	symbol->r_exp->accept(*this);
  1891 	symbol->l_exp->accept(*this); // if the lvalue has an array, do contant folding of the array indexes!
  1912 	symbol->l_exp->accept(*this); // if the lvalue has an array, do contant folding of the array indexes!
  1892 	symbol->l_exp->const_value = symbol->r_exp->const_value;
  1913 	symbol->l_exp->const_value = symbol->r_exp->const_value;
  1895 }
  1916 }
  1896 
  1917 
  1897 /********************************/
  1918 /********************************/
  1898 /* B 3.2.3 Selection Statements */
  1919 /* B 3.2.3 Selection Statements */
  1899 /********************************/
  1920 /********************************/
  1900 void *constant_folding_c::visit(if_statement_c *symbol) {
  1921 void *constant_propagation_c::visit(if_statement_c *symbol) {
  1901 	map_values_t values_incoming;
  1922 	map_values_t values_incoming;
  1902 	map_values_t values_statement_result;
  1923 	map_values_t values_statement_result;
  1903 	map_values_t values_elsestatement_result;
  1924 	map_values_t values_elsestatement_result;
  1904 	map_values_t::iterator itr;
  1925 	map_values_t::iterator itr;
  1905 
  1926 
  1923 }
  1944 }
  1924 
  1945 
  1925 /********************************/
  1946 /********************************/
  1926 /* B 3.2.4 Iteration Statements */
  1947 /* B 3.2.4 Iteration Statements */
  1927 /********************************/
  1948 /********************************/
  1928 void *constant_folding_c::visit(for_statement_c *symbol) {
  1949 void *constant_propagation_c::visit(for_statement_c *symbol) {
  1929 	map_values_t values_incoming;
  1950 	map_values_t values_incoming;
  1930 	map_values_t values_statement_result;
  1951 	map_values_t values_statement_result;
  1931 
  1952 
  1932 	values_incoming = values; /* save incoming status */
  1953 	values_incoming = values; /* save incoming status */
  1933 	symbol->beg_expression->accept(*this);
  1954 	symbol->beg_expression->accept(*this);
  1960 	values = inner_left_join_values(values_statement_result, values_incoming);
  1981 	values = inner_left_join_values(values_statement_result, values_incoming);
  1961 
  1982 
  1962 	return NULL;
  1983 	return NULL;
  1963 }
  1984 }
  1964 
  1985 
  1965 void *constant_folding_c::visit(while_statement_c *symbol) {
  1986 void *constant_propagation_c::visit(while_statement_c *symbol) {
  1966 	map_values_t values_incoming;
  1987 	map_values_t values_incoming;
  1967 	map_values_t values_statement_result;
  1988 	map_values_t values_statement_result;
  1968 
  1989 
  1969 	/* Optimize dead code */
  1990 	/* Optimize dead code */
  1970 	symbol->expression->accept(*this);
  1991 	symbol->expression->accept(*this);
  1977 	values = inner_left_join_values(values_statement_result, values_incoming);
  1998 	values = inner_left_join_values(values_statement_result, values_incoming);
  1978 
  1999 
  1979 	return NULL;
  2000 	return NULL;
  1980 }
  2001 }
  1981 
  2002 
  1982 void *constant_folding_c::visit(repeat_statement_c *symbol) {
  2003 void *constant_propagation_c::visit(repeat_statement_c *symbol) {
  1983 	map_values_t values_incoming;
  2004 	map_values_t values_incoming;
  1984 	map_values_t values_statement_result;
  2005 	map_values_t values_statement_result;
  1985 
  2006 
  1986 	values_incoming = values; /* save incoming status */
  2007 	values_incoming = values; /* save incoming status */
  1987 	symbol->statement_list->accept(*this);
  2008 	symbol->statement_list->accept(*this);
  2001 
  2022 
  2002 
  2023 
  2003 
  2024 
  2004 
  2025 
  2005 
  2026 
  2006