merge
authorMario de Sousa <msousa@fe.up.pt>
Thu, 22 Nov 2012 19:26:56 +0000
changeset 751 0a5c050d64bb
parent 744 6ecb38715724 (current diff)
parent 750 25f7b35bdff7 (diff)
child 752 8f05bde3efa8
merge
stage3/Makefile.in
--- a/absyntax_utils/Makefile.in	Thu Nov 22 19:19:48 2012 +0000
+++ b/absyntax_utils/Makefile.in	Thu Nov 22 19:26:56 2012 +0000
@@ -93,9 +93,7 @@
 	search_varfb_instance_type.$(OBJEXT) \
 	search_var_instance_decl.$(OBJEXT) \
 	spec_init_separator.$(OBJEXT) type_initial_value.$(OBJEXT) \
-	debug_ast.$(OBJEXT) \
-	get_datatype_info.$(OBJEXT)
-
+	debug_ast.$(OBJEXT) get_datatype_info.$(OBJEXT)
 libabsyntax_utils_a_OBJECTS = $(am_libabsyntax_utils_a_OBJECTS)
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config
 depcomp = $(SHELL) $(top_srcdir)/config/depcomp
@@ -236,7 +234,6 @@
 	debug_ast.cc \
 	get_datatype_info.cc
 
-
 all: all-am
 
 .SUFFIXES:
--- a/absyntax_utils/add_en_eno_param_decl.hh	Thu Nov 22 19:19:48 2012 +0000
+++ b/absyntax_utils/add_en_eno_param_decl.hh	Thu Nov 22 19:26:56 2012 +0000
@@ -42,6 +42,9 @@
  * and eno_param_declaration_c objects.
  */
 
+#ifndef _ADD_EN_ENO_PARAM_DECL_HH
+#define _ADD_EN_ENO_PARAM_DECL_HH
+
 #include "../absyntax/visitor.hh"
 
 
@@ -96,9 +99,11 @@
 
 }; // function_param_iterator_c
 
+#endif /* _ADD_EN_ENO_PARAM_DECL_HH */
 
 
 
 
 
 
+
--- a/main.cc	Thu Nov 22 19:19:48 2012 +0000
+++ b/main.cc	Thu Nov 22 19:26:56 2012 +0000
@@ -67,21 +67,28 @@
 
 
 
-//#include <stdio.h>   // printf()
+#include <stdio.h>
 #include <getopt.h>
 #include <string.h>
-#include <stdlib.h>  // EXIT_FAILURE
-#include "absyntax/absyntax.hh"  // symbol_c type
-
-/* A macro for printing out internal parser errors... */
-#include <iostream> // required for std::cerr
+#include <stdlib.h>
+#include <stdarg.h>
+#include <iostream>
+
+
+#include "config/config.h"
+#include "absyntax/absyntax.hh"
+#include "absyntax_utils/absyntax_utils.hh"
+#include "stage1_2/stage1_2.hh"
+#include "stage3/stage3.hh"
+#include "stage4/stage4.hh"
+#include "main.hh"
+
 
 #ifndef HGVERSION
-#define HGVERSION ""
+   #define HGVERSION ""
 #endif
 
-#include "main.hh"  // symbol_c type
-#include <stdarg.h> // required for va_start(), va_list
+
 
 void error_exit(const char *file_name, int line_no, const char *errmsg, ...) {
   va_list argptr;
@@ -101,28 +108,20 @@
 }
 
 
