diff -r 136d6ae70745 -r f5dfadf5de54 stage4/generate_c/generate_c_il.cc --- a/stage4/generate_c/generate_c_il.cc Wed Nov 18 10:53:15 2009 +0100 +++ b/stage4/generate_c/generate_c_il.cc Sun Nov 29 16:38:11 2009 +0100 @@ -139,6 +139,13 @@ class generate_c_il_c: public generate_c_typedecl_c, il_default_variable_visitor_c { + public: + typedef enum { + expression_vg, + assignment_vg, + fparam_output_vg + } variablegeneration_t; + private: /* When compiling il code, it becomes necessary to determine the * data type of il operands. To do this, we must first find the @@ -237,10 +244,13 @@ search_base_type_c search_base_type; - bool current_param_is_pointer; + int fcall_number; + symbol_c *fbname; + + variablegeneration_t wanted_variablegeneration; public: - generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL) + generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *name, symbol_c *scope, const char *variable_prefix = NULL) : generate_c_typedecl_c(s4o_ptr), default_variable_name(IL_DEFVAR, NULL), default_variable_back_name(IL_DEFVAR_BACK, NULL) @@ -251,7 +261,9 @@ current_operand = NULL; current_operand_type = NULL; il_default_variable_init_value = NULL; - current_param_is_pointer = false; + fcall_number = 0; + fbname = name; + wanted_variablegeneration = expression_vg; this->set_variable_prefix(variable_prefix); } @@ -423,7 +435,12 @@ symbol->var_name->accept(*this); if (NULL != symbol->current_type) { s4o.print("."); - symbol->current_type->accept(*this); + if (search_expression_type->is_literal_integer_type(symbol->current_type)) + this->lint_type.accept(*this); + else if (search_expression_type->is_literal_real_type(this->default_variable_name.current_type)) + this->lreal_type.accept(*this); + else + symbol->current_type->accept(*this); s4o.print("var"); } return NULL; @@ -452,20 +469,75 @@ /*********************/ /* B 1.4 - Variables */ /*********************/ +/* B 1.4 - Variables */ +/*********************/ void *visit(symbolic_variable_c *symbol) { unsigned int vartype = search_varfb_instance_type->get_vartype(symbol); - if (!current_param_is_pointer && (vartype == search_var_instance_decl_c::external_vt || vartype == search_var_instance_decl_c::located_vt)) { - s4o.print("*("); - generate_c_base_c::visit(symbol); - s4o.print(")"); - } - else if (current_param_is_pointer && vartype != search_var_instance_decl_c::external_vt && vartype != search_var_instance_decl_c::located_vt) { - s4o.print("&("); - generate_c_base_c::visit(symbol); - s4o.print(")"); + if (this->is_variable_prefix_null()) { + if (wanted_variablegeneration == fparam_output_vg) { + if (vartype == search_var_instance_decl_c::external_vt) { + s4o.print(GET_EXTERNAL); + s4o.print("("); + symbol->var_name->accept(*this); + } + else { + s4o.print("&("); + generate_c_base_c::visit(symbol); + } + s4o.print(")"); + } + else { + if (vartype == search_var_instance_decl_c::external_vt) { + s4o.print(GET_EXTERNAL); + s4o.print("("); + symbol->var_name->accept(*this); + s4o.print(")"); + } + else + generate_c_base_c::visit(symbol); + } } else { - generate_c_base_c::visit(symbol); + switch (wanted_variablegeneration) { + case expression_vg: + if (vartype == search_var_instance_decl_c::external_vt) { + s4o.print(GET_EXTERNAL); + s4o.print("("); + symbol->var_name->accept(*this); + } + else { + if (vartype == search_var_instance_decl_c::located_vt) + s4o.print(GET_LOCATED); + else + s4o.print(GET_VAR); + s4o.print("("); + generate_c_base_c::visit(symbol); + } + s4o.print(")"); + break; + case fparam_output_vg: + if (vartype == search_var_instance_decl_c::external_vt) { + s4o.print(GET_EXTERNAL_BY_REF); + s4o.print("("); + symbol->var_name->accept(*this); + } + else { + if (vartype == search_var_instance_decl_c::located_vt) + s4o.print(GET_LOCATED_BY_REF); + else + s4o.print(GET_VAR_BY_REF); + s4o.print("("); + generate_c_base_c::visit(symbol); + } + s4o.print(")"); + break; + default: + if (vartype == search_var_instance_decl_c::external_vt) + symbol->var_name->accept(*this); + else + generate_c_base_c::visit(symbol); + break; + } } return NULL; } @@ -478,14 +550,29 @@ TRACE("direct_variable_c"); /* Do not use print_token() as it will change everything into uppercase */ if (strlen(symbol->value) == 0) ERROR; - if (!current_param_is_pointer) { - s4o.print("*("); + if (this->is_variable_prefix_null()) { + if (wanted_variablegeneration != fparam_output_vg) + s4o.print("*("); + } + else { + switch (wanted_variablegeneration) { + case expression_vg: + s4o.print(GET_LOCATED); + s4o.print("("); + break; + case fparam_output_vg: + s4o.print(GET_LOCATED_BY_REF); + s4o.print("("); + break; + default: + break; + } } this->print_variable_prefix(); s4o.printlocation(symbol->value + 1); - if (!current_param_is_pointer) { + if ((this->is_variable_prefix_null() && wanted_variablegeneration != fparam_output_vg) || + wanted_variablegeneration != assignment_vg) s4o.print(")"); - } return NULL; } @@ -597,8 +684,7 @@ symbol_c* function_type_prefix = NULL; symbol_c* function_name = NULL; symbol_c* function_type_suffix = NULL; - std::list param_list; - FUNCTION_PARAM *param; + DECLARE_PARAM_LIST() symbol_c *param_data_type = default_variable_name.current_type; symbol_c *return_data_type = NULL; @@ -612,13 +698,16 @@ function_call_param_iterator_c function_call_param_iterator(symbol); + identifier_c en_param_name("EN"); /* Add the value from EN param */ - ADD_PARAM_LIST((symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c())), + ADD_PARAM_LIST(&en_param_name, + (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c())), (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in) + identifier_c eno_param_name("ENO"); /* Add the value from ENO param */ - ADD_PARAM_LIST(NULL, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out) + ADD_PARAM_LIST(&eno_param_name, NULL, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out) int nb_param = 1; if (symbol->il_operand_list != NULL) @@ -677,10 +766,24 @@ param_value = fp_iterator.default_value(); } - ADD_PARAM_LIST(param_value, param_type, fp_iterator.param_direction()) + ADD_PARAM_LIST(param_name, param_value, param_type, fp_iterator.param_direction()) } /* for(...) */ } + bool has_output_params = false; + + if (!this->is_variable_prefix_null()) { + PARAM_LIST_ITERATOR() { + if ((PARAM_DIRECTION == function_param_iterator_c::direction_out || + PARAM_DIRECTION == function_param_iterator_c::direction_inout) && + PARAM_VALUE != NULL) { + if (!has_output_params) { + has_output_params = true; + } + } + } + } + default_variable_name.current_type = return_data_type; this->default_variable_name.accept(*this); default_variable_name.current_type = param_data_type; @@ -691,27 +794,38 @@ function_type_prefix->accept(*this); s4o.print(")"); } - if (function_name != NULL) + if (has_output_params) { + fcall_number++; + s4o.print("__"); + fbname->accept(*this); + s4o.print("_"); function_name->accept(*this); - if (function_type_suffix != NULL) - function_type_suffix->accept(*this); + s4o.print_integer(fcall_number); + } + else { + if (function_name != NULL) + function_name->accept(*this); + if (function_type_suffix != NULL) + function_type_suffix->accept(*this); + } s4o.print("("); s4o.indent_right(); - std::list::iterator pt; - for(pt = param_list.begin(); pt != param_list.end(); pt++) { - if (pt != param_list.begin()) - s4o.print(",\n"+s4o.indent_spaces); - symbol_c *param_value = pt->param_value; - symbol_c *param_type = pt->param_type; + int nb_param = 0; + PARAM_LIST_ITERATOR() { + symbol_c *param_value = PARAM_VALUE; + symbol_c *param_type = PARAM_TYPE; - switch (pt->param_direction) { + switch (PARAM_DIRECTION) { case function_param_iterator_c::direction_in: + if (nb_param > 0) + s4o.print(",\n"+s4o.indent_spaces); if (param_value == NULL) { /* If not, get the default value of this variable's type */ param_value = (symbol_c *)param_type->accept(*type_initial_value_c::instance()); } if (param_value == NULL) ERROR; + s4o.print("("); if (search_expression_type->is_literal_integer_type(param_type) || search_expression_type->is_literal_real_type(param_type)) { if (function_type_suffix == NULL) ERROR; @@ -719,24 +833,24 @@ } else param_type->accept(*this); - if (search_base_type.type_is_subrange(param_type)) { - s4o.print("__CHECK_"); - param_type->accept(*this); - s4o.print("("); - } - param_value->accept(*this); - if (search_base_type.type_is_subrange(param_type)) - s4o.print(")"); + s4o.print(")"); + print_check_function(param_type, param_value); + nb_param++; break; case function_param_iterator_c::direction_out: case function_param_iterator_c::direction_inout: - current_param_is_pointer = true; - if (param_value == NULL) { - s4o.print("NULL"); - } else { - param_value->accept(*this); - } - current_param_is_pointer = false; + if (!has_output_params) { + if (nb_param > 0) + s4o.print(",\n"+s4o.indent_spaces); + if (param_value == NULL) { + s4o.print("NULL"); + } else { + wanted_variablegeneration = fparam_output_vg; + param_value->accept(*this); + wanted_variablegeneration = expression_vg; + } + nb_param++; + } break; case function_param_iterator_c::direction_extref: /* TODO! */ @@ -744,10 +858,18 @@ break; } /* switch */ } + if (has_output_params) { + if (nb_param > 0) + s4o.print(",\n"+s4o.indent_spaces); + s4o.print(FB_FUNCTION_PARAM); + } s4o.print(")"); /* the data type returned by the function, and stored in the il default variable... */ default_variable_name.current_type = return_data_type; + + CLEAR_PARAM_LIST() + return NULL; } @@ -856,17 +978,19 @@ if (param_value != NULL) if ((param_direction == function_param_iterator_c::direction_in) || (param_direction == function_param_iterator_c::direction_inout)) { - symbol->fb_name->accept(*this); + if (!this->is_variable_prefix_null()) { + s4o.print(SET_VAR); + s4o.print("("); + } + symbol->fb_name->accept(*this); s4o.print("."); param_name->accept(*this); - s4o.print(" = "); - if (search_base_type.type_is_subrange(param_type)) { - s4o.print("__CHECK_"); - param_type->accept(*this); - s4o.print("("); - } - param_value->accept(*this); - if (search_base_type.type_is_subrange(param_type)) + if (this->is_variable_prefix_null()) + s4o.print(" = "); + else + s4o.print(","); + print_check_function(param_type, param_value); + if (!this->is_variable_prefix_null()) s4o.print(")"); s4o.print(";\n" + s4o.indent_spaces); } @@ -899,19 +1023,29 @@ if ((param_direction == function_param_iterator_c::direction_out) || (param_direction == function_param_iterator_c::direction_inout)) { symbol_c *param_type = search_varfb_instance_type->get_type(param_value, false); - - s4o.print(";\n"+ s4o.indent_spaces); - param_value->accept(*this); - s4o.print(" = "); - if (search_base_type.type_is_subrange(param_type)) { - s4o.print("__CHECK_"); - param_type->accept(*this); - s4o.print("("); + unsigned int vartype = search_varfb_instance_type->get_vartype(param_value); + + if (!this->is_variable_prefix_null()) { + s4o.print(";\n"+ s4o.indent_spaces); + if (vartype == search_var_instance_decl_c::external_vt) + s4o.print(SET_EXTERNAL); + else if (vartype == search_var_instance_decl_c::located_vt) + s4o.print(SET_LOCATED); + else + s4o.print(SET_VAR); + s4o.print("("); + + wanted_variablegeneration = assignment_vg; + param_value->accept(*this); + wanted_variablegeneration = expression_vg; + s4o.print(","); } - symbol->fb_name->accept(*this); - s4o.print("."); - param_name->accept(*this); - if (search_base_type.type_is_subrange(param_type)) + else { + param_value->accept(*this); + s4o.print(" = "); + } + print_check_function(param_type, param_name, symbol->fb_name); + if (!this->is_variable_prefix_null()) s4o.print(")"); } } /* for(...) */ @@ -934,8 +1068,7 @@ symbol_c* function_type_prefix = NULL; symbol_c* function_name = NULL; symbol_c* function_type_suffix = NULL; - std::list param_list; - FUNCTION_PARAM *param; + DECLARE_PARAM_LIST() symbol_c *return_data_type = NULL; @@ -959,14 +1092,14 @@ EN_param_value = (symbol_c*)(new boolean_literal_c((symbol_c*)(new bool_type_name_c()), new boolean_true_c())); else nb_param --; - ADD_PARAM_LIST(EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in) + ADD_PARAM_LIST(&en_param_name, EN_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_in) identifier_c eno_param_name("EN0"); /* Get the value from ENO param */ symbol_c *ENO_param_value = function_call_param_iterator.search_f(&eno_param_name); if (ENO_param_value != NULL) nb_param --; - ADD_PARAM_LIST(ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out) + ADD_PARAM_LIST(&eno_param_name, ENO_param_value, (symbol_c*)(new bool_type_name_c()), function_param_iterator_c::direction_out) #include "st_code_gen.c" @@ -1016,10 +1149,24 @@ param_value = fp_iterator.default_value(); } - ADD_PARAM_LIST(param_value, param_type, fp_iterator.param_direction()) - } - } - + ADD_PARAM_LIST(param_name, param_value, param_type, fp_iterator.param_direction()) + } + } + + bool has_output_params = false; + + if (!this->is_variable_prefix_null()) { + PARAM_LIST_ITERATOR() { + if ((PARAM_DIRECTION == function_param_iterator_c::direction_out || + PARAM_DIRECTION == function_param_iterator_c::direction_inout) && + PARAM_VALUE != NULL) { + if (!has_output_params) { + has_output_params = true; + } + } + } + } + default_variable_name.current_type = return_data_type; this->default_variable_name.accept(*this); s4o.print(" = "); @@ -1029,27 +1176,38 @@ function_type_prefix->accept(*this); s4o.print(")"); } - if (function_name != NULL) + if (has_output_params) { + fcall_number++; + s4o.print("__"); + fbname->accept(*this); + s4o.print("_"); function_name->accept(*this); - if (function_type_suffix != NULL) - function_type_suffix->accept(*this); + s4o.print_integer(fcall_number); + } + else { + if (function_name != NULL) + function_name->accept(*this); + if (function_type_suffix != NULL) + function_type_suffix->accept(*this); + } s4o.print("("); s4o.indent_right(); - std::list::iterator pt; - for(pt = param_list.begin(); pt != param_list.end(); pt++) { - if (pt != param_list.begin()) - s4o.print(",\n"+s4o.indent_spaces); - symbol_c *param_value = pt->param_value; - symbol_c *param_type = pt->param_type; + int nb_param = 0; + PARAM_LIST_ITERATOR() { + symbol_c *param_value = PARAM_VALUE; + symbol_c *param_type = PARAM_TYPE; - switch (pt->param_direction) { + switch (PARAM_DIRECTION) { case function_param_iterator_c::direction_in: - if (param_value == NULL) { + if (nb_param > 0) + s4o.print(",\n"+s4o.indent_spaces); + if (param_value == NULL) { /* If not, get the default value of this variable's type */ param_value = (symbol_c *)param_type->accept(*type_initial_value_c::instance()); } if (param_value == NULL) ERROR; + s4o.print("("); if (search_expression_type->is_literal_integer_type(param_type) || search_expression_type->is_literal_real_type(param_type)) { if (function_type_suffix == NULL) ERROR; @@ -1057,35 +1215,42 @@ } else param_type->accept(*this); - if (search_base_type.type_is_subrange(param_type)) { - s4o.print("__CHECK_"); - param_type->accept(*this); - s4o.print("("); - } - param_value->accept(*this); - if (search_base_type.type_is_subrange(param_type)) - s4o.print(")"); - break; + s4o.print(")"); + print_check_function(param_type, param_value); + nb_param++; + break; case function_param_iterator_c::direction_out: case function_param_iterator_c::direction_inout: - current_param_is_pointer = true; - if (param_value == NULL) { - s4o.print("NULL"); - } else { - param_value->accept(*this); - } - current_param_is_pointer = false; - break; + if (!has_output_params) { + if (nb_param > 0) + s4o.print(",\n"+s4o.indent_spaces); + if (param_value == NULL) { + s4o.print("NULL"); + } else { + wanted_variablegeneration = fparam_output_vg; + param_value->accept(*this); + wanted_variablegeneration = expression_vg; + } + } + break; case function_param_iterator_c::direction_extref: /* TODO! */ ERROR; break; } /* switch */ } /* for(...) */ + if (has_output_params) { + if (nb_param > 0) + s4o.print(",\n"+s4o.indent_spaces); + s4o.print(FB_FUNCTION_PARAM); + } // symbol->parameter_assignment->accept(*this); s4o.print(")"); /* the data type returned by the function, and stored in the il default variable... */ + + CLEAR_PARAM_LIST() + return NULL; } @@ -1215,23 +1380,14 @@ void *visit(LD_operator_c *symbol) { /* the data type resulting from this operation... */ - if (search_expression_type->is_literal_integer_type(this->current_operand_type)) - this->default_variable_name.current_type = &(this->lint_type); - else if (search_expression_type->is_literal_real_type(this->current_operand_type)) - this->default_variable_name.current_type = &(this->lreal_type); - else - this->default_variable_name.current_type = this->current_operand_type; + this->default_variable_name.current_type = this->current_operand_type; XXX_operator(&(this->default_variable_name), " = ", this->current_operand); - this->default_variable_name.current_type = this->current_operand_type; return NULL; } void *visit(LDN_operator_c *symbol) { /* the data type resulting from this operation... */ - if (search_expression_type->is_literal_integer_type(this->current_operand_type)) - this->default_variable_name.current_type = &(this->lword_type); - else - this->default_variable_name.current_type = this->current_operand_type; + this->default_variable_name.current_type = this->current_operand_type; XXX_operator(&(this->default_variable_name), search_expression_type->is_bool_type(this->current_operand_type)?" = !":" = ~", this->current_operand); @@ -1241,32 +1397,58 @@ void *visit(ST_operator_c *symbol) { symbol_c *operand_type = search_varfb_instance_type->get_type(this->current_operand, false); - this->current_operand->accept(*this); - s4o.print(" = "); - if (search_base_type.type_is_subrange(operand_type)) { - s4o.print("__CHECK_"); - operand_type->accept(*this); + if (!this->is_variable_prefix_null()) { + unsigned int vartype = search_varfb_instance_type->get_vartype(this->current_operand); + if (vartype == search_var_instance_decl_c::external_vt) + s4o.print(SET_EXTERNAL); + else if (vartype == search_var_instance_decl_c::located_vt) + s4o.print(SET_LOCATED); + else + s4o.print(SET_VAR); s4o.print("("); + + wanted_variablegeneration = assignment_vg; + this->current_operand->accept(*this); + wanted_variablegeneration = expression_vg; + + s4o.print(","); + } + else { + this->current_operand->accept(*this); + s4o.print(" = "); } if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type) || search_expression_type->is_literal_real_type(this->default_variable_name.current_type)) this->default_variable_name.current_type = this->current_operand_type; - this->default_variable_name.accept(*this); - if (search_base_type.type_is_subrange(operand_type)) + print_check_function(operand_type, (symbol_c*)&(this->default_variable_name)); + if (!this->is_variable_prefix_null()) s4o.print(")"); - /* the data type resulting from this operation is unchamged. */ + /* the data type resulting from this operation is unchanged. */ return NULL; } void *visit(STN_operator_c *symbol) { symbol_c *operand_type = search_varfb_instance_type->get_type(this->current_operand, false); - this->current_operand->accept(*this); - s4o.print(" = "); - if (search_base_type.type_is_subrange(operand_type)) { - s4o.print("__CHECK_"); - operand_type->accept(*this); + if (!this->is_variable_prefix_null()) { + unsigned int vartype = search_varfb_instance_type->get_vartype(this->current_operand); + if (vartype == search_var_instance_decl_c::external_vt) + s4o.print(SET_EXTERNAL); + else if (vartype == search_var_instance_decl_c::located_vt) + s4o.print(SET_LOCATED); + else + s4o.print(SET_VAR); s4o.print("("); + + wanted_variablegeneration = assignment_vg; + this->current_operand->accept(*this); + wanted_variablegeneration = expression_vg; + + s4o.print(","); + } + else { + this->current_operand->accept(*this); + s4o.print(" = "); } if (search_expression_type->is_bool_type(this->current_operand_type)) s4o.print("!"); @@ -1275,7 +1457,7 @@ if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) this->default_variable_name.current_type = this->current_operand_type; this->default_variable_name.accept(*this); - if (search_base_type.type_is_subrange(operand_type)) + if (!this->is_variable_prefix_null()) s4o.print(")"); /* the data type resulting from this operation is unchamged. */ return NULL;