stage4/generate_cc/generate_location_list.cc
author etisserant
Fri, 13 Jul 2007 19:20:26 +0200
changeset 41 8998c8b24b60
parent 31 c6959b0f539d
child 55 8b7a21820737
permissions -rw-r--r--
First working IEC std lib test, actually test from string and to_string functions.
30
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
     1
/*
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
     2
 * (c) 2007 Mario de Sousa and Laurent Bessard
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
     3
 *
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
     4
 * Offered to the public under the terms of the GNU General Public License
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
     5
 * as published by the Free Software Foundation; either version 2 of the
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
     6
 * License, or (at your option) any later version.
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
     7
 *
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
     8
 * This program is distributed in the hope that it will be useful, but
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
     9
 * WITHOUT ANY WARRANTY; without even the implied warranty of
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    11
 * Public License for more details.
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    12
 *
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    13
 * This code is made available on the understanding that it will not be
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    14
 * used in safety-critical situations without a full and competent review.
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    15
 */
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    16
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    17
/*
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    18
 * An IEC 61131-3 IL and ST compiler.
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    19
 *
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    20
 * Based on the
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    21
 * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    22
 *
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    23
 */
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    24
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    25
/*
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    26
 * This is one of the versions available for the 4th stage.
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    27
 *
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    28
 * This 4th stage generates a c++ source program equivalent
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    29
 * to the IL and ST code.
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    30
 */
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    31
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    32
//#include <stdio.h>  /* required for NULL */
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    33
//#include <string>
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    34
//#include <iostream>
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    35
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    36
//#include "../../util/symtable.hh"
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    37
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    38
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    39
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    40
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    41
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    42
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    43
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    44
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    45
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    46
/***********************************************************************/
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    47
/***********************************************************************/
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    48
/***********************************************************************/
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    49
/***********************************************************************/
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    50
/***********************************************************************/
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    51
/***********************************************************************/
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    52
/***********************************************************************/
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    53
/***********************************************************************/
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    54
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    55
class generate_location_list_c: protected iterator_visitor_c {
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    56
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    57
  protected:
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    58
    stage4out_c &s4o;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    59
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    60
  private:
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    61
    symbol_c *current_var_type_symbol;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    62
    generate_cc_base_c *generate_cc_base;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    63
    search_base_type_c search_base_type;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    64
    
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    65
  public:
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    66
    generate_location_list_c(stage4out_c *s4o_ptr): s4o(*s4o_ptr) {
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    67
      generate_cc_base = new generate_cc_base_c(s4o_ptr);
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    68
      current_var_type_symbol = NULL;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    69
    }
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    70
    ~generate_location_list_c(void) {
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    71
      delete generate_cc_base;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    72
    }
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    73
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    74
    bool test_location_type(symbol_c *direct_variable) {
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    75
      
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    76
      token_c *location = dynamic_cast<token_c *>(direct_variable);
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    77
      
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    78
      if (location == NULL)
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    79
        /* invalid identifiers... */
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    80
        return false;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    81
      
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    82
      switch (location->value[2]) {
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    83
        case 'X': // bit
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    84
          if (typeid(*current_var_type_symbol) == typeid(bool_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    85
          break;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    86
        case 'B': // Byte, 8 bits
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    87
          if (typeid(*current_var_type_symbol) == typeid(sint_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    88
          if (typeid(*current_var_type_symbol) == typeid(usint_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    89
          if (typeid(*current_var_type_symbol) == typeid(string_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    90
          if (typeid(*current_var_type_symbol) == typeid(byte_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    91
          break;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    92
        case 'W': // Word, 16 bits
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    93
          if (typeid(*current_var_type_symbol) == typeid(int_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    94
          if (typeid(*current_var_type_symbol) == typeid(uint_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    95
          if (typeid(*current_var_type_symbol) == typeid(word_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    96
          if (typeid(*current_var_type_symbol) == typeid(wstring_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    97
          break;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    98
        case 'D': // Double, 32 bits
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
    99
          if (typeid(*current_var_type_symbol) == typeid(dint_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   100
          if (typeid(*current_var_type_symbol) == typeid(udint_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   101
          if (typeid(*current_var_type_symbol) == typeid(real_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   102
          if (typeid(*current_var_type_symbol) == typeid(dword_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   103
          break;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   104
        case 'L': // Long, 64 bits
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   105
          if (typeid(*current_var_type_symbol) == typeid(lint_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   106
          if (typeid(*current_var_type_symbol) == typeid(ulint_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   107
          if (typeid(*current_var_type_symbol) == typeid(lreal_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   108
          if (typeid(*current_var_type_symbol) == typeid(lword_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   109
          break;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   110
        default:
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   111
          if (typeid(*current_var_type_symbol) == typeid(bool_type_name_c)) return true;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   112
      }
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   113
      return false;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   114
    }
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   115
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   116
/********************************************/
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   117
/* B.1.4.1   Directly Represented Variables */
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   118
/********************************************/
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   119
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   120
    void *visit(direct_variable_c *symbol) {
41
8998c8b24b60 First working IEC std lib test, actually test from string and to_string functions.
etisserant
parents: 31
diff changeset
   121
      s4o.print("__LOCATED_VAR(");
30
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   122
      current_var_type_symbol->accept(*generate_cc_base);
41
8998c8b24b60 First working IEC std lib test, actually test from string and to_string functions.
etisserant
parents: 31
diff changeset
   123
      s4o.print(",");
30
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   124
      /* Do not use print_token() as it will change everything into uppercase */
31
c6959b0f539d Correct bug on location list generation
lbessard
parents: 30
diff changeset
   125
      s4o.printlocation((symbol->value)+1);
41
8998c8b24b60 First working IEC std lib test, actually test from string and to_string functions.
etisserant
parents: 31
diff changeset
   126
      s4o.print(")\n");
30
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   127
      return NULL;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   128
    }
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   129
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   130
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   131
/********************************************/
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   132
/* B.1.4.3   Declaration and initilization  */
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   133
/********************************************/
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   134
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   135
/*  [variable_name] location ':' located_var_spec_init */
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   136
/* variable_name -> may be NULL ! */
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   137
//SYM_REF4(located_var_decl_c, variable_name, location, located_var_spec_init, unused)
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   138
    void *visit(located_var_decl_c *symbol) {
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   139
        current_var_type_symbol = spec_init_sperator_c::get_spec(symbol->located_var_spec_init);
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   140
        if (current_var_type_symbol == NULL)
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   141
          ERROR;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   142
        
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   143
        current_var_type_symbol = (symbol_c *)(current_var_type_symbol->accept(search_base_type));
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   144
        if (current_var_type_symbol == NULL)
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   145
          ERROR;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   146
        
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   147
        symbol->location->accept(*this);
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   148
        
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   149
        current_var_type_symbol = NULL;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   150
        return NULL;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   151
    }
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   152
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   153
/*| global_var_spec ':' [located_var_spec_init|function_block_type_name] */
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   154
/* type_specification ->may be NULL ! */
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   155
//SYM_REF2(global_var_decl_c, global_var_spec, type_specification)
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   156
    void *visit(global_var_decl_c *symbol) {
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   157
        current_var_type_symbol = spec_init_sperator_c::get_spec(symbol->type_specification);
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   158
        if (current_var_type_symbol == NULL)
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   159
          ERROR;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   160
        
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   161
        current_var_type_symbol = (symbol_c *)(current_var_type_symbol->accept(search_base_type));
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   162
        if (current_var_type_symbol == NULL)
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   163
          ERROR;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   164
        
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   165
        symbol->global_var_spec->accept(*this);
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   166
        
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   167
        current_var_type_symbol = NULL;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   168
        return NULL;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   169
    }
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   170
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   171
/*  AT direct_variable */
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   172
//SYM_REF2(location_c, direct_variable, unused)
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   173
    void *visit(location_c *symbol) {
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   174
      if (test_location_type(symbol->direct_variable))
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   175
        symbol->direct_variable->accept(*this); 
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   176
      else
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   177
        ERROR;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   178
      return NULL;
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   179
    }
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   180
83201ec94ef4 Adding location list generation
lbessard
parents:
diff changeset
   181
}; /* generate_location_list_c */