-
-#include "config/config.h"
-#include "stage1_2/stage1_2.hh"
-#include "absyntax_utils/absyntax_utils.hh"
-
-int stage3(symbol_c *tree_root);
-int stage4(symbol_c *tree_root, const char *builddir);
-
-
 static void printusage(const char *cmd) {
-  printf("syntax: %s [-h] [-v] [-f] [-s] [-I <include_directory>] [-T <target_directory>] <input_file>\n", cmd);
+  printf("\nsyntax: %s [-h] [-v] [-f] [-s] [-c] [-I <include_directory>] [-T <target_directory>] <input_file>\n", cmd);
   printf("  h : show this help message\n");
   printf("  v : print version number\n");  
   printf("  f : display full token location on error messages\n");
       /******************************************************/
-      /* whether we are suporting safe extensions           */
+      /* whether we are supporting safe extensions          */
       /* as defined in PLCopen - Technical Committee 5      */
       /* Safety Software Technical Specification,           */
       /* Part 1: Concepts and Function Blocks,              */
-      /* Version 1.0 – Official Release                     */
+      /* Version 1.0 is Official Release                    */
       /******************************************************/
   printf("  s : allow use of safe extensions\n");
+  printf("  c : create conversion functions\n");
   printf("\n");
   printf("%s - Copyright (C) 2003-2011 \n"
          "This program comes with ABSOLUTELY NO WARRANTY!\n"
@@ -137,29 +136,34 @@
   stage1_2_options_t stage1_2_options = {false, false, NULL};
   int optres, errflg = 0;
   int path_len;
-/*
-  extern char *optarg;
-  extern int optind, optopt;
-*/
+
 
   /******************************************/
   /*   Parse command line options...        */
   /******************************************/
-  while ((optres = getopt(argc, argv, ":hvfsI:T:")) != -1) {
+  while ((optres = getopt(argc, argv, ":hvfscI:T:")) != -1) {
     switch(optres) {
     case 'h':
       printusage(argv[0]);
       return 0;
+
     case 'v':
       fprintf(stdout, "%s version %s\n"
 		      "changeset id: %s\n", PACKAGE_NAME, PACKAGE_VERSION, HGVERSION);      
-      return 0;        
+      return 0;
+
     case 'f':
       stage1_2_options.full_token_loc = true;
       break;
+
     case 's':
       stage1_2_options.safe_extensions = true;
       break;
+
+    case 'c':
+      stage1_2_options.conversion_functions = true;
+      break;
+
     case 'I':
       /* NOTE: To improve the usability under windows:
        *       We delete last char's path if it ends with "\".
@@ -170,20 +174,24 @@
       if (optarg[path_len] == '\\') optarg[path_len]= '\0';
       stage1_2_options.includedir = optarg;
       break;
+
     case 'T':
       /* NOTE: see note above */
       path_len = strlen(optarg) - 1;
       if (optarg[path_len] == '\\') optarg[path_len]= '\0';
       builddir = optarg;
       break;
+
     case ':':       /* -I or -T without operand */
       fprintf(stderr, "Option -%c requires an operand\n", optopt);
       errflg++;
       break;
+
     case '?':
       fprintf(stderr, "Unrecognized option: -%c\n", optopt);
       errflg++;
       break;
+
     default:
       fprintf(stderr, "Unknown error while parsing command line options.");
       errflg++;
@@ -202,9 +210,8 @@
   }
 
   if (errflg) {
-      printf("\n");
-      printusage(argv[0]);
-      return EXIT_FAILURE;
+    printusage(argv[0]);
+    return EXIT_FAILURE;
   }
 
 
@@ -225,7 +232,6 @@
   if (stage3(tree_root) < 0)
     return EXIT_FAILURE;
   
-
   /* 3rd Pass */
   if (stage4(tree_root, builddir) < 0)
     return EXIT_FAILURE;
--- a/stage1_2/Makefile.am	Thu Nov 22 19:19:48 2012 +0000
+++ b/stage1_2/Makefile.am	Thu Nov 22 19:26:56 2012 +0000
@@ -16,6 +16,7 @@
 libstage1_2_a_SOURCES = \
 	iec_flex.ll \
 	iec_bison.yy \
+    create_enumtype_conversion_functions.cc \
 	stage1_2.cc 
 
 libstage1_2_a_CPPFLAGS =  -DDEFAULT_LIBDIR='"lib"' -I../../absyntax
--- a/stage1_2/Makefile.in	Thu Nov 22 19:19:48 2012 +0000
+++ b/stage1_2/Makefile.in	Thu Nov 22 19:26:56 2012 +0000
@@ -78,6 +78,7 @@
 libstage1_2_a_LIBADD =
 am_libstage1_2_a_OBJECTS = libstage1_2_a-iec_flex.$(OBJEXT) \
 	libstage1_2_a-iec_bison.$(OBJEXT) \
+	libstage1_2_a-create_enumtype_conversion_functions.$(OBJEXT) \
 	libstage1_2_a-stage1_2.$(OBJEXT)
 libstage1_2_a_OBJECTS = $(am_libstage1_2_a_OBJECTS)
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config
@@ -214,6 +215,7 @@
 libstage1_2_a_SOURCES = \
 	iec_flex.ll \
 	iec_bison.yy \
+    create_enumtype_conversion_functions.cc \
 	stage1_2.cc 
 
 libstage1_2_a_CPPFLAGS = -DDEFAULT_LIBDIR='"lib"' -I../../absyntax
@@ -297,6 +299,7 @@
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstage1_2_a-create_enumtype_conversion_functions.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstage1_2_a-iec_bison.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstage1_2_a-iec_flex.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstage1_2_a-stage1_2.Po@am__quote@
@@ -343,6 +346,20 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstage1_2_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libstage1_2_a-iec_bison.obj `if test -f 'iec_bison.cc'; then $(CYGPATH_W) 'iec_bison.cc'; else $(CYGPATH_W) '$(srcdir)/iec_bison.cc'; fi`
 
+libstage1_2_a-create_enumtype_conversion_functions.o: create_enumtype_conversion_functions.cc
+@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstage1_2_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libstage1_2_a-create_enumtype_conversion_functions.o -MD -MP -MF $(DEPDIR)/libstage1_2_a-create_enumtype_conversion_functions.Tpo -c -o libstage1_2_a-create_enumtype_conversion_functions.o `test -f 'create_enumtype_conversion_functions.cc' || echo '$(srcdir)/'`create_enumtype_conversion_functions.cc
+@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libstage1_2_a-create_enumtype_conversion_functions.Tpo $(DEPDIR)/libstage1_2_a-create_enumtype_conversion_functions.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='create_enumtype_conversion_functions.cc' object='libstage1_2_a-create_enumtype_conversion_functions.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstage1_2_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libstage1_2_a-create_enumtype_conversion_functions.o `test -f 'create_enumtype_conversion_functions.cc' || echo '$(srcdir)/'`create_enumtype_conversion_functions.cc
+
+libstage1_2_a-create_enumtype_conversion_functions.obj: create_enumtype_conversion_functions.cc
+@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstage1_2_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libstage1_2_a-create_enumtype_conversion_functions.obj -MD -MP -MF $(DEPDIR)/libstage1_2_a-create_enumtype_conversion_functions.Tpo -c -o libstage1_2_a-create_enumtype_conversion_functions.obj `if test -f 'create_enumtype_conversion_functions.cc'; then $(CYGPATH_W) 'create_enumtype_conversion_functions.cc'; else $(CYGPATH_W) '$(srcdir)/create_enumtype_conversion_functions.cc'; fi`
+@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libstage1_2_a-create_enumtype_conversion_functions.Tpo $(DEPDIR)/libstage1_2_a-create_enumtype_conversion_functions.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='create_enumtype_conversion_functions.cc' object='libstage1_2_a-create_enumtype_conversion_functions.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstage1_2_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libstage1_2_a-create_enumtype_conversion_functions.obj `if test -f 'create_enumtype_conversion_functions.cc'; then $(CYGPATH_W) 'create_enumtype_conversion_functions.cc'; else $(CYGPATH_W) '$(srcdir)/create_enumtype_conversion_functions.cc'; fi`
+
 libstage1_2_a-stage1_2.o: stage1_2.cc
 @am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstage1_2_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libstage1_2_a-stage1_2.o -MD -MP -MF $(DEPDIR)/libstage1_2_a-stage1_2.Tpo -c -o libstage1_2_a-stage1_2.o `test -f 'stage1_2.cc' || echo '$(srcdir)/'`stage1_2.cc
 @am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libstage1_2_a-stage1_2.Tpo $(DEPDIR)/libstage1_2_a-stage1_2.Po
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stage1_2/create_enumtype_conversion_functions.cc	Thu Nov 22 19:26:56 2012 +0000
@@ -0,0 +1,313 @@
+/*
+ *  matiec - a compiler for the programming languages defined in IEC 61131-3
+ *
+ *  Copyright (C) 2009-2012  Mario de Sousa (msousa@fe.up.pt)
+ *  Copyright (C) 2012       Manuele Conti  (conti.ma@alice.it)
+ *
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+/*
+ * An IEC 61131-3 compiler.
+ *
+ * Based on the
+ * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
+ *
+ */
+
+#include <sstream>
+#include "create_enumtype_conversion_functions.hh"
+
+/* set to 1 to see debug info during execution */
+static const int debug = 0;
+
+/*
+ * functionDataType array contains all supported data type conversion.
+ */
+const char *create_enumtype_conversion_functions_c::functionDataType[] = {
+		"STRING",
+		"SINT"  ,
+		"INT"   ,
+		"DINT"  ,
+		"LINT"  ,
+		"USINT" ,
+		"UNIT"  ,
+		"UDINT" ,
+		"ULINT" ,
+		NULL
+};
+
+create_enumtype_conversion_functions_c::create_enumtype_conversion_functions_c(symbol_c *ignore) {
+
+}
+
+create_enumtype_conversion_functions_c::~create_enumtype_conversion_functions_c(void) {
+
+}
+
+std::string &create_enumtype_conversion_functions_c::get_declaration(symbol_c *root) {
+    text = "";
+    if (NULL != root) {
+        root->accept(*this);
+    }
+
+    return text;
+}
+
+void *create_enumtype_conversion_functions_c::visit(identifier_c *symbol) {
+    currentToken = symbol->value;
+
+    return NULL;
+}
+
+/**********************/
+/* B 1.3 - Data types */
+/**********************/
+/********************************/
+/* B 1.3.3 - Derived data types */
+/********************************/
+void *create_enumtype_conversion_functions_c::visit(enumerated_type_declaration_c *symbol) {
+    std::string enumerateName;
+    std::string functionName;
+    std::list <std::string> enumerateValues;
+
+    symbol->enumerated_type_name->accept(*this);
+    enumerateName = currentToken;
+
+    symbol->enumerated_spec_init->accept(*this);
+    enumerateValues = currentTokenList;
+
+    printStringToEnum  (enumerateName, enumerateValues);
+    printEnumToString  (enumerateName, enumerateValues);
+    for (size_t s = 8; s <= 64; s*= 2) {
+        printIntegerToEnum (enumerateName, enumerateValues, true , s);
+        printEnumToInteger (enumerateName, enumerateValues, true , s);
+        printIntegerToEnum (enumerateName, enumerateValues, false, s);
+        printEnumToInteger (enumerateName, enumerateValues, false, s);
+    }
+    if (debug) std::cout << text << std::endl;
+    
+    return NULL;
+}
+
+void *create_enumtype_conversion_functions_c::visit(enumerated_value_list_c *symbol) {
+    list_c *list;
+
+    currentTokenList.clear();
+    list = (list_c *)symbol;
+    for (int i = 0; i < list->n; i++) {
+        list->elements[i]->accept(*this);
+        currentTokenList.push_back(currentToken);
+    }
+
+    return NULL;
+}
+
+/*
+ * getIntegerName function generate a integer data name from signed and size.
+ */
+std::string create_enumtype_conversion_functions_c::getIntegerName(bool isSigned, size_t size) {
+    std::string integerType = "";
+    if (! isSigned) {
+        integerType = "U";
+    }
+    switch(size) {
+    case 8 : integerType += "S"; break;
+    case 16:                     break;
+    case 32: integerType += "D"; break;
+    case 64: integerType += "L"; break;
+    default:                     break;
+    }
+    integerType +="INT";
+
+    return integerType;
+}
+
+/*
+ * printStringToEnum function print conversion function from STRING to <ENUM>:
+ * ST Output:
+ *
+
+ FUNCTION STRING_TO_<ENUM> : <ENUM>
+  VAR_INPUT
+  IN: STRING;
+  END_VAR
+  IF IN = '<ENUM.VALUE_1>' THEN
+   STRING_TO_<ENUM> := <ENUM.VALUE_1>;
+   RETURN;
+  END_IF;
+  ...
+  IF IN = '<ENUM.VALU_N>' THEN
+   STRING_TO_<ENUM> := <ENUM.VALUE_N>;
+   RETURN;
+  END_IF;
+  END_FUNCTION
+
+  Note: if you change code below remember to update this comment.
+ */
+void create_enumtype_conversion_functions_c::printStringToEnum  (std::string &enumerateName, std::list<std::string> &enumerateValues) {
+    std::list <std::string>::const_iterator itr;
+    std::string functionName;
+
+    functionName = "STRING_TO_" + enumerateName;
+    text += "FUNCTION " + functionName + " : " + enumerateName;
+    text += "\nVAR_INPUT\nIN : STRING;\nEND_VAR\n";
+    for (itr = enumerateValues.begin(); itr != enumerateValues.end(); ++itr) {
+       std::string value = *itr;
+       text += "IF IN = '" + value + "' THEN\n";
+       text += " " + functionName + " := " + value + ";\n";
+       text += " RETURN;\n";
+       text += "END_IF;\n";
+    }
+    text += "END_FUNCTION\n\n";
+}
+
+/*
+ * printEnumToString function print conversion function from <ENUM> to STRING:
+ * ST Output:
+ *
+
+ FUNCTION <ENUM>_TO_STRING : STRING
+  VAR_INPUT
+  IN: <ENUM>;
+  END_VAR
+  IF IN = <ENUM.VALUE_1> THEN
+   <ENUM>_TO_STRING := '<ENUM.VALUE_1>';
+   RETURN;
+  END_IF;
+  ...
+  IF IN = <ENUM.VALUE_N> THEN
+   <ENUM>_TO_STRING := '<ENUM.VALUE_N>';
+   RETURN;
+  END_IF;
+  END_FUNCTION
+
+  Note: if you change code below remember to update this comment.
+ */
+void create_enumtype_conversion_functions_c::printEnumToString  (std::string &enumerateName, std::list<std::string> &enumerateValues) {
+    std::list <std::string>::const_iterator itr;
+    std::string functionName;
+
+    functionName = enumerateName + "_TO_STRING";
+    text += "FUNCTION " + functionName + " : STRING";
+    text += "\nVAR_INPUT\nIN : " + enumerateName + ";\nEND_VAR\n";
+    for (itr = enumerateValues.begin(); itr != enumerateValues.end(); ++itr) {
+        std::string value = *itr;
+        text += "IF IN = " + value + " THEN\n";
+        text += " " + functionName + " := '" + value + "';\n";
+        text += " RETURN;\n";
+        text += "END_IF;\n";
+    }
+    text += "END_FUNCTION\n\n";
+}
+
+/*
+ * printIntegerToEnum function print conversion function from <INTEGER> to <ENUM>:
+ * ST Output:
+ *
+
+ FUNCTION <INTEGER>_TO_<ENUM> : <ENUM>
+  VAR_INPUT
+  IN: <INTEGER>;
+  END_VAR
+  IF IN = 1 THEN
+   <INTEGER>_TO_<ENUM> := <ENUM.VALUE_1>;
+   RETURN;
+  END_IF;
+  ...
+  IF IN = N THEN
+   <INTEGER>_TO_<ENUM> := <ENUM.VALUE_N>;
+   RETURN;
+  END_IF;
+  END_FUNCTION
+
+  Note: if you change code below remember to update this comment.
+ */
+void create_enumtype_conversion_functions_c::printIntegerToEnum (std::string &enumerateName, std::list<std::string> &enumerateValues, bool isSigned, size_t size) {
+    std::list <std::string>::const_iterator itr;
+    std::string functionName;
+    std::string integerType;
+    int count;
+
+    integerType  = getIntegerName(isSigned, size);
+    functionName = integerType + "_TO_" + enumerateName;
+    text += "FUNCTION " + functionName + " : " + enumerateName;
+    text += "\nVAR_INPUT\nIN : " + integerType + ";\nEND_VAR\n";
+    count = 0;
+    for (itr = enumerateValues.begin(); itr != enumerateValues.end(); ++itr) {
+        std::string value = *itr;
+        std::stringstream out;
+        out << count;
+        text += "IF IN = " + out.str() + " THEN\n";
+        text += " " + functionName + " := " + value + ";\n";
+        text += " RETURN;\n";
+        text += "END_IF;\n";
+        count++;
+    }
+    text += "END_FUNCTION\n\n";
+}
+
+/*
+ * printEnumToInteger function print conversion function from <ENUM> to <INTEGER>:
+ * ST Output:
+ *
+
+ FUNCTION <ENUM>_TO_<INTEGER> : <INTEGER>
+  VAR_INPUT
+  IN: <INTEGER>;
+  END_VAR
+  IF IN = <ENUM.VALUE_1> THEN
+   <ENUM>_TO_<INTEGER> := 1;
+   RETURN;
+  END_IF;
+  ...
+  IF IN = <ENUM.VALUE_N> THEN
+   <ENUM>_TO_<INTEGER> := N;
+   RETURN;
+  END_IF;
+  END_FUNCTION
+
+  Note: if you change code below remember to update this comment.
+ */
+void create_enumtype_conversion_functions_c::printEnumToInteger (std::string &enumerateName, std::list<std::string> &enumerateValues, bool isSigned, size_t size) {
+    std::list <std::string>::const_iterator itr;
+    std::string functionName;
+    std::string integerType;
+    int count;
+
+    integerType  = getIntegerName(isSigned, size);
+    functionName = enumerateName + "_TO_" + integerType;
+    text += "FUNCTION " + functionName + " : " + integerType;
+    text += "\nVAR_INPUT\nIN : " + enumerateName + ";\nEND_VAR\n";
+    count = 0;
+    for (itr = enumerateValues.begin(); itr != enumerateValues.end(); ++itr) {
+        std::string value = *itr;
+        std::stringstream out;
+        out << count;
+        text += "IF IN = " + value + " THEN\n";
+        text += " " + functionName + " := " + out.str() + ";\n";
+        text += " RETURN;\n";
+        text += "END_IF;\n";
+        count++;
+    }
+    text += "END_FUNCTION\n\n";
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stage1_2/create_enumtype_conversion_functions.hh	Thu Nov 22 19:26:56 2012 +0000
@@ -0,0 +1,78 @@
+/*
+ *  matiec - a compiler for the programming languages defined in IEC 61131-3
+ *
+ *  Copyright (C) 2009-2012  Mario de Sousa (msousa@fe.up.pt)
+ *  Copyright (C) 2012       Manuele Conti  (conti.ma@alice.it)
+ *
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+/*
+ * An IEC 61131-3 compiler.
+ *
+ * Based on the
+ * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
+ *
+ */
+
+/*
+ * create_enumtype_conversion_functions_c generates ST conversion functions source code for
+ * enumerate user defined data types.
+ *
+ */
+
+#ifndef _CREATE_ENUMTYPE_CONVERSION_FUNCTIONS_HH
+#define _CREATE_ENUMTYPE_CONVERSION_FUNCTIONS_HH
+
+#include <string>
+#include <list>
+
+#include "../absyntax_utils/absyntax_utils.hh"
+
+
+class create_enumtype_conversion_functions_c: public iterator_visitor_c {
+  public:
+    explicit create_enumtype_conversion_functions_c(symbol_c *ignore);
+    virtual ~create_enumtype_conversion_functions_c(void);
+    std::string &get_declaration(symbol_c *root);
+
+    const static char *functionDataType [];
+
+    void *visit(identifier_c *symbol);
+    /**********************/
+    /* B 1.3 - Data types */
+    /**********************/
+    /********************************/
+    /* B 1.3.3 - Derived data types */
+    /********************************/
+    void *visit(enumerated_type_declaration_c *symbol);
+    void *visit(enumerated_value_list_c *symbol);
+
+  private:
+    std::string text;
+    std::string currentToken;
+    std::list <std::string> currentTokenList;
+    std::string getIntegerName(bool isSigned, size_t size);
+    void printStringToEnum  (std::string &enumerateName, std::list <std::string> &enumerateValues);
+    void printEnumToString  (std::string &enumerateName, std::list <std::string> &enumerateValues);
+    void printIntegerToEnum (std::string &enumerateName, std::list <std::string> &enumerateValues, bool isSigned, size_t size);
+    void printEnumToInteger (std::string &enumerateName, std::list <std::string> &enumerateValues, bool isSigned, size_t size);
+};
+
+#endif /* _CREATE_ENUMTYPE_CONVERSION_FUNCTIONS_HH */
--- a/stage1_2/iec_bison.yy	Thu Nov 22 19:19:48 2012 +0000
+++ b/stage1_2/iec_bison.yy	Thu Nov 22 19:26:56 2012 +0000
@@ -100,7 +100,7 @@
 
 /* The interface through which bison and flex interact. */
 #include "stage1_2_priv.hh"
-
+#include "create_enumtype_conversion_functions.hh"
 
 #include "../absyntax_utils/add_en_eno_param_decl.hh"	/* required for  add_en_eno_param_decl_c */
 
@@ -203,6 +203,11 @@
  */
 extern bool full_token_loc;
 
+/* A global flag used to tell the parser whether to generate conversion function
+ * for enumerated data types.
+ */
+extern bool conversion_functions_;
+
 /* A pointer to the root of the parsing tree that will be generated 
  * by bison.
  */
@@ -233,6 +238,9 @@
                    const char *last_filename,
                    long int last_order,
                    const char *additional_error_msg);
+                   
+/* Create entry in symbol table for function conversion data type*/
+void add_enumtype_conversion_functions(const char * dname);
 %}
 
 
@@ -2704,7 +2712,13 @@
  *       and include the library_element_symtable.insert(...) code in the rule actions!
  */
   identifier ':' enumerated_specification {library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);}
-	{$$ = new enumerated_type_declaration_c($1, new enumerated_spec_init_c($3, NULL, locloc(@3)), locloc(@$));}
+	{
+      $$ = new enumerated_type_declaration_c($1, new enumerated_spec_init_c($3, NULL, locloc(@3)), locloc(@$));
+      if (conversion_functions_) {
+        const char *name = ((identifier_c *)$1)->value;
+	    add_enumtype_conversion_functions(name);
+	  }
+    }
 | identifier ':' enumerated_specification {library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);} ASSIGN enumerated_value
 	{$$ = new enumerated_type_declaration_c($1, new enumerated_spec_init_c($3, $6, locf(@3), locl(@6)), locloc(@$));}
 /* ERROR_CHECK_BEGIN */
@@ -8340,5 +8354,84 @@
   return 0;
 }
 
