stage3/print_datatypes_error.cc
changeset 625 c0bda77b37a0
parent 558 9273dfc5fa7c
child 676 ca4f17211251
equal deleted inserted replaced
412:aad38592bdde 625:c0bda77b37a0
       
     1 /*
       
     2  *  matiec - a compiler for the programming languages defined in IEC 61131-3
       
     3  *
       
     4  *  Copyright (C) 2009-2011  Mario de Sousa (msousa@fe.up.pt)
       
     5  *  Copyright (C) 2011-2012 Manuele Conti (manuele.conti@sirius-es.it)
       
     6  *  Copyright (C) 2011-2012 Matteo Facchinetti (matteo.facchinetti@sirius-es.it)
       
     7  *
       
     8  *  This program is free software: you can redistribute it and/or modify
       
     9  *  it under the terms of the GNU General Public License as published by
       
    10  *  the Free Software Foundation, either version 3 of the License, or
       
    11  *  (at your option) any later version.
       
    12  *
       
    13  *  This program is distributed in the hope that it will be useful,
       
    14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    16  *  GNU General Public License for more details.
       
    17  *
       
    18  *  You should have received a copy of the GNU General Public License
       
    19  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
       
    20  *
       
    21  *
       
    22  * This code is made available on the understanding that it will not be
       
    23  * used in safety-critical situations without a full and competent review.
       
    24  */
       
    25 
       
    26 /*
       
    27  * An IEC 61131-3 compiler.
       
    28  *
       
    29  * Based on the
       
    30  * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
       
    31  *
       
    32  */
       
    33 
       
    34 /* NOTE: The algorithm implemented here assumes that the symbol_c.candidate_datatype, and the symbol_c.datatype 
       
    35  *       annotations have already been apropriately filled in!
       
    36  *       BEFORE running this visitor, be sure to CALL the fill_candidate_datatypes_c, and the narrow_candidate_datatypes_c visitors!
       
    37  */
       
    38 
       
    39 
       
    40 /*
       
    41  *  By analysing the candidate datatype lists, as well as the chosen datatype for each expression, determine
       
    42  *  if an datatype error has been found, and if so, print out an error message.
       
    43  */
       
    44 
       
    45 
       
    46 #include "print_datatypes_error.hh"
       
    47 #include "datatype_functions.hh"
       
    48 
       
    49 #include <typeinfo>
       
    50 #include <list>
       
    51 #include <string>
       
    52 #include <string.h>
       
    53 #include <strings.h>
       
    54 
       
    55 
       
    56 
       
    57 
       
    58 
       
    59 
       
    60 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
       
    61 #define  LAST_(symbol1, symbol2) (((symbol1)->last_order  > (symbol2)->last_order)    ? (symbol1) : (symbol2))
       
    62 
       
    63 #define STAGE3_ERROR(error_level, symbol1, symbol2, ...) {                                                                  \
       
    64   if (current_display_error_level >= error_level) {                                                                         \
       
    65     fprintf(stderr, "%s:%d-%d..%d-%d: error: ",                                                                             \
       
    66             FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
       
    67                                                  LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
       
    68     fprintf(stderr, __VA_ARGS__);                                                                                           \
       
    69     fprintf(stderr, "\n");                                                                                                  \
       
    70     il_error = true;                                                                                                        \
       
    71     error_count++;                                                                                                     \
       
    72   }                                                                                                                         \
       
    73 }  
       
    74 
       
    75 
       
    76 #define STAGE3_WARNING(symbol1, symbol2, ...) {                                                                             \
       
    77     fprintf(stderr, "%s:%d-%d..%d-%d: warning: ",                                                                           \
       
    78             FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
       
    79                                                  LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
       
    80     fprintf(stderr, __VA_ARGS__);                                                                                           \
       
    81     fprintf(stderr, "\n");                                                                                                  \
       
    82     warning_found = true;                                                                                                   \
       
    83 }  
       
    84 
       
    85 
       
    86 /* set to 1 to see debug info during execution */
       
    87 static int debug = 0;
       
    88 
       
    89 print_datatypes_error_c::print_datatypes_error_c(symbol_c *ignore) {
       
    90 	error_count = 0;
       
    91 	warning_found = false;
       
    92 	current_display_error_level = error_level_default;
       
    93 }
       
    94 
       
    95 print_datatypes_error_c::~print_datatypes_error_c(void) {
       
    96 }
       
    97 
       
    98 int print_datatypes_error_c::get_error_count() {
       
    99 	return error_count;
       
   100 }
       
   101 
       
   102 
       
   103 
       
   104 
       
   105 
       
   106 /* Verify if the datatypes of all prev_il_instructions are valid and equal!  */
       
   107 static bool are_all_datatypes_of_prev_il_instructions_datatypes_equal(il_instruction_c *symbol) {
       
   108 	if (NULL == symbol) ERROR;
       
   109 	bool res;
       
   110 	
       
   111 	if (symbol->prev_il_instruction.size() > 0)
       
   112 		res = is_type_valid(symbol->prev_il_instruction[0]->datatype);
       
   113 
       
   114 	for (unsigned int i = 1; i < symbol->prev_il_instruction.size(); i++)
       
   115 		res &= is_type_equal(symbol->prev_il_instruction[i-1]->datatype, symbol->prev_il_instruction[i]->datatype);
       
   116 	
       
   117 	return res;
       
   118 }
       
   119 
       
   120 
       
   121 
       
   122 
       
   123 /* a helper function... */
       
   124 symbol_c *print_datatypes_error_c::base_type(symbol_c *symbol) {
       
   125 	/* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used
       
   126 	 *       in the code.
       
   127 	 */
       
   128 	if (symbol == NULL) return NULL;
       
   129 	return (symbol_c *)symbol->accept(search_base_type);
       
   130 }
       
   131 
       
   132 
       
   133 
       
   134 /*
       
   135 typedef struct {
       
   136   symbol_c *function_name,
       
   137   symbol_c *nonformal_operand_list,
       
   138   symbol_c *   formal_operand_list,
       
   139 
       
   140   std::vector <symbol_c *> &candidate_functions,  
       
   141   symbol_c &*called_function_declaration,
       
   142   int      &extensible_param_count
       
   143 } generic_function_call_t;
       
   144 */
       
   145 void print_datatypes_error_c::handle_function_invocation(symbol_c *fcall, generic_function_call_t fcall_data) {
       
   146 	symbol_c *param_value, *param_name;
       
   147 	function_call_param_iterator_c fcp_iterator(fcall);
       
   148 	bool function_invocation_error = false;
       
   149 	const char *POU_str = NULL;
       
   150 
       
   151 	if (generic_function_call_t::POU_FB       == fcall_data.POU_type)  POU_str = "FB";
       
   152 	if (generic_function_call_t::POU_function == fcall_data.POU_type)  POU_str = "function";
       
   153 	if (NULL == POU_str) ERROR;
       
   154 
       
   155 	if ((NULL != fcall_data.formal_operand_list) && (NULL != fcall_data.nonformal_operand_list)) 
       
   156 		ERROR;
       
   157 
       
   158 	symbol_c *f_decl = fcall_data.called_function_declaration;
       
   159 	if ((NULL == f_decl) && (generic_function_call_t::POU_FB ==fcall_data.POU_type)) {
       
   160 		/* Due to the way the syntax analysis is buit (i.e. stage 2), this should never occur. */
       
   161 		/* I.e., a FB invocation using an undefined FB variable is not possible in the current implementation of stage 2. */
       
   162 		ERROR;
       
   163 	}
       
   164 	if (NULL == f_decl) {
       
   165 		/* we now try to find any function declaration with the same name, just so we can provide some relevant error messages */
       
   166 		function_symtable_t::iterator lower = function_symtable.lower_bound(fcall_data.function_name);
       
   167 		if (lower == function_symtable.end()) ERROR;
       
   168 		f_decl = function_symtable.get_value(lower);
       
   169 	}
       
   170 
       
   171 	if (NULL != fcall_data.formal_operand_list) {
       
   172 		fcall_data.formal_operand_list->accept(*this);
       
   173 		if (NULL != f_decl) {
       
   174 			function_param_iterator_c fp_iterator(f_decl);
       
   175 			while ((param_name = fcp_iterator.next_f()) != NULL) {
       
   176 				param_value = fcp_iterator.get_current_value();
       
   177 
       
   178 				/* Check if there are duplicate parameter values */
       
   179 				if(fcp_iterator.search_f(param_name) != param_value) {
       
   180 					function_invocation_error = true;
       
   181 					STAGE3_ERROR(0, param_name, param_name, "Duplicate parameter '%s' when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   182 					continue; /* jump to next parameter */
       
   183 				}
       
   184 
       
   185 				/* Find the corresponding parameter in function declaration */
       
   186 				if (NULL == fp_iterator.search(param_name)) {
       
   187 					function_invocation_error = true;
       
   188 					STAGE3_ERROR(0, param_name, param_name, "Invalid parameter '%s' when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   189 					continue; /* jump to next parameter */
       
   190 				} 
       
   191 
       
   192 				/* check whether direction (IN, OUT, IN_OUT) and assignment types (:= , =>) are compatible !!! */
       
   193 				/* Obtaining the assignment direction:  := (assign_in) or => (assign_out) */
       
   194 				function_call_param_iterator_c::assign_direction_t call_param_dir = fcp_iterator.get_assign_direction();
       
   195 				/* Get the parameter direction: IN, OUT, IN_OUT */
       
   196 				function_param_iterator_c::param_direction_t param_dir = fp_iterator.param_direction();
       
   197 				if          (function_call_param_iterator_c::assign_in  == call_param_dir) {
       
   198 					if ((function_param_iterator_c::direction_in    != param_dir) &&
       
   199 					    (function_param_iterator_c::direction_inout != param_dir)) {
       
   200 						function_invocation_error = true;
       
   201 						STAGE3_ERROR(0, param_name, param_name, "Invalid assignment syntax ':=' used for parameter '%s', when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   202 						continue; /* jump to next parameter */
       
   203 					}
       
   204 				} else if   (function_call_param_iterator_c::assign_out == call_param_dir) {
       
   205 					if ((function_param_iterator_c::direction_out   != param_dir)) {
       
   206 						function_invocation_error = true;
       
   207 						STAGE3_ERROR(0, param_name, param_name, "Invalid assignment syntax '=>' used for parameter '%s', when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   208 						continue; /* jump to next parameter */
       
   209 					}
       
   210 				} else ERROR;
       
   211 
       
   212 				if (NULL == param_value->datatype) {
       
   213 					function_invocation_error = true;
       
   214 					STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility between parameter '%s' and value being passed, when invoking %s '%s'", ((identifier_c *)param_name)->value, POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   215 					continue; /* jump to next parameter */
       
   216 				}
       
   217 			}
       
   218 		}
       
   219 	}
       
   220 	if (NULL != fcall_data.nonformal_operand_list) {
       
   221 		fcall_data.nonformal_operand_list->accept(*this);
       
   222 		if (f_decl)
       
   223 			for (int i = 1; (param_value = fcp_iterator.next_nf()) != NULL; i++) {
       
   224 		  		/* TODO: verify if it is lvalue when INOUT or OUTPUT parameters! */
       
   225 
       
   226 				/* This handle_function_invocation() will be called to handle IL function calls, where the first parameter comes from the previous IL instruction.
       
   227 				 * In this case, the previous IL instruction will be artifically (and temporarily) added to the begining ot the parameter list
       
   228 				 * so we (in this function) can handle this situation like all the other function calls.
       
   229 				 * However, 
       
   230 				 *     a) if NO previous IL function exists, then we get a fake previous IL function, with no location data (i.e. not found anywhere in the source code.
       
   231 				 *     b) the function call may actually have several prev IL instructions (if several JMP instructions jump directly to the il function call).
       
   232 				 * In order to handle these situations gracefully, we first check whether the first parameter is really an IL istruction!
       
   233 				 */
       
   234 				il_instruction_c *il_instruction_symbol = dynamic_cast<il_instruction_c *>(param_value);
       
   235 				if ((NULL != il_instruction_symbol) && (i == 1)) {
       
   236 					/* We are in a situation where an IL function call is passed the first parameter, which is actually the previous IL instruction */
       
   237 					/* However, this is really a fake previous il instruction (see visit(il_instruction_c *) )
       
   238 					 * We will iterate through all the real previous IL instructions, and analyse each of them one by one */
       
   239 					if (il_instruction_symbol->prev_il_instruction.size() == 0) {
       
   240 						function_invocation_error = true;
       
   241 						STAGE3_ERROR(0, fcall, fcall, "No available data to pass to first parameter of IL function %s. Missing a previous LD instruction?", ((identifier_c *)fcall_data.function_name)->value);
       
   242 					}
       
   243 #if 0
       
   244 					/* NOTE: We currently comment out this code...
       
   245 					 * This does not currently work, since the narrow operation is currently done on the intersection 
       
   246 					 * of all the previous IL instructions, so we currently either accept them all, or none at all.
       
   247 					 * In order to be able to produce these user freindly error messages, we will need to update the 
       
   248 					 * narrow algorithm. We leave this untill somebody aks for it...
       
   249 					 * So, for now, we simply comment out this code.
       
   250 					 */
       
   251 					for (unsigned int p = 0; p < il_instruction_symbol->prev_il_instruction.size(); p++) {
       
   252 						symbol_c *value = il_instruction_symbol->prev_il_instruction[p];  
       
   253 						if (!is_type_valid(value->datatype)) {
       
   254 							function_invocation_error = true;
       
   255 							STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility for value passed to first parameter when invoking function '%s'", ((identifier_c *)fcall_data.function_name)->value);
       
   256 							STAGE3_ERROR(0, value, value, "This is the IL instruction producing the incompatible data type to first parameter of function '%s'", ((identifier_c *)fcall_data.function_name)->value);
       
   257 						}
       
   258 					}
       
   259 #else
       
   260 					if (!is_type_valid(il_instruction_symbol->datatype)) {
       
   261 						function_invocation_error = true;
       
   262 						STAGE3_ERROR(0, fcall, fcall, "Data type incompatibility between value in IL 'accumulator' and first parameter of function '%s'", ((identifier_c *)fcall_data.function_name)->value);
       
   263 					}
       
   264 #endif
       
   265 					if (function_invocation_error)
       
   266 						/* when handling a IL function call, and an error is found in the first parameter, then we bug out and do not print out any more error messages. */
       
   267 						return;
       
   268 				}
       
   269 				else if (!is_type_valid(param_value->datatype)) {
       
   270 					function_invocation_error = true;
       
   271 					STAGE3_ERROR(0, param_value, param_value, "Data type incompatibility for value passed in position %d when invoking %s '%s'", i, POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   272 				}
       
   273 			}
       
   274 	}
       
   275 
       
   276 	if (NULL == fcall_data.called_function_declaration) {
       
   277 		function_invocation_error = true;
       
   278 		STAGE3_ERROR(0, fcall, fcall, "Unable to resolve which overloaded %s '%s' is being invoked.", POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   279 	}
       
   280 
       
   281 	if (function_invocation_error) {
       
   282 		/* No compatible function exists */
       
   283 		STAGE3_ERROR(2, fcall, fcall, "Invalid parameters when invoking %s '%s'", POU_str, ((identifier_c *)fcall_data.function_name)->value);
       
   284 	} 
       
   285 
       
   286 	return;
       
   287 }
       
   288 
       
   289 
       
   290 
       
   291 void *print_datatypes_error_c::handle_implicit_il_fb_invocation(const char *param_name, symbol_c *il_operator, symbol_c *called_fb_declaration) {
       
   292 	if (NULL == il_operand) {
       
   293 		STAGE3_ERROR(0, il_operator, il_operator, "Missing operand for FB call operator '%s'.", param_name);
       
   294 		return NULL;
       
   295 	}
       
   296 	il_operand->accept(*this);
       
   297 	
       
   298 	if (NULL == called_fb_declaration) {
       
   299 		STAGE3_ERROR(0, il_operator, il_operand, "Invalid FB call: operand is not a FB instance.");
       
   300 		return NULL;
       
   301 	}
       
   302 
       
   303 	if (fake_prev_il_instruction->prev_il_instruction.empty()) {
       
   304 		STAGE3_ERROR(0, il_operator, il_operand, "FB invocation operator '%s' must be preceded by a 'LD' (or equivalent) operator.", param_name);	
       
   305 		return NULL;
       
   306 	}
       
   307 
       
   308 	/* Find the corresponding parameter in function declaration */
       
   309 	function_param_iterator_c fp_iterator(called_fb_declaration);
       
   310 	if (NULL == fp_iterator.search(param_name)) {
       
   311 		/* TODO: must also check whther it is an IN parameter!! */
       
   312 		/* NOTE: although all standard FBs have the implicit FB calls defined as input parameters
       
   313 		*        (i.e., for all standard FBs, CLK, PT, IN, CU, CD, S1, R1, etc... is always an input parameter)
       
   314 		*        if a non-standard (i.e. a FB not defined in the standard library) FB is being called, then
       
   315 		*        this (CLK, PT, IN, CU, ...) parameter may just have been defined as OUT or INOUT,
       
   316 		*        which will not work for an implicit FB call!
       
   317 		*/
       
   318 		STAGE3_ERROR(0, il_operator, il_operand, "FB called by '%s' operator does not have a parameter named '%s'", param_name, param_name);	
       
   319 		return NULL;
       
   320 	}
       
   321 	if (!are_all_datatypes_of_prev_il_instructions_datatypes_equal(fake_prev_il_instruction)) {
       
   322 		STAGE3_ERROR(0, il_operator, il_operand, "Data type incompatibility between parameter '%s' and value being passed.", param_name);
       
   323 		return NULL;
       
   324 	}
       
   325 	
       
   326 
       
   327 	/* NOTE: The error_level currently being used for errors in variables/constants etc... is rather high.
       
   328 	 *       However, in the case of an implicit FB call, if the datatype of the operand == NULL, this may be
       
   329 	 *       the __only__ indication of an error! So we test it here again, to make sure thtis error will really
       
   330 	 *       be printed out!
       
   331 	 */
       
   332 	if (NULL == il_operand->datatype) {
       
   333 		/* Note: the case of (NULL == fb_declaration) was already caught above! */
       
   334 // 		if (NULL != fb_declaration) {
       
   335 			STAGE3_ERROR(0, il_operator, il_operator, "Invalid FB call: Datatype incompatibility between the FB's '%s' parameter and value being passed, or paramater '%s' is not a 'VAR_INPUT' parameter.", param_name, param_name);
       
   336 			return NULL;
       
   337 // 		}
       
   338 	}
       
   339 
       
   340 	return NULL;
       
   341 }
       
   342 
       
   343 
       
   344 /*********************/
       
   345 /* B 1.2 - Constants */
       
   346 /*********************/
       
   347 /******************************/
       
   348 /* B 1.2.1 - Numeric Literals */
       
   349 /******************************/
       
   350 void *print_datatypes_error_c::visit(real_c *symbol) {
       
   351 	if (symbol->candidate_datatypes.size() == 0) {
       
   352 		STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for ANY_REAL data type.");
       
   353 	} else if (NULL == symbol->datatype) {
       
   354 		STAGE3_ERROR(4, symbol, symbol, "ANY_REAL data type not valid in this location.");
       
   355 	}
       
   356 	return NULL;
       
   357 }
       
   358 
       
   359 void *print_datatypes_error_c::visit(integer_c *symbol) {
       
   360 	if (symbol->candidate_datatypes.size() == 0) {
       
   361 		STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for ANY_INT data type.");
       
   362 	} else if (NULL == symbol->datatype) {
       
   363 		STAGE3_ERROR(4, symbol, symbol, "ANY_INT data type not valid in this location.");
       
   364 	}
       
   365 	return NULL;
       
   366 }
       
   367 
       
   368 void *print_datatypes_error_c::visit(neg_real_c *symbol) {
       
   369 	if (symbol->candidate_datatypes.size() == 0) {
       
   370 		STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for ANY_REAL data type.");
       
   371 	} else if (NULL == symbol->datatype) {
       
   372 		STAGE3_ERROR(4, symbol, symbol, "ANY_REAL data type not valid in this location.");
       
   373 	}
       
   374 	return NULL;
       
   375 }
       
   376 
       
   377 void *print_datatypes_error_c::visit(neg_integer_c *symbol) {
       
   378 	if (symbol->candidate_datatypes.size() == 0) {
       
   379 		STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for ANY_INT data type.");
       
   380 	} else if (NULL == symbol->datatype) {
       
   381 		STAGE3_ERROR(4, symbol, symbol, "ANY_INT data type not valid in this location.");
       
   382 	}
       
   383 	return NULL;
       
   384 }
       
   385 
       
   386 void *print_datatypes_error_c::visit(binary_integer_c *symbol) {
       
   387 	if (symbol->candidate_datatypes.size() == 0) {
       
   388 		STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for ANY_INT data type.");
       
   389 	} else if (NULL == symbol->datatype) {
       
   390 		STAGE3_ERROR(4, symbol, symbol, "ANY_INT data type not valid in this location.");
       
   391 	}
       
   392 	return NULL;
       
   393 }
       
   394 
       
   395 void *print_datatypes_error_c::visit(octal_integer_c *symbol) {
       
   396 	if (symbol->candidate_datatypes.size() == 0) {
       
   397 		STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for ANY_INT data type.");
       
   398 	} else if (NULL == symbol->datatype) {
       
   399 		STAGE3_ERROR(4, symbol, symbol, "ANY_INT data type not valid in this location.");
       
   400 	}
       
   401 	return NULL;
       
   402 }
       
   403 
       
   404 void *print_datatypes_error_c::visit(hex_integer_c *symbol) {
       
   405 	if (symbol->candidate_datatypes.size() == 0) {
       
   406 		STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for ANY_INT data type.");
       
   407 	} else if (NULL == symbol->datatype) {
       
   408 		STAGE3_ERROR(4, symbol, symbol, "ANY_INT data type not valid in this location.");
       
   409 	}
       
   410 	return NULL;
       
   411 }
       
   412 
       
   413 void *print_datatypes_error_c::visit(integer_literal_c *symbol) {
       
   414 	if (symbol->candidate_datatypes.size() == 0) {
       
   415 		STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for %s data type.", elementary_type_c::to_string(symbol->type));
       
   416 	} else if (NULL == symbol->datatype) {
       
   417 		STAGE3_ERROR(4, symbol, symbol, "ANY_INT data type not valid in this location.");
       
   418 	}
       
   419 	return NULL;
       
   420 }
       
   421 
       
   422 void *print_datatypes_error_c::visit(real_literal_c *symbol) {
       
   423 	if (symbol->candidate_datatypes.size() == 0) {
       
   424 		STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for %s data type.", elementary_type_c::to_string(symbol->type));
       
   425 	} else if (NULL == symbol->datatype) {
       
   426 		STAGE3_ERROR(4, symbol, symbol, "ANY_REAL data type not valid in this location.");
       
   427 	}
       
   428 	return NULL;
       
   429 }
       
   430 
       
   431 void *print_datatypes_error_c::visit(bit_string_literal_c *symbol) {
       
   432 	if (symbol->candidate_datatypes.size() == 0) {
       
   433 		STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for %s data type.", elementary_type_c::to_string(symbol->type));
       
   434 	} else if (NULL == symbol->datatype) {
       
   435 		STAGE3_ERROR(4, symbol, symbol, "ANY_BIT data type not valid in this location.");
       
   436 	}
       
   437 	return NULL;
       
   438 }
       
   439 
       
   440 void *print_datatypes_error_c::visit(boolean_literal_c *symbol) {
       
   441 	if (symbol->candidate_datatypes.size() == 0) {
       
   442 		STAGE3_ERROR(0, symbol, symbol, "Value is not valid for %s data type.", elementary_type_c::to_string(symbol->type));
       
   443 	} else if (NULL == symbol->datatype) {
       
   444 		STAGE3_ERROR(4, symbol, symbol, "ANY_BOOL data type not valid in this location.");
       
   445 	}
       
   446 	return NULL;
       
   447 }
       
   448 
       
   449 void *print_datatypes_error_c::visit(boolean_true_c *symbol) {
       
   450 	if (symbol->candidate_datatypes.size() == 0) {
       
   451 		STAGE3_ERROR(0, symbol, symbol, "Value is not valid for ANY_BOOL data type.");
       
   452 	} else if (NULL == symbol->datatype) {
       
   453 		STAGE3_ERROR(4, symbol, symbol, "ANY_BOOL data type not valid in this location.");
       
   454 	}
       
   455 	return NULL;
       
   456 }
       
   457 
       
   458 void *print_datatypes_error_c::visit(boolean_false_c *symbol) {
       
   459 	if (symbol->candidate_datatypes.size() == 0) {
       
   460 		STAGE3_ERROR(0, symbol, symbol, "Value is not valid for ANY_BOOL data type.");
       
   461 	} else if (NULL == symbol->datatype) {
       
   462 		STAGE3_ERROR(4, symbol, symbol, "ANY_BOOL data type not valid in this location.");
       
   463 	}
       
   464 	return NULL;
       
   465 }
       
   466 
       
   467 /*******************************/
       
   468 /* B.1.2.2   Character Strings */
       
   469 /*******************************/
       
   470 void *print_datatypes_error_c::visit(double_byte_character_string_c *symbol) {
       
   471 	if (symbol->candidate_datatypes.size() == 0) {
       
   472 		STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for WSTRING data type.");
       
   473 	} else if (NULL == symbol->datatype) {
       
   474 		STAGE3_ERROR(4, symbol, symbol, "WSTRING data type not valid in this location.");
       
   475 	}
       
   476 	return NULL;
       
   477 }
       
   478 
       
   479 void *print_datatypes_error_c::visit(single_byte_character_string_c *symbol) {
       
   480 	if (symbol->candidate_datatypes.size() == 0) {
       
   481 		STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for STRING data type.");
       
   482 	} else if (NULL == symbol->datatype) {
       
   483 		STAGE3_ERROR(4, symbol, symbol, "STRING data type not valid in this location.");
       
   484 	}
       
   485 	return NULL;
       
   486 }
       
   487 
       
   488 /***************************/
       
   489 /* B 1.2.3 - Time Literals */
       
   490 /***************************/
       
   491 /************************/
       
   492 /* B 1.2.3.1 - Duration */
       
   493 /************************/
       
   494 void *print_datatypes_error_c::visit(duration_c *symbol) {
       
   495 	if (symbol->candidate_datatypes.size() == 0) {
       
   496 		STAGE3_ERROR(0, symbol, symbol, "Invalid syntax for TIME data type.");
       
   497 	} else if (NULL == symbol->datatype) {
       
   498 		STAGE3_ERROR(4, symbol, symbol, "TIME data type not valid in this location.");
       
   499 	}
       
   500 	return NULL;
       
   501 }
       
   502 
       
   503 /************************************/
       
   504 /* B 1.2.3.2 - Time of day and Date */
       
   505 /************************************/
       
   506 void *print_datatypes_error_c::visit(time_of_day_c *symbol) {
       
   507 	if (symbol->candidate_datatypes.size() == 0) {
       
   508 		STAGE3_ERROR(0, symbol, symbol, "Invalid syntax for TOD data type.");
       
   509 	} else if (NULL == symbol->datatype) {
       
   510 		STAGE3_ERROR(4, symbol, symbol, "TOD data type not valid in this location.");
       
   511 	}
       
   512 	return NULL;
       
   513 }
       
   514 
       
   515 void *print_datatypes_error_c::visit(date_c *symbol) {
       
   516 	if (symbol->candidate_datatypes.size() == 0) {
       
   517 		STAGE3_ERROR(0, symbol, symbol, "Invalid syntax for DATE data type.");
       
   518 	} else if (NULL == symbol->datatype) {
       
   519 		STAGE3_ERROR(4, symbol, symbol, "DATE data type not valid in this location.");
       
   520 	}
       
   521 	return NULL;
       
   522 }
       
   523 
       
   524 void *print_datatypes_error_c::visit(date_and_time_c *symbol) {
       
   525 	if (symbol->candidate_datatypes.size() == 0) {
       
   526 		STAGE3_ERROR(0, symbol, symbol, "Invalid syntax for DT data type.");
       
   527 	} else if (NULL == symbol->datatype) {
       
   528 		STAGE3_ERROR(4, symbol, symbol, "DT data type not valid in this location.");
       
   529 	}
       
   530 	return NULL;
       
   531 }
       
   532 
       
   533 /**********************/
       
   534 /* B 1.3 - Data types */
       
   535 /**********************/
       
   536 /********************************/
       
   537 /* B 1.3.3 - Derived data types */
       
   538 /********************************/
       
   539 void *print_datatypes_error_c::visit(simple_spec_init_c *symbol) {
       
   540 	if (!is_type_valid(symbol->simple_specification->datatype)) {
       
   541 		STAGE3_ERROR(0, symbol->simple_specification, symbol->simple_specification, "Invalid data type.");
       
   542 	} else if (NULL != symbol->constant) {
       
   543 		if (!is_type_valid(symbol->constant->datatype))
       
   544 			STAGE3_ERROR(0, symbol->constant, symbol->constant, "Initial value has incompatible data type.");
       
   545 	} else if (!is_type_valid(symbol->datatype)) {
       
   546 		ERROR; /* If we have an error here, then we must also have an error in one of
       
   547 		        * the two previous tests. If we reach this point, some strange error is ocurring!
       
   548 			*/
       
   549 	}
       
   550 	return NULL;
       
   551 }
       
   552 
       
   553 void *print_datatypes_error_c::visit(data_type_declaration_c *symbol) {
       
   554 	// TODO !!!
       
   555 	/* for the moment we must return NULL so semantic analysis of remaining code is not interrupted! */
       
   556 	return NULL;
       
   557 }
       
   558 
       
   559 void *print_datatypes_error_c::visit(enumerated_value_c *symbol) {
       
   560 	if (symbol->candidate_datatypes.size() == 0)
       
   561 		STAGE3_ERROR(0, symbol, symbol, "Ambiguous enumerate value or Variable not declared in this scope.");
       
   562 	return NULL;
       
   563 }
       
   564 
       
   565 
       
   566 /*********************/
       
   567 /* B 1.4 - Variables */
       
   568 /*********************/
       
   569 void *print_datatypes_error_c::visit(symbolic_variable_c *symbol) {
       
   570 	if (symbol->candidate_datatypes.size() == 0)
       
   571 		STAGE3_ERROR(0, symbol, symbol, "Variable not declared in this scope.");
       
   572 	return NULL;
       
   573 }
       
   574 
       
   575 /********************************************/
       
   576 /* B 1.4.1 - Directly Represented Variables */
       
   577 /********************************************/
       
   578 void *print_datatypes_error_c::visit(direct_variable_c *symbol) {
       
   579 	if (symbol->candidate_datatypes.size() == 0) ERROR;
       
   580 	if (!is_type_valid(symbol->datatype))
       
   581 		STAGE3_ERROR(4, symbol, symbol, "Direct variable has incompatible data type with expression.");
       
   582 	return NULL;
       
   583 }
       
   584 
       
   585 /*************************************/
       
   586 /* B 1.4.2 - Multi-element variables */
       
   587 /*************************************/
       
   588 /*  subscripted_variable '[' subscript_list ']' */
       
   589 // SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
       
   590 void *print_datatypes_error_c::visit(array_variable_c *symbol) {
       
   591 	if (symbol->candidate_datatypes.size() == 0)
       
   592 		STAGE3_ERROR(0, symbol, symbol, "Array variable not declared in this scope.");
       
   593 	
       
   594 	/* recursively call the subscript list to print any errors in the expressions used in the subscript...*/
       
   595 	symbol->subscript_list->accept(*this);
       
   596 	return NULL;
       
   597 }
       
   598 
       
   599 /* subscript_list ',' subscript */
       
   600 // SYM_LIST(subscript_list_c)
       
   601 void *print_datatypes_error_c::visit(subscript_list_c *symbol) {
       
   602 	for (int i = 0; i < symbol->n; i++) {
       
   603 		int start_error_count = error_count;
       
   604 		symbol->elements[i]->accept(*this);
       
   605 		/* The following error message will only get printed if the current_display_error_level is set higher than 0! */
       
   606 		if ((start_error_count == error_count) && (NULL == symbol->elements[i]->datatype))
       
   607 			STAGE3_ERROR(0, symbol, symbol, "Invalid data type for array subscript field.");
       
   608 	}
       
   609 	return NULL;
       
   610 }
       
   611 
       
   612 
       
   613 /*  record_variable '.' field_selector */
       
   614 /*  WARNING: input and/or output variables of function blocks
       
   615  *           may be accessed as fields of a structured variable!
       
   616  *           Code handling a structured_variable_c must take
       
   617  *           this into account!
       
   618  */
       
   619 // SYM_REF2(structured_variable_c, record_variable, field_selector)
       
   620 /* NOTE: We do not recursively determine the data types of each field_selector in fill_candidate_datatypes_c,
       
   621  * so it does not make sense to recursively visit all the field_selectors to print out error messages. 
       
   622  * Maybe in the future, if we find the need to print out more detailed error messages, we might do it that way. For now, we don't!
       
   623  */
       
   624 void *print_datatypes_error_c::visit(structured_variable_c *symbol) {
       
   625 	if (symbol->candidate_datatypes.size() == 0)
       
   626 		STAGE3_ERROR(0, symbol, symbol, "Undeclared structured/FB variable.");
       
   627 	return NULL;
       
   628 }
       
   629 
       
   630 
       
   631 
       
   632 /******************************************/
       
   633 /* B 1.4.3 - Declaration & Initialisation */
       
   634 /******************************************/
       
   635 
       
   636 /*  AT direct_variable */
       
   637 // SYM_REF1(location_c, direct_variable)
       
   638 void *print_datatypes_error_c::visit(location_c *symbol) {
       
   639 	symbol->direct_variable->accept(*this);
       
   640 	return NULL;
       
   641 }
       
   642 
       
   643 
       
   644 /*  [variable_name] location ':' located_var_spec_init */
       
   645 /* variable_name -> may be NULL ! */
       
   646 // SYM_REF3(located_var_decl_c, variable_name, location, located_var_spec_init)
       
   647 void *print_datatypes_error_c::visit(located_var_decl_c *symbol) {
       
   648   symbol->located_var_spec_init->accept(*this);
       
   649   /* It does not make sense to call symbol->location->accept(*this). The check is done right here if the following if() */
       
   650   // symbol->location->accept(*this); 
       
   651   if ((is_type_valid(symbol->located_var_spec_init->datatype)) && (!is_type_valid(symbol->location->datatype)))
       
   652     STAGE3_ERROR(0, symbol, symbol, "Bit size of data type is incompatible with bit size of location.");
       
   653   return NULL;
       
   654 }  
       
   655 
       
   656 
       
   657 /************************************/
       
   658 /* B 1.5 Program organization units */
       
   659 /************************************/
       
   660 /*********************/
       
   661 /* B 1.5.1 Functions */
       
   662 /*********************/
       
   663 void *print_datatypes_error_c::visit(function_declaration_c *symbol) {
       
   664 	search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
       
   665 	/* We do not check for data type errors in variable declarations, Skip this for now... */
       
   666 // 	symbol->var_declarations_list->accept(*this);
       
   667 	if (debug) printf("Print error data types list in body of function %s\n", ((token_c *)(symbol->derived_function_name))->value);
       
   668 	il_parenthesis_level = 0;
       
   669 	il_error = false;
       
   670 	symbol->function_body->accept(*this);
       
   671 	delete search_varfb_instance_type;
       
   672 	search_varfb_instance_type = NULL;
       
   673 	return NULL;
       
   674 }
       
   675 
       
   676 /***************************/
       
   677 /* B 1.5.2 Function blocks */
       
   678 /***************************/
       
   679 void *print_datatypes_error_c::visit(function_block_declaration_c *symbol) {
       
   680 	search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
       
   681 	/* We do not check for data type errors in variable declarations, Skip this for now... */
       
   682 // 	symbol->var_declarations->accept(*this);
       
   683 	if (debug) printf("Print error data types list in body of FB %s\n", ((token_c *)(symbol->fblock_name))->value);
       
   684 	il_parenthesis_level = 0;
       
   685 	il_error = false;
       
   686 	symbol->fblock_body->accept(*this);
       
   687 	delete search_varfb_instance_type;
       
   688 	search_varfb_instance_type = NULL;
       
   689 	return NULL;
       
   690 }
       
   691 
       
   692 /**********************/
       
   693 /* B 1.5.3 - Programs */
       
   694 /**********************/
       
   695 void *print_datatypes_error_c::visit(program_declaration_c *symbol) {
       
   696 	search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
       
   697 	/* We do not check for data type errors in variable declarations, Skip this for now... */
       
   698 	symbol->var_declarations->accept(*this);
       
   699 	if (debug) printf("Print error data types list in body of program %s\n", ((token_c *)(symbol->program_type_name))->value);
       
   700 	il_parenthesis_level = 0;
       
   701 	il_error = false;
       
   702 	symbol->function_block_body->accept(*this);
       
   703 	delete search_varfb_instance_type;
       
   704 	search_varfb_instance_type = NULL;
       
   705 	return NULL;
       
   706 }
       
   707 
       
   708 
       
   709 
       
   710 /********************************/
       
   711 /* B 1.7 Configuration elements */
       
   712 /********************************/
       
   713 void *print_datatypes_error_c::visit(configuration_declaration_c *symbol) {
       
   714 	// TODO !!!
       
   715 	/* for the moment we must return NULL so semantic analysis of remaining code is not interrupted! */
       
   716 	return NULL;
       
   717 }
       
   718 
       
   719 /****************************************/
       
   720 /* B.2 - Language IL (Instruction List) */
       
   721 /****************************************/
       
   722 /***********************************/
       
   723 /* B 2.1 Instructions and Operands */
       
   724 /***********************************/
       
   725 
       
   726 // void *visit(instruction_list_c *symbol);
       
   727 
       
   728 /* | label ':' [il_incomplete_instruction] eol_list */
       
   729 // SYM_REF2(il_instruction_c, label, il_instruction)
       
   730 void *print_datatypes_error_c::visit(il_instruction_c *symbol) {
       
   731 	if (NULL != symbol->il_instruction) {
       
   732 		il_instruction_c tmp_prev_il_instruction(NULL, NULL);
       
   733 #if 0
       
   734 		/* NOTE: The following is currently no longer needed. Since the following code is actually cool, 
       
   735 		 * we don't delete it, but simply comment it out. It might just come in handy later on...
       
   736 		 */
       
   737 		/* When handling a il function call, this fake_prev_il_instruction may be used as a standard function call parameter, so it is important that 
       
   738 		 * it contain some valid location info so error messages make sense.
       
   739 		 */
       
   740 		if (symbol->prev_il_instruction.size() > 0) {
       
   741 			/* since we don't want to copy all that data one variable at a time, we copy it all at once */
       
   742 			/* This has the advantage that, if we ever add some more data to the base symbol_c later on, we will not need to
       
   743 			 * change the following line to guarantee that the data is copied correctly!
       
   744 			 * However, it does have the drawback of copying more data than what we want!
       
   745 			 * In order to only copy the data in the base class symbol_c, we use the tmp_symbol pointer!
       
   746 			 * I (mario) have checked with a debugger, and it is working as intended!
       
   747 			 */
       
   748 			symbol_c *tmp_symbol1 = symbol->prev_il_instruction[0];
       
   749 			symbol_c *tmp_symbol2 = &tmp_prev_il_instruction;
       
   750 			*tmp_symbol2 = *tmp_symbol1;
       
   751 			/* we do not want to copy the datatype variable, so we reset it to NULL */
       
   752 			tmp_prev_il_instruction.datatype = NULL;
       
   753 			/* We don't need to worry about the candidate_datatype list (which we don't want to copy just yet), since that will 
       
   754 			 * be reset to the correct value when we call intersect_prev_candidate_datatype_lists() later on...
       
   755 			 */
       
   756 		}
       
   757 #endif
       
   758 		/* the print error algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the 
       
   759 		 * list of the prev_il_instructions.
       
   760 		 * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction),
       
   761 		 * and shove that data into this single variable.
       
   762 		 */
       
   763 		tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction;
       
   764 		intersect_prev_candidate_datatype_lists(&tmp_prev_il_instruction);
       
   765 		if (are_all_datatypes_of_prev_il_instructions_datatypes_equal(symbol))
       
   766 			if (symbol->prev_il_instruction.size() > 0)
       
   767 				tmp_prev_il_instruction.datatype = (symbol->prev_il_instruction[0])->datatype;
       
   768 		
       
   769 		/* Tell the il_instruction the datatype that it must generate - this was chosen by the next il_instruction (remember: we are iterating backwards!) */
       
   770 		fake_prev_il_instruction = &tmp_prev_il_instruction;
       
   771 		symbol->il_instruction->accept(*this);
       
   772 		fake_prev_il_instruction = NULL;
       
   773 	}
       
   774 
       
   775 	return NULL;
       
   776 }
       
   777 
       
   778 
       
   779 
       
   780 void *print_datatypes_error_c::visit(il_simple_operation_c *symbol) {
       
   781 	il_operand = symbol->il_operand;
       
   782 	if (NULL != symbol->il_operand) {
       
   783 		symbol->il_operand->accept(*this);
       
   784 	}
       
   785 	/* recursive call to see whether data types are compatible */
       
   786 	symbol->il_simple_operator->accept(*this);
       
   787 	il_operand = NULL;
       
   788 	return NULL;
       
   789 }
       
   790 
       
   791 /* | function_name [il_operand_list] */
       
   792 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */
       
   793 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
       
   794 void *print_datatypes_error_c::visit(il_function_call_c *symbol) {
       
   795 	/* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction)
       
   796 	 * In order to be able to handle this without coding special cases, we will simply prepend that symbol
       
   797 	 * to the il_operand_list, and remove it after calling handle_function_call().
       
   798 	 *
       
   799 	 * However, if no further paramters are given, then il_operand_list will be NULL, and we will
       
   800 	 * need to create a new object to hold the pointer to prev_il_instruction.
       
   801 	 * This change will also be undone later in print_datatypes_error_c.
       
   802 	 */
       
   803 	if (NULL == symbol->il_operand_list)  symbol->il_operand_list = new il_operand_list_c;
       
   804 	if (NULL == symbol->il_operand_list)  ERROR;
       
   805 
       
   806 	((list_c *)symbol->il_operand_list)->insert_element(fake_prev_il_instruction, 0);
       
   807 
       
   808 	generic_function_call_t fcall_param = {
       
   809 		/* fcall_param.function_name               = */ symbol->function_name,
       
   810 		/* fcall_param.nonformal_operand_list      = */ symbol->il_operand_list,
       
   811 		/* fcall_param.formal_operand_list         = */ NULL,
       
   812 		/* enum {POU_FB, POU_function} POU_type    = */ generic_function_call_t::POU_function,
       
   813 		/* fcall_param.candidate_functions         = */ symbol->candidate_functions,
       
   814 		/* fcall_param.called_function_declaration = */ symbol->called_function_declaration,
       
   815 		/* fcall_param.extensible_param_count      = */ symbol->extensible_param_count
       
   816 	};
       
   817 
       
   818 /* TODO: check what error message (if any) the compiler will give out if this function invocation
       
   819  * is not preceded by a LD operator (or another equivalent operator or list of operators).
       
   820  */
       
   821 	handle_function_invocation(symbol, fcall_param);
       
   822 	
       
   823 	/* We now undo those changes to the abstract syntax tree made above! */
       
   824 	((list_c *)symbol->il_operand_list)->remove_element(0);
       
   825 	if (((list_c *)symbol->il_operand_list)->n == 0) {
       
   826 		/* if the list becomes empty, then that means that it did not exist before we made these changes, so we delete it! */
       
   827 		delete 	symbol->il_operand_list;
       
   828 		symbol->il_operand_list = NULL;
       
   829 	}
       
   830 
       
   831 	return NULL;
       
   832 }
       
   833 
       
   834 
       
   835 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
       
   836 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
       
   837 void *print_datatypes_error_c::visit(il_expression_c *symbol) {
       
   838   /* first give the parenthesised IL list a chance to print errors */
       
   839   il_instruction_c *save_fake_prev_il_instruction = fake_prev_il_instruction;
       
   840   symbol->simple_instr_list->accept(*this);
       
   841   fake_prev_il_instruction = save_fake_prev_il_instruction;
       
   842 
       
   843   /* Now handle the operation (il_expr_operator) that will use the result coming from the parenthesised IL list (i.e. simple_instr_list) */
       
   844   il_operand = symbol->simple_instr_list; /* This is not a bug! The parenthesised expression will be used as the operator! */
       
   845   symbol->il_expr_operator->accept(*this);
       
   846 
       
   847 return NULL;
       
   848 }
       
   849 
       
   850 
       
   851 /*   il_call_operator prev_declared_fb_name
       
   852  * | il_call_operator prev_declared_fb_name '(' ')'
       
   853  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
       
   854  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
       
   855  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
       
   856  */
       
   857 /* 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 */
       
   858 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
       
   859 void *print_datatypes_error_c::visit(il_fb_call_c *symbol) {
       
   860 	int extensible_param_count;                      /* unused vairable! Needed for compilation only! */
       
   861 	std::vector <symbol_c *> candidate_functions;    /* unused vairable! Needed for compilation only! */
       
   862 	generic_function_call_t fcall_param = {
       
   863 		/* fcall_param.function_name               = */ symbol->fb_name,
       
   864 		/* fcall_param.nonformal_operand_list      = */ symbol->il_operand_list,
       
   865 		/* fcall_param.formal_operand_list         = */ symbol->il_param_list,
       
   866 		/* enum {POU_FB, POU_function} POU_type    = */ generic_function_call_t::POU_FB,
       
   867 		/* fcall_param.candidate_functions         = */ candidate_functions,             /* will not be used, but must provide a reference to be able to compile */
       
   868 		/* fcall_param.called_function_declaration = */ symbol->called_fb_declaration,
       
   869 		/* fcall_param.extensible_param_count      = */ extensible_param_count           /* will not be used, but must provide a reference to be able to compile */
       
   870 	};
       
   871   
       
   872 	handle_function_invocation(symbol, fcall_param);
       
   873 	/* check the semantics of the CALC, CALCN operators! */
       
   874 	symbol->il_call_operator->accept(*this);
       
   875 	return NULL;
       
   876 }
       
   877 
       
   878 /* | function_name '(' eol_list [il_param_list] ')' */
       
   879 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */
       
   880 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;)
       
   881 void *print_datatypes_error_c::visit(il_formal_funct_call_c *symbol) {
       
   882 	generic_function_call_t fcall_param = {
       
   883 		/* fcall_param.function_name               = */ symbol->function_name,
       
   884 		/* fcall_param.nonformal_operand_list      = */ NULL,
       
   885 		/* fcall_param.formal_operand_list         = */ symbol->il_param_list,
       
   886 		/* enum {POU_FB, POU_function} POU_type    = */ generic_function_call_t::POU_function,
       
   887 		/* fcall_param.candidate_functions         = */ symbol->candidate_functions,
       
   888 		/* fcall_param.called_function_declaration = */ symbol->called_function_declaration,
       
   889 		/* fcall_param.extensible_param_count      = */ symbol->extensible_param_count
       
   890 	};
       
   891   
       
   892 	handle_function_invocation(symbol, fcall_param);
       
   893 	return NULL;
       
   894 }
       
   895 
       
   896 
       
   897 //     void *visit(il_operand_list_c *symbol);
       
   898 //     void *visit(simple_instr_list_c *symbol);
       
   899 
       
   900 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
       
   901 void *print_datatypes_error_c::visit(il_simple_instruction_c *symbol)	{
       
   902   if (symbol->prev_il_instruction.size() > 1) ERROR; /* There should be no labeled insructions inside an IL expression! */
       
   903     
       
   904   il_instruction_c tmp_prev_il_instruction(NULL, NULL);
       
   905   /* the print error algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the 
       
   906    * list of the prev_il_instructions.
       
   907    * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction),
       
   908    * and shove that data into this single variable.
       
   909    */
       
   910   if (symbol->prev_il_instruction.size() > 0)
       
   911     tmp_prev_il_instruction.candidate_datatypes = symbol->prev_il_instruction[0]->candidate_datatypes;
       
   912   tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction;
       
   913   
       
   914    /* copy the candidate_datatypes list */
       
   915   fake_prev_il_instruction = &tmp_prev_il_instruction;
       
   916   symbol->il_simple_instruction->accept(*this);
       
   917   fake_prev_il_instruction = NULL;
       
   918   return NULL;
       
   919   
       
   920   
       
   921 //   if (symbol->prev_il_instruction.size() == 0)  prev_il_instruction = NULL;
       
   922 //   else                                          prev_il_instruction = symbol->prev_il_instruction[0];
       
   923 
       
   924 //   symbol->il_simple_instruction->accept(*this);
       
   925 //   prev_il_instruction = NULL;
       
   926 //   return NULL;
       
   927 }
       
   928 
       
   929 
       
   930 //     void *visit(il_param_list_c *symbol);
       
   931 //     void *visit(il_param_assignment_c *symbol);
       
   932 //     void *visit(il_param_out_assignment_c *symbol);
       
   933 
       
   934 /*******************/
       
   935 /* B 2.2 Operators */
       
   936 /*******************/
       
   937 void *print_datatypes_error_c::print_binary_operator_errors(const char *il_operator, symbol_c *symbol, bool deprecated_operation) {
       
   938 	if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) {
       
   939 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for '%s' operator.", il_operator);
       
   940 	} else if (NULL == symbol->datatype) {
       
   941 		STAGE3_WARNING(symbol, symbol, "Result of '%s' operation is never used.", il_operator);
       
   942 	} else if (deprecated_operation)
       
   943 		STAGE3_WARNING(symbol, symbol, "Deprecated operation for '%s' operator.", il_operator);
       
   944 	return NULL;
       
   945 }
       
   946 
       
   947 
       
   948 void *print_datatypes_error_c::visit(LD_operator_c *symbol) {
       
   949 	return NULL;
       
   950 }
       
   951 
       
   952 void *print_datatypes_error_c::visit(LDN_operator_c *symbol) {
       
   953 	if ((symbol->candidate_datatypes.size() == 0) 		&&
       
   954 		(il_operand->candidate_datatypes.size() > 0))
       
   955 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'LDN' operator.");
       
   956 	return NULL;
       
   957 }
       
   958 
       
   959 void *print_datatypes_error_c::visit(ST_operator_c *symbol) {
       
   960 	/* MANU:
       
   961 	 * if prev_instruction is NULL we can print a message error or warning error like:
       
   962 	 * we can't use a ST like first instruction.
       
   963 	 * What do you think?
       
   964 	 */
       
   965 	if ((symbol->candidate_datatypes.size() == 0) 		&&
       
   966 		(il_operand->candidate_datatypes.size() > 0))
       
   967 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'ST' operator.");
       
   968 	return NULL;
       
   969 }
       
   970 
       
   971 void *print_datatypes_error_c::visit(STN_operator_c *symbol) {
       
   972 	/* MANU:
       
   973 	 * if prev_instruction is NULL we can print a message error or warning error like:
       
   974 	 * we can't use a ST like first instruction.
       
   975 	 * What do you think?
       
   976 	 */
       
   977 	if ((symbol->candidate_datatypes.size() == 0) 		&&
       
   978 		(il_operand->candidate_datatypes.size() > 0))
       
   979 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'STN' operator.");
       
   980 	return NULL;
       
   981 }
       
   982 
       
   983 void *print_datatypes_error_c::visit(NOT_operator_c *symbol) {
       
   984 	/* NOTE: the standard allows syntax in which the NOT operator is followed by an optional <il_operand>
       
   985 	 *              NOT [<il_operand>]
       
   986 	 *       However, it does not define the semantic of the NOT operation when the <il_operand> is specified.
       
   987 	 *       We therefore consider it an error if an il_operand is specified!
       
   988 	 */
       
   989 	if (il_operand != NULL)
       
   990 		STAGE3_ERROR(0, symbol, symbol, "'NOT' operator may not have an operand.");
       
   991 	if (symbol->candidate_datatypes.size() == 0)
       
   992 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'NOT' operator.");
       
   993 	return NULL;
       
   994 }
       
   995 
       
   996 void *print_datatypes_error_c::visit(S_operator_c *symbol) {
       
   997   /* TODO: what if this is a FB call ?? */
       
   998 	if ((symbol->candidate_datatypes.size() == 0) 		&&
       
   999 		(il_operand->candidate_datatypes.size() > 0))
       
  1000 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'S' operator.");
       
  1001 	return NULL;
       
  1002 }
       
  1003 
       
  1004 void *print_datatypes_error_c::visit(R_operator_c *symbol) {
       
  1005   /* TODO: what if this is a FB call ?? */
       
  1006 	if ((symbol->candidate_datatypes.size() == 0) 		&&
       
  1007 		(il_operand->candidate_datatypes.size() > 0))
       
  1008 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'R' operator.");
       
  1009 	return NULL;
       
  1010 }
       
  1011 
       
  1012 void *print_datatypes_error_c::visit( S1_operator_c *symbol) {return handle_implicit_il_fb_invocation( "S1", symbol, symbol->called_fb_declaration);}
       
  1013 void *print_datatypes_error_c::visit( R1_operator_c *symbol) {return handle_implicit_il_fb_invocation( "R1", symbol, symbol->called_fb_declaration);}
       
  1014 void *print_datatypes_error_c::visit(CLK_operator_c *symbol) {return handle_implicit_il_fb_invocation("CLK", symbol, symbol->called_fb_declaration);}
       
  1015 void *print_datatypes_error_c::visit( CU_operator_c *symbol) {return handle_implicit_il_fb_invocation( "CU", symbol, symbol->called_fb_declaration);}
       
  1016 void *print_datatypes_error_c::visit( CD_operator_c *symbol) {return handle_implicit_il_fb_invocation( "CD", symbol, symbol->called_fb_declaration);}
       
  1017 void *print_datatypes_error_c::visit( PV_operator_c *symbol) {return handle_implicit_il_fb_invocation( "PV", symbol, symbol->called_fb_declaration);}
       
  1018 void *print_datatypes_error_c::visit( IN_operator_c *symbol) {return handle_implicit_il_fb_invocation( "IN", symbol, symbol->called_fb_declaration);}
       
  1019 void *print_datatypes_error_c::visit( PT_operator_c *symbol) {return handle_implicit_il_fb_invocation( "PT", symbol, symbol->called_fb_declaration);}
       
  1020 
       
  1021 void *print_datatypes_error_c::visit( AND_operator_c *symbol) {return print_binary_operator_errors("AND" , symbol);}
       
  1022 void *print_datatypes_error_c::visit(  OR_operator_c *symbol) {return print_binary_operator_errors( "OR" , symbol);}
       
  1023 void *print_datatypes_error_c::visit( XOR_operator_c *symbol) {return print_binary_operator_errors("XOR" , symbol);}
       
  1024 void *print_datatypes_error_c::visit(ANDN_operator_c *symbol) {return print_binary_operator_errors("ANDN", symbol);}
       
  1025 void *print_datatypes_error_c::visit( ORN_operator_c *symbol) {return print_binary_operator_errors( "ORN", symbol);}
       
  1026 void *print_datatypes_error_c::visit(XORN_operator_c *symbol) {return print_binary_operator_errors("XORN", symbol);}
       
  1027 void *print_datatypes_error_c::visit( ADD_operator_c *symbol) {return print_binary_operator_errors("ADD" , symbol, symbol->deprecated_operation);}
       
  1028 void *print_datatypes_error_c::visit( SUB_operator_c *symbol) {return print_binary_operator_errors("SUB" , symbol, symbol->deprecated_operation);}
       
  1029 void *print_datatypes_error_c::visit( MUL_operator_c *symbol) {return print_binary_operator_errors("MUL" , symbol, symbol->deprecated_operation);}
       
  1030 void *print_datatypes_error_c::visit( DIV_operator_c *symbol) {return print_binary_operator_errors("DIV" , symbol, symbol->deprecated_operation);}
       
  1031 void *print_datatypes_error_c::visit( MOD_operator_c *symbol) {return print_binary_operator_errors("MOD" , symbol);}
       
  1032 
       
  1033 void *print_datatypes_error_c::visit(  GT_operator_c *symbol) {return print_binary_operator_errors( "GT" , symbol);}
       
  1034 void *print_datatypes_error_c::visit(  GE_operator_c *symbol) {return print_binary_operator_errors( "GE" , symbol);}
       
  1035 void *print_datatypes_error_c::visit(  EQ_operator_c *symbol) {return print_binary_operator_errors( "EQ" , symbol);}
       
  1036 void *print_datatypes_error_c::visit(  LT_operator_c *symbol) {return print_binary_operator_errors( "LT" , symbol);}
       
  1037 void *print_datatypes_error_c::visit(  LE_operator_c *symbol) {return print_binary_operator_errors( "LE" , symbol);}
       
  1038 void *print_datatypes_error_c::visit(  NE_operator_c *symbol) {return print_binary_operator_errors( "NE" , symbol);}
       
  1039 
       
  1040   
       
  1041 
       
  1042 
       
  1043 void *print_datatypes_error_c::handle_conditional_flow_control_IL_instruction(symbol_c *symbol, const char *oper) {
       
  1044 	if (NULL == symbol->datatype)
       
  1045 		STAGE3_ERROR(0, symbol, symbol, "%s operator must be preceded by an IL instruction producing a BOOL value.", oper);
       
  1046 	return NULL;
       
  1047 }
       
  1048 
       
  1049 void *print_datatypes_error_c::visit(  CAL_operator_c *symbol) {return NULL;}
       
  1050 void *print_datatypes_error_c::visit( CALC_operator_c *symbol) {return handle_conditional_flow_control_IL_instruction(symbol, "CALC" );}
       
  1051 void *print_datatypes_error_c::visit(CALCN_operator_c *symbol) {return handle_conditional_flow_control_IL_instruction(symbol, "CALCN");}
       
  1052 void *print_datatypes_error_c::visit(  RET_operator_c *symbol) {return NULL;}
       
  1053 void *print_datatypes_error_c::visit( RETC_operator_c *symbol) {return handle_conditional_flow_control_IL_instruction(symbol, "RETC" );}
       
  1054 void *print_datatypes_error_c::visit(RETCN_operator_c *symbol) {return handle_conditional_flow_control_IL_instruction(symbol, "RETCN");}
       
  1055 void *print_datatypes_error_c::visit(  JMP_operator_c *symbol) {return NULL;}
       
  1056 void *print_datatypes_error_c::visit( JMPC_operator_c *symbol) {return handle_conditional_flow_control_IL_instruction(symbol, "JMPC" );}
       
  1057 void *print_datatypes_error_c::visit(JMPCN_operator_c *symbol) {return handle_conditional_flow_control_IL_instruction(symbol, "JMPCN");}
       
  1058 
       
  1059 
       
  1060 
       
  1061 /* Symbol class handled together with function call checks */
       
  1062 // void *visit(il_assign_operator_c *symbol, variable_name);
       
  1063 /* Symbol class handled together with function call checks */
       
  1064 // void *visit(il_assign_operator_c *symbol, option, variable_name);
       
  1065 
       
  1066 /***************************************/
       
  1067 /* B.3 - Language ST (Structured Text) */
       
  1068 /***************************************/
       
  1069 /***********************/
       
  1070 /* B 3.1 - Expressions */
       
  1071 /***********************/
       
  1072 
       
  1073 void *print_datatypes_error_c::print_binary_expression_errors(const char *operation, symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool deprecated_operation) {
       
  1074 	l_expr->accept(*this);
       
  1075 	r_expr->accept(*this);
       
  1076 	if ((symbol->candidate_datatypes.size() == 0) 		&&
       
  1077 		(l_expr->candidate_datatypes.size() > 0)	&&
       
  1078 		(r_expr->candidate_datatypes.size() > 0))
       
  1079 		STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for '%s' expression.", operation);
       
  1080         if (deprecated_operation)
       
  1081                 STAGE3_WARNING(symbol, symbol, "Deprecated operation for '%s' expression.", operation);
       
  1082 	return NULL;
       
  1083 }
       
  1084 
       
  1085 
       
  1086 void *print_datatypes_error_c::visit(    or_expression_c *symbol) {return print_binary_expression_errors( "OR", symbol, symbol->l_exp, symbol->r_exp);}
       
  1087 void *print_datatypes_error_c::visit(   xor_expression_c *symbol) {return print_binary_expression_errors("XOR", symbol, symbol->l_exp, symbol->r_exp);}
       
  1088 void *print_datatypes_error_c::visit(   and_expression_c *symbol) {return print_binary_expression_errors("AND", symbol, symbol->l_exp, symbol->r_exp);}
       
  1089 void *print_datatypes_error_c::visit(   equ_expression_c *symbol) {return print_binary_expression_errors( "=" , symbol, symbol->l_exp, symbol->r_exp);}
       
  1090 void *print_datatypes_error_c::visit(notequ_expression_c *symbol) {return print_binary_expression_errors( "<>", symbol, symbol->l_exp, symbol->r_exp);}
       
  1091 void *print_datatypes_error_c::visit(    lt_expression_c *symbol) {return print_binary_expression_errors( "<" , symbol, symbol->l_exp, symbol->r_exp);}
       
  1092 void *print_datatypes_error_c::visit(    gt_expression_c *symbol) {return print_binary_expression_errors( ">" , symbol, symbol->l_exp, symbol->r_exp);}
       
  1093 void *print_datatypes_error_c::visit(    le_expression_c *symbol) {return print_binary_expression_errors( "<=", symbol, symbol->l_exp, symbol->r_exp);}
       
  1094 void *print_datatypes_error_c::visit(    ge_expression_c *symbol) {return print_binary_expression_errors( ">=", symbol, symbol->l_exp, symbol->r_exp);}
       
  1095 void *print_datatypes_error_c::visit(   add_expression_c *symbol) {return print_binary_expression_errors( "+" , symbol, symbol->l_exp, symbol->r_exp, symbol->deprecated_operation);}
       
  1096 void *print_datatypes_error_c::visit(   sub_expression_c *symbol) {return print_binary_expression_errors( "-" , symbol, symbol->l_exp, symbol->r_exp, symbol->deprecated_operation);}
       
  1097 void *print_datatypes_error_c::visit(   mul_expression_c *symbol) {return print_binary_expression_errors( "*" , symbol, symbol->l_exp, symbol->r_exp, symbol->deprecated_operation);}
       
  1098 void *print_datatypes_error_c::visit(   div_expression_c *symbol) {return print_binary_expression_errors( "/" , symbol, symbol->l_exp, symbol->r_exp, symbol->deprecated_operation);}
       
  1099 void *print_datatypes_error_c::visit(   mod_expression_c *symbol) {return print_binary_expression_errors("MOD", symbol, symbol->l_exp, symbol->r_exp);}
       
  1100 void *print_datatypes_error_c::visit( power_expression_c *symbol) {return print_binary_expression_errors( "**", symbol, symbol->l_exp, symbol->r_exp);}
       
  1101 
       
  1102 
       
  1103 void *print_datatypes_error_c::visit(neg_expression_c *symbol) {
       
  1104 	symbol->exp->accept(*this);
       
  1105 	if ((symbol->candidate_datatypes.size() == 0)      &&
       
  1106 		(symbol->exp->candidate_datatypes.size() > 0))
       
  1107 		STAGE3_ERROR(0, symbol, symbol, "Invalid data type for 'NEG' expression.");
       
  1108 	return NULL;
       
  1109 }
       
  1110 
       
  1111 
       
  1112 void *print_datatypes_error_c::visit(not_expression_c *symbol) {
       
  1113 	symbol->exp->accept(*this);
       
  1114 	if ((symbol->candidate_datatypes.size() == 0)      &&
       
  1115 		(symbol->exp->candidate_datatypes.size() > 0))
       
  1116 		STAGE3_ERROR(0, symbol, symbol, "Invalid data type for 'NOT' expression.");
       
  1117 	return NULL;
       
  1118 }
       
  1119 
       
  1120 /* NOTE: The parameter 'called_function_declaration', 'extensible_param_count' and 'candidate_functions' are used to pass data between the stage 3 and stage 4. */
       
  1121 /*    formal_param_list -> may be NULL ! */
       
  1122 /* nonformal_param_list -> may be NULL ! */
       
  1123 // SYM_REF3(function_invocation_c, function_name, formal_param_list, nonformal_param_list, symbol_c *called_function_declaration; int extensible_param_count; std::vector <symbol_c *> candidate_functions;)
       
  1124 void *print_datatypes_error_c::visit(function_invocation_c *symbol) {
       
  1125 	generic_function_call_t fcall_param = {
       
  1126 		/* fcall_param.function_name               = */ symbol->function_name,
       
  1127 		/* fcall_param.nonformal_operand_list      = */ symbol->nonformal_param_list,
       
  1128 		/* fcall_param.formal_operand_list         = */ symbol->formal_param_list,
       
  1129 		/* enum {POU_FB, POU_function} POU_type    = */ generic_function_call_t::POU_function,
       
  1130 		/* fcall_param.candidate_functions         = */ symbol->candidate_functions,
       
  1131 		/* fcall_param.called_function_declaration = */ symbol->called_function_declaration,
       
  1132 		/* fcall_param.extensible_param_count      = */ symbol->extensible_param_count
       
  1133 	};
       
  1134 
       
  1135 	handle_function_invocation(symbol, fcall_param);
       
  1136 	return NULL;
       
  1137 }
       
  1138 
       
  1139 
       
  1140 
       
  1141 /********************/
       
  1142 /* B 3.2 Statements */
       
  1143 /********************/
       
  1144 
       
  1145 /*********************************/
       
  1146 /* B 3.2.1 Assignment Statements */
       
  1147 /*********************************/
       
  1148 void *print_datatypes_error_c::visit(assignment_statement_c *symbol) {
       
  1149 	symbol->l_exp->accept(*this);
       
  1150 	symbol->r_exp->accept(*this);
       
  1151 	if ((NULL == symbol->l_exp->datatype) &&
       
  1152 	    (NULL == symbol->r_exp->datatype) &&
       
  1153 		(symbol->l_exp->candidate_datatypes.size() > 0)	&&
       
  1154 		(symbol->r_exp->candidate_datatypes.size() > 0))
       
  1155 		STAGE3_ERROR(0, symbol, symbol, "Incompatible data types for ':=' operation.");
       
  1156 	return NULL;
       
  1157 }
       
  1158 
       
  1159 
       
  1160 /*****************************************/
       
  1161 /* B 3.2.2 Subprogram Control Statements */
       
  1162 /*****************************************/
       
  1163 /* fb_name '(' [param_assignment_list] ')' */
       
  1164 /*    formal_param_list -> may be NULL ! */
       
  1165 /* nonformal_param_list -> may be NULL ! */
       
  1166 /* 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 */
       
  1167 // SYM_REF3(fb_invocation_c, fb_name, formal_param_list, nonformal_param_list, symbol_c *called_fb_declaration;)
       
  1168 void *print_datatypes_error_c::visit(fb_invocation_c *symbol) {
       
  1169 	int extensible_param_count;                      /* unused vairable! Needed for compilation only! */
       
  1170 	std::vector <symbol_c *> candidate_functions;    /* unused vairable! Needed for compilation only! */
       
  1171 	generic_function_call_t fcall_param = {
       
  1172 		/* fcall_param.function_name               = */ symbol->fb_name,
       
  1173 		/* fcall_param.nonformal_operand_list      = */ symbol->nonformal_param_list,
       
  1174 		/* fcall_param.formal_operand_list         = */ symbol->formal_param_list,
       
  1175 		/* enum {POU_FB, POU_function} POU_type    = */ generic_function_call_t::POU_FB,
       
  1176 		/* fcall_param.candidate_functions         = */ candidate_functions,             /* will not be used, but must provide a reference to be able to compile */
       
  1177 		/* fcall_param.called_function_declaration = */ symbol->called_fb_declaration,
       
  1178 		/* fcall_param.extensible_param_count      = */ extensible_param_count           /* will not be used, but must provide a reference to be able to compile */
       
  1179 	};
       
  1180 	
       
  1181 	handle_function_invocation(symbol, fcall_param);
       
  1182 	return NULL;
       
  1183 }
       
  1184 
       
  1185 
       
  1186 /********************************/
       
  1187 /* B 3.2.3 Selection Statements */
       
  1188 /********************************/
       
  1189 
       
  1190 void *print_datatypes_error_c::visit(if_statement_c *symbol) {
       
  1191 	symbol->expression->accept(*this);
       
  1192 	if ((NULL == symbol->expression->datatype) &&
       
  1193 		(symbol->expression->candidate_datatypes.size() > 0)) {
       
  1194 		STAGE3_ERROR(0, symbol, symbol, "Invalid data type for 'IF' condition.");
       
  1195 	}
       
  1196 	if (NULL != symbol->statement_list)
       
  1197 		symbol->statement_list->accept(*this);
       
  1198 	if (NULL != symbol->elseif_statement_list)
       
  1199 		symbol->elseif_statement_list->accept(*this);
       
  1200 	if (NULL != symbol->else_statement_list)
       
  1201 		symbol->else_statement_list->accept(*this);
       
  1202 	return NULL;
       
  1203 }
       
  1204 
       
  1205 void *print_datatypes_error_c::visit(elseif_statement_c *symbol) {
       
  1206 	symbol->expression->accept(*this);
       
  1207 	if ((NULL == symbol->expression->datatype) &&
       
  1208 		(symbol->expression->candidate_datatypes.size() > 0)) {
       
  1209 		STAGE3_ERROR(0, symbol, symbol, "Invalid data type for 'ELSIF' condition.");
       
  1210 	}
       
  1211 	if (NULL != symbol->statement_list)
       
  1212 		symbol->statement_list->accept(*this);
       
  1213 	return NULL;
       
  1214 }
       
  1215 
       
  1216 
       
  1217 void *print_datatypes_error_c::visit(case_statement_c *symbol) {
       
  1218 	symbol->expression->accept(*this);
       
  1219 	if ((NULL == symbol->expression->datatype) &&
       
  1220 		(symbol->expression->candidate_datatypes.size() > 0)) {
       
  1221 		STAGE3_ERROR(0, symbol, symbol, "'CASE' quantity not an integer or enumerated.");
       
  1222 	}
       
  1223 	symbol->case_element_list->accept(*this);
       
  1224 	if (NULL != symbol->statement_list)
       
  1225 		symbol->statement_list->accept(*this);
       
  1226 	return NULL;
       
  1227 }
       
  1228 
       
  1229 /********************************/
       
  1230 /* B 3.2.4 Iteration Statements */
       
  1231 /********************************/
       
  1232 
       
  1233 void *print_datatypes_error_c::visit(for_statement_c *symbol) {
       
  1234 	symbol->control_variable->accept(*this);
       
  1235 	symbol->beg_expression->accept(*this);
       
  1236 	symbol->end_expression->accept(*this);
       
  1237 	/* Control variable */
       
  1238 	if ((NULL == symbol->control_variable->datatype) &&
       
  1239 		(symbol->control_variable->candidate_datatypes.size() > 0)) {
       
  1240 		STAGE3_ERROR(0, symbol, symbol, "Invalid data type for 'FOR' control variable.");
       
  1241 	}
       
  1242 	/* BEG expression */
       
  1243 	if ((NULL == symbol->beg_expression->datatype) &&
       
  1244 		(symbol->beg_expression->candidate_datatypes.size() > 0)) {
       
  1245 		STAGE3_ERROR(0, symbol, symbol, "Invalid data type for 'FOR' begin expression.");
       
  1246 	}
       
  1247 	/* END expression */
       
  1248 	if ((NULL == symbol->end_expression->datatype) &&
       
  1249 		(symbol->end_expression->candidate_datatypes.size() > 0)) {
       
  1250 		STAGE3_ERROR(0, symbol, symbol, "Invalid data type for 'FOR' end expression.");
       
  1251 	}
       
  1252 	/* BY expression */
       
  1253 	if ((NULL != symbol->by_expression) &&
       
  1254 		(NULL == symbol->by_expression->datatype) &&
       
  1255 		(symbol->end_expression->candidate_datatypes.size() > 0)) {
       
  1256 		STAGE3_ERROR(0, symbol, symbol, "Invalid data type for 'FOR' by expression.");
       
  1257 	}
       
  1258 	/* DO statement */
       
  1259 	if (NULL != symbol->statement_list)
       
  1260 		symbol->statement_list->accept(*this);
       
  1261 
       
  1262 	return NULL;
       
  1263 }
       
  1264 
       
  1265 void *print_datatypes_error_c::visit(while_statement_c *symbol) {
       
  1266 	symbol->expression->accept(*this);
       
  1267 	if (!is_type_valid(symbol->expression->datatype)) {
       
  1268 		STAGE3_ERROR(0, symbol, symbol, "Invalid data type for 'WHILE' condition.");
       
  1269 		return NULL;
       
  1270 	}
       
  1271 	if (NULL != symbol->statement_list)
       
  1272 		symbol->statement_list->accept(*this);
       
  1273 	return NULL;
       
  1274 }
       
  1275 
       
  1276 void *print_datatypes_error_c::visit(repeat_statement_c *symbol) {
       
  1277 	if (!is_type_valid(symbol->expression->datatype)) {
       
  1278 		STAGE3_ERROR(0, symbol, symbol, "Invalid data type for 'REPEAT' condition.");
       
  1279 		return NULL;
       
  1280 	}
       
  1281 	if (NULL != symbol->statement_list)
       
  1282 		symbol->statement_list->accept(*this);
       
  1283 	symbol->expression->accept(*this);
       
  1284 	return NULL;
       
  1285 }
       
  1286 
       
  1287 
       
  1288 
       
  1289 
       
  1290