# HG changeset patch # User Mario de Sousa # Date 1330003549 0 # Node ID 099aa5d655dea024838eb8fb9e7048be23658bad # Parent 4733f662362a7cfe10b695a61e862d045083438b Finish support for semantic verification of IL paranthesised expressions. diff -r 4733f662362a -r 099aa5d655de stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Tue Feb 21 17:39:57 2012 +0000 +++ b/stage3/fill_candidate_datatypes.cc Thu Feb 23 13:25:49 2012 +0000 @@ -45,7 +45,7 @@ #include /* set to 1 to see debug info during execution */ -static int debug = 1; +static int debug = 0; fill_candidate_datatypes_c::fill_candidate_datatypes_c(symbol_c *ignore) { } @@ -921,6 +921,9 @@ prev_il_instruction = prev_il_instruction_backup; symbol->il_expr_operator->accept(*this); il_operand = NULL; + + /* This object has the same candidate datatypes as the il_expr_operator. */ + copy_candidate_datatype_list(symbol->il_expr_operator/*from*/, symbol/*to*/); return NULL; } @@ -998,7 +1001,6 @@ /* | simple_instr_list il_simple_instruction */ /* This object is referenced by il_expression_c objects */ void *fill_candidate_datatypes_c::visit(simple_instr_list_c *symbol) { -std::cout << "simple_instr_list_c [filling starting]\n"; if (symbol->n <= 0) return NULL; /* List is empty! Nothing to do. */ @@ -1009,7 +1011,6 @@ copy_candidate_datatype_list(symbol->elements[symbol->n-1] /*from*/, symbol /*to*/); if (debug) std::cout << "simple_instr_list_c [" << symbol->candidate_datatypes.size() << "] result.\n"; -std::cout << "simple_instr_list_c [" << symbol->candidate_datatypes.size() << "] result.\n"; return NULL; } diff -r 4733f662362a -r 099aa5d655de stage3/flow_control_analysis.cc --- a/stage3/flow_control_analysis.cc Tue Feb 21 17:39:57 2012 +0000 +++ b/stage3/flow_control_analysis.cc Thu Feb 23 13:25:49 2012 +0000 @@ -99,7 +99,7 @@ * list of il_simple_instruction * * il_simple_instruction: - * il_simple_operation (il_simple_operation_c) + * il_simple_operation (il_simple_operation_c, il_function_call_c) * | il_expression (il_expression_c) * | il_formal_funct_call (il_formal_funct_call_c) * @@ -257,8 +257,7 @@ // void *visit(il_operand_list_c *symbol); void *flow_control_analysis_c::visit(simple_instr_list_c *symbol) { - /* The prev_il_instruction for element[0] was set in visit(il_expression_c *) */ - for(int i = 1; i < symbol->n; i++) { + for(int i = 0; i < symbol->n; i++) { /* The prev_il_instruction for element[0] was set in visit(il_expression_c *) */ if (i>0) prev_il_instruction = symbol->elements[i-1]; symbol->elements[i]->accept(*this); diff -r 4733f662362a -r 099aa5d655de stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Tue Feb 21 17:39:57 2012 +0000 +++ b/stage3/narrow_candidate_datatypes.cc Thu Feb 23 13:25:49 2012 +0000 @@ -572,10 +572,11 @@ void *narrow_candidate_datatypes_c::visit(il_expression_c *symbol) { /* first handle the operation (il_expr_operator) that will use the result coming from the parenthesised IL list (i.e. simple_instr_list) */ symbol->il_expr_operator->datatype = symbol->datatype; - il_operand = symbol->il_operand; + il_operand = symbol->simple_instr_list; /* This is not a bug! The parenthesised expression will be used as the operator! */ symbol->il_expr_operator->accept(*this); /* now give the parenthesised IL list a chance to narrow the datatypes */ + /* The datatype that is must return was set by the call symbol->il_expr_operator->accept(*this) */ symbol_c *save_prev_il_instruction = prev_il_instruction; /*this is not really necessary, but lets play it safe */ symbol->simple_instr_list->accept(*this); prev_il_instruction = save_prev_il_instruction; @@ -679,11 +680,26 @@ if (NULL == symbol->datatype) /* next IL instructions were unable to determine the datatype this instruction should produce */ return NULL; + /* NOTE 1: the il_operand __may__ be pointing to a parenthesized list of IL instructions. + * e.g. LD 33 + * AND ( 45 + * OR 56 + * ) + * When we handle the first 'AND' IL_operator, the il_operand will point to an simple_instr_list_c. + * In this case, when we call il_operand->accept(*this);, the prev_il_instruction pointer will be overwritten! + * + * We must therefore set the prev_il_instruction->datatype = symbol->datatype; + * __before__ calling il_operand->accept(*this) !! + * + * NOTE 2: We do not need to call prev_il_instruction->accept(*this), as the object to which prev_il_instruction + * is pointing to will be later narrowed by the call from the for() loop of the instruction_list_c + * (or simple_instr_list_c), which iterates backwards. + */ + /* set the desired datatype of the previous il instruction */ + prev_il_instruction->datatype = symbol->datatype; /* set the datatype for the operand */ il_operand->datatype = symbol->datatype; il_operand->accept(*this); - /* set the desired datatype of the previous il instruction */ - prev_il_instruction->datatype = symbol->datatype; return NULL; } @@ -735,7 +751,6 @@ } void *narrow_candidate_datatypes_c::visit(NOT_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } diff -r 4733f662362a -r 099aa5d655de stage3/narrow_candidate_datatypes.hh --- a/stage3/narrow_candidate_datatypes.hh Tue Feb 21 17:39:57 2012 +0000 +++ b/stage3/narrow_candidate_datatypes.hh Thu Feb 23 13:25:49 2012 +0000 @@ -77,7 +77,6 @@ /* B 1.4.2 - Multi-element variables */ /*************************************/ void *visit(array_variable_c *symbol); - void *visit(il_instruction_c *symbol); void *visit(subscript_list_c *symbol); /**************************************/ @@ -109,6 +108,7 @@ /* B 2.1 Instructions and Operands */ /***********************************/ void *visit(instruction_list_c *symbol); + void *visit(il_instruction_c *symbol); void *visit(il_simple_operation_c *symbol); void *visit(il_function_call_c *symbol); void *visit(il_expression_c *symbol); diff -r 4733f662362a -r 099aa5d655de stage3/print_datatypes_error.cc --- a/stage3/print_datatypes_error.cc Tue Feb 21 17:39:57 2012 +0000 +++ b/stage3/print_datatypes_error.cc Thu Feb 23 13:25:49 2012 +0000 @@ -475,10 +475,7 @@ /* subscript_list ',' subscript */ // SYM_LIST(subscript_list_c) /* NOTE: we inherit from iterator visitor, so we do not need to implement this method... */ -#if 0 -void *print_datatypes_error_c::visit(subscript_list_c *symbol) { -} -#endif +// void *print_datatypes_error_c::visit(subscript_list_c *symbol) /* record_variable '.' field_selector */ @@ -511,9 +508,7 @@ if (debug) printf("Print error data types list in body of function %s\n", ((token_c *)(symbol->derived_function_name))->value); il_parenthesis_level = 0; il_error = false; - prev_il_instruction = NULL; symbol->function_body->accept(*this); - prev_il_instruction = NULL; delete search_varfb_instance_type; search_varfb_instance_type = NULL; return NULL; @@ -529,9 +524,7 @@ if (debug) printf("Print error data types list in body of FB %s\n", ((token_c *)(symbol->fblock_name))->value); il_parenthesis_level = 0; il_error = false; - prev_il_instruction = NULL; symbol->fblock_body->accept(*this); - prev_il_instruction = NULL; delete search_varfb_instance_type; search_varfb_instance_type = NULL; return NULL; @@ -547,9 +540,7 @@ if (debug) printf("Print error data types list in body of program %s\n", ((token_c *)(symbol->program_type_name))->value); il_parenthesis_level = 0; il_error = false; - prev_il_instruction = NULL; symbol->function_block_body->accept(*this); - prev_il_instruction = NULL; delete search_varfb_instance_type; search_varfb_instance_type = NULL; return NULL; @@ -574,7 +565,23 @@ /***********************************/ /* B 2.1 Instructions and Operands */ /***********************************/ + // void *visit(instruction_list_c *symbol); + +/* | label ':' [il_incomplete_instruction] eol_list */ +// SYM_REF2(il_instruction_c, label, il_instruction) +void *print_datatypes_error_c::visit(il_instruction_c *symbol) { + if (NULL != symbol->il_instruction) { + prev_il_instruction = symbol->prev_il_instruction; + symbol->il_instruction->accept(*this); + prev_il_instruction = NULL; + } + + return NULL; +} + + + void *print_datatypes_error_c::visit(il_simple_operation_c *symbol) { il_operand = symbol->il_operand; if (NULL != symbol->il_operand) { @@ -635,10 +642,22 @@ return NULL; } + +/* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ +// SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list); void *print_datatypes_error_c::visit(il_expression_c *symbol) { - /* TODO */ - return NULL; -} + /* first give the parenthesised IL list a chance to print errors */ + symbol_c *save_prev_il_instruction = prev_il_instruction; + symbol->simple_instr_list->accept(*this); + prev_il_instruction = save_prev_il_instruction; + + /* Now handle the operation (il_expr_operator) that will use the result coming from the parenthesised IL list (i.e. simple_instr_list) */ + il_operand = symbol->simple_instr_list; /* This is not a bug! The parenthesised expression will be used as the operator! */ + symbol->il_expr_operator->accept(*this); + +return NULL; +} + /* il_call_operator prev_declared_fb_name * | il_call_operator prev_declared_fb_name '(' ')' @@ -685,22 +704,17 @@ // void *visit(il_operand_list_c *symbol); - - -/* | simple_instr_list il_simple_instruction */ -/* This object is referenced by il_expression_c objects */ -void *print_datatypes_error_c::visit(simple_instr_list_c *symbol) { - /* TODO */ - return NULL; -} +// void *visit(simple_instr_list_c *symbol); // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;) -void *print_datatypes_error_c::visit(il_simple_instruction_c *symbol) { - /* TODO */ - return NULL; -} - -// void *visit(simple_instr_list_c *symbol); +void *print_datatypes_error_c::visit(il_simple_instruction_c *symbol) { + prev_il_instruction = symbol->prev_il_instruction; + symbol->il_simple_instruction->accept(*this); + prev_il_instruction = NULL; + return NULL; +} + + // void *visit(il_param_list_c *symbol); // void *visit(il_param_assignment_c *symbol); // void *visit(il_param_out_assignment_c *symbol); @@ -709,16 +723,13 @@ /* B 2.2 Operators */ /*******************/ void *print_datatypes_error_c::visit(LD_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(LDN_operator_c *symbol) { - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'LDN' operator."); - prev_il_instruction = symbol; return NULL; } @@ -728,11 +739,9 @@ * we can't use a ST like first instruction. * What do you think? */ - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'ST' operator."); - prev_il_instruction = symbol; return NULL; } @@ -742,36 +751,29 @@ * we can't use a ST like first instruction. * What do you think? */ - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'STN' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(NOT_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(S_operator_c *symbol) { /* TODO: what if this is a FB call ?? */ - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'S' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(R_operator_c *symbol) { /* TODO: what if this is a FB call ?? */ - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'R' operator."); - prev_il_instruction = symbol; return NULL; } @@ -816,176 +818,139 @@ } void *print_datatypes_error_c::visit(AND_operator_c *symbol) { - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'AND' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(OR_operator_c *symbol) { - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'OR' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(XOR_operator_c *symbol) { - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'XOR' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(ANDN_operator_c *symbol) { - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'ANDN' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(ORN_operator_c *symbol) { - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'ORN' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(XORN_operator_c *symbol) { - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'ORN' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(ADD_operator_c *symbol) { - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'ADD' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(SUB_operator_c *symbol) { - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'SUB' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(MUL_operator_c *symbol) { - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'MUL' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(DIV_operator_c *symbol) { - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'DIV' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(MOD_operator_c *symbol) { - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) STAGE3_ERROR(0, symbol, symbol, "Data type mismatch for 'MOD' operator."); - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(GT_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(GE_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(EQ_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(LT_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(LE_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(NE_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(CAL_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(CALC_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(CALCN_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(RET_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(RETC_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(RETCN_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(JMP_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(JMPC_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } void *print_datatypes_error_c::visit(JMPCN_operator_c *symbol) { - prev_il_instruction = symbol; return NULL; } diff -r 4733f662362a -r 099aa5d655de stage3/print_datatypes_error.hh --- a/stage3/print_datatypes_error.hh Tue Feb 21 17:39:57 2012 +0000 +++ b/stage3/print_datatypes_error.hh Thu Feb 23 13:25:49 2012 +0000 @@ -42,7 +42,7 @@ private: /* The level of detail that the user wants us to display error messages. */ // #define error_level_default (1) - #define error_level_default (1) + #define error_level_default (4) #define error_level_nagging (4) unsigned int current_display_error_level; @@ -187,14 +187,15 @@ /***********************************/ /* B 2.1 Instructions and Operands */ /***********************************/ - // void *visit(instruction_list_c *symbol); +// void *visit(instruction_list_c *symbol); + void *visit(il_instruction_c *symbol); void *visit(il_simple_operation_c *symbol); void *visit(il_function_call_c *symbol); void *visit(il_expression_c *symbol); void *visit(il_fb_call_c *symbol); void *visit(il_formal_funct_call_c *symbol); // void *visit(il_operand_list_c *symbol); - void *visit(simple_instr_list_c *symbol); +// void *visit(simple_instr_list_c *symbol); void *visit(il_simple_instruction_c*symbol); // void *visit(il_param_list_c *symbol); // void *visit(il_param_assignment_c *symbol);