-
-
+/* Create a tmp file from a char buffer. */
+FILE *ftmpopen (void *buf, size_t size, const char *opentype)
+{
+  FILE *f;
+  f = tmpfile();
+  fwrite(buf, 1, size, f);
+  rewind(f);
+  return f;
+}
+
+/*  sstage2__ function allow to parse a ST code inside a string.
+ *  We use this function to add into AST auto generated code like enum conversion functions.
+ *  This appoach allow us to write future changes code indipendetly and to check generate code
+ *  during developing.
+ */
+int sstage2__(const char *text, 
+              symbol_c **tree_root_ref,
+              bool full_token_loc_        /* error messages specify full token location */
+             ) {
+
+  FILE *in_file = NULL;
+    
+  if((in_file = ftmpopen((void *)text, strlen(text), "r")) == NULL) {
+    perror("Error creating temp file.");
+    return -1;
+  }
+
+  /* now parse the input file... */
+  #if YYDEBUG
+    yydebug = 1;
+  #endif
+  yyin = in_file;
+  
+  /* We turn on "allow_function_overloading" flag to disable some checks. 
+   * In detail when we add to symboltable a symbol already processed we
+   * don't want to get any error. 
+   */  
+   
+  allow_function_overloading = true;
+  allow_extensible_function_parameters = false;
+  full_token_loc = full_token_loc_;
+  current_filename = "built-in";
+  current_tracking = GetNewTracking(yyin);
+  {int res;
+    if ((res = yyparse()) != 0) {
+      fprintf (stderr, "\nParsing failed because of too many consecutive syntax errors. Bailing out!\n");
+        exit(EXIT_FAILURE);
+    }
+  }
+
+  if (yynerrs > 0) {
+    fprintf (stderr, "\n%d error(s) found. Bailing out!\n", yynerrs /* global variable */);
+    exit(EXIT_FAILURE);
+  }
+  
+  if (tree_root_ref != NULL)
+    *tree_root_ref = tree_root;
+
+  fclose(in_file);
+  return 0;
+}
+
+
+/* Create entry in symbol table for function conversion data type*/
+void add_enumtype_conversion_functions(const char * dname) {
+  std::string strname;
+  std::string tmp;
+  
+  strname = dname; 
+  for (int i = 0; create_enumtype_conversion_functions_c::functionDataType[i] != NULL; i++) {
+    tmp = strname + std::string("_TO_") + create_enumtype_conversion_functions_c::functionDataType[i];
+    library_element_symtable.insert(tmp.c_str(), prev_declared_derived_function_name_token);
+    
+    tmp = create_enumtype_conversion_functions_c::functionDataType[i] + std::string("_TO_") + strname;
+    library_element_symtable.insert(tmp.c_str(), prev_declared_derived_function_name_token);
+  }  
+}
+
+
+
+
--- a/stage1_2/stage1_2.cc	Thu Nov 22 19:19:48 2012 +0000
+++ b/stage1_2/stage1_2.cc	Thu Nov 22 19:26:56 2012 +0000
@@ -46,7 +46,7 @@
 #include "stage1_2.hh"
 #include "iec_bison.h"
 #include "stage1_2_priv.hh"
