--- a/stage3/narrow_candidate_datatypes.cc Thu Mar 01 10:28:27 2012 +0000
+++ b/stage3/narrow_candidate_datatypes.cc Fri Mar 02 12:53:41 2012 +0000
@@ -57,15 +57,38 @@
/* Only set the symbol's desired datatype to 'datatype' if that datatype is in the candidate_datatype list */
static void set_datatype(symbol_c *datatype, symbol_c *symbol) {
- symbol->datatype = NULL;
- if (search_in_candidate_datatype_list(datatype, symbol->candidate_datatypes) >= 0)
- symbol->datatype = datatype;
+
+ /* If we are trying to set to the undefined type, and the symbol's datatype has already been set to something else,
+ * we abort the compoiler as I don't think this should ever occur.
+ * However, I (Mario) am not too sure of this, so if the compiler ever aborts here, please analyse the situation
+ * carefully as it might be perfectly legal and something I have missed!
+ */
+ if ((NULL == datatype) && (NULL != symbol->datatype)) ERROR;
+
+ if ((NULL == datatype) && (NULL == symbol->datatype)) return;
+
+ if (search_in_candidate_datatype_list(datatype, symbol->candidate_datatypes) < 0)
+ symbol->datatype = &(search_constant_type_c::invalid_type_name);
+ else {
+ if (NULL == symbol->datatype)
+ /* not yet set to anything, so we set it to the requested data type */
+ symbol->datatype = datatype;
+ else {
+ /* had already been set previously to some data type. Let's check if they are the same! */
+ if (!is_type_equal(symbol->datatype, datatype))
+ symbol->datatype = &(search_constant_type_c::invalid_type_name);
+// else
+ /* we leave it unchanged, as it is the same as the requested data type! */
+ }
+ }
}
/* Only set the symbol's desired datatype to 'datatype' if that datatype is in the candidate_datatype list */
-static void set_datatype_in_prev_il_instruction(symbol_c *datatype, il_instruction_c *symbol) {
+// static void set_datatype_in_prev_il_instructions(symbol_c *datatype, std::vector <symbol_c *> prev_il_instructions) {
+static void set_datatype_in_prev_il_instructions(symbol_c *datatype, il_instruction_c *symbol) {
+ if (NULL == symbol) ERROR;
for (unsigned int i = 0; i < symbol->prev_il_instruction.size(); i++)
set_datatype(datatype, symbol->prev_il_instruction[i]);
}
@@ -276,7 +299,7 @@
}
symbol_c *fb_decl = il_operand->datatype;
- if (NULL == prev_il_instruction) {
+ if (0 == fake_prev_il_instruction->prev_il_instruction.size()) {
/* This IL implicit FB call (e.g. CLK ton_var) is not preceded by another IL instruction
* (or list of instructions) that will set the IL current/default value.
* We cannot proceed verifying type compatibility of something that does not exist.
@@ -286,9 +309,9 @@
if (NULL == fb_decl) {
/* the il_operand is a not FB instance */
- /* so we simply pass on the required datatype to the prev_il_instruction */
- /* The invalid FB invocation will be caught by the print_datatypes_error_c by analysing NULL value in il_operand->datatype! */
- prev_il_instruction->datatype = il_instruction->datatype;
+ /* so we simply pass on the required datatype to the prev_il_instructions */
+ /* The invalid FB invocation will be caught in the print_datatypes_error_c by analysing NULL value in il_operand->datatype! */
+ set_datatype_in_prev_il_instructions(il_instruction->datatype, fake_prev_il_instruction);
return NULL;
}
@@ -302,8 +325,15 @@
* would be changed to the IL instruction coming before the current prev_il_instruction! => things would get all messed up!)
* The easiest way to work around this is to simply use a new object, and copy the relevant details to that object!
*/
- symbol_c param_value = *prev_il_instruction;
-
+printf("XX::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): fake_prev_il_instruction->candidate_datatypes.size() = %d\n",fake_prev_il_instruction->candidate_datatypes.size());
+printf("XX::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): fake_prev_il_instruction->candidate_datatypes[0] = %p\n",fake_prev_il_instruction->candidate_datatypes[0]);
+ symbol_c param_value = *fake_prev_il_instruction; /* copy the candidate_datatypes list ! */
+printf("XX::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.candidate_datatypes.size() = %d\n",param_value.candidate_datatypes.size());
+printf("XX::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.candidate_datatypes[0] = %p\n",param_value.candidate_datatypes[0]);
+printf("00::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): search_constant_type::time_type_name = %p\n", &search_constant_type_c::time_type_name);
+printf("00::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): search_constant_type::invalid_type_name = %p\n", &search_constant_type_c::invalid_type_name);
+
+printf("11::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.datatype = %p\n", param_value.datatype);
identifier_c variable_name(param_name);
// SYM_REF1(il_assign_operator_c, variable_name)
il_assign_operator_c il_assign_operator(&variable_name);
@@ -314,6 +344,7 @@
// SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration)
CAL_operator_c CAL_operator;
il_fb_call_c il_fb_call(&CAL_operator, il_operand, NULL, &il_param_list);
+printf("22::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.datatype = %p\n", param_value.datatype);
/* A FB call does not return any datatype, but the IL instructions that come after this
* FB call may require a specific datatype in the il current/default variable,
@@ -326,6 +357,7 @@
// copy_candidate_datatype_list(il_instruction/*from*/, &il_fb_call/*to*/);
il_fb_call.called_fb_declaration = called_fb_declaration;
il_fb_call.accept(*this);
+printf("33::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.datatype = %p\n", param_value.datatype);
/* set the required datatype of the previous IL instruction! */
/* NOTE:
@@ -338,7 +370,7 @@
* This means that we have two consumers/users for the same value.
* We must therefore check whether the datatype required by the IL instructions following this FB call
* is the same as that required for the first parameter. If not, then we have a semantic error,
- * and we set it to NULL.
+ * and we set it to invalid_type_name.
*
* However, we only do that if:
* - The IL instruction that comes after this IL FB call actually asked this FB call for a specific
@@ -348,9 +380,11 @@
* FB call must be left unchanged!
*/
if ((NULL == il_instruction->datatype) || (is_type_equal(param_value.datatype, il_instruction->datatype))) {
- prev_il_instruction->datatype = param_value.datatype;
+printf("44::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.datatype = %p\n", param_value.datatype);
+ set_datatype_in_prev_il_instructions(param_value.datatype, fake_prev_il_instruction);
} else {
- prev_il_instruction->datatype = NULL;
+printf("55::narrow_candidate_datatypes_c::narrow_implicit_il_fb_call(): param_value.datatype = %p\n", param_value.datatype);
+ set_datatype_in_prev_il_instructions(&search_constant_type_c::invalid_type_name, fake_prev_il_instruction);
}
return NULL;
}
@@ -510,14 +544,21 @@
void *narrow_candidate_datatypes_c::visit(il_instruction_c *symbol) {
if (NULL == symbol->il_instruction) {
/* this empty/null il_instruction cannot generate the desired datatype. We pass on the request to the previous il instruction. */
- set_datatype_in_prev_il_instruction(symbol->datatype, symbol);
+ set_datatype_in_prev_il_instructions(symbol->datatype, symbol);
} else {
+ il_instruction_c tmp_prev_il_instruction(NULL, NULL);
+ /* the narrow algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the
+ * list of the prev_il_instructions.
+ * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction),
+ * and shove that data into this single variable.
+ */
+ tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction;
+ intersect_prev_candidate_datatype_lists(&tmp_prev_il_instruction);
/* Tell the il_instruction the datatype that it must generate - this was chosen by the next il_instruction (remember: we are iterating backwards!) */
- if (symbol->prev_il_instruction.size() > 1) ERROR; /* This assertion is only valid for now. Remove it once flow_control_analysis_c is complete */
- if (symbol->prev_il_instruction.size() == 0) prev_il_instruction = NULL;
- else prev_il_instruction = symbol->prev_il_instruction[0];
+ fake_prev_il_instruction = &tmp_prev_il_instruction;
+ symbol->il_instruction->datatype = symbol->datatype;
symbol->il_instruction->accept(*this);
- prev_il_instruction = NULL;
+ fake_prev_il_instruction = NULL;
}
return NULL;
}
@@ -552,12 +593,10 @@
* need to create a new object to hold the pointer to prev_il_instruction.
* This change will also be undone later in print_datatypes_error_c.
*/
- symbol_c param_value;
+ symbol_c param_value = *fake_prev_il_instruction; /* copy the candidate_datatypes list */
if (NULL == symbol->il_operand_list) symbol->il_operand_list = new il_operand_list_c;
if (NULL == symbol->il_operand_list) ERROR;
- if (NULL != prev_il_instruction)
- param_value = *prev_il_instruction;
((list_c *)symbol->il_operand_list)->insert_element(¶m_value, 0);
generic_function_call_t fcall_param = {
@@ -571,8 +610,7 @@
};
narrow_function_invocation(symbol, fcall_param);
- if (NULL != prev_il_instruction)
- prev_il_instruction->datatype = param_value.datatype;
+ set_datatype_in_prev_il_instructions(param_value.datatype, fake_prev_il_instruction);
/* Undo the changes to the abstract syntax tree we made above... */
((list_c *)symbol->il_operand_list)->remove_element(0);
@@ -596,10 +634,10 @@
/* 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 */
+ il_instruction_c *save_fake_prev_il_instruction = fake_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;
-return NULL;
+ fake_prev_il_instruction = save_fake_prev_il_instruction;
+ return NULL;
}
@@ -664,12 +702,23 @@
// SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
void *narrow_candidate_datatypes_c::visit(il_simple_instruction_c *symbol) {
- if (symbol->prev_il_instruction.size() > 1) ERROR; /* This assertion is only valid for now. Remove it once flow_control_analysis_c is complete */
- if (symbol->prev_il_instruction.size() == 0) prev_il_instruction = NULL;
- else prev_il_instruction = symbol->prev_il_instruction[0];
+ if (symbol->prev_il_instruction.size() > 1) ERROR; /* There should be no labeled insructions inside an IL expression! */
+
+ il_instruction_c tmp_prev_il_instruction(NULL, NULL);
+ /* the narrow algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the
+ * list of the prev_il_instructions.
+ * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction),
+ * and shove that data into this single variable.
+ */
+ if (symbol->prev_il_instruction.size() > 0)
+ tmp_prev_il_instruction.candidate_datatypes = symbol->prev_il_instruction[0]->candidate_datatypes;
+ tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction;
+
+ /* copy the candidate_datatypes list */
+ fake_prev_il_instruction = &tmp_prev_il_instruction;
symbol->il_simple_instruction->datatype = symbol->datatype;
symbol->il_simple_instruction->accept(*this);
- prev_il_instruction = NULL;
+ fake_prev_il_instruction = NULL;
return NULL;
}
@@ -702,7 +751,8 @@
* (or simple_instr_list_c), which iterates backwards.
*/
/* set the desired datatype of the previous il instruction */
- prev_il_instruction->datatype = symbol->datatype;
+ set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
+
/* set the datatype for the operand */
il_operand->datatype = symbol->datatype;
il_operand->accept(*this);
@@ -739,8 +789,7 @@
il_operand->datatype = symbol->datatype;
il_operand->accept(*this);
/* set the desired datatype of the previous il instruction */
- prev_il_instruction->datatype = symbol->datatype;
- if (debug) printf("narrow_candidate_datatypes_c::visit(ST_operator_c *symbol) returning. previous_il_instruction->datatype = %p\n", prev_il_instruction->datatype);
+ set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
return NULL;
}
@@ -752,7 +801,7 @@
il_operand->datatype = symbol->datatype;
il_operand->accept(*this);
/* set the desired datatype of the previous il instruction */
- prev_il_instruction->datatype = symbol->datatype;
+ set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
return NULL;
}
@@ -805,8 +854,7 @@
void *narrow_candidate_datatypes_c::visit(CAL_operator_c *symbol) {
/* set the desired datatype of the previous il instruction */
/* This FB call does not change the value in the current/default IL variable, so we pass the required datatype to the previous IL instruction */
- if (NULL != prev_il_instruction)
- prev_il_instruction->datatype = symbol->datatype;
+ set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
return NULL;
}
@@ -827,7 +875,7 @@
if ((NULL != symbol->datatype) && (!is_type(symbol->datatype, bool_type_name_c))) ERROR;
/* set the required datatype of the previous IL instruction, i.e. a bool_type_name_c! */
- if (NULL != prev_il_instruction) prev_il_instruction->datatype = symbol->datatype;
+ set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
return NULL;
}
@@ -846,8 +894,7 @@
* However, since that class has not yet been completely finished, we do not yet check this assertion!
*/
// if (NULL != symbol->datatype) ERROR;
- if (NULL != prev_il_instruction)
- prev_il_instruction->datatype = symbol->datatype;
+ set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
return NULL;
}
@@ -861,8 +908,7 @@
* However, since that class has not yet been completely finished, we do not yet check this assertion!
*/
// if (NULL != symbol->datatype) ERROR;
- if (NULL != prev_il_instruction)
- prev_il_instruction->datatype = symbol->datatype;
+ set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
return NULL;
}