# HG changeset patch # User Mario de Sousa # Date 1333811657 -3600 # Node ID a6211f73690baf9f5df33f5611513cdd685b4f1c # Parent 19bc099215d89685e5dfb4e851607d77ad7c9a9a Start data type checking of var declarations (including direct variables!) diff -r 19bc099215d8 -r a6211f73690b stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Tue Apr 03 12:42:16 2012 +0100 +++ b/stage3/fill_candidate_datatypes.cc Sat Apr 07 16:14:17 2012 +0100 @@ -522,6 +522,22 @@ /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ + +/* simple_specification ASSIGN constant */ +// SYM_REF2(simple_spec_init_c, simple_specification, constant) +void *fill_candidate_datatypes_c::visit(simple_spec_init_c *symbol) { + if (NULL != symbol->constant) symbol->constant->accept(*this); + add_datatype_to_candidate_list(symbol->simple_specification, base_type(symbol->simple_specification)); + symbol->candidate_datatypes = symbol->simple_specification->candidate_datatypes; + /* NOTE: Even if the constant and the type are of incompatible data types, we let the + * simple_spec_init_c object inherit the data type of the type declaration (simple_specification) + * This will let us produce more informative error messages when checking data type compatibility + * with located variables (AT %QW3.4 : WORD). + */ + // if (NULL != symbol->constant) intersect_candidate_datatype_list(symbol /*origin, dest.*/, symbol->constant /*with*/); + return NULL; +} + /* signed_integer DOTDOT signed_integer */ // SYM_REF2(subrange_c, lower_limit, upper_limit) void *fill_candidate_datatypes_c::visit(subrange_c *symbol) { @@ -575,6 +591,7 @@ return NULL; } + /********************************************/ /* B 1.4.1 - Directly Represented Variables */ /********************************************/ @@ -588,11 +605,11 @@ * if (symbol->value[1] == '\0') ERROR; */ switch (symbol->value[2]) { - case 'X': /* bit - 1 bit */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name); break; - case 'B': /* byte - 8 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::byte_type_name); break; - case 'W': /* word - 16 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::word_type_name); break; - case 'D': /* dword - 32 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::dword_type_name); break; - case 'L': /* lword - 64 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::lword_type_name); break; + case 'x': case 'X': /* bit - 1 bit */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name); break; + case 'b': case 'B': /* byte - 8 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::byte_type_name); break; + case 'w': case 'W': /* word - 16 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::word_type_name); break; + case 'd': case 'D': /* dword - 32 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::dword_type_name); break; + case 'l': case 'L': /* lword - 64 bits */ add_datatype_to_candidate_list(symbol, &search_constant_type_c::lword_type_name); break; /* if none of the above, then the empty string was used <=> boolean */ default: add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name); break; } @@ -641,6 +658,46 @@ return NULL; } + + +/******************************************/ +/* B 1.4.3 - Declaration & Initialisation */ +/******************************************/ + +void *fill_candidate_datatypes_c::visit(var1_list_c *symbol) { +#if 0 /* We don't really need to set the datatype of each variable. We just check the declaration itself! */ + for(int i = 0; i < symbol->n; i++) { + add_datatype_to_candidate_list(symbol->elements[i], search_varfb_instance_type->get_basetype_decl(symbol->elements[i])); /* will only add if non NULL */ + } +#endif + return NULL; +} + + +/* AT direct_variable */ +// SYM_REF1(location_c, direct_variable) +void *fill_candidate_datatypes_c::visit(location_c *symbol) { + symbol->direct_variable->accept(*this); + symbol->candidate_datatypes = symbol->direct_variable->candidate_datatypes; + return NULL; +} + + +/* [variable_name] location ':' located_var_spec_init */ +/* variable_name -> may be NULL ! */ +// SYM_REF3(located_var_decl_c, variable_name, location, located_var_spec_init) +void *fill_candidate_datatypes_c::visit(located_var_decl_c *symbol) { + symbol->located_var_spec_init->accept(*this); + symbol->location->accept(*this); + symbol->variable_name->candidate_datatypes = symbol->location->candidate_datatypes; + intersect_candidate_datatype_list(symbol->variable_name /*origin, dest.*/, symbol->located_var_spec_init /*with*/); + return NULL; +} + + + + + /************************************/ /* B 1.5 Program organization units */ /************************************/ diff -r 19bc099215d8 -r a6211f73690b stage3/fill_candidate_datatypes.hh --- a/stage3/fill_candidate_datatypes.hh Tue Apr 03 12:42:16 2012 +0100 +++ b/stage3/fill_candidate_datatypes.hh Sat Apr 07 16:14:17 2012 +0100 @@ -157,6 +157,7 @@ /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ + void *visit(simple_spec_init_c *symbol); void *visit(subrange_c *symbol); // void *visit(data_type_declaration_c *symbol); void *visit(enumerated_value_c *symbol); @@ -177,6 +178,14 @@ void *visit(array_variable_c *symbol); void *visit(structured_variable_c *symbol); + /******************************************/ + /* B 1.4.3 - Declaration & Initialisation */ + /******************************************/ + void *visit(var1_list_c *symbol); + void *visit(location_c *symbol); + void *visit(located_var_decl_c *symbol); + + /**************************************/ /* B 1.5 - Program organization units */ /**************************************/ diff -r 19bc099215d8 -r a6211f73690b stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Tue Apr 03 12:42:16 2012 +0100 +++ b/stage3/narrow_candidate_datatypes.cc Sat Apr 07 16:14:17 2012 +0100 @@ -399,6 +399,24 @@ /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ +/* simple_specification ASSIGN constant */ +// SYM_REF2(simple_spec_init_c, simple_specification, constant) +void *narrow_candidate_datatypes_c::visit(simple_spec_init_c *symbol) { + if (symbol->candidate_datatypes.size() == 1) + symbol->datatype = symbol->candidate_datatypes[0]; + + if (symbol->simple_specification->candidate_datatypes.size() == 1) + symbol->simple_specification->datatype = symbol->simple_specification->candidate_datatypes[0]; + + if (NULL != symbol->constant) { + set_datatype(symbol->datatype, symbol->constant); + symbol->constant->accept(*this); + } + return NULL; +} + + + /* signed_integer DOTDOT signed_integer */ // SYM_REF2(subrange_c, lower_limit, upper_limit) void *narrow_candidate_datatypes_c::visit(subrange_c *symbol) { @@ -409,17 +427,6 @@ return NULL; } -/* simple_specification ASSIGN constant */ -// SYM_REF2(simple_spec_init_c, simple_specification, constant) -void *narrow_candidate_datatypes_c::visit(simple_spec_init_c *symbol) { - symbol_c *datatype = base_type(symbol->simple_specification); - if (NULL != symbol->constant) { - int typeoffset = search_in_candidate_datatype_list(datatype, symbol->constant->candidate_datatypes); - if (typeoffset >= 0) - symbol->constant->datatype = symbol->constant->candidate_datatypes[typeoffset]; - } - return NULL; -} /*********************/ /* B 1.4 - Variables */ @@ -456,6 +463,47 @@ + +/******************************************/ +/* B 1.4.3 - Declaration & Initialisation */ +/******************************************/ + +void *narrow_candidate_datatypes_c::visit(var1_list_c *symbol) { +#if 0 /* We don't really need to set the datatype of each variable. We just check the declaration itself! */ + for(int i = 0; i < symbol->n; i++) { + if (symbol->elements[i]->candidate_datatypes.size() == 1) + symbol->elements[i]->datatype = symbol->elements[i]->candidate_datatypes[0]; + } +#endif + return NULL; +} + + +/* AT direct_variable */ +// SYM_REF1(location_c, direct_variable) +void *narrow_candidate_datatypes_c::visit(location_c *symbol) { + set_datatype(symbol->datatype, symbol->direct_variable); + symbol->direct_variable->accept(*this); /* currently does nothing! */ + return NULL; +} + + +/* [variable_name] location ':' located_var_spec_init */ +/* variable_name -> may be NULL ! */ +// SYM_REF3(located_var_decl_c, variable_name, location, located_var_spec_init) +void *narrow_candidate_datatypes_c::visit(located_var_decl_c *symbol) { + /* let the var_spec_init set its own symbol->datatype value */ + symbol->located_var_spec_init->accept(*this); + + if (NULL != symbol->variable_name) + set_datatype(symbol->located_var_spec_init->datatype, symbol->variable_name); + + set_datatype(symbol->located_var_spec_init->datatype, symbol->location); + symbol->location->accept(*this); + return NULL; +} + + /************************************/ /* B 1.5 Program organization units */ /************************************/ diff -r 19bc099215d8 -r a6211f73690b stage3/narrow_candidate_datatypes.hh --- a/stage3/narrow_candidate_datatypes.hh Tue Apr 03 12:42:16 2012 +0100 +++ b/stage3/narrow_candidate_datatypes.hh Sat Apr 07 16:14:17 2012 +0100 @@ -87,6 +87,13 @@ void *visit(array_variable_c *symbol); void *visit(subscript_list_c *symbol); + /******************************************/ + /* B 1.4.3 - Declaration & Initialisation */ + /******************************************/ + void *visit(var1_list_c *symbol); + void *visit(location_c *symbol); + void *visit(located_var_decl_c *symbol); + /**************************************/ /* B 1.5 - Program organization units */ /**************************************/ diff -r 19bc099215d8 -r a6211f73690b stage3/print_datatypes_error.cc --- a/stage3/print_datatypes_error.cc Tue Apr 03 12:42:16 2012 +0100 +++ b/stage3/print_datatypes_error.cc Sat Apr 07 16:14:17 2012 +0100 @@ -529,6 +529,20 @@ /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ +void *print_datatypes_error_c::visit(simple_spec_init_c *symbol) { + if (!is_type_valid(symbol->simple_specification->datatype)) { + STAGE3_ERROR(0, symbol->simple_specification, symbol->simple_specification, "Invalid data type."); + } else if (NULL != symbol->constant) { + if (!is_type_valid(symbol->constant->datatype)) + STAGE3_ERROR(0, symbol->constant, symbol->constant, "Initial value has incompatible data type."); + } else if (!is_type_valid(symbol->datatype)) { + ERROR; /* If we have an error here, then we must also have an error in one of + * the two previous tests. If we reach this point, some strange error is ocurring! + */ + } + return NULL; +} + void *print_datatypes_error_c::visit(data_type_declaration_c *symbol) { // TODO !!! /* for the moment we must return NULL so semantic analysis of remaining code is not interrupted! */ @@ -555,8 +569,9 @@ /* B 1.4.1 - Directly Represented Variables */ /********************************************/ void *print_datatypes_error_c::visit(direct_variable_c *symbol) { - if (symbol->candidate_datatypes.size() == 0) - STAGE3_ERROR(0, symbol, symbol, "Numerical value exceeds range for located variable data type."); + if (symbol->candidate_datatypes.size() == 0) ERROR; + if (!is_type_valid(symbol->datatype)) + STAGE3_ERROR(4, symbol, symbol, "Direct variable has incompatible data type with expression."); return NULL; } @@ -597,6 +612,33 @@ return NULL; } + + +/******************************************/ +/* B 1.4.3 - Declaration & Initialisation */ +/******************************************/ + +/* AT direct_variable */ +// SYM_REF1(location_c, direct_variable) +void *print_datatypes_error_c::visit(location_c *symbol) { + symbol->direct_variable->accept(*this); + return NULL; +} + + +/* [variable_name] location ':' located_var_spec_init */ +/* variable_name -> may be NULL ! */ +// SYM_REF3(located_var_decl_c, variable_name, location, located_var_spec_init) +void *print_datatypes_error_c::visit(located_var_decl_c *symbol) { + symbol->located_var_spec_init->accept(*this); + /* It does not make sense to call symbol->location->accept(*this). The check is done right here if the following if() */ + // symbol->location->accept(*this); + if ((is_type_valid(symbol->located_var_spec_init->datatype)) && (!is_type_valid(symbol->location->datatype))) + STAGE3_ERROR(0, symbol, symbol, "Location is incompatible with data type."); + return NULL; +} + + /************************************/ /* B 1.5 Program organization units */ /************************************/ @@ -638,7 +680,7 @@ void *print_datatypes_error_c::visit(program_declaration_c *symbol) { search_varfb_instance_type = new search_varfb_instance_type_c(symbol); /* We do not check for data type errors in variable declarations, Skip this for now... */ -// symbol->var_declarations->accept(*this); + symbol->var_declarations->accept(*this); 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; diff -r 19bc099215d8 -r a6211f73690b stage3/print_datatypes_error.hh --- a/stage3/print_datatypes_error.hh Tue Apr 03 12:42:16 2012 +0100 +++ b/stage3/print_datatypes_error.hh Sat Apr 07 16:14:17 2012 +0100 @@ -149,6 +149,7 @@ /********************************/ /* B 1.3.3 - Derived data types */ /********************************/ + void *visit(simple_spec_init_c *symbol); void *visit(data_type_declaration_c *symbol); void *visit(enumerated_value_c *symbol); @@ -168,6 +169,12 @@ void *visit(array_variable_c *symbol); void *visit(structured_variable_c *symbol); + /******************************************/ + /* B 1.4.3 - Declaration & Initialisation */ + /******************************************/ + void *visit(location_c *symbol); + void *visit(located_var_decl_c *symbol); + /**************************************/ /* B 1.5 - Program organization units */ /**************************************/