--- a/absyntax_utils/search_var_instance_decl.cc Tue Aug 14 19:40:01 2012 +0200
+++ b/absyntax_utils/search_var_instance_decl.cc Wed Aug 22 16:46:17 2012 +0200
@@ -30,27 +30,51 @@
*
*/
-/* Determine the data type of a specific variable instance, including
- * function block instances.
- * A reference to the relevant variable declaration is returned.
- * The variable instance may NOT be a member of a structure of a member
+/* Search in a VAR* END_VAR declaration for the delcration of the specified variable instance.
+ * Will return:
+ * - the declaration itself (get_decl() )
+ * - the type of declaration in which the variable was declared (get_vartype() )
+ *
+ * The variable instance may NOT be a member of a structure of a memeber
* of a structure of an element of an array of ...
*
- * example:
+ * For example, considering the following 'variables':
* window.points[1].coordinate.x
* window.points[1].colour
- * etc... ARE NOT ALLOWED!
+ * offset[99]
+ *
+ * passing a reference to 'points', 'points[1]', 'points[1].colour', 'colour'
+ * ARE NOT ALLOWED!
*
* This class must only be passed the name of the variable that will appear
* in the variable declaration. In the above examples, this would be
- * 'window' !!
- *
- *
- * If you need to pass a complete name of a variable instance (such as
- * 'window.points[1].coordinate.x') use the search_varfb_instance_type_c instead!
+ * 'window.points[1].coordinate.x'
+ * 'window.points[1].coordinate'
+ * 'window.points[1]'
+ * 'window'
+ * 'window.points[1].colour'
+ * 'offset'
+ * 'offset[99]'
+ *
+ *
*/
-
-/* Note that current_type_decl that this class returns may reference the
+
+/* Note:
+ * Determining the declaration type of a specific variable instance (including
+ * function block instances) really means determining whether the variable was declared in a
+ * VAR_INPUT
+ * VAR_OUTPUT
+ * VAR_IN_OUT
+ * VAR
+ * VAR_TEMP
+ * VAR_EXTERNAL
+ * VAR_GLOBAL
+ * VAR <var_name> AT <location> -> Located variable!
+ *
+ */
+
+/* Note:
+ * The current_type_decl that this class returns may reference the
* name of a type, or the type declaration itself!
* For an example of the first, consider a variable declared as ...
* x : AAA;
@@ -61,25 +85,71 @@
* If it is the first, we will return a reference to the name, if the second
* we return a reference to the declaration!!
*/
+
+
#include "absyntax_utils.hh"
+
+
+
search_var_instance_decl_c::search_var_instance_decl_c(symbol_c *search_scope) {
this->current_vartype = none_vt;
this->search_scope = search_scope;
this->search_name = NULL;
this->current_type_decl = NULL;
-}
-
-symbol_c *search_var_instance_decl_c::get_decl(symbol_c *variable_instance_name) {
+ this->current_option = none_opt;
+}
+
+symbol_c *search_var_instance_decl_c::get_decl(symbol_c *variable) {
this->current_vartype = none_vt;
- this->search_name = variable_instance_name;
+ this->current_option = none_opt;
+ this->search_name = get_var_name_c::get_name(variable);
return (symbol_c *)search_scope->accept(*this);
}
-unsigned int search_var_instance_decl_c::get_vartype(void) {
- return current_vartype;
-}
+search_var_instance_decl_c::vt_t search_var_instance_decl_c::get_vartype(symbol_c *variable) {
+ this->current_vartype = none_vt;
+ this->current_option = none_opt;
+ this->search_name = get_var_name_c::get_name(variable);
+ search_scope->accept(*this);
+ return this->current_vartype;
+}
+
+search_var_instance_decl_c::opt_t search_var_instance_decl_c::get_option(symbol_c *variable) {
+ this->current_vartype = none_vt;
+ this->current_option = none_opt;
+ this->search_name = get_var_name_c::get_name(variable);
+ search_scope->accept(*this);
+ return this->current_option;
+}
+
+
+
+/* This is a temporary fix. Hopefully, once I clean up stage4 code, and I change the way
+ * we generate C code, this function will no longer be needed!
+ */
+#include <typeinfo> /* required for typeid() */
+bool search_var_instance_decl_c::type_is_complex(symbol_c *symbol) {
+ symbol_c *decl;
+ search_base_type_c search_base_type;
+
+ decl = this->get_decl(symbol);
+ if (NULL == decl) ERROR;
+ decl = search_base_type.get_basetype_decl(decl);
+ if (NULL == decl) ERROR;
+
+ return ((typeid( *(decl) ) == typeid( array_specification_c )) ||
+// (typeid( *(decl) ) == typeid( array_spec_init_c )) || /* does not seem to be necessary */
+ (typeid( *(decl) ) == typeid( structure_type_declaration_c )) ||
+ (typeid( *(decl) ) == typeid( structure_element_declaration_list_c )) ||
+// (typeid( *(decl) ) == typeid( structure_type_declaration_c )) || /* does not seem to be necessary */
+ (typeid( *(decl) ) == typeid( initialized_structure_c ))
+
+ );
+}
+
+
/***************************/
/* B 0 - Programming Model */
@@ -100,12 +170,30 @@
/* edge -> The F_EDGE or R_EDGE directive */
// SYM_REF2(edge_declaration_c, edge, var1_list)
// TODO
+void *search_var_instance_decl_c::visit(constant_option_c *symbol) {
+ current_option = constant_opt;
+ return NULL;
+}
+
+void *search_var_instance_decl_c::visit(retain_option_c *symbol) {
+ current_option = retain_opt;
+ return NULL;
+}
+
+void *search_var_instance_decl_c::visit(non_retain_option_c *symbol) {
+ current_option = non_retain_opt;
+ return NULL;
+}
void *search_var_instance_decl_c::visit(input_declarations_c *symbol) {
current_vartype = input_vt;
+ current_option = none_opt; /* not really required. Just to make the code more readable */
+ if (NULL != symbol->option)
+ symbol->option->accept(*this);
void *res = symbol->input_declaration_list->accept(*this);
if (res == NULL) {
current_vartype = none_vt;
+ current_option = none_opt;
}
return res;
}
@@ -114,9 +202,13 @@
/* option -> may be NULL ! */
void *search_var_instance_decl_c::visit(output_declarations_c *symbol) {
current_vartype = output_vt;
+ current_option = none_opt; /* not really required. Just to make the code more readable */
+ if (NULL != symbol->option)
+ symbol->option->accept(*this);
void *res = symbol->var_init_decl_list->accept(*this);
if (res == NULL) {
current_vartype = none_vt;
+ current_option = none_opt;
}
return res;
}
@@ -124,6 +216,7 @@
/* VAR_IN_OUT var_declaration_list END_VAR */
void *search_var_instance_decl_c::visit(input_output_declarations_c *symbol) {
current_vartype = inoutput_vt;
+ current_option = none_opt; /* not really required. Just to make the code more readable */
void *res = symbol->var_declaration_list->accept(*this);
if (res == NULL) {
current_vartype = none_vt;
@@ -144,9 +237,13 @@
/* helper symbol for input_declarations */
void *search_var_instance_decl_c::visit(var_declarations_c *symbol) {
current_vartype = private_vt;
+ current_option = none_opt; /* not really required. Just to make the code more readable */
+ if (NULL != symbol->option)
+ symbol->option->accept(*this);
void *res = symbol->var_init_decl_list->accept(*this);
if (res == NULL) {
current_vartype = none_vt;
+ current_option = none_opt;
}
return res;
}
@@ -154,9 +251,11 @@
/* VAR RETAIN var_init_decl_list END_VAR */
void *search_var_instance_decl_c::visit(retentive_var_declarations_c *symbol) {
current_vartype = private_vt;
+ current_option = retain_opt;
void *res = symbol->var_init_decl_list->accept(*this);
if (res == NULL) {
current_vartype = none_vt;
+ current_option = none_opt;
}
return res;
}
@@ -166,9 +265,13 @@
//SYM_REF2(located_var_declarations_c, option, located_var_decl_list)
void *search_var_instance_decl_c::visit(located_var_declarations_c *symbol) {
current_vartype = located_vt;
+ current_option = none_opt; /* not really required. Just to make the code more readable */
+ if (NULL != symbol->option)
+ symbol->option->accept(*this);
void *res = symbol->located_var_decl_list->accept(*this);
if (res == NULL) {
current_vartype = none_vt;
+ current_option = none_opt;
}
return res;
}
@@ -178,9 +281,13 @@
//SYM_REF2(external_var_declarations_c, option, external_declaration_list)
void *search_var_instance_decl_c::visit(external_var_declarations_c *symbol) {
current_vartype = external_vt;
+ current_option = none_opt; /* not really required. Just to make the code more readable */
+ if (NULL != symbol->option)
+ symbol->option->accept(*this);
void *res = symbol->external_declaration_list->accept(*this);
if (res == NULL) {
current_vartype = none_vt;
+ current_option = none_opt;
}
return res;
}
@@ -190,9 +297,13 @@
//SYM_REF2(global_var_declarations_c, option, global_var_decl_list)
void *search_var_instance_decl_c::visit(global_var_declarations_c *symbol) {
current_vartype = global_vt;
+ current_option = none_opt; /* not really required. Just to make the code more readable */
+ if (NULL != symbol->option)
+ symbol->option->accept(*this);
void *res = symbol->global_var_decl_list->accept(*this);
if (res == NULL) {
current_vartype = none_vt;
+ current_option = none_opt;
}
return res;
}
@@ -232,7 +343,7 @@
list_c *list = symbol;
for(int i = 0; i < list->n; i++) {
if (compare_identifiers(list->elements[i], search_name) == 0)
- /* by now, current_fb_declaration should be != NULL */
+ /* by now, current_fb_declaration should be != NULL */
return current_type_decl;
}
return NULL;
@@ -262,7 +373,7 @@
/* var1_list ':' structure_type_name */
// SYM_REF2(structured_var_declaration_c, var1_list, structure_type_name)
void *search_var_instance_decl_c::visit(structured_var_declaration_c *symbol) {
- current_type_decl = symbol;
+ current_type_decl = symbol->structure_type_name;
return symbol->var1_list->accept(*this);
}
@@ -400,21 +511,62 @@
/*****************************/
/* 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 *search_var_instance_decl_c::visit(function_block_declaration_c *symbol) {
- /* no need to search through all the body, so we only
- * visit the variable declarations...!
- */
- return symbol->var_declarations->accept(*this);
+ /* visit the variable declarations...! */
+ void *res = symbol->var_declarations->accept(*this);
+ if (NULL != res)
+ return res;
+
+ /* not yet found, so we look into the body, to see if it is an SFC step! */
+ return symbol->fblock_body->accept(*this);
}
/**********************/
/* B 1.5.3 - Programs */
/**********************/
+/* 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 *search_var_instance_decl_c::visit(program_declaration_c *symbol) {
- /* no need to search through all the body, so we only
- * visit the variable declarations...!
- */
- return symbol->var_declarations->accept(*this);
+ /* visit the variable declarations...! */
+ void *res = symbol->var_declarations->accept(*this);
+ if (NULL != res)
+ return res;
+
+ /* not yet found, so we look into the body, to see if it is an SFC step! */
+ return symbol->function_block_body->accept(*this);
+}
+
+
+/*********************************************/
+/* B.1.6 Sequential function chart elements */
+/*********************************************/
+/* | sequential_function_chart sfc_network */
+// SYM_LIST(sequential_function_chart_c)
+/* search_var_instance_decl_c inherits from serach_visitor_c, so no need to implement the following method. */
+// void *search_var_instance_decl_c::visit(sequential_function_chart_c *symbol) {...}
+
+/* initial_step {step | transition | action} */
+// SYM_LIST(sfc_network_c)
+/* search_var_instance_decl_c inherits from serach_visitor_c, so no need to implement the following method. */
+// void *search_var_instance_decl_c::visit(sfc_network_c *symbol) {...}
+
+
+/* INITIAL_STEP step_name ':' action_association_list END_STEP */
+// SYM_REF2(initial_step_c, step_name, action_association_list)
+void *search_var_instance_decl_c::visit(initial_step_c *symbol) {
+ if (compare_identifiers(symbol->step_name, search_name) == 0)
+ return symbol;
+ return NULL;
+}
+
+/* STEP step_name ':' action_association_list END_STEP */
+// SYM_REF2(step_c, step_name, action_association_list)
+void *search_var_instance_decl_c::visit(step_c *symbol) {
+ if (compare_identifiers(symbol->step_name, search_name) == 0)
+ return symbol;
+ return NULL;
}
@@ -469,35 +621,30 @@
return NULL;
}
-#if 0
-/*********************/
-/* B 1.4 - Variables */
-/*********************/
-SYM_REF2(symbolic_variable_c, var_name, unused)
-
-/********************************************/
-/* B.1.4.1 Directly Represented Variables */
-/********************************************/
-SYM_TOKEN(direct_variable_c)
-
-/*************************************/
-/* B.1.4.2 Multi-element Variables */
-/*************************************/
-/* subscripted_variable '[' subscript_list ']' */
-SYM_REF2(array_variable_c, subscripted_variable, subscript_list)
-
-/* subscript_list ',' subscript */
-SYM_LIST(subscript_list_c)
-
-/* record_variable '.' field_selector */
-/* WARNING: input and/or output variables of function blocks
- * may be accessed as fields of a tructured variable!
- * Code handling a structured_variable_c must take
- * this into account!
- */
-SYM_REF2(structured_variable_c, record_variable, field_selector)
-
-
-
-};
-#endif
+
+
+/****************************************/
+/* B.2 - Language IL (Instruction List) */
+/****************************************/
+/***********************************/
+/* B 2.1 Instructions and Operands */
+/***********************************/
+/*| instruction_list il_instruction */
+// SYM_LIST(instruction_list_c)
+void *search_var_instance_decl_c::visit(instruction_list_c *symbol) {
+ /* IL code does not contain any variable declarations! */
+ return NULL;
+}
+
+
+/***************************************/
+/* B.3 - Language ST (Structured Text) */
+/***************************************/
+/********************/
+/* B 3.2 Statements */
+/********************/
+// SYM_LIST(statement_list_c)
+void *search_var_instance_decl_c::visit(statement_list_c *symbol) {
+ /* ST code does not contain any variable declarations! */
+ return NULL;
+}