stage3/flow_control_analysis.cc
changeset 459 01f6664bf8c5
parent 457 67d8b07bac22
child 463 fafa9abc166e
--- a/stage3/flow_control_analysis.cc	Thu Mar 01 10:28:27 2012 +0000
+++ b/stage3/flow_control_analysis.cc	Fri Mar 02 12:53:41 2012 +0000
@@ -113,6 +113,8 @@
 static int debug = 0;
 
 flow_control_analysis_c::flow_control_analysis_c(symbol_c *ignore) {
+  prev_il_instruction = NULL;
+  curr_il_instruction = NULL;
 }
 
 flow_control_analysis_c::~flow_control_analysis_c(void) {
@@ -127,11 +129,11 @@
 /* B 1.5.1 Functions */
 /*********************/
 void *flow_control_analysis_c::visit(function_declaration_c *symbol) {
-	search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
+	search_il_label = new search_il_label_c(symbol);
 	if (debug) printf("Doing flow control analysis in body of function %s\n", ((token_c *)(symbol->derived_function_name))->value);
 	symbol->function_body->accept(*this);
-	delete search_varfb_instance_type;
-	search_varfb_instance_type = NULL;
+	delete search_il_label;
+	search_il_label = NULL;
 	return NULL;
 }
 
@@ -139,11 +141,11 @@
 /* B 1.5.2 Function blocks */
 /***************************/
 void *flow_control_analysis_c::visit(function_block_declaration_c *symbol) {
-	search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
+	search_il_label = new search_il_label_c(symbol);
 	if (debug) printf("Doing flow control analysis in body of FB %s\n", ((token_c *)(symbol->fblock_name))->value);
 	symbol->fblock_body->accept(*this);
-	delete search_varfb_instance_type;
-	search_varfb_instance_type = NULL;
+	delete search_il_label;
+	search_il_label = NULL;
 	return NULL;
 }
 
@@ -151,11 +153,11 @@
 /* B 1.5.3 Programs */
 /********************/
 void *flow_control_analysis_c::visit(program_declaration_c *symbol) {
-	search_varfb_instance_type = new search_varfb_instance_type_c(symbol);
+	search_il_label = new search_il_label_c(symbol);
 	if (debug) printf("Doing flow control analysis in body of program %s\n", ((token_c *)(symbol->program_type_name))->value);
 	symbol->function_block_body->accept(*this);
-	delete search_varfb_instance_type;
-	search_varfb_instance_type = NULL;
+	delete search_il_label;
+	search_il_label = NULL;
 	return NULL;
 }
 
@@ -181,7 +183,9 @@
 	for(int i = 0; i < symbol->n; i++) {
 		prev_il_instruction = NULL;
 		if (i > 0) prev_il_instruction = symbol->elements[i-1];
-		symbol->elements[i]->accept(*this);
+		curr_il_instruction = symbol->elements[i];
+		curr_il_instruction->accept(*this);
+		curr_il_instruction = NULL;
 	}
 	return NULL;
 }
@@ -190,34 +194,28 @@
 // SYM_REF2(il_instruction_c, label, il_instruction)
 // void *visit(instruction_list_c *symbol);
 void *flow_control_analysis_c::visit(il_instruction_c *symbol) {
-	symbol->prev_il_instruction.push_back(prev_il_instruction);
-	/* TODO: handle labels correctly!
-	 *
-	 *      Don't forget to handle multiple consecutive lables too!
-	 *        label2:
-	 *        label3:
-	 *        label4:
-	 *                LD I
-	 */
-	/* NOTE: the following recursive call will mess up the value in the
-	 *       this->prev_il_instruction variable, so be sure not to use it
-	 *       after the return of symbol->il_instruction->accept(*this);
-	 */
-	/* check if it is an il_expression_c, and if so, handle it correctly */
+	if (NULL != prev_il_instruction)
+		symbol->prev_il_instruction.push_back(prev_il_instruction);
+
+	/* check if it is an il_expression_c, or a JMP[C[N]] and if so, handle it correctly */
 	if (NULL != symbol->il_instruction)
 		symbol->il_instruction->accept(*this);
 	return NULL;
 }
 
 
-#if 0
+
+/* | il_simple_operator [il_operand] */
+// SYM_REF2(il_simple_operation_c, il_simple_operator, il_operand)
+// void *flow_control_analysis_c::visit(il_simple_operation_c *symbol)
+
+
+
 /* | function_name [il_operand_list] */
 /* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */
 // SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;)
-void *flow_control_analysis_c::visit(il_function_call_c *symbol) {
-	return NULL;
-}
-#endif
+// void *flow_control_analysis_c::visit(il_function_call_c *symbol) 
+
 
 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
@@ -226,13 +224,28 @@
 		/* nothing to do... */
 		return NULL;
   
