stage3/lvalue_check.cc
changeset 535 70140bd7fe67
parent 532 cb78940b2cb8
child 553 b654ca7a031a
equal deleted inserted replaced
534:d13a38011af4 535:70140bd7fe67
   262 			/* If there is no other parameter declared, then we are passing too many parameters... */
   262 			/* If there is no other parameter declared, then we are passing too many parameters... */
   263 			/* This error should have been caught in data type verification, so we simply abandon our check! */
   263 			/* This error should have been caught in data type verification, so we simply abandon our check! */
   264 			if(param_name == NULL) return;
   264 			if(param_name == NULL) return;
   265 		} while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0));
   265 		} while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0));
   266 
   266 
   267 		/* Find the corresponding parameter in function declaration, and it's direction (IN, OUT, IN_OUT) */
   267 		/* Determine the direction (IN, OUT, IN_OUT) of the parameter... */
   268 		function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   268 		function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction();
   269 		
   269 		
   270 		/* We only check if 'call_param_value' is a valid lvalue if the value is being passed
   270 		/* We only check if 'call_param_value' is a valid lvalue if the value is being passed
   271 		 * to a valid paramater of the function being called, and that parameter is either OUT or IN_OUT.
   271 		 * to a valid paramater of the function being called, and that parameter is either OUT or IN_OUT.
   272 		 */
   272 		 */
   388 	current_il_operand = NULL;
   388 	current_il_operand = NULL;
   389 	return NULL;
   389 	return NULL;
   390 }
   390 }
   391 
   391 
   392 
   392 
       
   393 
       
   394 
       
   395 /* | function_name [il_operand_list] */
       
   396 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */
       
   397 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
       
   398 void *lvalue_check_c::visit(il_function_call_c *symbol) {
       
   399 	/* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction)
       
   400 	 * In order to be able to handle this without coding special cases, we will simply prepend that symbol
       
   401 	 * to the il_operand_list, and remove it after calling handle_function_call().
       
   402 	 *
       
   403 	 * However, if no further paramters are given, then il_operand_list will be NULL, and we will
       
   404 	 * need to create a new object to hold the pointer to prev_il_instruction.
       
   405 	 * This change will also be undone at the end of this method.
       
   406 	 */
       
   407 	/* TODO: Copying the location data will result in confusing error message. 
       
   408 	 *       We need to make this better, by inserting code to handle this special situation explicitly!
       
   409 	 */
       
   410 	/* NOTE: When calling a function, using the 'current value' as the first parameter of the function invocation
       
   411 	 *       implies that we can only call functions whose first parameter is IN. It would not do to pass
       
   412 	 *       the 'current value' to an OUT or IN_OUT parameter.
       
   413 	 *       In order to make sure that this will be caught by the check_nonformal_call() function,
       
   414 	 *       we add a symbol that cannot be an lvalue; in this case, a real_c (REAL literal).
       
   415 	 */
       
   416 	real_c param_value(NULL);
       
   417 	*((symbol_c *)(&param_value)) = *((symbol_c *)symbol); /* copy the symbol location (file, line, offset) data */
       
   418 	if (NULL == symbol->il_operand_list)  symbol->il_operand_list = new il_operand_list_c;
       
   419 	if (NULL == symbol->il_operand_list)  ERROR;
       
   420 	((list_c *)symbol->il_operand_list)->insert_element(&param_value, 0);
       
   421 
       
   422 	check_nonformal_call(symbol, symbol->called_function_declaration);
       
   423 
       
   424 	/* Undo the changes to the abstract syntax tree we made above... */
       
   425 	((list_c *)symbol->il_operand_list)->remove_element(0);
       
   426 	if (((list_c *)symbol->il_operand_list)->n == 0) {
       
   427 		/* if the list becomes empty, then that means that it did not exist before we made these changes, so we delete it! */
       
   428 		delete 	symbol->il_operand_list;
       
   429 		symbol->il_operand_list = NULL;
       
   430 	}
       
   431 
       
   432 	return NULL;
       
   433 }
       
   434 
       
   435 
       
   436 
       
   437 
       
   438 
       
   439 
       
   440 /*   il_call_operator prev_declared_fb_name
       
   441  * | il_call_operator prev_declared_fb_name '(' ')'
       
   442  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
       
   443  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
       
   444  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
       
   445  */
       
   446 /* 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 */
       
   447 // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
       
   448 void *lvalue_check_c::visit(il_fb_call_c *symbol) {
       
   449 	if (NULL != symbol->il_operand_list)  check_nonformal_call(symbol, symbol->called_fb_declaration);
       
   450 	if (NULL != symbol->  il_param_list)     check_formal_call(symbol, symbol->called_fb_declaration);
       
   451 	return NULL;
       
   452 }
       
   453 
       
   454 
       
   455 /* | function_name '(' eol_list [il_param_list] ')' */
       
   456 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */
       
   457 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;)
       
   458 void *lvalue_check_c::visit(il_formal_funct_call_c *symbol) {
       
   459 	check_formal_call(symbol, symbol->called_function_declaration);
       
   460 	return NULL;
       
   461 }
       
   462 
       
   463 
       
   464 
       
   465 
       
   466 
       
   467 
   393 /*******************/
   468 /*******************/
   394 /* B 2.2 Operators */
   469 /* B 2.2 Operators */
   395 /*******************/
   470 /*******************/
   396 void *lvalue_check_c::visit(ST_operator_c *symbol) {
   471 void *lvalue_check_c::visit(ST_operator_c *symbol) {
   397 	verify_is_lvalue(current_il_operand);
   472 	verify_is_lvalue(current_il_operand);