# HG changeset patch # User mjsousa # Date 1393778576 0 # Node ID dea39ef02847614f327637f9345f272b1dc084b6 # Parent 3d682f87c870b952c1a1f8b9fc0cc928238ef29e Add limited support for the REF() operator (defined in v3 of IEC 61131-3) diff -r 3d682f87c870 -r dea39ef02847 absyntax/absyntax.def --- a/absyntax/absyntax.def Mon Feb 24 22:00:55 2014 +0000 +++ b/absyntax/absyntax.def Sun Mar 02 16:42:56 2014 +0000 @@ -1090,6 +1090,7 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ +SYM_REF1(ref_expression_c, exp) /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ SYM_REF2(or_expression_c, l_exp, r_exp) SYM_REF2(xor_expression_c, l_exp, r_exp) SYM_REF2(and_expression_c, l_exp, r_exp) diff -r 3d682f87c870 -r dea39ef02847 lib/accessor.h --- a/lib/accessor.h Mon Feb 24 22:00:55 2014 +0000 +++ b/lib/accessor.h Sun Mar 02 16:42:56 2014 +0000 @@ -92,6 +92,7 @@ __GET_VAR(((*name) __VA_ARGS__)) #define __GET_LOCATED(name, ...)\ ((name.flags & __IEC_FORCE_FLAG) ? name.fvalue __VA_ARGS__ : (*(name.value)) __VA_ARGS__) + #define __GET_VAR_BY_REF(name, ...)\ ((name.flags & __IEC_FORCE_FLAG) ? &(name.fvalue __VA_ARGS__) : &(name.value __VA_ARGS__)) #define __GET_EXTERNAL_BY_REF(name, ...)\ @@ -101,6 +102,16 @@ #define __GET_LOCATED_BY_REF(name, ...)\ ((name.flags & __IEC_FORCE_FLAG) ? &(name.fvalue __VA_ARGS__) : &((*(name.value)) __VA_ARGS__)) +#define __GET_VAR_REF(name, ...)\ + (&(name.value __VA_ARGS__)) +#define __GET_EXTERNAL_REF(name, ...)\ + (&((*(name.value)) __VA_ARGS__)) +#define __GET_EXTERNAL_FB_REF(name, ...)\ + (&(__GET_VAR(((*name) __VA_ARGS__)))) +#define __GET_LOCATED_REF(name, ...)\ + (&((*(name.value)) __VA_ARGS__)) + + // variable setting macros #define __SET_VAR(prefix, name, new_value, ...)\ if (!(prefix name.flags & __IEC_FORCE_FLAG)) prefix name.value __VA_ARGS__ = new_value diff -r 3d682f87c870 -r dea39ef02847 main.cc --- a/main.cc Mon Feb 24 22:00:55 2014 +0000 +++ b/main.cc Sun Mar 02 16:42:56 2014 +0000 @@ -121,10 +121,11 @@ /* Version 1.0 is Official Release */ /******************************************************/ printf(" s : allow use of safe extensions (e.g. SAFExxx data types))\n"); - printf(" n : allow use of nested comments\n"); + printf(" n : allow use of nested comments (an IEC 61131-3 v3 feature)\n"); + printf(" r : allow use of REF() operator (an IEC 61131-3 v3 feature)\n"); printf(" c : create conversion functions for enumerated data types\n"); printf("\n"); - printf("%s - Copyright (C) 2003-2011 \n" + printf("%s - Copyright (C) 2003-2014 \n" "This program comes with ABSOLUTELY NO WARRANTY!\n" "This is free software licensed under GPL v3, and you are welcome to redistribute it under the conditions specified by this license.\n", PACKAGE_NAME); } @@ -143,12 +144,13 @@ stage1_2_options.full_token_loc = false; /* error messages specify full token location */ stage1_2_options.conversion_functions = false; /* Create a conversion function for derived datatype */ stage1_2_options.nested_comments = false; /* Allow the use of nested comments. */ + stage1_2_options.ref_operator = false; /* Allow the use of REF() operator. */ stage1_2_options.includedir = NULL; /* Include directory, where included files will be searched for... */ /******************************************/ /* Parse command line options... */ /******************************************/ - while ((optres = getopt(argc, argv, ":nhvfscI:T:")) != -1) { + while ((optres = getopt(argc, argv, ":nhvfrscI:T:")) != -1) { switch(optres) { case 'h': printusage(argv[0]); @@ -167,6 +169,10 @@ stage1_2_options.safe_extensions = true; break; + case 'r': + stage1_2_options.ref_operator = true; + break; + case 'c': stage1_2_options.conversion_functions = true; break; diff -r 3d682f87c870 -r dea39ef02847 stage1_2/iec_bison.yy --- a/stage1_2/iec_bison.yy Mon Feb 24 22:00:55 2014 +0000 +++ b/stage1_2/iec_bison.yy Sun Mar 02 16:42:56 2014 +0000 @@ -412,6 +412,8 @@ %type en_identifier %type eno_identifier +/* Keyword in IEC 61131-3 v3 */ +%token REF @@ -1290,6 +1292,7 @@ * are not required. Their values are integrated * directly into other rules... */ +%type ref_expression /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ %type expression %type xor_expression %type and_expression @@ -7057,6 +7060,7 @@ /***********************/ expression: xor_expression +| ref_expression /* an extension to the IEC 61131-3 v2 standard, based on the IEC 61131-3 v3 standard */ | expression OR xor_expression {$$ = new or_expression_c($1, $3, locloc(@$));} /* ERROR_CHECK_BEGIN */ @@ -7069,6 +7073,14 @@ /* ERROR_CHECK_END */ ; +/* REF(var_name) */ +/* This is an extension to the IEC 61131-3 standard. It is actually defined in the IEC 61131-3 v3 standard */ +/* The REF() operator returns the adrress of the variable. Basically, it returns a pointer to the variable */ +ref_expression: + REF '(' symbolic_variable ')' + {$$ = new ref_expression_c($3, locloc(@$));} +; + xor_expression: and_expression | xor_expression XOR and_expression diff -r 3d682f87c870 -r dea39ef02847 stage1_2/iec_flex.ll --- a/stage1_2/iec_flex.ll Mon Feb 24 22:00:55 2014 +0000 +++ b/stage1_2/iec_flex.ll Sun Mar 02 16:42:56 2014 +0000 @@ -1245,6 +1245,8 @@ /******************************************************/ +REF {if (get_opt_ref_operator()) return REF; else unput(0);} /* Keyword in IEC 61131-3 v3 */ + EN return EN; /* Keyword */ ENO return ENO; /* Keyword */ diff -r 3d682f87c870 -r dea39ef02847 stage1_2/stage1_2.cc --- a/stage1_2/stage1_2.cc Mon Feb 24 22:00:55 2014 +0000 +++ b/stage1_2/stage1_2.cc Sun Mar 02 16:42:56 2014 +0000 @@ -69,6 +69,13 @@ bool nested_comments_ = false; bool get_opt_nested_comments() {return nested_comments_;} +/************************************/ +/* whether to allow REF() operator */ +/************************************/ +bool ref_operator_ = false; +bool get_opt_ref_operator() {return ref_operator_;} + + /******************************************************/ /* whether we are supporting conversion functions */ /* for enumerate data types */ @@ -248,6 +255,7 @@ */ nested_comments_ = options.nested_comments; + ref_operator_ = options.ref_operator; safe_extensions_ = options.safe_extensions; conversion_functions_ = options.conversion_functions; return stage2__(filename, options.includedir, tree_root_ref, options.full_token_loc); diff -r 3d682f87c870 -r dea39ef02847 stage1_2/stage1_2.hh --- a/stage1_2/stage1_2.hh Mon Feb 24 22:00:55 2014 +0000 +++ b/stage1_2/stage1_2.hh Sun Mar 02 16:42:56 2014 +0000 @@ -60,6 +60,7 @@ bool full_token_loc; /* error messages specify full token location */ bool conversion_functions; /* Create a conversion function for derived datatype */ bool nested_comments; /* Allow the use of nested comments. */ + bool ref_operator; /* Allow the use of REF() operator. */ const char *includedir; /* Include directory, where included files will be searched for... */ } stage1_2_options_t; diff -r 3d682f87c870 -r dea39ef02847 stage1_2/stage1_2_priv.hh --- a/stage1_2/stage1_2_priv.hh Mon Feb 24 22:00:55 2014 +0000 +++ b/stage1_2/stage1_2_priv.hh Sun Mar 02 16:42:56 2014 +0000 @@ -93,6 +93,12 @@ /************************************/ bool get_opt_nested_comments(); +/************************************/ +/* whether to allow REF() operator */ +/************************************/ +bool get_opt_ref_operator(); + + /*************************************************************/ /*************************************************************/ diff -r 3d682f87c870 -r dea39ef02847 stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Mon Feb 24 22:00:55 2014 +0000 +++ b/stage3/fill_candidate_datatypes.cc Sun Mar 02 16:42:56 2014 +0000 @@ -1832,6 +1832,15 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ +/* SYM_REF1(ref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ +void *fill_candidate_datatypes_c::visit( ref_expression_c *symbol) { + symbol->exp->accept(*this); + /* we should really check whether the expression is merely a variable. For now, leave it for the future! */ + /* For now, we handle references (i.e. pointers) as ULINT datatypes! */ + add_datatype_to_candidate_list(symbol, &get_datatype_info_c::ulint_type_name); + return NULL; +} + void *fill_candidate_datatypes_c::visit( or_expression_c *symbol) {return handle_binary_expression (widen_OR_table, symbol, symbol->l_exp, symbol->r_exp);} void *fill_candidate_datatypes_c::visit( xor_expression_c *symbol) {return handle_binary_expression (widen_XOR_table, symbol, symbol->l_exp, symbol->r_exp);} void *fill_candidate_datatypes_c::visit( and_expression_c *symbol) {return handle_binary_expression (widen_AND_table, symbol, symbol->l_exp, symbol->r_exp);} diff -r 3d682f87c870 -r dea39ef02847 stage3/fill_candidate_datatypes.hh --- a/stage3/fill_candidate_datatypes.hh Mon Feb 24 22:00:55 2014 +0000 +++ b/stage3/fill_candidate_datatypes.hh Sun Mar 02 16:42:56 2014 +0000 @@ -327,6 +327,7 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ + void *visit(ref_expression_c *symbol); void *visit(or_expression_c *symbol); void *visit(xor_expression_c *symbol); void *visit(and_expression_c *symbol); diff -r 3d682f87c870 -r dea39ef02847 stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Mon Feb 24 22:00:55 2014 +0000 +++ b/stage3/narrow_candidate_datatypes.cc Sun Mar 02 16:42:56 2014 +0000 @@ -1337,6 +1337,17 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ +/* SYM_REF1(ref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ +void *narrow_candidate_datatypes_c::visit( ref_expression_c *symbol) { + if (symbol->exp->candidate_datatypes.size() > 0) { + symbol->exp->datatype = symbol->exp->candidate_datatypes[0]; /* just use the first possible datatype */ + symbol->exp->accept(*this); + } + return NULL; +} + + + /* allow_enums is FALSE by default!! * deprecated_operation is NULL by default!! * if (allow_enums) then consider that we are ectually processing an equ_expression or notequ_expression, where two enums of the same data type may also be legally compared diff -r 3d682f87c870 -r dea39ef02847 stage3/narrow_candidate_datatypes.hh --- a/stage3/narrow_candidate_datatypes.hh Mon Feb 24 22:00:55 2014 +0000 +++ b/stage3/narrow_candidate_datatypes.hh Sun Mar 02 16:42:56 2014 +0000 @@ -303,6 +303,7 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ + void *visit(ref_expression_c *symbol); void *visit(or_expression_c *symbol); void *visit(xor_expression_c *symbol); void *visit(and_expression_c *symbol); diff -r 3d682f87c870 -r dea39ef02847 stage3/print_datatypes_error.cc --- a/stage3/print_datatypes_error.cc Mon Feb 24 22:00:55 2014 +0000 +++ b/stage3/print_datatypes_error.cc Sun Mar 02 16:42:56 2014 +0000 @@ -1032,6 +1032,15 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ +/* SYM_REF1(ref_expression_c, exp) --> an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ +void *print_datatypes_error_c::visit( ref_expression_c *symbol) { + symbol->exp->accept(*this); + /* we should really check whether the expression is merely a variable. For now, leave it for the future! */ + if ((symbol->candidate_datatypes.size() == 0) && (symbol->exp->candidate_datatypes.size() > 0)) + STAGE3_ERROR(0, symbol, symbol, "REF operator must be used with a variable."); + return NULL; +} + 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) { l_expr->accept(*this); diff -r 3d682f87c870 -r dea39ef02847 stage3/print_datatypes_error.hh --- a/stage3/print_datatypes_error.hh Mon Feb 24 22:00:55 2014 +0000 +++ b/stage3/print_datatypes_error.hh Sun Mar 02 16:42:56 2014 +0000 @@ -283,6 +283,7 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ + void *visit(ref_expression_c *symbol); void *visit(or_expression_c *symbol); void *visit(xor_expression_c *symbol); void *visit(and_expression_c *symbol); diff -r 3d682f87c870 -r dea39ef02847 stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Mon Feb 24 22:00:55 2014 +0000 +++ b/stage4/generate_c/generate_c.cc Sun Mar 02 16:42:56 2014 +0000 @@ -132,6 +132,12 @@ #define GET_EXTERNAL "__GET_EXTERNAL" #define GET_EXTERNAL_FB "__GET_EXTERNAL_FB" #define GET_LOCATED "__GET_LOCATED" + +#define GET_VAR_REF "__GET_VAR_REF" +#define GET_EXTERNAL_REF "__GET_EXTERNAL_REF" +#define GET_EXTERNAL_FB_REF "__GET_EXTERNAL_FB_REF" +#define GET_LOCATED_REF "__GET_LOCATED_REF" + #define GET_VAR_BY_REF "__GET_VAR_BY_REF" #define GET_EXTERNAL_BY_REF "__GET_EXTERNAL_BY_REF" #define GET_EXTERNAL_FB_BY_REF "__GET_EXTERNAL_FB_BY_REF" diff -r 3d682f87c870 -r dea39ef02847 stage4/generate_c/generate_c_st.cc --- a/stage4/generate_c/generate_c_st.cc Mon Feb 24 22:00:55 2014 +0000 +++ b/stage4/generate_c/generate_c_st.cc Sun Mar 02 16:42:56 2014 +0000 @@ -456,6 +456,47 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ +void *visit(ref_expression_c *symbol) { + s4o.print("((IEC_UDINT)"); + if (this->is_variable_prefix_null()) { + /* For code in FUNCTIONs */ + s4o.print("&("); + symbol->exp->accept(*this); + s4o.print(")"); + } else { + /* For code in FBs, and PROGRAMS... */ + s4o.print("("); + unsigned int vartype = analyse_variable_c::first_nonfb_vardecltype(symbol->exp, scope_); + if (vartype == search_var_instance_decl_c::external_vt) { + if (!get_datatype_info_c::is_type_valid (symbol->exp->datatype)) ERROR; + if ( get_datatype_info_c::is_function_block(symbol->exp->datatype)) + s4o.print(GET_EXTERNAL_FB_REF); + else + s4o.print(GET_EXTERNAL_REF); + } + else if (vartype == search_var_instance_decl_c::located_vt) + s4o.print(GET_LOCATED_REF); + else + s4o.print(GET_VAR_REF); + + variablegeneration_t old_wanted_variablegeneration = wanted_variablegeneration; + s4o.print("("); + wanted_variablegeneration = complextype_base_vg; + symbol->exp->accept(*this); + s4o.print(","); + wanted_variablegeneration = complextype_suffix_vg; + symbol->exp->accept(*this); + s4o.print(")"); + wanted_variablegeneration = old_wanted_variablegeneration; + + s4o.print(")"); + } + s4o.print(")"); + + return NULL; +} + + void *visit(or_expression_c *symbol) { if (get_datatype_info_c::is_BOOL_compatible(symbol->datatype)) return print_binary_expression(symbol->l_exp, symbol->r_exp, " || "); diff -r 3d682f87c870 -r dea39ef02847 stage4/generate_iec/generate_iec.cc --- a/stage4/generate_iec/generate_iec.cc Mon Feb 24 22:00:55 2014 +0000 +++ b/stage4/generate_iec/generate_iec.cc Sun Mar 02 16:42:56 2014 +0000 @@ -1856,6 +1856,7 @@ /***********************/ /* B 3.1 - Expressions */ /***********************/ +void *visit(ref_expression_c *symbol) {return s4o.print("REF("); symbol->exp->accept(*this); s4o.print(")");} /* an extension to the IEC 61131-3 standard - based on the IEC 61131-3 v3 standard. Returns address of the varible! */ void *visit(or_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " OR ");} void *visit(xor_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " XOR ");} void *visit(and_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " AND ");}