-
+#include "create_enumtype_conversion_functions.hh"
 
 
 
@@ -66,15 +66,22 @@
 
 
 /******************************************************/
-/* whether we are suporting safe extensions           */
+/* whether we are supporting safe extensions          */
 /* as defined in PLCopen - Technical Committee 5      */
 /* Safety Software Technical Specification,           */
 /* Part 1: Concepts and Function Blocks,              */
-/* Version 1.0 – Official Release                     */
+/* Version 1.0 – Official Release                   */
 /******************************************************/
 bool safe_extensions_ = false;
 bool get_opt_safe_extensions() {return safe_extensions_;}
 
+/******************************************************/
+/* whether we are supporting conversion functions     */
+/* for enumerate data types                           */
+/******************************************************/
+bool conversion_functions_ = false;
+
+
 /****************************************************/
 /* Controlling the entry to the body_state in flex. */
 /****************************************************/
@@ -285,6 +292,11 @@
              bool full_token_loc         /* error messages specify full token location */
             );
 
+int sstage2__(const char *text,
+              symbol_c **tree_root_ref,
+              bool full_token_loc         /* error messages specify full token location */
+             );
+
 
 int stage1_2(const char *filename, symbol_c **tree_root_ref, stage1_2_options_t options) {
       /* NOTE: we only call stage2 (bison - syntax analysis) directly, as stage 2 will itself call stage1 (flex - lexical analysis)
@@ -297,8 +309,16 @@
        *       These callback functions will get their data from local (to this file) global variables...
        *       We now set those variables...
        */
+
   safe_extensions_ = options.safe_extensions;
-  
-  return stage2__(filename, options.includedir, tree_root_ref, options.full_token_loc);
-}
-
+  conversion_functions_ = options.conversion_functions;
+  int ret = stage2__(filename, options.includedir, tree_root_ref, options.full_token_loc);
+
+  if (conversion_functions_) {
+	  create_enumtype_conversion_functions_c create_enumtype_conversion_functions_c(*tree_root_ref);
+	  std::string source_code = create_enumtype_conversion_functions_c.get_declaration(*tree_root_ref);
+	  ret = sstage2__(source_code.c_str(), tree_root_ref, false);
+  }
+  return ret;
+}
+
--- a/stage1_2/stage1_2.hh	Thu Nov 22 19:19:48 2012 +0000
+++ b/stage1_2/stage1_2.hh	Thu Nov 22 19:26:56 2012 +0000
@@ -60,6 +60,8 @@
 		/* error messages specify full token location */
 	bool full_token_loc; 
 		/* Include directory, where included files will be searched for... */
+	bool conversion_functions;
+		/* Create a conversion function for derived datatype */
 	const char *includedir;
 } stage1_2_options_t;
 
--- a/stage3/stage3.hh	Thu Nov 22 19:19:48 2012 +0000
+++ b/stage3/stage3.hh	Thu Nov 22 19:26:56 2012 +0000
@@ -30,9 +30,12 @@
  *
  */
 
+#ifndef _STAGE3_HH
+#define _STAGE3_HH
 
 #include "../util/symtable.hh"
 
 
 int stage3(symbol_c *tree_root);
 
+#endif /* _STAGE3_HH */
--- a/stage4/stage4.hh	Thu Nov 22 19:19:48 2012 +0000
+++ b/stage4/stage4.hh	Thu Nov 22 19:26:56 2012 +0000
@@ -36,6 +36,8 @@
  * by each specific version of the 4th stage.
  */
 
+#ifndef _STAGE4_HH
+#define _STAGE4_HH
 
 #include "../absyntax/absyntax.hh"
 
@@ -100,6 +102,6 @@
 
 
 
+int stage4(symbol_c *tree_root, const char *builddir);
 
-
-int stage4(symbol_c *tree_root);
+#endif /* _STAGE4_HH */