--- a/absyntax/absyntax.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/absyntax/absyntax.cc Wed May 28 11:32:09 2014 +0200
@@ -57,6 +57,7 @@
this->last_column = last_column;
this->last_order = last_order;
this->datatype = NULL;
+ this->scope = NULL;
this->const_value._real64.status = cs_undefined;
this->const_value._int64.status = cs_undefined;
this->const_value._uint64.status = cs_undefined;
--- a/absyntax/absyntax.hh Thu Mar 20 17:27:29 2014 +0100
+++ b/absyntax/absyntax.hh Wed May 28 11:32:09 2014 +0200
@@ -131,6 +131,10 @@
* Otherwise, it points to an object of the apropriate data type (e.g. int_type_name_c, bool_type_name_c, ...)
*/
symbol_c *datatype;
+ /* The POU in which the symbolic variable (or structured variable, or array variable, or located variable, - any more?)
+ * was declared. This will point to a Configuration, Resource, Program, FB, or Function.
+ */
+ symbol_c *scope;
/*** constant folding ***/
/* During stage 3 (semantic analysis/checking) we will be doing constant folding.
--- a/absyntax_utils/get_var_name.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/absyntax_utils/get_var_name.cc Wed May 28 11:32:09 2014 +0200
@@ -35,26 +35,6 @@
* appear in the variable declaration.
*/
-/* For ex.:
- * VAR
- * A : int;
- * B : ARRAY [1..9] of int;
- * C : some_struct_t;
- * END_VAR
- *
- * A := 56;
- * B[8] := 99;
- * C.e := 77;
- *
- * Calling this visitor class with symbolic_variable_c instance referencing 'A' in
- * the line 'A := 56', will return the string "A".
- *
- * Calling this visitor class with array_variable_c instance referencing 'B[8]' in
- * the line 'B[8] := 99', will return the string "B".
- *
- * Calling this visitor class with array_variable_c instance referencing 'C.e' in
- * the line 'C.e := 77', will return the string "C".
- */
#include "absyntax_utils.hh"
@@ -68,6 +48,26 @@
+/* For ex.:
+ * VAR
+ * A : int;
+ * B : ARRAY [1..9] of int;
+ * C : some_struct_t;
+ * END_VAR
+ *
+ * A := 56;
+ * B[8] := 99;
+ * C.e := 77;
+ *
+ * Calling this method with symbolic_variable_c instance referencing 'A' in
+ * the line 'A := 56', will return the string "A".
+ *
+ * Calling this method with array_variable_c instance referencing 'B[8]' in
+ * the line 'B[8] := 99', will return the string "B".
+ *
+ * Calling this method with array_variable_c instance referencing 'C.e' in
+ * the line 'C.e := 77', will return the string "C".
+ */
token_c *get_var_name_c::get_name(symbol_c *symbol) {
if (NULL == singleton_instance_) singleton_instance_ = new get_var_name_c();
@@ -77,6 +77,24 @@
}
+/* Return the last field of a structured variable...
+ *
+ * A := 56; --> returns A
+ * B[8] := 99; --> returns B
+ * C.e := 77; --> returns e !!!
+ */
+symbol_c *get_var_name_c::get_last_field(symbol_c *symbol) {
+ if (NULL == singleton_instance_) singleton_instance_ = new get_var_name_c();
+ if (NULL == singleton_instance_) ERROR;
+
+ singleton_instance_->last_field = NULL;
+ symbol_c *res = (symbol_c*)(symbol->accept(*singleton_instance_));
+ return (NULL != singleton_instance_->last_field)? singleton_instance_->last_field : res;
+}
+
+
+
+
/*************************/
/* B.1 - Common elements */
/*************************/
@@ -114,7 +132,11 @@
* this into account!
*/
// SYM_REF2(structured_variable_c, record_variable, field_selector)
-void *get_var_name_c::visit(structured_variable_c *symbol) {return symbol->record_variable->accept(*this);}
+void *get_var_name_c::visit(structured_variable_c *symbol) {
+ void *res = symbol->record_variable->accept(*this);
+ last_field = symbol->field_selector;
+ return res;
+}
--- a/absyntax_utils/get_var_name.hh Thu Mar 20 17:27:29 2014 +0100
+++ b/absyntax_utils/get_var_name.hh Wed May 28 11:32:09 2014 +0200
@@ -63,10 +63,12 @@
public:
get_var_name_c(void) {};
~get_var_name_c(void) {};
- static token_c *get_name(symbol_c *symbol);
-
+ static token_c *get_name(symbol_c *symbol);
+ static symbol_c *get_last_field(symbol_c *symbol);
+
private:
static get_var_name_c *singleton_instance_;
+ symbol_c *last_field;
private:
/*************************/
--- a/lib/accessor.h Thu Mar 20 17:27:29 2014 +0100
+++ b/lib/accessor.h Wed May 28 11:32:09 2014 +0200
@@ -113,15 +113,15 @@
// variable setting macros
-#define __SET_VAR(prefix, name, new_value, ...)\
- if (!(prefix name.flags & __IEC_FORCE_FLAG)) prefix name.value __VA_ARGS__ = new_value
-#define __SET_EXTERNAL(prefix, name, new_value, ...)\
- {extern IEC_BYTE __IS_GLOBAL_##name##_FORCED(void);\
- if (!(prefix name.flags & __IEC_FORCE_FLAG || __IS_GLOBAL_##name##_FORCED()))\
- (*(prefix name.value)) __VA_ARGS__ = new_value;}
-#define __SET_EXTERNAL_FB(prefix, name, new_value, ...)\
- __SET_VAR((*(prefix name)), __VA_ARGS__, new_value)
-#define __SET_LOCATED(prefix, name, new_value, ...)\
- if (!(prefix name.flags & __IEC_FORCE_FLAG)) *(prefix name.value) __VA_ARGS__ = new_value
+#define __SET_VAR(prefix, name, suffix, new_value)\
+ if (!(prefix name.flags & __IEC_FORCE_FLAG)) prefix name.value suffix = new_value
+#define __SET_EXTERNAL(prefix, name, suffix, new_value)\
+ {extern IEC_BYTE __IS_GLOBAL_##name##_FORCED();\
+ if (!(prefix name.flags & __IEC_FORCE_FLAG || __IS_GLOBAL_##name##_FORCED()))\
+ (*(prefix name.value)) suffix = new_value;}
+#define __SET_EXTERNAL_FB(prefix, name, suffix, new_value)\
+ __SET_VAR((*(prefix name)), suffix, new_value)
+#define __SET_LOCATED(prefix, name, suffix, new_value)\
+ if (!(prefix name.flags & __IEC_FORCE_FLAG)) *(prefix name.value) suffix = new_value
#endif //__ACCESSOR_H
--- a/lib/rtc.txt Thu Mar 20 17:27:29 2014 +0100
+++ b/lib/rtc.txt Wed May 28 11:32:09 2014 +0200
@@ -29,7 +29,7 @@
CURRENT_TIME : DT;
END_VAR
- {__SET_VAR(data__->,CURRENT_TIME,__CURRENT_TIME)}
+ {__SET_VAR(data__->,CURRENT_TIME,,__CURRENT_TIME)}
IF IN
THEN
--- a/lib/timer.txt Thu Mar 20 17:27:29 2014 +0100
+++ b/lib/timer.txt Wed May 28 11:32:09 2014 +0200
@@ -90,7 +90,7 @@
CURRENT_TIME, START_TIME : TIME;
END_VAR
- {__SET_VAR(data__->,CURRENT_TIME,__CURRENT_TIME)}
+ {__SET_VAR(data__->,CURRENT_TIME,,__CURRENT_TIME)}
IF ((STATE = 0) AND NOT(PREV_IN) AND IN) (* found rising edge on IN *)
THEN
@@ -171,7 +171,7 @@
CURRENT_TIME, START_TIME : TIME;
END_VAR
- {__SET_VAR(data__->,CURRENT_TIME,__CURRENT_TIME)}
+ {__SET_VAR(data__->,CURRENT_TIME,,__CURRENT_TIME)}
IF ((STATE = 0) AND NOT(PREV_IN) AND IN) (* found rising edge on IN *)
THEN
@@ -255,7 +255,7 @@
CURRENT_TIME, START_TIME : TIME;
END_VAR
- {__SET_VAR(data__->,CURRENT_TIME,__CURRENT_TIME)}
+ {__SET_VAR(data__->,CURRENT_TIME,,__CURRENT_TIME)}
IF ((STATE = 0) AND PREV_IN AND NOT(IN)) (* found falling edge on IN *)
THEN
--- a/main.hh Thu Mar 20 17:27:29 2014 +0100
+++ b/main.hh Wed May 28 11:32:09 2014 +0200
@@ -78,14 +78,16 @@
#include <float.h>
#if (LDBL_MANT_DIG == 53) /* NOTE: 64 bit IEC559 real has 53 bits for mantissa! */
- #define long_double long double
- #define real64_t long_double /* so we can later use #if (real64_t == long_double) directives in the code! */
+ #define real64_tX long_double /* so we can later use #if (real64_t == long_double) directives in the code! */
+ #define real64_t long double /* NOTE: no underscore '_' between 'long' and 'double' */
#define REAL64_MAX LDBL_MAX
#elif ( DBL_MANT_DIG == 53) /* NOTE: 64 bit IEC559 real has 53 bits for mantissa! */
- #define real64_t double
+ #define real64_tX double
+ #define real64_t double
#define REAL64_MAX DBL_MAX
#elif ( FLT_MANT_DIG == 53) /* NOTE: 64 bit IEC559 real has 53 bits for mantissa! */
- #define real64_t float
+ #define real64_tX float
+ #define real64_t float
#define REAL64_MAX FLT_MAX
#else
#error Could not find a 64 bit floating point data type on this platform. Aborting...
@@ -93,16 +95,16 @@
#if (LDBL_MANT_DIG == 24) /* NOTE: 32 bit IEC559 real has 24 bits for mantissa! */
- #ifndef long_double
- #define long_double long double
- #endif
- #define real32_t long_double /* so we can later use #if (real32_t == long_double) directives in the code! */
+ #define real32_tX long_double /* so we can later use #if (real32_t == long_double) directives in the code! */
+ #define real32_t long double /* NOTE: no underscore '_' between 'long' and 'double' */
#define REAL32_MAX LDBL_MAX
#elif ( DBL_MANT_DIG == 24) /* NOTE: 32 bit IEC559 real has 24 bits for mantissa! */
- #define real32_t double
+ #define real32_tX double
+ #define real32_t double
#define REAL32_MAX DBL_MAX
#elif ( FLT_MANT_DIG == 24) /* NOTE: 32 bit IEC559 real has 24 bits for mantissa! */
- #define real32_t float
+ #define real32_tX float
+ #define real32_t float
#define REAL32_MAX FLT_MAX
#else
#error Could not find a 32 bit floating point data type on this platform. Aborting...
--- a/stage1_2/iec_bison.yy Thu Mar 20 17:27:29 2014 +0100
+++ b/stage1_2/iec_bison.yy Wed May 28 11:32:09 2014 +0200
@@ -4116,7 +4116,7 @@
variable_name_symtable.insert($1, prev_declared_fb_name_token);
}
| global_var_name ':' ref_spec /* defined in IEC 61131-3 v3 (REF_TO ...)*/
- {$$ = new external_declaration_c($1, new fb_spec_init_c($3, NULL, locloc(@3)), locloc(@$));
+ {$$ = new external_declaration_c($1, $3, locloc(@$));
variable_name_symtable.insert($1, prev_declared_fb_name_token);
}
/* ERROR_CHECK_BEGIN */
--- a/stage3/constant_folding.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/stage3/constant_folding.cc Wed May 28 11:32:09 2014 +0200
@@ -379,14 +379,14 @@
else ERROR;
errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
- #if (real64_t == float)
+ #if (real64_tX == float)
ret = strtof(str.c_str(), &endptr);
- #elif (real64_t == double)
+ #elif (real64_tX == double)
ret = strtod(str.c_str(), &endptr);
- #elif (real64_t == long_double)
+ #elif (real64_tX == long_double)
ret = strtold(str.c_str(), &endptr);
#else
- #error Could not determine which data type is being used for real64_t (defined in absyntax.hh). Aborting!
+ #error Could not determine which data type is being used for real64_t (defined in main.hh). Aborting!
#endif
if (overflow != NULL)
*overflow = (errno == ERANGE);
--- a/stage3/declaration_check.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/stage3/declaration_check.cc Wed May 28 11:32:09 2014 +0200
@@ -70,6 +70,162 @@
}
+
+
+
+
+
+
+
+#include <set>
+class check_extern_c: public iterator_visitor_c {
+ public:
+
+ private:
+ int current_display_error_level;
+ symbol_c *current_pou_decl;
+ symbol_c *current_resource_decl;
+ static std::set<symbol_c *> checked_decl; // A set with all the declarations that have already been checked, so we don't recheck it again!
+
+
+ public:
+ static int error_count;
+
+ check_extern_c(symbol_c *current_pou, symbol_c *current_resource) {
+ current_display_error_level = 0;
+ current_pou_decl = current_pou;
+ current_resource_decl = current_resource;
+ }
+
+ ~check_extern_c(void) {}
+
+
+
+ void check_global_decl(symbol_c *p_decl) {
+ if (NULL == current_pou_decl) ERROR;
+
+ if (checked_decl.find(p_decl) != checked_decl.end()) return; // has already been checked!
+ checked_decl.insert(p_decl);
+
+ search_var_instance_decl_c search_var_instance_pou_glo_decl(current_pou_decl);
+ search_var_instance_decl_c search_var_instance_res_glo_decl(current_resource_decl);
+ search_var_instance_decl_c search_var_instance_ext_decl(p_decl);
+ function_param_iterator_c fpi(p_decl);
+
+ symbol_c *var_name;
+ while((var_name = fpi.next()) != NULL) {
+ if (fpi.param_direction() == function_param_iterator_c::direction_extref) {
+ /* found an external reference parameter. */
+ symbol_c *ext_decl = search_var_instance_ext_decl.get_decl(var_name);
+
+ // NOTE: Must check the POU first, and RESOURCE second!
+ symbol_c *glo_decl = search_var_instance_res_glo_decl.get_decl(var_name);
+ search_var_instance_decl_c *search_var_instance_glo_decl = &search_var_instance_res_glo_decl;
+ if (NULL == glo_decl) {
+ glo_decl = search_var_instance_pou_glo_decl.get_decl(var_name);
+ search_var_instance_glo_decl = &search_var_instance_pou_glo_decl;
+ }
+
+ if (NULL == glo_decl) {
+ STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error. The external variable does not match with any global variable.");
+ continue;
+ }
+
+ /* Check whether variable's constness (CONSTANT) is compatible.
+ * VAR_GLOBAL is contant => VAR_EXTERNAL must also be CONSTANT
+ * VAR_GLOBAL is not contant => VAR_EXTERNAL may be CONSTANT, or not!
+ */
+ search_var_instance_decl_c::opt_t ext_opt = search_var_instance_ext_decl. get_option(var_name);
+ search_var_instance_decl_c::opt_t glo_opt = search_var_instance_glo_decl->get_option(var_name);
+ if ((glo_opt == search_var_instance_decl_c::constant_opt) && (ext_opt != search_var_instance_decl_c::constant_opt))
+ STAGE3_ERROR(0, glo_decl, glo_decl, "Declaration error. The external variable must be declared as constant, as it maps to a constant global variable.");
+
+ /* TODO: Check redefinition data type.
+ * We need a new class (like search_base_type class) to get type id by variable declaration.
+ * symbol_c *glo_type = ????;
+ * symbol_c *ext_type = fpi.param_type();
+ */
+ /* For the moment, we will just use search_base_type_c instead... */
+ symbol_c *glo_type = search_base_type_c::get_basetype_decl(glo_decl);
+ symbol_c *ext_type = search_base_type_c::get_basetype_decl(ext_decl);
+ if (! get_datatype_info_c::is_type_equal(glo_type, ext_type))
+ STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error. Data type mismatch between external and global variable declarations.");
+ }
+ }
+ }
+
+
+
+ /********************************/
+ /* B 1.3.3 - Derived data types */
+ /********************************/
+ /* function_block_type_name ASSIGN structure_initialization */
+ /* structure_initialization -> may be NULL ! */
+ //SYM_REF2(fb_spec_init_c, function_block_type_name, structure_initialization)
+ /* NOTE: This class is only used when declaring FB variables, as in:
+ * name_list ':' function_block_type_name ASSIGN structure_initialization
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * fb_spec_init_c
+ * Here, fb_spec_init_c is used whether it is an external, local, or global variable!
+ * Note too that we must also check the datatypes of external and global variables!!
+ */
+ void *visit(fb_spec_init_c *symbol) {
+ symbol_c *fb_decl = function_block_type_symtable.find_value(symbol->function_block_type_name);
+ /* stage1_2 guarantees that we are sure to find a declaration in FB or Program symtable. */
+ if (fb_decl == function_block_type_symtable.end_value())
+ ERROR;
+ fb_decl->accept(*this);
+ return NULL;
+ }
+
+ /*****************************/
+ /* B 1.5.2 - Function Blocks */
+ /*****************************/
+ /* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
+ // SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body)
+ void *visit(function_block_declaration_c *symbol) {
+ check_global_decl(symbol);
+ /* The following two lines of code are only valid for v3 of IEC 61131-3, that allows VAR_GLOBAL declarations inside FBs!
+ * current_pou_decl = symbol;
+ * current_resource_decl = NULL;
+ */
+ /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
+ if (NULL != symbol->var_declarations)
+ symbol->var_declarations->accept(*this); // This will eventually call the visit(fb_spec_init_c *) method, if any FB are declared here!
+ return NULL;
+ }
+
+ /******************************************/
+ /* B 1.5.3 - Declaration & Initialisation */
+ /******************************************/
+ /* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
+ // SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body)
+ void *visit(program_declaration_c *symbol) {
+ check_global_decl(symbol);
+ /* The following two lines of code are only valid for v3 of IEC 61131-3, that allows VAR_GLOBAL declarations inside PROGRAMs!
+ * current_pou_decl = symbol;
+ * current_resource_decl = NULL;
+ */
+ /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
+ if (NULL != symbol->var_declarations)
+ symbol->var_declarations->accept(*this); // This will eventually call the visit(fb_spec_init_c *) method, if any FB are declared here!
+ return NULL;
+ }
+
+};
+
+int check_extern_c::error_count = 0;
+std::set<symbol_c *> check_extern_c::checked_decl;
+
+
+
+
+
+
+
+
+
+
declaration_check_c::declaration_check_c(symbol_c *ignore) {
current_display_error_level = 0;
current_pou_decl = NULL;
@@ -82,92 +238,26 @@
}
int declaration_check_c::get_error_count() {
- return error_count;
-}
-
-void declaration_check_c::check_global_decl(symbol_c *p_decl) {
- if (NULL == current_pou_decl) ERROR;
-
- search_var_instance_decl_c search_var_instance_pou_glo_decl(current_pou_decl);
- search_var_instance_decl_c search_var_instance_res_glo_decl(current_resource_decl);
- search_var_instance_decl_c search_var_instance_ext_decl(p_decl);
- function_param_iterator_c fpi(p_decl);
-
- symbol_c *var_name;
- while((var_name = fpi.next()) != NULL) {
- if (fpi.param_direction() == function_param_iterator_c::direction_extref) {
- /* found an external reference parameter. */
- symbol_c *ext_decl = search_var_instance_ext_decl.get_decl(var_name);
-
- // NOTE: Must check the POU first, and RESOURCE second!
- symbol_c *glo_decl = search_var_instance_res_glo_decl.get_decl(var_name);
- search_var_instance_decl_c *search_var_instance_glo_decl = &search_var_instance_res_glo_decl;
- if (NULL == glo_decl) {
- glo_decl = search_var_instance_pou_glo_decl.get_decl(var_name);
- search_var_instance_glo_decl = &search_var_instance_pou_glo_decl;
- }
-
- if (NULL == glo_decl) {
- STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error. The external variable does not match with any global variable.");
- continue;
- }
-
- /* Check whether variable's constness (CONSTANT) is compatible.
- * VAR_GLOBAL is contant => VAR_EXTERNAL must also be CONSTANT
- * VAR_GLOBAL is not contant => VAR_EXTERNAL may be CONSTANT, or not!
- */
- search_var_instance_decl_c::opt_t ext_opt = search_var_instance_ext_decl. get_option(var_name);
- search_var_instance_decl_c::opt_t glo_opt = search_var_instance_glo_decl->get_option(var_name);
- if ((glo_opt == search_var_instance_decl_c::constant_opt) && (ext_opt != search_var_instance_decl_c::constant_opt))
- STAGE3_ERROR(0, glo_decl, glo_decl, "Declaration error. The external variable must be declared as constant, as it maps to a constant global variable.");
-
- /* TODO: Check redefinition data type.
- * We need a new class (like search_base_type class) to get type id by variable declaration.
- * symbol_c *glo_type = ????;
- * symbol_c *ext_type = fpi.param_type();
- */
- /* For the moment, we will just use search_base_type_c instead... */
- symbol_c *glo_type = search_base_type_c::get_basetype_decl(glo_decl);
- symbol_c *ext_type = search_base_type_c::get_basetype_decl(ext_decl);
- if (! get_datatype_info_c::is_type_equal(glo_type, ext_type))
- STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error. Data type mismatch between external and global variable declarations.");
- }
- }
-}
-
-
+ return check_extern_c::error_count;
+}
/*****************************/
/* B 1.5.2 - Function Blocks */
/*****************************/
/* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
// SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body)
-void *declaration_check_c::visit(function_block_declaration_c *symbol) {
- /* The following two lines of code are only valid for v3 of IEC 61131-3, that allows VAR_GLOBAL declarations inside FBs!
- * current_pou_decl = symbol;
- * current_resource_decl = NULL;
- */
- /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
- if (NULL != symbol->var_declarations)
- symbol->var_declarations->accept(*this);
- return NULL;
-}
+void *declaration_check_c::visit(function_block_declaration_c *symbol)
+ {return NULL;} // We only check the declarations that are used to instantiate variables. This is done in the configuration!
/******************************************/
/* B 1.5.3 - Declaration & Initialisation */
/******************************************/
/* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
// SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body)
-void *declaration_check_c::visit(program_declaration_c *symbol) {
- /* The following two lines of code are only valid for v3 of IEC 61131-3, that allows VAR_GLOBAL declarations inside PROGRAMs!
- * current_pou_decl = symbol;
- * current_resource_decl = NULL;
- */
- /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
- if (NULL != symbol->var_declarations)
- symbol->var_declarations->accept(*this);
- return NULL;
-}
+void *declaration_check_c::visit(program_declaration_c *symbol)
+ {return NULL;} // We only check the declarations that are used to instantiate variables. This is done in the configuration!
+
+
/********************************/
/* B 1.7 Configuration elements */
@@ -199,8 +289,11 @@
/* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */
// SYM_REF4(resource_declaration_c, resource_name, resource_type_name, global_var_declarations, resource_declaration, enumvalue_symtable_t enumvalue_symtable;)
void *declaration_check_c::visit(resource_declaration_c *symbol) {
+ // check if any FB instantiated inside this resource (in a VAR_GLOBAL) has any VAR_EXTERNAL declarations incompatible with the configuration's VAR_GLOBALs
+ check_extern_c check_extern(current_pou_decl, current_resource_decl);
+ symbol->global_var_declarations->accept(check_extern);
+ // Now check the Programs instantiated in this resource
current_resource_decl = symbol;
- /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
symbol->resource_declaration->accept(*this);
current_resource_decl = NULL;
return NULL;
@@ -211,10 +304,11 @@
symbol_c *p_decl = program_type_symtable.find_value(symbol->program_type_name);
if (p_decl == program_type_symtable.end_value())
p_decl = function_block_type_symtable.find_value(symbol->program_type_name);
- /* stage1_2 guarantees that we are sure to find a declaration in FB or Program symtable. */
if (p_decl == function_block_type_symtable.end_value())
- ERROR;
- check_global_decl(p_decl);
+ ERROR; // Should never occur! stage1_2 guarantees that we are sure to find a declaration in FB or Program symtable.
+
+ check_extern_c check_extern(current_pou_decl, current_resource_decl);
+ p_decl->accept(check_extern);
return NULL;
}
--- a/stage3/narrow_candidate_datatypes.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/stage3/narrow_candidate_datatypes.cc Wed May 28 11:32:09 2014 +0200
@@ -70,6 +70,7 @@
fake_prev_il_instruction = NULL;
current_il_instruction = NULL;
il_operand = NULL;
+ current_scope = NULL;
}
narrow_candidate_datatypes_c::~narrow_candidate_datatypes_c(void) {
@@ -651,6 +652,7 @@
/*********************/
// SYM_REF1(symbolic_variable_c, var_name)
void *narrow_candidate_datatypes_c::visit(symbolic_variable_c *symbol) {
+ symbol->scope = current_scope; // the scope in which this variable was declared!
symbol->var_name->datatype = symbol->datatype;
return NULL;
}
@@ -674,6 +676,8 @@
if (symbol->subscripted_variable->candidate_datatypes.size() == 1)
symbol->subscripted_variable->datatype = symbol->subscripted_variable->candidate_datatypes[0]; // set the datatype
+ // the scope in which this variable was declared! It will be the same as the subscripted variable (a symbolic_variable_ !)
+ symbol->scope = symbol->subscripted_variable->scope;
return NULL;
}
@@ -708,6 +712,7 @@
if (symbol->record_variable->candidate_datatypes.size() == 1)
symbol->record_variable->datatype = symbol->record_variable->candidate_datatypes[0]; // set the datatype
+ symbol->scope = symbol->record_variable->datatype; // the scope in which this variable was declared!
return NULL;
}
@@ -764,12 +769,14 @@
symbol->type_name->datatype = search_base_type_c::get_basetype_decl(symbol->type_name);
symbol->datatype = symbol->type_name->datatype;
+ current_scope = symbol;
search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
symbol->var_declarations_list->accept(*this);
if (debug) printf("Narrowing candidate data types list in body of function %s\n", ((token_c *)(symbol->derived_function_name))->value);
symbol->function_body->accept(*this);
delete search_varfb_instance_type;
search_varfb_instance_type = NULL;
+ current_scope = NULL;
return NULL;
}
@@ -777,13 +784,15 @@
/* B 1.5.2 Function blocks */
/***************************/
void *narrow_candidate_datatypes_c::visit(function_block_declaration_c *symbol) {
+ current_scope = symbol;
search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
symbol->var_declarations->accept(*this);
if (debug) printf("Narrowing candidate data types list in body of FB %s\n", ((token_c *)(symbol->fblock_name))->value);
symbol->fblock_body->accept(*this);
delete search_varfb_instance_type;
search_varfb_instance_type = NULL;
-
+ current_scope = NULL;
+
// A FB declaration can also be used as a Datatype! We now do the narrow algorithm considering it as such!
if (symbol->candidate_datatypes.size() == 1)
symbol->datatype = symbol->candidate_datatypes[0];
@@ -794,12 +803,14 @@
/* B 1.5.3 Programs */
/********************/
void *narrow_candidate_datatypes_c::visit(program_declaration_c *symbol) {
+ current_scope = symbol;
search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
symbol->var_declarations->accept(*this);
if (debug) printf("Narrowing candidate data types list in body of program %s\n", ((token_c *)(symbol->program_type_name))->value);
symbol->function_block_body->accept(*this);
delete search_varfb_instance_type;
search_varfb_instance_type = NULL;
+ current_scope = NULL;
return NULL;
}
--- a/stage3/narrow_candidate_datatypes.hh Thu Mar 20 17:27:29 2014 +0100
+++ b/stage3/narrow_candidate_datatypes.hh Wed May 28 11:32:09 2014 +0200
@@ -65,6 +65,7 @@
private:
search_varfb_instance_type_c *search_varfb_instance_type;
+ symbol_c *current_scope;
symbol_c *il_operand;
il_instruction_c *fake_prev_il_instruction;
il_instruction_c *current_il_instruction;
--- a/stage4/generate_c/generate_c.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/stage4/generate_c/generate_c.cc Wed May 28 11:32:09 2014 +0200
@@ -386,6 +386,131 @@
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/
+/* A helper class that analyses if the datatype of a variable is 'complex'. */
+/* 'complex' means that it is either a strcuture or an array! */
+class print_getter_c: public search_visitor_c {
+ private:
+ static print_getter_c *singleton_;
+
+ public:
+ print_getter_c(void) {};
+
+ static bool is_complex_type(symbol_c *symbol) {
+ if (NULL == symbol) ERROR;
+ if (!get_datatype_info_c::is_type_valid (symbol->datatype)) return false;
+ return ( get_datatype_info_c::is_structure(symbol->datatype)
+ || get_datatype_info_c::is_array (symbol->datatype)
+ );
+ }
+
+
+ private:
+ symbol_c *last_fb, *first_non_fb_identifier;
+
+ public:
+ /* returns the first element (from left to right) in a structured variable that is not a FB, i.e. is either a structure or an array! */
+ /* eg:
+ * fb1.fb2.fb3.real returns ??????
+ * fb1.fb2.struct1.real returns struct1
+ * struct1.real returns struct1
+ */
+ static symbol_c *find_first_nonfb(symbol_c *symbol) {
+ if (NULL == singleton_) singleton_ = new print_getter_c();
+ if (NULL == singleton_) ERROR;
+ if (NULL == symbol) ERROR;
+
+ singleton_->last_fb = NULL;
+ singleton_->first_non_fb_identifier = NULL;
+ return (symbol_c *)symbol->accept(*singleton_);
+ }
+
+ /* returns true if a strcutured variable (e.g. fb1.fb2.strcut1.real) contains a structure or array */
+ /* eg:
+ * fb1.fb2.fb3.real returns FALSE
+ * fb1.fb2.struct1.real returns TRUE
+ * struct1.real returns TRUE
+ */
+ static bool contains_complex_type(symbol_c *symbol) {
+ if (NULL == symbol) ERROR;
+ if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR;
+
+ symbol_c *first_non_fb = (symbol_c *)find_first_nonfb(symbol);
+ return is_complex_type(first_non_fb->datatype);
+ }
+
+
+ /* returns the datatype of the variable returned by find_first_nonfb() */
+ /* eg:
+ * fb1.fb2.fb3.real returns ??????
+ * fb1.fb2.struct1.real returns datatype of struct1
+ * struct1.real returns datatype of struct1
+ */
+ static search_var_instance_decl_c::vt_t first_nonfb_vardecltype(symbol_c *symbol, symbol_c *scope) {
+ if (NULL == symbol) ERROR;
+ if (!get_datatype_info_c::is_type_valid(symbol->datatype)) ERROR;
+
+ symbol_c *first_non_fb = (symbol_c *)find_first_nonfb(symbol);
+ if (NULL != singleton_->last_fb) {
+ scope = singleton_->last_fb->datatype;
+ symbol = singleton_->first_non_fb_identifier;
+ }
+
+ search_var_instance_decl_c search_var_instance_decl(scope);
+
+ return search_var_instance_decl.get_vartype(symbol);
+ }
+
+
+ /*********************/
+ /* B 1.4 - Variables */
+ /*********************/
+ void *visit(symbolic_variable_c *symbol) {
+ if (!get_datatype_info_c::is_type_valid (symbol->datatype)) ERROR;
+ if (!get_datatype_info_c::is_function_block(symbol->datatype)) {
+ first_non_fb_identifier = symbol;
+ return (void *)symbol;
+ }
+ last_fb = symbol;
+ return NULL;
+ }
+
+ /*************************************/
+ /* B.1.4.2 Multi-element Variables */
+ /*************************************/
+
+ // SYM_REF2(structured_variable_c, record_variable, field_selector)
+ void *visit(structured_variable_c *symbol) {
+ symbol_c *res = (symbol_c *)symbol->record_variable->accept(*this);
+ if (NULL != res) return res;
+
+ if (!get_datatype_info_c::is_type_valid (symbol->datatype)) ERROR;
+ if (!get_datatype_info_c::is_function_block(symbol->datatype)) {
+ first_non_fb_identifier = symbol->field_selector;
+ return (void *)symbol;
+ }
+
+ last_fb = symbol;
+ return NULL;
+ }
+
+ /* subscripted_variable '[' subscript_list ']' */
+ //SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
+ void *visit(array_variable_c *symbol) {
+ void *res = symbol->subscripted_variable->accept(*this);
+ if (NULL != res) return res;
+ return (void *)symbol;
+ }
+
+
+};
+
+print_getter_c *print_getter_c::singleton_ = NULL;
+
+
+
+
+
+
/* A helper class that analyses if the datatype of a variable is 'complex'. */
/* 'complex' means that it is either a strcuture or an array! */
@@ -1573,7 +1698,7 @@
s4o.print(SET_VAR);
s4o.print("(");
s4o.print(FB_FUNCTION_PARAM);
- s4o.print("->,ENO,__BOOL_LITERAL(FALSE));\n");
+ s4o.print("->,ENO,,__BOOL_LITERAL(FALSE));\n");
s4o.print(s4o.indent_spaces + "return;\n");
s4o.indent_left();
s4o.print(s4o.indent_spaces + "}\n");
@@ -1583,7 +1708,7 @@
s4o.print(SET_VAR);
s4o.print("(");
s4o.print(FB_FUNCTION_PARAM);
- s4o.print("->,ENO,__BOOL_LITERAL(TRUE));\n");
+ s4o.print("->,ENO,,__BOOL_LITERAL(TRUE));\n");
s4o.indent_left();
s4o.print(s4o.indent_spaces + "}\n");
@@ -2403,7 +2528,7 @@
s4o.print(SET_VAR);
s4o.print("(");
current_task_name->accept(*this);
- s4o.print("_R_TRIG.,CLK, *");
+ s4o.print("_R_TRIG.,CLK,, *");
symbol->single_data_source->accept(*this);
s4o.print(");}\n");
s4o.print(s4o.indent_spaces + "R_TRIG");
--- a/stage4/generate_c/generate_c_base.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/stage4/generate_c/generate_c_base.cc Wed May 28 11:32:09 2014 +0200
@@ -270,10 +270,9 @@
/* Do not use print_token() as it will change everything into uppercase */
void *visit(pragma_c *symbol) {
- s4o.print(s4o.indent_spaces);
s4o.print("#define GetFbVar(var,...) __GET_VAR(data__->var,__VA_ARGS__)\n");
s4o.print(s4o.indent_spaces);
- s4o.print("#define SetFbVar(var,val,...) __SET_VAR(data__->,var,val,__VA_ARGS__)\n");
+ s4o.print("#define SetFbVar(var,val,...) __SET_VAR(data__->,var,__VA_ARGS__,val)\n");
s4o.print(symbol->value);
s4o.print("\n");
s4o.print(s4o.indent_spaces);
--- a/stage4/generate_c/generate_c_il.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/stage4/generate_c/generate_c_il.cc Wed May 28 11:32:09 2014 +0200
@@ -445,8 +445,8 @@
wanted_variablegeneration = complextype_base_assignment_vg;
else
wanted_variablegeneration = assignment_vg;
-
symbol->accept(*this);
+/*
s4o.print(",");
if (negative) {
if (get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype))
@@ -464,6 +464,24 @@
s4o.print(")");
wanted_variablegeneration = expression_vg;
return NULL;
+*/
+ s4o.print(",");
+ if (type_is_complex) {
+ wanted_variablegeneration = complextype_suffix_vg;
+ symbol->accept(*this);
+ }
+ s4o.print(",");
+ if (negative) {
+ if (get_datatype_info_c::is_BOOL_compatible(this->current_operand->datatype))
+ s4o.print("!");
+ else
+ s4o.print("~");
+ }
+ wanted_variablegeneration = expression_vg;
+ print_check_function(type, value, fb_value);
+ s4o.print(")");
+ wanted_variablegeneration = expression_vg;
+ return NULL;
}
public:
--- a/stage4/generate_c/generate_c_inlinefcall.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/stage4/generate_c/generate_c_inlinefcall.cc Wed May 28 11:32:09 2014 +0200
@@ -281,7 +281,7 @@
else
s4o.print(SET_VAR);
s4o.print("(,");
-
+/*
wanted_variablegeneration = complextype_base_vg;
symbol->accept(*this);
s4o.print(",");
@@ -295,6 +295,20 @@
s4o.print(")");
wanted_variablegeneration = expression_vg;
return NULL;
+*/
+ wanted_variablegeneration = complextype_base_vg;
+ symbol->accept(*this);
+ s4o.print(",");
+ if (analyse_variable_c::contains_complex_type(symbol)) {
+ wanted_variablegeneration = complextype_suffix_vg;
+ symbol->accept(*this);
+ }
+ s4o.print(",");
+ wanted_variablegeneration = expression_vg;
+ print_check_function(type, value, NULL, true);
+ s4o.print(")");
+ wanted_variablegeneration = expression_vg;
+ return NULL;
}
/*********************/
--- a/stage4/generate_c/generate_c_sfc.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/stage4/generate_c/generate_c_sfc.cc Wed May 28 11:32:09 2014 +0200
@@ -136,7 +136,7 @@
s4o.print(SET_VAR);
s4o.print("(");
print_step_argument(step_name, "state", true);
- s4o.print(",0);\n");
+ s4o.print(",,0);\n");
}
void print_set_step(symbol_c *step_name) {
@@ -144,7 +144,7 @@
s4o.print(SET_VAR);
s4o.print("(");
print_step_argument(step_name, "state", true);
- s4o.print(",1);\n" + s4o.indent_spaces);
+ s4o.print(",,1);\n" + s4o.indent_spaces);
print_step_argument(step_name, "elapsed_time");
s4o.print(" = __time_to_timespec(1, 0, 0, 0, 0, 0);\n");
}
@@ -299,7 +299,7 @@
print_variable_prefix();
s4o.print(",__transition_list[");
print_transition_number();
- s4o.print("],0);\n");
+ s4o.print("],,0);\n");
s4o.indent_left();
s4o.print(s4o.indent_spaces + "}\n");
break;
@@ -358,7 +358,7 @@
s4o.print("__");
s4o.print("transition_list[");
print_transition_number();
- s4o.print("],");
+ s4o.print("],,");
generate_c_il->print_implicit_variable_back();
// generate_c_il->reset_default_variable_name(); // generate_c_il does not require his anymore
s4o.print(");\n");
@@ -376,7 +376,7 @@
s4o.print("__");
s4o.print("transition_list[");
print_transition_number();
- s4o.print("],");
+ s4o.print("],,");
symbol->transition_condition_st->accept(*generate_c_st);
s4o.print(");\n");
}
@@ -389,7 +389,7 @@
print_variable_prefix();
s4o.print(",__debug_transition_list[");
print_transition_number();
- s4o.print("],");
+ s4o.print("],,");
s4o.print(GET_VAR);
s4o.print("(");
print_variable_prefix();
@@ -514,7 +514,7 @@
s4o.print(SET_VAR);
s4o.print("(");
print_action_argument(symbol->action_name, "state", true);
- s4o.print(",1);\n");
+ s4o.print(",,1);\n");
s4o.indent_left();
s4o.print(s4o.indent_spaces + "}");
}
@@ -575,7 +575,7 @@
print_variable_prefix();
s4o.print(",");
current_action->accept(*this);
- s4o.print(",1);\n");
+ s4o.print(",,1);\n");
s4o.indent_left();
s4o.print(s4o.indent_spaces + "}\n");
s4o.print(s4o.indent_spaces + "else if (active) {\n");
@@ -591,14 +591,14 @@
print_variable_prefix();
s4o.print(",");
current_action->accept(*this);
- s4o.print(",0);\n");
+ s4o.print(",,0);\n");
}
else {
s4o.print(SET_VAR);
s4o.print("(");
print_action_argument(current_action, "state", true);
- s4o.print(",1);\n");
+ s4o.print(",,1);\n");
}
}
if (strcmp(qualifier, "S") == 0 || strcmp(qualifier, "SL") == 0) {
@@ -773,7 +773,7 @@
s4o.print(SET_VAR);
s4o.print("(");
print_variable_prefix();
- s4o.print(",__action_list[i].state,0);\n");
+ s4o.print(",__action_list[i].state,,0);\n");
s4o.print(s4o.indent_spaces);
print_variable_prefix();
s4o.print("__action_list[i].set = 0;\n");
@@ -895,7 +895,7 @@
s4o.print(SET_VAR);
s4o.print("(");
print_variable_prefix();
- s4o.print(",__action_list[i].state,");
+ s4o.print(",__action_list[i].state,,");
s4o.print(GET_VAR);
s4o.print("(");
print_variable_prefix();
@@ -932,7 +932,7 @@
print_variable_prefix();
s4o.print(",");
pt->symbol->accept(*this);
- s4o.print(",0);\n");
+ s4o.print(",,0);\n");
s4o.indent_left();
s4o.print(s4o.indent_spaces + "}\n");
s4o.print(s4o.indent_spaces + "else if (");
@@ -953,7 +953,7 @@
print_variable_prefix();
s4o.print(",");
pt->symbol->accept(*this);
- s4o.print(",1);\n");
+ s4o.print(",,1);\n");
s4o.indent_left();
s4o.print(s4o.indent_spaces + "}\n");
}
--- a/stage4/generate_c/generate_c_sfcdecl.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/stage4/generate_c/generate_c_sfcdecl.cc Wed May 28 11:32:09 2014 +0200
@@ -252,7 +252,7 @@
print_variable_prefix();
s4o.print(",__step_list[");
s4o.print(step_number);
- s4o.print("].state,1);\n");
+ s4o.print("].state,,1);\n");
step_number++;
break;
case stepdef_sd:
--- a/stage4/generate_c/generate_c_st.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/stage4/generate_c/generate_c_st.cc Wed May 28 11:32:09 2014 +0200
@@ -49,9 +49,7 @@
public:
typedef enum {
expression_vg,
- assignment_vg,
complextype_base_vg,
- complextype_base_assignment_vg,
complextype_suffix_vg,
fparam_output_vg
} variablegeneration_t;
@@ -157,9 +155,10 @@
else
s4o.print(GET_VAR);
}
+
+ variablegeneration_t old_wanted_variablegeneration = wanted_variablegeneration;
s4o.print("(");
-
- variablegeneration_t old_wanted_variablegeneration = wanted_variablegeneration;
+ print_variable_prefix();
wanted_variablegeneration = complextype_base_vg;
symbol->accept(*this);
s4o.print(",");
@@ -177,14 +176,14 @@
symbol_c* value,
symbol_c* fb_symbol = NULL,
symbol_c* fb_value = NULL) {
-
- bool type_is_complex = false;
+
if (fb_symbol == NULL) {
unsigned int vartype = analyse_variable_c::first_nonfb_vardecltype(symbol, scope_);
- type_is_complex = analyse_variable_c::contains_complex_type(symbol);
+ symbol_c *first_nonfb = analyse_variable_c::find_first_nonfb(symbol);
+ if (first_nonfb == NULL) ERROR;
if (vartype == search_var_instance_decl_c::external_vt) {
- if (!get_datatype_info_c::is_type_valid (symbol->datatype)) ERROR;
- if ( get_datatype_info_c::is_function_block(symbol->datatype))
+ if (!get_datatype_info_c::is_type_valid (first_nonfb->datatype)) ERROR;
+ if ( get_datatype_info_c::is_function_block(first_nonfb->datatype)) // handle situation where we are copying a complete fb -> fb1.fb2.fb3 := fb4 (and fb3 is external!)
s4o.print(SET_EXTERNAL_FB);
else
s4o.print(SET_EXTERNAL);
@@ -202,26 +201,29 @@
s4o.print(SET_VAR);
}
s4o.print("(");
-
+
if (fb_symbol != NULL) {
print_variable_prefix();
+ // It is my (MJS) conviction that by this time the following will always be true...
+ // wanted_variablegeneration == expression_vg;
fb_symbol->accept(*this);
s4o.print(".,");
- }
- else if (type_is_complex)
- wanted_variablegeneration = complextype_base_assignment_vg;
- else
- wanted_variablegeneration = assignment_vg;
-
- symbol->accept(*this);
- s4o.print(",");
- wanted_variablegeneration = expression_vg;
- print_check_function(type, value, fb_value);
- if (type_is_complex) {
+ symbol->accept(*this);
+ s4o.print(",");
+ s4o.print(",");
+ }
+ else {
+ print_variable_prefix();
+ s4o.print(",");
+ wanted_variablegeneration = complextype_base_vg;
+ symbol->accept(*this);
s4o.print(",");
wanted_variablegeneration = complextype_suffix_vg;
symbol->accept(*this);
- }
+ s4o.print(",");
+ }
+ wanted_variablegeneration = expression_vg;
+ print_check_function(type, value, fb_value);
s4o.print(")");
wanted_variablegeneration = expression_vg;
return NULL;
@@ -264,14 +266,8 @@
/*********************/
void *visit(symbolic_variable_c *symbol) {
switch (wanted_variablegeneration) {
- case complextype_base_assignment_vg:
- case assignment_vg:
- this->print_variable_prefix();
- s4o.print(",");
- symbol->var_name->accept(*this);
- break;
case complextype_base_vg:
- generate_c_base_c::visit(symbol);
+ symbol->var_name->accept(*this); //generate_c_base_c::visit(symbol);
break;
case complextype_suffix_vg:
break;
@@ -321,8 +317,9 @@
}
this->print_variable_prefix();
s4o.printlocation(symbol->value + 1);
- if ((this->is_variable_prefix_null() && wanted_variablegeneration != fparam_output_vg) ||
- wanted_variablegeneration != assignment_vg)
+ if (( this->is_variable_prefix_null() && (wanted_variablegeneration != fparam_output_vg)) ||
+ (!this->is_variable_prefix_null() && (wanted_variablegeneration == expression_vg )) ||
+ (!this->is_variable_prefix_null() && (wanted_variablegeneration == fparam_output_vg)))
s4o.print(")");
return NULL;
}
@@ -334,28 +331,26 @@
// SYM_REF2(structured_variable_c, record_variable, field_selector)
void *visit(structured_variable_c *symbol) {
TRACE("structured_variable_c");
- bool type_is_complex = analyse_variable_c::is_complex_type(symbol->record_variable);
switch (wanted_variablegeneration) {
case complextype_base_vg:
- case complextype_base_assignment_vg:
symbol->record_variable->accept(*this);
- if (!type_is_complex) {
+ if ( get_datatype_info_c::is_function_block(symbol->record_variable->datatype)) {
+ if (NULL == symbol->record_variable->scope) ERROR;
+ search_var_instance_decl_c search_var_instance_decl(symbol->record_variable->scope);
+ if (search_var_instance_decl_c::external_vt == search_var_instance_decl.get_vartype(get_var_name_c::get_last_field(symbol->record_variable)))
+ s4o.print("->");
+ else
+ s4o.print(".");
+ symbol->field_selector->accept(*this);
+ }
+ break;
+ case complextype_suffix_vg:
+ symbol->record_variable->accept(*this);
+ if (!get_datatype_info_c::is_function_block(symbol->record_variable->datatype)) { // if the record variable is not a FB, then it will certainly be a structure!
s4o.print(".");
symbol->field_selector->accept(*this);
}
break;
- case complextype_suffix_vg:
- symbol->record_variable->accept(*this);
- if (type_is_complex) {
- s4o.print(".");
- symbol->field_selector->accept(*this);
- }
- break;
- case assignment_vg:
- symbol->record_variable->accept(*this);
- s4o.print(".");
- symbol->field_selector->accept(*this);
- break;
default:
if (this->is_variable_prefix_null()) {
symbol->record_variable->accept(*this);
@@ -374,7 +369,6 @@
void *visit(array_variable_c *symbol) {
switch (wanted_variablegeneration) {
case complextype_base_vg:
- case complextype_base_assignment_vg:
symbol->subscripted_variable->accept(*this);
break;
case complextype_suffix_vg:
@@ -482,6 +476,7 @@
variablegeneration_t old_wanted_variablegeneration = wanted_variablegeneration;
s4o.print("(");
wanted_variablegeneration = complextype_base_vg;
+ print_variable_prefix();
symbol->exp->accept(*this);
s4o.print(",");
wanted_variablegeneration = complextype_suffix_vg;
--- a/stage4/generate_c/generate_c_vardecl.cc Thu Mar 20 17:27:29 2014 +0100
+++ b/stage4/generate_c/generate_c_vardecl.cc Wed May 28 11:32:09 2014 +0200
@@ -169,7 +169,7 @@
print_variable_prefix();
s4o.print(",");
symbol->elements[i]->accept(*this);
- s4o.print(",temp);\n");
+ s4o.print(",,temp);\n");
}
return NULL;
}
@@ -577,7 +577,7 @@
print_variable_prefix();
s4o.print(",");
symbol->elements[i]->accept(*this);
- s4o.print(",temp);\n");
+ s4o.print(",,temp);\n");
}
return NULL;
}
@@ -1000,7 +1000,7 @@
s4o.print("}\n");
}
else if (wanted_varformat == init_vf) {
- s4o.print(",");
+ s4o.print(",,");
this->current_var_init_symbol->accept(*this);
s4o.print(");\n");
}