# HG changeset patch # User Mario de Sousa # Date 1329508078 0 # Node ID aad0f3e5df33696db3de0bae71c6ef70f6a82836 # Parent d871f0eb88fb089cdcd76772833e1099b21b3113 Start of support for semantic verification of FB calls in IL using special IL instructions. diff -r d871f0eb88fb -r aad0f3e5df33 absyntax/absyntax.def --- 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) diff -r d871f0eb88fb -r aad0f3e5df33 stage3/datatype_functions.cc --- 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()); } diff -r d871f0eb88fb -r aad0f3e5df33 stage3/fill_candidate_datatypes.cc --- 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; diff -r d871f0eb88fb -r aad0f3e5df33 stage3/fill_candidate_datatypes.hh --- 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: