diff -r 41cb5b80416e -r e1f0ebd2d9ec stage4/generate_cc/generate_cc_tempvardecl.cc --- a/stage4/generate_cc/generate_cc_tempvardecl.cc Tue Oct 23 10:35:58 2007 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,179 +0,0 @@ -/* - * (c) 2003 Mario de Sousa - * - * Offered to the public under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * This code is made available on the understanding that it will not be - * used in safety-critical situations without a full and competent review. - */ - -/* - * An IEC 61131-3 IL and ST compiler. - * - * Based on the - * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) - * - */ - - -/* - * Declare temporary variables to be later used as output parameters - * in function calls for which not all output parameters were - * defined in the original (st or il) source code. - * - * This is part of the 4th stage that generates - * a c++ source program equivalent to the IL and ST - * code. - */ - - - - -class temp_var_name_c { - private: - int counter; - - public: - void reset(void) {counter = 0;} - temp_var_name_c(void) {reset();} - - public: - std::string *new_name(void) { - std::string *new_str = new std::string(TEMP_VAR); - /* yikes!!! How to convert an int to a string elegantly??? - * Right now I (Mario) can only think of snprintf() - * C++ must have a more elegant method! - */ - int int_str_size = snprintf(NULL, 0, "%d", counter); - if (int_str_size <= 0) ERROR; - char *int_str = (char *)malloc(int_str_size+1); - if (snprintf(int_str, int_str_size+1, "%d", counter++) >= int_str_size+1) ERROR; - *new_str += int_str; - free(int_str); - return new_str; - } - -}; - - - -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ - - - -/* Some function calls in the body of functions or function blocks - * may leave some parameters to their default values, and - * ignore some output parameters of the function being called. - * Our conversion of ST functions to C++ does not contemplate that, - * i.e. each called function must get all it's input and output - * parameters set correctly. - * For input parameters we merely need to call the function with - * the apropriate default value, but for output parameters - * we must create temporary variables to hold the output value. - * - * We declare all the temporary output variables at the begining of - * the body of each function or function block, and use them as - * in function calls later on as they become necessary... - * Note that we cannot create these variables just before a function - * call, as the function call itself may be integrated within an - * expression, or another function call! - * - * The variables are declared in the exact same order in which they - * will be used later on during the function calls, which allows us - * to simply re-create the name that was used for the temporary variable - * instead of keeping it in some list. - * The names are recreated by the temp_var_name_factory, after reset() - * has been called! - * - * This function will genertae code similar to... - * - * INT __TMP_0 = 23; - * REAL __TMP_1 = 45.5; - * ... - */ - -class generate_cc_tempvardecl_c: generate_cc_typedecl_c { - public: - generate_cc_tempvardecl_c(stage4out_c *s4o_ptr): generate_cc_typedecl_c(s4o_ptr) {} - - void generate(symbol_c *body, temp_var_name_c *temp_var_name_factory) { - temp_var_name_factory->reset(); - function_call_iterator_c fcall_iterator(body); - for(symbol_c *finvocation = NULL; (finvocation = fcall_iterator.next()) != NULL;) { - /* get the name of the next function that gets called */ - identifier_c *fcalled_name = fcall_iterator.fname(); - /* get that function's declaration... */ - function_declaration_c *fdecl = function_symtable.find_value(fcalled_name); - if (fdecl == function_symtable.end_value()) { - function_type_t function_type = get_function_type(fcalled_name); - if (function_type == function_none) ERROR; - return; - } - /* create iterator to iterate through each of the called function's parameters... */ - function_param_iterator_c fp_iterator(fdecl); - - /* iterate through each of the called function's parameters... */ - identifier_c *param_name = NULL; - function_call_param_iterator_c function_call_param_iterator(finvocation); - for(int i = 1; (param_name = fp_iterator.next()) != NULL; i++) { - - function_param_iterator_c::param_direction_t param_direction = fp_iterator.param_direction(); - if (param_direction == function_param_iterator_c::direction_in) - /* ignore input only parameters... - * we do not need to create temporary variables for these! - */ - continue; - - /* Get the value from a foo( = ) style call */ - symbol_c *param_value = function_call_param_iterator.search(param_name); - - /* Get the value from a foo() style call */ - if (param_value == NULL) - param_value = function_call_param_iterator.next(); - - if (param_value != NULL) - /* ignore output parameters to which a variable is passed... - * we do not need to create temporary variables for these! - */ - continue; - - symbol_c *param_type = fp_iterator.param_type(); - - /* get the parameter's default value */ - param_value = fp_iterator.default_value(); - - /* If no default value specified in function declaration, - * get the default value of this variable's type - */ - if (param_value == NULL) - param_value = (symbol_c *)param_type->accept(*type_initial_value_c::instance()); - if (param_value == NULL) ERROR; - - /* now declare a temporary variable, with the correct default value... */ - s4o.print(s4o.indent_spaces); - param_type->accept(*this); - s4o.print(" "); - - std::string *temp_var_name = temp_var_name_factory->new_name(); - s4o.print(*temp_var_name); - delete temp_var_name; - - s4o.print(" = "); - param_value->accept(*this); - s4o.print(";\n"); - } - } - temp_var_name_factory->reset(); - s4o.print("\n"); - } -};