Start of support for semantic verification of FB calls in IL using special IL instructions.
--- a/absyntax/absyntax.def Fri Feb 17 19:47:23 2012 +0000
+++ b/absyntax/absyntax.def Fri Feb 17 19:47:58 2012 +0000
@@ -974,21 +974,22 @@
/*******************/
/* B 2.2 Operators */
/*******************/
+/* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */
SYM_REF0(LD_operator_c)
SYM_REF0(LDN_operator_c)
SYM_REF0(ST_operator_c)
SYM_REF0(STN_operator_c)
SYM_REF0(NOT_operator_c)
-SYM_REF0(S_operator_c)
-SYM_REF0(R_operator_c)
-SYM_REF0(S1_operator_c)
-SYM_REF0(R1_operator_c)
-SYM_REF0(CLK_operator_c)
-SYM_REF0(CU_operator_c)
-SYM_REF0(CD_operator_c)
-SYM_REF0(PV_operator_c)
-SYM_REF0(IN_operator_c)
-SYM_REF0(PT_operator_c)
+SYM_REF0(S_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(R_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(S1_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(R1_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(CLK_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(CU_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(CD_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(PV_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(IN_operator_c, symbol_c *called_fb_declaration;)
+SYM_REF0(PT_operator_c, symbol_c *called_fb_declaration;)
SYM_REF0(AND_operator_c)
SYM_REF0(OR_operator_c)
SYM_REF0(XOR_operator_c)
--- a/stage3/datatype_functions.cc Fri Feb 17 19:47:23 2012 +0000
+++ b/stage3/datatype_functions.cc Fri Feb 17 19:47:58 2012 +0000
@@ -193,7 +193,10 @@
void copy_candidate_datatype_list(symbol_c *from, symbol_c *to) {
if ((NULL == from) || (NULL == to))
return;
- std::copy(from->candidate_datatypes.begin(), from->candidate_datatypes.end(), to->candidate_datatypes.begin());
+ for(unsigned int i = 0; i < from->candidate_datatypes.size(); i++)
+ to->candidate_datatypes.push_back(from->candidate_datatypes[i]);
+ /* for some reason, the following alternative implementation results in a segmentation fault! I am not going to bother with this for now! */
+// std::copy(from->candidate_datatypes.begin(), from->candidate_datatypes.end(), to->candidate_datatypes.begin());
}
--- a/stage3/fill_candidate_datatypes.cc Fri Feb 17 19:47:23 2012 +0000
+++ b/stage3/fill_candidate_datatypes.cc Fri Feb 17 19:47:58 2012 +0000
@@ -237,7 +237,44 @@
}
-
+/* handle implicit FB call in IL.
+ * e.g. CLK ton_car
+ * CU counter_var
+ *
+ * The algorithm will be to build a fake il_fb_call_c equivalent to the implicit IL FB call, and let
+ * the visit(il_fb_call_c *) method handle it!
+ */
+void fill_candidate_datatypes_c::handle_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration) {
+ symbol_c *fb_type_id = search_varfb_instance_type->get_basetype_id(il_operand);
+ /* This is a call to a non-declared FB/Variable is a semantic error (which is currently caught by stage 2, so this should never occur)
+ * or no operand was given (il_operand == NULL). In this case, we just give up!
+ */
+ if (NULL == fb_type_id)
+ return;
+
+ function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(fb_type_id);
+ if (function_block_type_symtable.end_value() == fb_decl)
+ /* The il_operand is not the name of a FB instance. Most probably it is the name of a variable of some other type.
+ * this is a smeantic error, so there is no way we can evaluate the rest of the code. We simply give up, and leave
+ * the candidate_datatype_list empty, and the called_fb_declaration pointing to NULL
+ */
+ return;
+
+
+ identifier_c variable_name(param_name);
+ // SYM_REF1(il_assign_operator_c, variable_name)
+ il_assign_operator_c il_assign_operator(&variable_name);
+ // SYM_REF3(il_param_assignment_c, il_assign_operator, il_operand, simple_instr_list)
+ il_param_assignment_c il_param_assignment(&il_assign_operator, prev_il_instruction/*il_operand*/, NULL);
+ il_param_list_c il_param_list;
+ il_param_list.add_element(&il_param_assignment);
+ // SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
+ il_fb_call_c il_fb_call(NULL, il_operand, NULL, &il_param_list);
+
+ il_fb_call.accept(*this);
+ copy_candidate_datatype_list(&il_fb_call/*from*/, il_instruction/*to*/);
+ called_fb_declaration = il_fb_call.called_fb_declaration;
+}
/* a helper function... */
@@ -971,7 +1008,9 @@
return NULL;
}
+
void *fill_candidate_datatypes_c::visit(S_operator_c *symbol) {
+ /* TODO: what if this is a FB call ?? */
symbol_c *prev_instruction_type, *operand_type;
if (NULL == prev_il_instruction) return NULL;
@@ -987,7 +1026,9 @@
return NULL;
}
+
void *fill_candidate_datatypes_c::visit(R_operator_c *symbol) {
+ /* TODO: what if this is a FB call ?? */
symbol_c *prev_instruction_type, *operand_type;
if (NULL == prev_il_instruction) return NULL;
@@ -1003,79 +1044,47 @@
return NULL;
}
+
void *fill_candidate_datatypes_c::visit(S1_operator_c *symbol) {
- symbol_c *prev_instruction_type, *operand_type;
-
- if (NULL == prev_il_instruction) return NULL;
- for (unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) {
- for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) {
- prev_instruction_type = prev_il_instruction->candidate_datatypes[i];
- operand_type = il_operand->candidate_datatypes[j];
- if (is_type_equal(prev_instruction_type,operand_type) && is_ANY_BOOL_compatible(operand_type))
- symbol->candidate_datatypes.push_back(prev_instruction_type);
- }
- }
- if (debug) std::cout << "S1 [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n";
+ handle_implicit_il_fb_call(symbol, "S1", symbol->called_fb_declaration);
return NULL;
}
void *fill_candidate_datatypes_c::visit(R1_operator_c *symbol) {
- symbol_c *prev_instruction_type, *operand_type;
-
- if (NULL == prev_il_instruction) return NULL;
- for (unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) {
- for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) {
- prev_instruction_type = prev_il_instruction->candidate_datatypes[i];
- operand_type = il_operand->candidate_datatypes[j];
- if (is_type_equal(prev_instruction_type,operand_type) && is_ANY_BOOL_compatible(operand_type))
- symbol->candidate_datatypes.push_back(prev_instruction_type);
- }
- }
- if (debug) std::cout << "R1 [" << prev_il_instruction->candidate_datatypes.size() << "," << il_operand->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n";
+ handle_implicit_il_fb_call(symbol, "R1", symbol->called_fb_declaration);
return NULL;
}
void *fill_candidate_datatypes_c::visit(CLK_operator_c *symbol) {
- /* MANU:
- * How it works? I(MANU) don't know this function
- */
+ handle_implicit_il_fb_call(symbol, "CLK", symbol->called_fb_declaration);
return NULL;
}
void *fill_candidate_datatypes_c::visit(CU_operator_c *symbol) {
- /* MANU:
- * How it works? I(MANU) don't know this function
- */
+ handle_implicit_il_fb_call(symbol, "CU", symbol->called_fb_declaration);
return NULL;
}
void *fill_candidate_datatypes_c::visit(CD_operator_c *symbol) {
- /* MANU:
- * How it works? I(MANU) don't know this function
- */
+ handle_implicit_il_fb_call(symbol, "CD", symbol->called_fb_declaration);
return NULL;
}
void *fill_candidate_datatypes_c::visit(PV_operator_c *symbol) {
- /* MANU:
- * How it works? I(MANU) don't know this function
- */
+ handle_implicit_il_fb_call(symbol, "PV", symbol->called_fb_declaration);
return NULL;
}
void *fill_candidate_datatypes_c::visit(IN_operator_c *symbol) {
- /* MANU:
- * How it works? I(MANU) don't know this function
- */
+ handle_implicit_il_fb_call(symbol, "IN", symbol->called_fb_declaration);
return NULL;
}
void *fill_candidate_datatypes_c::visit(PT_operator_c *symbol) {
- /* MANU:
- * How it works? I(MANU) don't know this function
- */
- return NULL;
-}
+ handle_implicit_il_fb_call(symbol, "PT", symbol->called_fb_declaration);
+ return NULL;
+}
+
void *fill_candidate_datatypes_c::visit(AND_operator_c *symbol) {
symbol_c *prev_instruction_type, *operand_type;
--- a/stage3/fill_candidate_datatypes.hh Fri Feb 17 19:47:23 2012 +0000
+++ b/stage3/fill_candidate_datatypes.hh Fri Feb 17 19:47:58 2012 +0000
@@ -86,9 +86,10 @@
bool match_nonformal_call(symbol_c *f_call, symbol_c *f_decl);
bool match_formal_call (symbol_c *f_call, symbol_c *f_decl);
void handle_function_call(symbol_c *fcall, generic_function_call_t fcall_data);
-
+ void handle_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration);
+
/* a helper function... */
- symbol_c *base_type(symbol_c *symbol);
+ symbol_c *base_type(symbol_c *symbol);
public: