# HG changeset patch # User lbessard # Date 1222432925 -7200 # Node ID eef5e62048c76eef4cc9fdaace230aea3a7022b5 # Parent 72ae82e65dbc950516d9e28f7f341b7dc75daaef Adding support for EN/ENO params in function and function blocks (standard function not supported yet) diff -r 72ae82e65dbc -r eef5e62048c7 absyntax/absyntax.def --- a/absyntax/absyntax.def Thu Sep 25 10:26:10 2008 +0200 +++ b/absyntax/absyntax.def Fri Sep 26 14:42:05 2008 +0200 @@ -365,6 +365,8 @@ /* edge -> The F_EDGE or R_EDGE directive */ SYM_REF2(edge_declaration_c, edge, var1_list) +SYM_REF0(en_param_declaration_c) + SYM_REF0(raising_edge_option_c) SYM_REF0(falling_edge_option_c) @@ -395,6 +397,8 @@ /* option -> may be NULL ! */ SYM_REF2(output_declarations_c, option, var_init_decl_list) +SYM_REF0(eno_param_declaration_c) + /* VAR_IN_OUT var_declaration_list END_VAR */ SYM_REF1(input_output_declarations_c, var_declaration_list) diff -r 72ae82e65dbc -r eef5e62048c7 stage1_2/iec.y --- a/stage1_2/iec.y Thu Sep 25 10:26:10 2008 +0200 +++ b/stage1_2/iec.y Fri Sep 26 14:42:05 2008 +0200 @@ -656,6 +656,7 @@ %type input_declaration_list %type input_declaration %type edge_declaration +%type en_param_declaration %type var_init_decl %type var1_init_decl %type var1_list @@ -669,6 +670,9 @@ // %type fb_name_list // %type fb_name %type output_declarations +%type var_output_init_decl +%type var_output_init_decl_list +%type en_param_declaration %type input_output_declarations /* helper symbol for input_output_declarations */ %type var_declaration_list @@ -711,7 +715,7 @@ %type string_spec /* intermediate helper symbol for: * - non_retentive_var_decls - * - output_declarations + * - var_declarations */ %type var_init_decl_list @@ -2964,6 +2968,7 @@ variable: symbolic_variable | direct_variable +| eno_param ; @@ -3160,6 +3165,7 @@ input_declaration: var_init_decl | edge_declaration +| en_param_declaration ; @@ -3170,9 +3176,9 @@ {$$ = new edge_declaration_c(new falling_edge_option_c(locloc(@3)), $1, locloc(@$));} /* ERROR_CHECK_BEGIN */ | var1_list BOOL R_EDGE - {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification."); yynerrs++;} + {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in edge declaration."); yynerrs++;} | var1_list BOOL F_EDGE - {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification."); yynerrs++;} + {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in edge declaration."); yynerrs++;} | var1_list ':' BOOL R_EDGE F_EDGE {$$ = NULL; print_err_msg(locf(@5), locl(@5), "'R_EDGE' and 'F_EDGE' can't be present at the same time in edge declaration."); yynerrs++;} | var1_list ':' R_EDGE @@ -3182,6 +3188,28 @@ /* ERROR_CHECK_END */ ; +en_param_declaration: + en_param ':' BOOL ASSIGN boolean_literal + {$$ = new en_param_declaration_c(locloc(@$));} +| en_param ':' BOOL ASSIGN integer + {$$ = new en_param_declaration_c(locloc(@$));} +/* ERROR_CHECK_BEGIN */ +| en_param BOOL ASSIGN boolean_literal + {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in EN declaration."); yynerrs++;} +| en_param BOOL ASSIGN integer + {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in EN declaration."); yynerrs++;} +| en_param ':' ASSIGN boolean_literal + {$$ = NULL; print_err_msg(locl(@2), locf(@3), "'BOOL' missing in EN declaration."); yynerrs++;} +| en_param ':' ASSIGN integer + {$$ = NULL; print_err_msg(locl(@2), locf(@3), "'BOOL' missing in EN declaration."); yynerrs++;} +| en_param ':' BOOL ASSIGN error + {$$ = NULL; + if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in EN declaration.");} + else {print_err_msg(locf(@3), locl(@3), "invalid specification in EN declaration."); yyclearin;} + yyerrok; + } +/* ERROR_CHECK_END */ +; var_init_decl: var1_init_decl @@ -3341,11 +3369,11 @@ output_declarations: - VAR_OUTPUT var_init_decl_list END_VAR + VAR_OUTPUT var_output_init_decl_list END_VAR {$$ = new output_declarations_c(NULL, $2, locloc(@$));} -| VAR_OUTPUT RETAIN var_init_decl_list END_VAR +| VAR_OUTPUT RETAIN var_output_init_decl_list END_VAR {$$ = new output_declarations_c(new retain_option_c(locloc(@2)), $3, locloc(@$));} -| VAR_OUTPUT NON_RETAIN var_init_decl_list END_VAR +| VAR_OUTPUT NON_RETAIN var_output_init_decl_list END_VAR {$$ = new output_declarations_c(new non_retain_option_c(locloc(@2)), $3, locloc(@$));} /* ERROR_CHECK_BEGIN */ | VAR_OUTPUT END_VAR @@ -3354,17 +3382,17 @@ {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in retentive output variable(s) declaration."); yynerrs++;} | VAR_OUTPUT NON_RETAIN END_VAR {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable declared in non-retentive output variable(s) declaration."); yynerrs++;} -| VAR_OUTPUT error var_init_decl_list END_VAR +| VAR_OUTPUT error var_output_init_decl_list END_VAR {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'VAR_OUPUT' in output variable(s) declaration."); yyerrok;} -| VAR_OUTPUT RETAIN error var_init_decl_list END_VAR +| VAR_OUTPUT RETAIN error var_output_init_decl_list END_VAR {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'RETAIN' in retentive output variable(s) declaration."); yyerrok;} -| VAR_OUTPUT NON_RETAIN error var_init_decl_list END_VAR +| VAR_OUTPUT NON_RETAIN error var_output_init_decl_list END_VAR {$$ = NULL; print_err_msg(locf(@3), locl(@3), "unexpected token after 'NON_RETAIN' in non-retentive output variable(s) declaration."); yyerrok;} -| VAR_OUTPUT var_init_decl_list error END_OF_INPUT +| VAR_OUTPUT var_output_init_decl_list error END_OF_INPUT {$$ = NULL; print_err_msg(locf(@1), locl(@1), "unclosed output variable(s) declaration."); yyerrok;} -| VAR_OUTPUT RETAIN var_init_decl_list error END_OF_INPUT +| VAR_OUTPUT RETAIN var_output_init_decl_list error END_OF_INPUT {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed retentive output variable(s) declaration."); yyerrok;} -| VAR_OUTPUT NON_RETAIN var_init_decl_list error END_OF_INPUT +| VAR_OUTPUT NON_RETAIN var_output_init_decl_list error END_OF_INPUT {$$ = NULL; print_err_msg(locf(@1), locl(@2), "unclosed non-retentive output variable(s) declaration."); yyerrok;} | VAR_OUTPUT error END_VAR {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in output variable(s) declaration."); yyerrok;} @@ -3375,6 +3403,38 @@ /* ERROR_CHECK_END */ ; +var_output_init_decl: + var_init_decl +| eno_param_declaration +; + +var_output_init_decl_list: + var_output_init_decl ';' + {$$ = new var_init_decl_list_c(locloc(@$)); $$->add_element($1);} +| var_output_init_decl_list var_output_init_decl ';' + {$$ = $1; $$->add_element($2);} +/* ERROR_CHECK_BEGIN */ +| var_output_init_decl_list var_output_init_decl error + {$$ = $1; print_err_msg(locl(@2), locf(@3), "';' missing at end of variable(s) declaration."); yyerrok;} +| var_output_init_decl_list error ';' + {$$ = $1; print_err_msg(locf(@2), locl(@2), "invalid variable(s) declaration."); yyerrok;} +/* ERROR_CHECK_END */ +; + +eno_param_declaration: + eno_param ':' BOOL + {$$ = new eno_param_declaration_c(locloc(@$));} +/* ERROR_CHECK_BEGIN */ +| en_param BOOL + {$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between variable list and specification in EN0 declaration."); yynerrs++;} +| en_param ':' error + {$$ = NULL; + if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no specification defined in ENO declaration.");} + else {print_err_msg(locf(@3), locl(@3), "invalid specification in ENO declaration."); yyclearin;} + yyerrok; + } +/* ERROR_CHECK_END */ +; input_output_declarations: @@ -4063,7 +4123,6 @@ /* intermediate helper symbol for: * - non_retentive_var_decls - * - output_declarations * - var_declarations */ var_init_decl_list: diff -r 72ae82e65dbc -r eef5e62048c7 stage4/generate_c/function_call_param_iterator.cc --- a/stage4/generate_c/function_call_param_iterator.cc Thu Sep 25 10:26:10 2008 +0200 +++ b/stage4/generate_c/function_call_param_iterator.cc Fri Sep 26 14:42:05 2008 +0200 @@ -127,7 +127,21 @@ case search_op: identifier_c *variable_name2 = dynamic_cast(variable_name); + + if (variable_name2 == NULL) { + en_param_c *en_param = dynamic_cast(variable_name); + if (en_param != NULL) + variable_name2 = new identifier_c("EN"); + } + + if (variable_name2 == NULL) { + eno_param_c *eno_param = dynamic_cast(variable_name); + if (eno_param != NULL) + variable_name2 = new identifier_c("ENO"); + } + if (variable_name2 == NULL) ERROR; + if (strcasecmp(search_param_name->value, variable_name2->value) == 0) /* FOUND! This is the same parameter!! */ return (void *)expression; diff -r 72ae82e65dbc -r eef5e62048c7 stage4/generate_c/function_param_iterator.cc --- a/stage4/generate_c/function_param_iterator.cc Thu Sep 25 10:26:10 2008 +0200 +++ b/stage4/generate_c/function_param_iterator.cc Fri Sep 26 14:42:05 2008 +0200 @@ -90,6 +90,8 @@ symbol_c *current_param_type; symbol_c *current_param_default_value; param_direction_t current_param_direction; + bool en_declared; + bool eno_declared; private: void* handle_param_list(list_c *list) { @@ -114,8 +116,8 @@ void *res; for (int i = 0; i < list->n; i++) { res = list->elements[i]->accept(*this); - if (res != NULL) - return res; + if (res != NULL) + return res; } return NULL; } @@ -127,6 +129,8 @@ next_param = param_count = 0; current_param_name = NULL; current_param_type = current_param_default_value = NULL; + en_declared = false; + eno_declared = false; } /* initialise the iterator object. @@ -165,21 +169,47 @@ */ identifier_c *next(void) { void *res; + identifier_c *identifier; param_count = 0; next_param++; res = f_decl->accept(*this); - if (res == NULL) + if (res != NULL) { + symbol_c *sym = (symbol_c *)res; + identifier = dynamic_cast(sym); + if (identifier == NULL) + ERROR; + } + else if (!en_declared) { + current_param_direction = direction_in; + identifier = declare_en_param(); + } + else if (!eno_declared) { + current_param_direction = direction_out; + identifier = declare_eno_param(); + } + else return NULL; - - symbol_c *sym = (symbol_c *)res; - identifier_c *identifier = dynamic_cast(sym); - if (identifier == NULL) - ERROR; - + current_param_name = identifier; return current_param_name; } + identifier_c *declare_en_param(void) { + en_declared = true; + identifier_c *identifier = new identifier_c("EN"); + current_param_type = (symbol_c*)(new bool_type_name_c()); + current_param_default_value = (symbol_c*)(new boolean_literal_c(current_param_type, new boolean_true_c())); + return identifier; + } + + identifier_c *declare_eno_param(void) { + eno_declared = true; + identifier_c *identifier = new identifier_c("ENO"); + current_param_type = (symbol_c*)(new bool_type_name_c()); + current_param_default_value = NULL; + return identifier; + } + /* Returns the currently referenced parameter's default value, * or NULL if none is specified in the function declrataion itself. */ @@ -209,7 +239,11 @@ } void *visit(input_declaration_list_c *symbol) {TRACE("input_declaration_list_c"); return iterate_list(symbol);} void *visit(edge_declaration_c *symbol) {TRACE("edge_declaration_c"); return symbol->var1_list->accept(*this);} - + void *visit(en_param_declaration_c *symbol) { + TRACE("en_param_declaration_c"); + if (en_declared) ERROR; + return (void *)declare_en_param(); + } #if 0 /* var1_list ':' array_spec_init */ SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init) @@ -230,6 +264,11 @@ current_param_direction = direction_out; return symbol->var_init_decl_list->accept(*this); } + void *visit(eno_param_declaration_c *symbol) { + TRACE("eno_param_declaration_c"); + if (eno_declared) ERROR; + return (void *)declare_eno_param(); + } void *visit(input_output_declarations_c *symbol) { TRACE("input_output_declarations_c"); current_param_direction = direction_inout; diff -r 72ae82e65dbc -r eef5e62048c7 stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Thu Sep 25 10:26:10 2008 +0200 +++ b/stage4/generate_c/generate_c.cc Fri Sep 26 14:42:05 2008 +0200 @@ -570,28 +570,34 @@ generate_c_vardecl_c::finterface_vf, generate_c_vardecl_c::input_vt | generate_c_vardecl_c::output_vt | - generate_c_vardecl_c::inoutput_vt); + generate_c_vardecl_c::inoutput_vt | + generate_c_vardecl_c::eneno_vt); + vardecl->print(symbol->var_declarations_list); + if (!vardecl->is_en_declared()) { + s4o.print(",\n" + s4o.indent_spaces + "BOOL EN"); + } + if (!vardecl->is_eno_declared()) { + s4o.print(",\n" + s4o.indent_spaces + "BOOL *ENO"); + } + delete vardecl; + + s4o.indent_left(); + + s4o.print(")\n" + s4o.indent_spaces + "{\n"); + + /* (B) Function local variable declaration */ + /* (B.1) Variables declared in ST source code */ + s4o.indent_right(); + + vardecl = new generate_c_vardecl_c(&s4o, + generate_c_vardecl_c::localinit_vf, + generate_c_vardecl_c::output_vt | + generate_c_vardecl_c::inoutput_vt | + generate_c_vardecl_c::private_vt); vardecl->print(symbol->var_declarations_list); delete vardecl; - s4o.indent_left(); - - s4o.print(")\n" + s4o.indent_spaces + "{\n"); - - /* (B) Function local variable declaration */ - /* (B.1) Variables declared in ST source code */ - s4o.indent_right(); - vardecl = new generate_c_vardecl_c(&s4o, - generate_c_vardecl_c::foutputdecl_vf, - generate_c_vardecl_c::output_vt | - generate_c_vardecl_c::inoutput_vt); - vardecl->print(symbol->var_declarations_list); - delete vardecl; - - vardecl = new generate_c_vardecl_c(&s4o, generate_c_vardecl_c::localinit_vf, generate_c_vardecl_c::private_vt); - vardecl->print(symbol->var_declarations_list); - delete vardecl; - - /* (B.2) Temporary variable for function's return value */ + + /* (B.2) Temporary variable for function's return value */ /* It will have the same name as the function itself! */ s4o.print(s4o.indent_spaces); symbol->type_name->accept(*this); /* return type */ @@ -605,7 +611,30 @@ default_value->accept(*this); } s4o.print(";\n\n"); - + + s4o.print(s4o.indent_spaces + "// Control execution\n"); + s4o.print(s4o.indent_spaces + "if (!EN) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces + "if (ENO != NULL) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces + "*ENO = __BOOL_LITERAL(FALSE);\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n"); + s4o.print(s4o.indent_spaces + "return "); + symbol->derived_function_name->accept(*this); + s4o.print(";\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n"); + s4o.print(s4o.indent_spaces + "else {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces + "if (ENO != NULL) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces + "*ENO = __BOOL_LITERAL(TRUE);\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n"); + /* (C) Function body */ generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol); symbol->function_body->accept(generate_c_code); @@ -663,8 +692,15 @@ generate_c_vardecl_c::local_vf, generate_c_vardecl_c::input_vt | generate_c_vardecl_c::output_vt | - generate_c_vardecl_c::inoutput_vt); + generate_c_vardecl_c::inoutput_vt | + generate_c_vardecl_c::eneno_vt); vardecl->print(symbol->var_declarations); + if (!vardecl->is_en_declared()) { + s4o_incl.print(s4o_incl.indent_spaces + "BOOL EN;\n"); + } + if (!vardecl->is_eno_declared()) { + s4o_incl.print(s4o_incl.indent_spaces + "BOOL ENO;\n"); + } delete vardecl; s4o_incl.print("\n"); /* (A.3) Private internal variables */ @@ -677,6 +713,7 @@ generate_c_vardecl_c::external_vt); vardecl->print(symbol->var_declarations); delete vardecl; + /* (A.4) Generate private internal variables for SFC */ sfcdecl = new generate_c_sfcdecl_c(&s4o_incl, generate_c_sfcdecl_c::sfcdecl_sd); sfcdecl->print(symbol->fblock_body); @@ -713,8 +750,19 @@ generate_c_vardecl_c::inoutput_vt | generate_c_vardecl_c::private_vt | generate_c_vardecl_c::located_vt | - generate_c_vardecl_c::external_vt); + generate_c_vardecl_c::external_vt | + generate_c_vardecl_c::eneno_vt); vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->"); + if (!vardecl->is_en_declared()) { + s4o.print("\n" + s4o.indent_spaces); + s4o.print(FB_FUNCTION_PARAM); + s4o.print("->EN = __BOOL_LITERAL(TRUE);"); + } + if (!vardecl->is_eno_declared()) { + s4o.print("\n" + s4o.indent_spaces); + s4o.print(FB_FUNCTION_PARAM); + s4o.print("->ENO = __BOOL_LITERAL(TRUE);"); + } delete vardecl; s4o.print("\n"); /* (B.3) Generate private internal variables for SFC */ @@ -750,6 +798,25 @@ s4o.print(") {\n"); s4o.indent_right(); + s4o.print(s4o.indent_spaces + "// Control execution\n"); + s4o.print(s4o.indent_spaces + "if (!"); + s4o.print(FB_FUNCTION_PARAM); + s4o.print("->EN) {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + s4o.print(FB_FUNCTION_PARAM); + s4o.print("->ENO = __BOOL_LITERAL(FALSE);\n"); + s4o.print(s4o.indent_spaces + "return;\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n"); + s4o.print(s4o.indent_spaces + "else {\n"); + s4o.indent_right(); + s4o.print(s4o.indent_spaces); + s4o.print(FB_FUNCTION_PARAM); + s4o.print("->ENO = __BOOL_LITERAL(TRUE);\n"); + s4o.indent_left(); + s4o.print(s4o.indent_spaces + "}\n"); + /* (C.4) Initialize TEMP variables */ /* function body */ s4o.print(s4o.indent_spaces + "// Initialise TEMP variables\n"); diff -r 72ae82e65dbc -r eef5e62048c7 stage4/generate_c/generate_c_base.cc --- a/stage4/generate_c/generate_c_base.cc Thu Sep 25 10:26:10 2008 +0200 +++ b/stage4/generate_c/generate_c_base.cc Fri Sep 26 14:42:05 2008 +0200 @@ -78,6 +78,7 @@ ~generate_c_base_c(void) {} void set_variable_prefix(const char *variable_prefix) {variable_prefix_ = variable_prefix;} + bool is_variable_prefix_null(void) {return variable_prefix_ == NULL;} void print_variable_prefix(void) { if (variable_prefix_ != NULL) s4o.print(variable_prefix_); diff -r 72ae82e65dbc -r eef5e62048c7 stage4/generate_c/generate_c_il.cc --- a/stage4/generate_c/generate_c_il.cc Thu Sep 25 10:26:10 2008 +0200 +++ b/stage4/generate_c/generate_c_il.cc Fri Sep 26 14:42:05 2008 +0200 @@ -295,6 +295,8 @@ search_base_type_c search_base_type; + bool current_param_is_pointer; + public: generate_c_il_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL) : generate_c_typedecl_c(s4o_ptr), @@ -308,6 +310,7 @@ current_operand = NULL; current_operand_type = NULL; il_default_variable_init_value = NULL; + current_param_is_pointer = false; this->set_variable_prefix(variable_prefix); } @@ -458,6 +461,38 @@ private: +void *visit(eno_param_c *symbol) { + if (this->is_variable_prefix_null()) { + s4o.print("*"); + } + else { + this->print_variable_prefix(); + } + s4o.print("ENO"); + return NULL; +} + +/*********************/ +/* 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(")"); + } + else { + generate_c_base_c::visit(symbol); + } + return NULL; +} + /********************************************/ /* B.1.4.1 Directly Represented Variables */ /********************************************/ @@ -466,10 +501,14 @@ TRACE("direct_variable_c"); /* Do not use print_token() as it will change everything into uppercase */ if (strlen(symbol->value) == 0) ERROR; - s4o.print("*("); + if (!current_param_is_pointer) { + s4o.print("*("); + } this->print_variable_prefix(); s4o.printlocation(symbol->value + 1); - s4o.print(")"); + if (!current_param_is_pointer) { + s4o.print(")"); + } return NULL; } @@ -583,44 +622,7 @@ if (symbol->il_operand_list != NULL) nb_param += ((list_c *)symbol->il_operand_list)->n; -#include "il_code_gen.c" - -#if 0 - for(int current_param = 0; current_param < nb_param; current_param++) { - symbol_c *param_value; - if (current_param == 0) - param_value = &this->default_variable_name; - else { - symbol_c *param_name = NULL; - switch (current_function_type) { - default: ERROR; - } - - - /* Get the value from a foo( = ) style call */ - param_value = function_call_param_iterator.search(param_name); - delete 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) ERROR; - } - - switch (current_function_type) { - case (function_sqrt): - if (current_param == 0) { - s4o.print("sqrt("); - param_value->accept(*this); - s4o.print(")"); - } - else ERROR; - break; - default: ERROR; - } - } /* for(...) */ -#endif + #include "il_code_gen.c" /* the data type returned by the function, and stored in the il default variable... */ default_variable_name.current_type = return_data_type; @@ -696,14 +698,13 @@ break; case function_param_iterator_c::direction_out: case function_param_iterator_c::direction_inout: + current_param_is_pointer = true; if (param_value == NULL) { - /* no parameter value given, so we pass a previously declared temporary variable. */ - std::string *temp_var_name = temp_var_name_factory.new_name(); - s4o.print(*temp_var_name); - delete temp_var_name; + s4o.print("NULL"); } else { param_value->accept(*this); } + current_param_is_pointer = false; break; case function_param_iterator_c::direction_extref: /* TODO! */ diff -r 72ae82e65dbc -r eef5e62048c7 stage4/generate_c/generate_c_st.cc --- a/stage4/generate_c/generate_c_st.cc Thu Sep 25 10:26:10 2008 +0200 +++ b/stage4/generate_c/generate_c_st.cc Fri Sep 26 14:42:05 2008 +0200 @@ -134,6 +134,17 @@ private: +void *visit(eno_param_c *symbol) { + if (this->is_variable_prefix_null()) { + s4o.print("*"); + } + else { + this->print_variable_prefix(); + } + s4o.print("ENO"); + return NULL; +} + /*********************/ /* B 1.4 - Variables */ /*********************/ @@ -447,114 +458,8 @@ int nb_param = ((list_c *)symbol->parameter_assignment_list)->n; -#include "st_code_gen.c" - -#if 0 - for(int current_param = 0; current_param < nb_param; current_param++) { - symbol_c *param_name = NULL; - switch (current_function_type) { - case function_add: - case function_and: - case function_or: - param_name = generate_param_name("IN%d", current_param + 1); - break; - case function_sub: - if (current_param < 2) - param_name = generate_param_name("IN%d", current_param + 1); - else - ERROR; - break; - default: ERROR; - } - - /* Get the value from a foo( = ) style call */ - symbol_c *param_value = function_call_param_iterator.search(param_name); - delete 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) ERROR; - - switch (current_function_type) { - case function_add: - if (search_expression_type->is_time_type(function_return_type)) { - if (current_param == 0) { - s4o.print("__time_add("); - param_value->accept(*this); - } - else if (current_param == 1) { - s4o.print(", "); - param_value->accept(*this); - s4o.print(")"); - } - else ERROR; - } - else { - if (current_param == 0) - s4o.print("("); - else - s4o.print(" + "); - param_value->accept(*this); - if (current_param == nb_param - 1) - s4o.print(")"); - } - break; - case function_sub: - if (search_expression_type->is_time_type(function_return_type)) { - if (current_param == 0) { - s4o.print("__time_sub("); - param_value->accept(*this); - } - else if (current_param == 1) { - s4o.print(", "); - param_value->accept(*this); - s4o.print(")"); - } - else ERROR; - } - else { - if (current_param == 0) { - s4o.print("("); - param_value->accept(*this); - } - else if (current_param == 1) { - s4o.print(" - "); - param_value->accept(*this); - s4o.print(")"); - } - else ERROR; - } - break; - case function_and: - if (current_param == 0) - s4o.print("("); - else - if (search_expression_type->is_bool_type(function_return_type)) - s4o.print(" && "); - else - s4o.print(" & "); - param_value->accept(*this); - if (current_param == nb_param - 1) - s4o.print(")"); - break; - case function_or: - if (current_param == 0) - s4o.print("("); - else - if (search_expression_type->is_bool_type(function_return_type)) - s4o.print(" || "); - else - s4o.print(" | "); - param_value->accept(*this); - if (current_param == nb_param - 1) - s4o.print(")"); - break; - default: ERROR; - } - } /* for(...) */ -#endif + #include "st_code_gen.c" + } else { /* loop through each function parameter, find the value we should pass @@ -609,10 +514,7 @@ case function_param_iterator_c::direction_inout: current_param_is_pointer = true; if (param_value == NULL) { - /* no parameter value given, so we pass a previously declared temporary variable. */ - std::string *temp_var_name = temp_var_name_factory.new_name(); - s4o.print(*temp_var_name); - delete temp_var_name; + s4o.print("NULL"); } else { param_value->accept(*this); } diff -r 72ae82e65dbc -r eef5e62048c7 stage4/generate_c/generate_c_vardecl.cc --- a/stage4/generate_c/generate_c_vardecl.cc Thu Sep 25 10:26:10 2008 +0200 +++ b/stage4/generate_c/generate_c_vardecl.cc Fri Sep 26 14:42:05 2008 +0200 @@ -345,6 +345,8 @@ // Programs declared inside a resource will not be declared // unless program_vt is acompanied by resource_vt + static const unsigned int eneno_vt = 0x0200; // EN/ENO declaration + static const unsigned int resource_vt = 0x8000; // RESOURCE (inside a configuration!) // This, just of itself, will not print out any declarations!! // It must be acompanied by either program_vt and/or global_vt @@ -401,7 +403,6 @@ * __plc_pt_c START_P::loc = __plc_pt_c("I2"); */ typedef enum {finterface_vf, - foutputdecl_vf, foutputassign_vf, local_vf, localinit_vf, @@ -436,6 +437,10 @@ * specific global variable declaration (with #define...)*/ symbol_c *resource_name; + /* Store if En and ENO parameters have been defined by user */ + bool en_declared; + bool eno_declared; + /* Holds the references to the type and initial value * of the variables currently being declared. * Please read the comment under var1_init_decl_c for further @@ -529,18 +534,6 @@ } } - if (wanted_varformat == foutputdecl_vf) { - for(int i = 0; i < list->n; i++) { - if ((current_vartype & (output_vt | inoutput_vt)) != 0) { - s4o.print(s4o.indent_spaces); - this->current_var_type_symbol->accept(*this); - s4o.print(" "); - list->elements[i]->accept(*this); - s4o.print(";\n"); - } - } - } - if (wanted_varformat == foutputassign_vf) { for(int i = 0; i < list->n; i++) { if ((current_vartype & (output_vt | inoutput_vt)) != 0) { @@ -599,12 +592,21 @@ globalnamespace = NULL; nv = NULL; resource_name = res_name; + en_declared = false; + eno_declared = false; } ~generate_c_vardecl_c(void) { delete generate_c_array_initialization; } + bool is_en_declared(void) { + return en_declared; + } + + bool is_eno_declared(void) { + return eno_declared; + } void print(symbol_c *symbol, symbol_c *scope = NULL, const char *variable_prefix = NULL) { this->set_variable_prefix(variable_prefix); @@ -750,6 +752,27 @@ return NULL; } +void *visit(en_param_declaration_c *symbol) { + TRACE("en_declaration_c"); + if (en_declared) ERROR; + if (wanted_varformat == finterface_vf) { + finterface_var_count++; + } + if ((current_vartype & eneno_vt) != 0) { + if (wanted_varformat == finterface_vf) { + s4o.print(nv->get()); + s4o.print("\n" + s4o.indent_spaces + "BOOL EN"); + } + if (wanted_varformat == constructorinit_vf) { + s4o.print(nv->get()); + this->print_variable_prefix(); + s4o.print("ENO = __BOOL_LITERAL(TRUE);"); + } + } + en_declared = true; + return NULL; +} + void *visit(raising_edge_option_c *symbol) { // TO DO ... s4o.print("R_EDGE"); @@ -861,6 +884,27 @@ return NULL; } +void *visit(eno_param_declaration_c *symbol) { + TRACE("eno_declaration_c"); + if (eno_declared) ERROR; + if (wanted_varformat == finterface_vf) { + finterface_var_count++; + } + if ((current_vartype & eneno_vt) != 0) { + if (wanted_varformat == finterface_vf) { + s4o.print(nv->get()); + s4o.print("\n" + s4o.indent_spaces + "BOOL *EN0"); + } + if (wanted_varformat == constructorinit_vf) { + s4o.print(nv->get()); + this->print_variable_prefix(); + s4o.print("ENO = __BOOL_LITERAL(TRUE);"); + } + } + eno_declared = true; + return NULL; +} + /* VAR_IN_OUT var_declaration_list END_VAR */ void *visit(input_output_declarations_c *symbol) { TRACE("input_output_declarations_c"); diff -r 72ae82e65dbc -r eef5e62048c7 stage4/generate_iec/generate_iec.cc --- a/stage4/generate_iec/generate_iec.cc Thu Sep 25 10:26:10 2008 +0200 +++ b/stage4/generate_iec/generate_iec.cc Fri Sep 26 14:42:05 2008 +0200 @@ -606,6 +606,10 @@ return NULL; } +void *visit(en_param_declaration_c *symbol) { + s4o.print("EN : BOOL := 1"); + return NULL; +} void *visit(raising_edge_option_c *symbol) { s4o.print("R_EDGE"); @@ -681,6 +685,11 @@ return NULL; } +void *visit(eno_param_declaration_c *symbol) { + s4o.print("EN0 : BOOL"); + return NULL; +} + /* VAR_IN_OUT END_VAR */ void *visit(input_output_declarations_c *symbol) { s4o.print(s4o.indent_spaces); s4o.print("VAR_IN_OUT ");