stage4/generate_iec/generate_iec.cc
changeset 625 c0bda77b37a0
parent 596 4efb11e44065
child 690 6156ee2b4e32
equal deleted inserted replaced
412:aad38592bdde 625:c0bda77b37a0
    42  * 4th stages.
    42  * 4th stages.
    43  */
    43  */
    44 
    44 
    45 
    45 
    46 
    46 
       
    47 /* Compile with the following option, to print out the const_value of each symbol, which was filled in by constant_folding_c during stage3 */
       
    48 // #define DEBUG_CONST_VALUE
    47 
    49 
    48 
    50 
    49 
    51 
    50 // #include <stdio.h>  /* required for NULL */
    52 // #include <stdio.h>  /* required for NULL */
    51 #include <string>
    53 #include <string>
    53 #include <sstream>
    55 #include <sstream>
    54 #include <typeinfo>
    56 #include <typeinfo>
    55 #include "generate_iec.hh"
    57 #include "generate_iec.hh"
    56 
    58 
    57 #include "../stage4.hh"
    59 #include "../stage4.hh"
       
    60 #include "../../main.hh" // required for ERROR() and ERROR_MSG() macros.
       
    61 
    58 
    62 
    59 
    63 
    60 
    64 
    61 
    65 
    62 
    66 
    72     ~generate_iec_c(void) {}
    76     ~generate_iec_c(void) {}
    73 
    77 
    74 
    78 
    75   private:
    79   private:
    76 
    80 
       
    81     
       
    82 void print_const_value(symbol_c *symbol) {
       
    83 #ifdef DEBUG_CONST_VALUE
       
    84   if (NULL == symbol) return;
       
    85   bool first = true;
       
    86   
       
    87   if (NULL != symbol->const_value_uint64) {
       
    88     first?s4o.print("{"):s4o.print("; ");
       
    89     first = false;
       
    90     s4o.print("uint64:");
       
    91     if (symbol->const_value_uint64->status == symbol_c::cs_const_value)
       
    92       s4o.print_uint64(symbol->const_value_uint64->value);
       
    93     if (symbol->const_value_uint64->status == symbol_c::cs_overflow)
       
    94     s4o.print("OVERFLOW");
       
    95   }
       
    96   if (NULL != symbol->const_value_int64) {
       
    97     first?s4o.print("{"):s4o.print("; ");
       
    98     first = false;
       
    99     s4o.print("int64:");
       
   100     if (symbol->const_value_int64->status == symbol_c::cs_const_value)
       
   101       s4o.print_int64(symbol->const_value_int64->value);
       
   102     if (symbol->const_value_int64->status == symbol_c::cs_overflow)
       
   103     s4o.print("OVERFLOW");
       
   104   }
       
   105   if (NULL != symbol->const_value_real64) {
       
   106     first?s4o.print("{"):s4o.print("; ");
       
   107     first = false;
       
   108     s4o.print("real64:");
       
   109     if (symbol->const_value_real64->status == symbol_c::cs_const_value)
       
   110       s4o.print_real64(symbol->const_value_real64->value);
       
   111     if (symbol->const_value_real64->status == symbol_c::cs_overflow)
       
   112     s4o.print("OVERFLOW");
       
   113   }
       
   114   if (NULL != symbol->const_value_bool) {
       
   115     first?s4o.print("{"):s4o.print("; ");
       
   116     first = false;
       
   117     s4o.print("bool:");
       
   118     if (symbol->const_value_bool->status == symbol_c::cs_const_value)
       
   119       s4o.print((symbol->const_value_bool->value)?"true":"false");
       
   120     if (symbol->const_value_bool->status == symbol_c::cs_overflow)
       
   121     s4o.print("OVERFLOW");
       
   122   }
       
   123   if (!first) s4o.print("}");  
       
   124 #endif
       
   125   return;
       
   126 }
       
   127 
       
   128 
       
   129 
    77 void *print_token(token_c *token) {
   130 void *print_token(token_c *token) {
       
   131   print_const_value(token);
    78   return s4o.print(token->value);
   132   return s4o.print(token->value);
    79 }
   133 }
    80 
   134 
       
   135 
    81 void *print_literal(symbol_c *type, symbol_c *value) {
   136 void *print_literal(symbol_c *type, symbol_c *value) {
       
   137   print_const_value(value);
    82   if (NULL != type) {
   138   if (NULL != type) {
    83     type->accept(*this);
   139     type->accept(*this);
    84     s4o.print("#");
   140     s4o.print("#");
    85   }
   141   }
    86   value->accept(*this);
   142   value->accept(*this);
   106 
   162 
   107   return NULL;
   163   return NULL;
   108 }
   164 }
   109 
   165 
   110 
   166 
   111 void *print_binary_expression(symbol_c *l_exp,
   167 void *print_binary_expression(symbol_c *symbol,
       
   168 			      symbol_c *l_exp,
   112 			      symbol_c *r_exp,
   169 			      symbol_c *r_exp,
   113 			      const char *operation) {
   170 			      const char *operation) {
       
   171   print_const_value(symbol);
   114   s4o.print("(");
   172   s4o.print("(");
   115   l_exp->accept(*this);
   173   l_exp->accept(*this);
   116   s4o.print(operation);
   174   s4o.print(operation);
   117   r_exp->accept(*this);
   175   r_exp->accept(*this);
   118   s4o.print(")");
   176   s4o.print(")");
   119   return NULL;
   177   return NULL;
   120 }
   178 }
   121 
   179 
   122 void *print_unary_expression(symbol_c *exp,
   180 void *print_unary_expression(symbol_c *symbol,
       
   181 			     symbol_c *exp,
   123 			     const char *operation) {
   182 			     const char *operation) {
       
   183   print_const_value(symbol);
   124   s4o.print(operation);
   184   s4o.print(operation);
   125   exp->accept(*this);
   185   exp->accept(*this);
   126   return NULL;
   186   return NULL;
   127 }
   187 }
   128 
   188 
   151   return symbol->param_name->accept(*this);
   211   return symbol->param_name->accept(*this);
   152 }
   212 }
   153 #endif
   213 #endif
   154 
   214 
   155 
   215 
       
   216 /* A class used to identify an entry (literal, variable, etc...) in the abstract syntax tree with an invalid data type */
       
   217 /* This is only used from stage3 onwards. Stages 1 and 2 will never create any instances of invalid_type_name_c */
       
   218 // SYM_REF0(invalid_type_name_c)
       
   219 void *visit(invalid_type_name_c *symbol) {
       
   220   ERROR;
       
   221   return NULL;
       
   222 }
   156 
   223 
   157 
   224 
   158 /******************/
   225 /******************/
   159 /* 2.1.6 Pragmas  */
   226 /* 2.1.6 Pragmas  */
   160 /******************/
   227 /******************/
   179 
   246 
   180 /******************************/
   247 /******************************/
   181 /* B 1.2.1 - Numeric Literals */
   248 /* B 1.2.1 - Numeric Literals */
   182 /******************************/
   249 /******************************/
   183 void *visit(real_c *symbol)               {return print_token(symbol);}
   250 void *visit(real_c *symbol)               {return print_token(symbol);}
   184 void *visit(neg_real_c *symbol)           {return print_unary_expression(symbol->exp, "-");}
   251 void *visit(neg_real_c *symbol)           {return print_unary_expression(symbol, symbol->exp, "-");}
   185 void *visit(integer_c *symbol)            {return print_token(symbol);}
   252 void *visit(integer_c *symbol)            {return print_token(symbol);}
   186 void *visit(neg_integer_c *symbol)        {return print_unary_expression(symbol->exp, "-");}
   253 void *visit(neg_integer_c *symbol)        {return print_unary_expression(symbol, symbol->exp, "-");}
   187 void *visit(binary_integer_c *symbol)     {return print_token(symbol);}
   254 void *visit(binary_integer_c *symbol)     {return print_token(symbol);}
   188 void *visit(octal_integer_c *symbol)      {return print_token(symbol);}
   255 void *visit(octal_integer_c *symbol)      {return print_token(symbol);}
   189 void *visit(hex_integer_c *symbol)        {return print_token(symbol);}
   256 void *visit(hex_integer_c *symbol)        {return print_token(symbol);}
   190 
   257 
   191 void *visit(integer_literal_c *symbol)    {return print_literal(symbol->type, symbol->value);}
   258 void *visit(integer_literal_c *symbol)    {return print_literal(symbol->type, symbol->value);}
   221   return NULL;
   288   return NULL;
   222 }
   289 }
   223 
   290 
   224 void *visit(fixed_point_c *symbol) {return print_token(symbol);}
   291 void *visit(fixed_point_c *symbol) {return print_token(symbol);}
   225 
   292 
   226 void *visit(days_c *symbol) {
   293 /* SYM_REF5(interval_c, days, hours, minutes, seconds, milliseconds) */
   227   symbol->days->accept(*this);
   294 void *visit(interval_c *symbol) {
   228   s4o.print("d");
   295   if (NULL != symbol->days) {
   229   if (symbol->hours != NULL)
   296     symbol->days->accept(*this);
       
   297     s4o.print("d");
       
   298   }
       
   299 
       
   300   if (NULL != symbol->hours) {
   230     symbol->hours->accept(*this);
   301     symbol->hours->accept(*this);
   231   return NULL;
   302     s4o.print("h");
   232 }
   303   }
   233 
   304 
   234 void *visit(hours_c *symbol) {
   305   if (NULL != symbol->minutes) {
   235   symbol->hours->accept(*this);
       
   236   s4o.print("h");
       
   237   if (symbol->minutes != NULL)
       
   238     symbol->minutes->accept(*this);
   306     symbol->minutes->accept(*this);
   239   return NULL;
   307     s4o.print("m");
   240 }
   308   }
   241 
   309 
   242 void *visit(minutes_c *symbol) {
   310   if (NULL != symbol->seconds) {
   243   symbol->minutes->accept(*this);
       
   244   s4o.print("m");
       
   245   if (symbol->seconds != NULL)
       
   246     symbol->seconds->accept(*this);
   311     symbol->seconds->accept(*this);
   247   return NULL;
   312     s4o.print("s");
   248 }
   313   }
   249 
   314 
   250 void *visit(seconds_c *symbol) {
   315   if (NULL != symbol->milliseconds) {
   251   symbol->seconds->accept(*this);
       
   252   s4o.print("s");
       
   253   if (symbol->milliseconds != NULL)
       
   254     symbol->milliseconds->accept(*this);
   316     symbol->milliseconds->accept(*this);
   255   return NULL;
   317     s4o.print("ms");
   256 }
   318   }
   257 
   319 
   258 void *visit(milliseconds_c *symbol) {
   320   return NULL;
   259   symbol->milliseconds->accept(*this);
   321 }
   260   s4o.print("ms");
   322 
   261   return NULL;
   323 
   262 }
       
   263 
   324 
   264 /************************************/
   325 /************************************/
   265 /* B 1.2.3.2 - Time of day and Date */
   326 /* B 1.2.3.2 - Time of day and Date */
   266 /************************************/
   327 /************************************/
   267 
   328 
  1667 
  1728 
  1668 /* | simple_instr_list il_simple_instruction */
  1729 /* | simple_instr_list il_simple_instruction */
  1669 void *visit(simple_instr_list_c *symbol) {
  1730 void *visit(simple_instr_list_c *symbol) {
  1670   return print_list(symbol,  s4o.indent_spaces, "\n" + s4o.indent_spaces, "\n");
  1731   return print_list(symbol,  s4o.indent_spaces, "\n" + s4o.indent_spaces, "\n");
  1671 }
  1732 }
       
  1733 
       
  1734 
       
  1735 /* il_simple_instruction:
       
  1736  *   il_simple_operation eol_list
       
  1737  * | il_expression eol_list
       
  1738  * | il_formal_funct_call eol_list
       
  1739  */
       
  1740 void *visit(il_simple_instruction_c *symbol)	{
       
  1741   return symbol->il_simple_instruction->accept(*this);
       
  1742 }
       
  1743 
  1672 
  1744 
  1673 /* | il_initial_param_list il_param_instruction */
  1745 /* | il_initial_param_list il_param_instruction */
  1674 void *visit(il_param_list_c *symbol) {
  1746 void *visit(il_param_list_c *symbol) {
  1675 // return print_list(symbol);
  1747 // return print_list(symbol);
  1676   return print_list(symbol,  s4o.indent_spaces, ",\n" + s4o.indent_spaces, "\n" + s4o.indent_spaces);
  1748   return print_list(symbol,  s4o.indent_spaces, ",\n" + s4o.indent_spaces, "\n" + s4o.indent_spaces);
  1767 
  1839 
  1768 
  1840 
  1769 /***********************/
  1841 /***********************/
  1770 /* B 3.1 - Expressions */
  1842 /* B 3.1 - Expressions */
  1771 /***********************/
  1843 /***********************/
  1772 void *visit(or_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " OR ");}
  1844 void *visit(or_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " OR ");}
  1773 void *visit(xor_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " XOR ");}
  1845 void *visit(xor_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " XOR ");}
  1774 void *visit(and_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " AND ");}
  1846 void *visit(and_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " AND ");}
  1775 void *visit(equ_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " = ");}
  1847 void *visit(equ_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " = ");}
  1776 void *visit(notequ_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " <> ");}
  1848 void *visit(notequ_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " <> ");}
  1777 void *visit(lt_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " < ");}
  1849 void *visit(lt_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " < ");}
  1778 void *visit(gt_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " > ");}
  1850 void *visit(gt_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " > ");}
  1779 void *visit(le_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " <= ");}
  1851 void *visit(le_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " <= ");}
  1780 void *visit(ge_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " >= ");}
  1852 void *visit(ge_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " >= ");}
  1781 void *visit(add_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " + ");}
  1853 void *visit(add_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " + ");}
  1782 void *visit(sub_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " - ");}
  1854 void *visit(sub_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " - ");}
  1783 void *visit(mul_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " * ");}
  1855 void *visit(mul_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " * ");}
  1784 void *visit(div_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " / ");}
  1856 void *visit(div_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " / ");}
  1785 void *visit(mod_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " MOD ");}
  1857 void *visit(mod_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " MOD ");}
  1786 void *visit(power_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " ** ");}
  1858 void *visit(power_expression_c *symbol) {return print_binary_expression(symbol, symbol->l_exp, symbol->r_exp, " ** ");}
  1787 void *visit(neg_expression_c *symbol) {return print_unary_expression(symbol->exp, "-");}
  1859 void *visit(neg_expression_c *symbol) {return print_unary_expression(symbol, symbol->exp, "-");}
  1788 void *visit(not_expression_c *symbol) {return print_unary_expression(symbol->exp, "NOT ");}
  1860 void *visit(not_expression_c *symbol) {return print_unary_expression(symbol, symbol->exp, "NOT ");}
  1789 
  1861 
  1790 void *visit(function_invocation_c *symbol) {
  1862 void *visit(function_invocation_c *symbol) {
  1791   symbol->function_name->accept(*this);
  1863   symbol->function_name->accept(*this);
  1792   s4o.print("(");
  1864   s4o.print("(");
  1793 
  1865