+	symbol_c *save_prev_il_instruction = prev_il_instruction;
 	prev_il_instruction = symbol->il_operand;
 	symbol->simple_instr_list->accept(*this);
-	return NULL;
-}
-
-
-#if 0
+	prev_il_instruction = save_prev_il_instruction;
+	return NULL;
+}
+
+
+/*  il_jump_operator label */
+// SYM_REF2(il_jump_operation_c, il_jump_operator, label)
+void *flow_control_analysis_c::visit(il_jump_operation_c *symbol) {
+  /* search for the il_instruction_c containing the label */
+  il_instruction_c *destination = search_il_label->find_label(symbol->label);
+
+  /* TODO: for JMP and RET (unconditional) instructions, make sure the next IL instruction does not point back! */
+  /* add, to that il_instruction's list of prev_il_intsructions, the curr_il_instruction */
+  if (NULL != destination)
+    destination->prev_il_instruction.push_back(curr_il_instruction);
+  return NULL;
+}
+
+
 /*   il_call_operator prev_declared_fb_name
  * | il_call_operator prev_declared_fb_name '(' ')'
  * | il_call_operator prev_declared_fb_name '(' eol_list ')'
@@ -241,18 +254,14 @@
  */
 /* 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_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
-void *flow_control_analysis_c::visit(il_fb_call_c *symbol) {
-	return NULL;
-}
+// void *flow_control_analysis_c::visit(il_fb_call_c *symbol)
 
 
 /* | function_name '(' eol_list [il_param_list] ')' */
 /* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */
 // SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;)
-void *flow_control_analysis_c::visit(il_formal_funct_call_c *symbol) {
-	return NULL;
-}
-#endif
+// void *flow_control_analysis_c::visit(il_formal_funct_call_c *symbol)
+
 
 
 //  void *visit(il_operand_list_c *symbol);
@@ -268,7 +277,8 @@
 
 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
 void *flow_control_analysis_c::visit(il_simple_instruction_c*symbol) {
-	symbol->prev_il_instruction.push_back(prev_il_instruction);
+	if (NULL != prev_il_instruction)
+		symbol->prev_il_instruction.push_back(prev_il_instruction);
 	return NULL;
 }
 
@@ -281,3 +291,54 @@
 
 
 
+
+/*******************/
+/* B 2.2 Operators */
+/*******************/
+// void *visit(   LD_operator_c *symbol);
+// void *visit(  LDN_operator_c *symbol);
+// void *visit(   ST_operator_c *symbol);
+// void *visit(  STN_operator_c *symbol);
+// void *visit(  NOT_operator_c *symbol);
+// void *visit(    S_operator_c *symbol);
+// void *visit(    R_operator_c *symbol);
+// void *visit(   S1_operator_c *symbol);
+// void *visit(   R1_operator_c *symbol);
+// void *visit(  CLK_operator_c *symbol);
+// void *visit(   CU_operator_c *symbol);
+// void *visit(   CD_operator_c *symbol);
+// void *visit(   PV_operator_c *symbol);
+// void *visit(   IN_operator_c *symbol);
+// void *visit(   PT_operator_c *symbol);
+// void *visit(  AND_operator_c *symbol);
+// void *visit(   OR_operator_c *symbol);
+// void *visit(  XOR_operator_c *symbol);
+// void *visit( ANDN_operator_c *symbol);
+// void *visit(  ORN_operator_c *symbol);
+// void *visit( XORN_operator_c *symbol);
+// void *visit(  ADD_operator_c *symbol);
+// void *visit(  SUB_operator_c *symbol);
+// void *visit(  MUL_operator_c *symbol);
+// void *visit(  DIV_operator_c *symbol);
+// void *visit(  MOD_operator_c *symbol);
+// void *visit(   GT_operator_c *symbol);
+// void *visit(   GE_operator_c *symbol);
+// void *visit(   EQ_operator_c *symbol);
+// void *visit(   LT_operator_c *symbol);
+// void *visit(   LE_operator_c *symbol);
+// void *visit(   NE_operator_c *symbol);
+// void *visit(  CAL_operator_c *symbol);
+// void *visit( CALC_operator_c *symbol);
+// void *visit(CALCN_operator_c *symbol);
+// void *visit(  RET_operator_c *symbol);
+// void *visit( RETC_operator_c *symbol);
+// void *visit(RETCN_operator_c *symbol);
+// void *visit(  JMP_operator_c *symbol);
+// void *visit( JMPC_operator_c *symbol);
+// void *visit(JMPCN_operator_c *symbol);
+
+/* Symbol class handled together with function call checks */
+// void *visit(il_assign_operator_c *symbol, variable_name);
+/* Symbol class handled together with function call checks */
+// void *visit(il_assign_operator_c *symbol, option, variable_name);
+