stage3/flow_control_analysis.cc
changeset 453 4733f662362a
parent 452 79ac274d1cc4
child 454 099aa5d655de
equal deleted inserted replaced
452:79ac274d1cc4 453:4733f662362a
    35  *
    35  *
    36  *  We currently only do this for IL code.
    36  *  We currently only do this for IL code.
    37  *  This class will annotate the abstract syntax tree, by filling in the
    37  *  This class will annotate the abstract syntax tree, by filling in the
    38  *  prev_il_instruction variable in the il_instruction_c, so it points to
    38  *  prev_il_instruction variable in the il_instruction_c, so it points to
    39  *  the previous il_instruction_c object in the instruction list instruction_list_c.
    39  *  the previous il_instruction_c object in the instruction list instruction_list_c.
       
    40  *
       
    41  *  The result will essentially be a linked list of il_instruction_c objects, each 
       
    42  *  pointing to the previous il_instruction_c object.
       
    43  *
       
    44  *  The reality is we will get several independent and isolated linked lists
       
    45  *  (actually, once we process labels correctly, this will become a graph):
       
    46  *  one for each block of IL code (e.g. inside a Function, FB or Program).
       
    47  *  Additionally, when the IL code has an expression (expression_c object), we will actually
       
    48  *  have one more isolated linked list for the IL code inside that expression.
       
    49  *
       
    50  *  e.g.
       
    51  *       line_1:   LD 1
       
    52  *       line_2:   ADD (42
       
    53  *       line_3:        ADD B
       
    54  *       line_4:        ADD C 
       
    55  *       line_5:       )
       
    56  *       line_6:   ADD D
       
    57  *       line_7:   ST  E
       
    58  * 
       
    59  *     will result in two independent linked lists:
       
    60  *       main list:  line_7 -> line_6 -> line2 -> line_1
       
    61  *       expr list:  lin4_4 -> line_3 -> (operand of line_2, i.e. '42')
       
    62  * 
       
    63  * 
       
    64  *     In the main list, each:
       
    65  *        line_x: IL_operation IL_operand
       
    66  *      is encoded as
       
    67  *          il_instruction_c(label, il_incomplete_instruction)
       
    68  *      these il_instruction_c objects will point back to the previous il_instruction_c object.
       
    69  *
       
    70  *     In the expr list, each 
       
    71  *        line_x:        IL_operation IL_operand
       
    72  *      is encoded as
       
    73  *          il_simple_instruction_c(il_simple_instruction)
       
    74  *      these il_simple_instruction_c objects will point back to the previous il_simple_instruction_c object,
       
    75  *      except the for the first il_simple_instruction_c object in the list, which will point back to
       
    76  *      the first il_operand (in the above example, '42'), or NULL is it does not exist.
       
    77  *          
       
    78  *
       
    79  * label:
       
    80  *   identifier_c  
       
    81  *   
       
    82  * il_incomplete_instruction:
       
    83  *   il_simple_operation   (il_simple_operation_c, il_function_call_c)
       
    84  * | il_expression         (il_expression_c)
       
    85  * | il_jump_operation     (il_jump_operation_c)
       
    86  * | il_fb_call            (il_fb_call_c)
       
    87  * | il_formal_funct_call  (il_formal_funct_call_c)
       
    88  * | il_return_operator    (RET_operator_c, RETC_operator_c, RETCN_operator_c)
       
    89  *  
       
    90  * 
       
    91  * il_expression_c(il_expr_operator, il_operand, simple_instr_list)
       
    92  * 
       
    93  * il_operand:
       
    94  *   variable            (symbolic_variable_c, direct_variable_c, array_variable_c, structured_variable_c)  
       
    95  * | enumerated_value    (enumerated_value_c)
       
    96  * | constant            (lots of literal classes _c)
       
    97  * 
       
    98  * simple_instr_list:
       
    99  *   list of il_simple_instruction
       
   100  * 
       
   101  * il_simple_instruction:
       
   102  *   il_simple_operation       (il_simple_operation_c)
       
   103  * | il_expression             (il_expression_c)
       
   104  * | il_formal_funct_call      (il_formal_funct_call_c)
       
   105  * 
    40  */
   106  */
    41 
   107 
    42 #include "flow_control_analysis.hh"
   108 #include "flow_control_analysis.hh"
    43 
   109 
    44 
   110 
   126 void *flow_control_analysis_c::visit(il_instruction_c *symbol) {
   192 void *flow_control_analysis_c::visit(il_instruction_c *symbol) {
   127 	symbol->prev_il_instruction = prev_il_instruction;
   193 	symbol->prev_il_instruction = prev_il_instruction;
   128 	/* TODO: handle labels correctly!
   194 	/* TODO: handle labels correctly!
   129 	 *
   195 	 *
   130 	 *      Don't forget to handle multiple consecutive lables too!
   196 	 *      Don't forget to handle multiple consecutive lables too!
   131 	 * 	  label2:
   197 	 *        label2:
   132 	 *        label3:
   198 	 *        label3:
   133 	 *        label4:
   199 	 *        label4:
   134 	 *                LD I
   200 	 *                LD I
   135 	 */
   201 	 */
       
   202 	/* NOTE: the following recursive call will mess up the value in the
       
   203 	 *       this->prev_il_instruction variable, so be sure not to use it
       
   204 	 *       after the return of symbol->il_instruction->accept(*this);
       
   205 	 */
       
   206 	/* check if it is an il_expression_c, and if so, handle it correctly */
   136 	if (NULL != symbol->il_instruction)
   207 	if (NULL != symbol->il_instruction)
   137 		symbol->il_instruction->accept(*this);
   208 		symbol->il_instruction->accept(*this);
   138 return NULL;
   209 	return NULL;
   139 }
   210 }
   140 
   211 
   141 
   212 
   142 #if 0
   213 #if 0
   143 /* | function_name [il_operand_list] */
   214 /* | function_name [il_operand_list] */
   144 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */
   215 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */
   145 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
   216 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
   146 void *flow_control_analysis_c::visit(il_function_call_c *symbol) {
   217 void *flow_control_analysis_c::visit(il_function_call_c *symbol) {
   147 	return NULL;
   218 	return NULL;
   148 }
   219 }
       
   220 #endif
   149 
   221 
   150 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
   222 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
   151 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
   223 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
   152 void *flow_control_analysis_c::visit(il_expression_c *symbol) {
   224 void *flow_control_analysis_c::visit(il_expression_c *symbol) {
   153 return NULL;
   225 	if(NULL == symbol->simple_instr_list) 
   154 }
   226 		/* nothing to do... */
   155 
   227 		return NULL;
       
   228   
       
   229 	prev_il_instruction = symbol->il_operand;
       
   230 	symbol->simple_instr_list->accept(*this);
       
   231 	return NULL;
       
   232 }
       
   233 
       
   234 
       
   235 #if 0
   156 /*   il_call_operator prev_declared_fb_name
   236 /*   il_call_operator prev_declared_fb_name
   157  * | il_call_operator prev_declared_fb_name '(' ')'
   237  * | il_call_operator prev_declared_fb_name '(' ')'
   158  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
   238  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
   159  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
   239  * | il_call_operator prev_declared_fb_name '(' il_operand_list ')'
   160  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
   240  * | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')'
   174 }
   254 }
   175 #endif
   255 #endif
   176 
   256 
   177 
   257 
   178 //  void *visit(il_operand_list_c *symbol);
   258 //  void *visit(il_operand_list_c *symbol);
   179 
       
   180 void *flow_control_analysis_c::visit(simple_instr_list_c *symbol) {
   259 void *flow_control_analysis_c::visit(simple_instr_list_c *symbol) {
   181 	for(int i = 0; i < symbol->n; i++) {
   260 	/* The prev_il_instruction for element[0] was set in visit(il_expression_c *) */
   182 		prev_il_instruction = NULL;
   261 	for(int i = 1; i < symbol->n; i++) {
   183 		if (i > 0) prev_il_instruction = symbol->elements[i-1];
   262 		/* The prev_il_instruction for element[0] was set in visit(il_expression_c *) */
       
   263 		if (i>0) prev_il_instruction = symbol->elements[i-1];
   184 		symbol->elements[i]->accept(*this);
   264 		symbol->elements[i]->accept(*this);
   185 	}
   265 	}
   186 	return NULL;
   266 	return NULL;
   187 }
   267 }
       
   268 
       
   269 
       
   270 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
       
   271 void *flow_control_analysis_c::visit(il_simple_instruction_c*symbol) {
       
   272 	symbol->prev_il_instruction = prev_il_instruction;
       
   273 	return NULL;
       
   274 }
       
   275 
   188 
   276 
   189 /*
   277 /*
   190     void *visit(il_param_list_c *symbol);
   278     void *visit(il_param_list_c *symbol);
   191     void *visit(il_param_assignment_c *symbol);
   279     void *visit(il_param_assignment_c *symbol);
   192     void *visit(il_param_out_assignment_c *symbol);
   280     void *visit(il_param_out_assignment_c *symbol);