diff --git a/THANKS b/THANKS
index bbbcda6..eda9bba 100644
--- a/THANKS
+++ b/THANKS
@@ -2,4 +2,7 @@ gengen THANKS file
 
 Andrew SG Rojek
 Dinesh Shanbhag
-Bob White
\ No newline at end of file
+Bob White
+Nitharsan Rony (For his support
+and encouragement towards GNU Gengen's Lua)
+
diff --git a/src/Makefile.am b/src/Makefile.am
index c830b07..f00fcbe 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -26,7 +26,9 @@ libgengen_a_SOURCES = parser.cc scanner.cc yyerror.cc \
 				skelitems_dbtab.cc skelitems.cpp stringutil.cpp 		skelstruct_c_common.cpp withtokeninfo.h \
 				errormanager.cpp skelfactory.cpp expressionwithop.cpp 	unaryexpression.cpp \
 				binaryexpression.cpp expressionvisitor.cpp expressionvisitor_dbtab.cc \
-				expressiongenerator_c.cpp expressionchecker.cpp expressiongenerator_cpp.cpp typeenv.cpp utils.cpp
+				expressiongenerator_c.cpp expressionchecker.cpp expressiongenerator_cpp.cpp typeenv.cpp utils.cpp \
+				skelstruct_lua.h skelstruct_lua.cpp skelfactory_lua.h skelfactory_lua.cpp skelstruct_strcnt_lua.h \
+				skelstruct_strcnt_lua.cpp skelstruct_luastring.cpp skelstruct_lua_common.cpp expressiongenerator_lua.cpp
 
 gengen_SOURCES = cmdline.c gengen.cc 
 
@@ -74,7 +76,7 @@ noinst_HEADERS = skelstruct_cstring.h ifstruct.h expression.h skelitems.h \
 							stringutil.h skelstruct_c_common.h errormanager.h streamstruct.h expressiontype.h \
 							expressionwithop.h unaryexpression.h binaryexpression.h expressionvisitor.h \
 						expressiongenerator_c.h asserttest.h expressionoperators.h expressionchecker.h \
-			expressiongenerator_cpp.h typeenv.h utils.h
+			expressiongenerator_cpp.h typeenv.h utils.h skelstruct_luastring.h skelstruct_lua_common.h expressiongenerator_lua.h
 
 # clean files generated by doublecpp
 clean-doublecpp:
diff --git a/src/cmdline.c b/src/cmdline.c
index 45bec91..4fe9796 100644
--- a/src/cmdline.c
+++ b/src/cmdline.c
@@ -37,7 +37,7 @@ const char *gengetopt_args_info_help[] = {
   "  -i, --input=file          input file (default std input)",
   "  -F, --file-name=name      name used for generating file (default stdout)",
   "  -f, --gen-name=STRING     prefix for generated code  (default=`gengen')",
-  "      --output-format=lang  target language (cpp, c)  (default=`cpp')",
+  "      --output-format=lang  target language (cpp, c, lua) (default=`cpp')",
   "      --output-dir=STRING   output directory (default current dir)",
   "      --separate-files      output to separate files (header, source). require \n                              --file-name",
   "      --expand-tabs         strings containing newlines are indented according \n                              to the current indentation level",
diff --git a/src/expressiongenerator_lua.cpp b/src/expressiongenerator_lua.cpp
new file mode 100644
index 0000000..7165432
--- /dev/null
+++ b/src/expressiongenerator_lua.cpp
@@ -0,0 +1,57 @@
+//
+// C++ Implementation: expressiongenerator_lua
+//
+// Description: output Lua interpretation of expressions
+//
+//
+// Author: Raman Gopalan <ramangopalan@gmail.com>
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "expressiongenerator_lua.h"
+#include "unaryexpression.h"
+#include "binaryexpression.h"
+#include "expressionoperators.h"
+
+#include <assert.h>
+
+ExpressionGeneratorLua::ExpressionGeneratorLua(std::ostream &o)
+  : out(&o)
+{
+  operatorMap[ANDOP] = "and";
+  operatorMap[OROP] = "or";
+  operatorMap[NOTOP] = "not";
+  operatorMap[LESSOP] = "<";
+  operatorMap[GREATEROP] = ">";
+  operatorMap[EQUALOP] = "==";
+  operatorMap[NEQUALOP] = "~=";
+  operatorMap[LESSEOP] = "<=";
+  operatorMap[GREATEREOP] = "=>";
+}
+
+
+void ExpressionGeneratorLua::visit(Expression *exp)
+{
+  *out << (exp->isConst() ? "" : prefix) << exp->getText();
+}
+
+void ExpressionGeneratorLua::visit(UnaryExpression *exp)
+{
+  assert(operatorMap.find(exp->getOperator()) != operatorMap.end());
+  
+  *out << "( " << operatorMap[exp->getOperator()] << " ";
+  ExpressionVisitor::visit(exp);
+  *out << " )";
+}
+
+void ExpressionGeneratorLua::visit(BinaryExpression *exp)
+{
+  assert(operatorMap.find(exp->getOperator()) != operatorMap.end());
+  
+  *out << "( ";
+  visit_DB(exp->getLeftExpression());
+  *out << " " << operatorMap[exp->getOperator()] << " ";
+  visit_DB(exp->getRightExpression());
+  *out << " )";
+}
diff --git a/src/expressiongenerator_lua.h b/src/expressiongenerator_lua.h
new file mode 100644
index 0000000..dda8921
--- /dev/null
+++ b/src/expressiongenerator_lua.h
@@ -0,0 +1,43 @@
+//
+// C++ Interface: expressiongenerator_lua
+//
+// Description: 
+//
+//
+// Author: Raman Gopalan <ramangopalan@gmail.com>
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef EXPRESSIONGENERATOR_LUA_H
+#define EXPRESSIONGENERATOR_LUA_H
+
+#include "expressionvisitor.hpp"
+
+#include <iostream>
+#include <map>
+#include <string>
+
+class ExpressionGeneratorLua : public ExpressionVisitor
+{
+  protected:
+    std::ostream *out;
+    typedef std::map<std::string, std::string> OperatorMap;
+    /// translation table for operators
+    OperatorMap operatorMap;
+    /// the prefix for non const base expressions, i.e., variables
+    std::string prefix;
+    
+  public:
+    ExpressionGeneratorLua(std::ostream &o);
+
+    void setStream(std::ostream &o) { out = &o; }
+    
+    virtual void visit(Expression *exp);
+    virtual void visit(UnaryExpression *exp);
+    virtual void visit(BinaryExpression *exp);
+    
+    void setPrefix(const std::string &p) { prefix = p; }
+};
+
+#endif
diff --git a/src/gengen.cc b/src/gengen.cc
index 9d9613d..3ec6f3d 100644
--- a/src/gengen.cc
+++ b/src/gengen.cc
@@ -28,6 +28,7 @@
 #include "skelstruct.hpp"
 #include "skelfactory_cpp.h"
 #include "skelfactory_c.h"
+#include "skelfactory_lua.h"
 #include "mainskelstruct.h"
 #include "mainskelfactory.h"
 #include "cmdline.h"
@@ -119,6 +120,11 @@ main(int argc, char **argv)
       skel_factory = new SkelFactoryC;
       source_ext = "c";
     }
+  else if (strcmp (args_info.output_format_arg, "lua") == 0)
+    {
+      skel_factory = new SkelFactoryLua;
+      source_ext = "lua";
+    }
   else
     {
       string serr = "target language ";
diff --git a/src/skelfactory_lua.cpp b/src/skelfactory_lua.cpp
new file mode 100644
index 0000000..fd6088d
--- /dev/null
+++ b/src/skelfactory_lua.cpp
@@ -0,0 +1,24 @@
+//
+//
+// C++ Implementation: skelfactory_lua
+//
+// Description:
+//
+//
+// Author: Raman Gopalan <ramangopalan@gmail.com>
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "skelfactory_lua.h"
+#include "skelstruct_lua.h"
+
+SkelStruct *
+SkelFactoryLua::createSkelStruct (SkelItems *items,
+                                const string &name, const string &file_name,
+                                StreamStruct &s, bool sep_files)
+{
+  return new SkelStructLua (items, name, file_name, s, sep_files);
+}
+
diff --git a/src/skelfactory_lua.h b/src/skelfactory_lua.h
new file mode 100644
index 0000000..31ffd53
--- /dev/null
+++ b/src/skelfactory_lua.h
@@ -0,0 +1,37 @@
+/*
+ * Raman Gopalan <ramangopalan@gmail.com>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef SKELFACTORY_LUA_H
+#define SKELFACTORY_LUA_H
+
+// implementation of pattern "Abstract Factory"
+// this generates Lua code
+
+#include "skelfactory.h"
+
+class SkelFactoryLua : public SkelFactory
+{
+ public:
+  virtual SkelStruct *createSkelStruct (SkelItems *items,
+                                        const string &name,
+                                        const string &file_name, StreamStruct &,
+                                        bool sep_files);
+};
+
+#endif // SKELFACTORY_LUA_H
diff --git a/src/skels/callextfun_lua.h b/src/skels/callextfun_lua.h
new file mode 100644
index 0000000..66f5ea7
--- /dev/null
+++ b/src/skels/callextfun_lua.h
@@ -0,0 +1,67 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef CALLEXTFUN_LUA_GEN_CLASS_H
+#define CALLEXTFUN_LUA_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class callextfun_lua_gen_class
+{
+ protected:
+  string name;
+
+ public:
+  callextfun_lua_gen_class()
+  {
+  }
+  
+  callextfun_lua_gen_class(const string &_name) :
+    name (_name)
+  {
+  }
+
+  void set_name(const string &_name)
+  {
+    name = _name;
+  }
+
+  void generate_callextfun_lua(ostream &stream, unsigned int indent = 0)
+  {
+    string indent_str (indent, ' ');
+    indent = 0;
+  
+    stream << "\n";
+    stream << indent_str;
+    stream << "if(record.";
+    stream << name;
+    stream << ") then";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  generate_string(record.";
+    stream << name;
+    stream << ", stream, indent + string.len(indent_str))";
+    stream << "\n";
+    stream << indent_str;
+    stream << "else";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  generate_";
+    stream << name;
+    stream << "(stream, record, indent + string.len(indent_str))";
+    stream << "\n";
+    stream << indent_str;
+    stream << "end";
+    stream << "\n";
+    stream << indent_str;
+  }
+};
+
+#endif // CALLEXTFUN_LUA_GEN_CLASS_H
diff --git a/src/skels/callextfun_lua.h_skel b/src/skels/callextfun_lua.h_skel
new file mode 100644
index 0000000..f7c73ea
--- /dev/null
+++ b/src/skels/callextfun_lua.h_skel
@@ -0,0 +1,6 @@
+
+if(record.@name@) then
+  generate_string(record.@name@, stream, indent + string.len(indent_str))
+else
+  generate_@name@(stream, record, indent + string.len(indent_str))
+end
diff --git a/src/skels/extern_function_lua.h b/src/skels/extern_function_lua.h
new file mode 100644
index 0000000..02662e0
--- /dev/null
+++ b/src/skels/extern_function_lua.h
@@ -0,0 +1,69 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef EXTERN_FUNCTION_LUA_GEN_CLASS_H
+#define EXTERN_FUNCTION_LUA_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class extern_function_lua_gen_class
+{
+ protected:
+  string name;
+
+ public:
+  extern_function_lua_gen_class()
+  {
+  }
+  
+  extern_function_lua_gen_class(const string &_name) :
+    name (_name)
+  {
+  }
+
+  void set_name(const string &_name)
+  {
+    name = _name;
+  }
+
+  void generate_extern_function_lua(ostream &stream, unsigned int indent = 0)
+  {
+    string indent_str (indent, ' ');
+    indent = 0;
+  
+    stream << "\n";
+    stream << indent_str;
+    stream << "generate_";
+    stream << name;
+    stream << " = function(stream, record, indent)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "--[[";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    This call back function will be executed if 'var'";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    associated with type 'method' is 'nil'. You could";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    add your Lua code here.";
+    stream << "\n";
+    stream << indent_str;
+    stream << "--]]";
+    stream << "\n";
+    stream << indent_str;
+    stream << "end";
+    stream << "\n";
+    stream << indent_str;
+  }
+};
+
+#endif // EXTERN_FUNCTION_LUA_GEN_CLASS_H
diff --git a/src/skels/extern_function_lua.h_skel b/src/skels/extern_function_lua.h_skel
new file mode 100644
index 0000000..137acf3
--- /dev/null
+++ b/src/skels/extern_function_lua.h_skel
@@ -0,0 +1,8 @@
+
+generate_@name@ = function(stream, record, indent)
+--[[
+    This call back function will be executed if 'var'
+    associated with type 'method' is 'nil'. You could
+    add your Lua code here.
+--]]
+end
diff --git a/src/skels/genfunction_lua.h b/src/skels/genfunction_lua.h
new file mode 100644
index 0000000..35dfd71
--- /dev/null
+++ b/src/skels/genfunction_lua.h
@@ -0,0 +1,177 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef GENFUNCTION_LUA_GEN_CLASS_H
+#define GENFUNCTION_LUA_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class genfunction_lua_gen_class
+{
+ protected:
+  string assignfields;
+  string geninstructions;
+  string genname;
+  string genparameters;
+
+ public:
+  genfunction_lua_gen_class()
+  {
+  }
+  
+  genfunction_lua_gen_class(const string &_assignfields, const string &_geninstructions, const string &_genname, const string &_genparameters) :
+    assignfields (_assignfields), geninstructions (_geninstructions), genname (_genname), genparameters (_genparameters)
+  {
+  }
+
+  virtual ~genfunction_lua_gen_class()
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  virtual void generate_assignfields(ostream &stream, unsigned int indent) = 0;
+
+  void set_assignfields(const string &_assignfields)
+  {
+    assignfields = _assignfields;
+  }
+
+  virtual void generate_geninstructions(ostream &stream, unsigned int indent) = 0;
+
+  void set_geninstructions(const string &_geninstructions)
+  {
+    geninstructions = _geninstructions;
+  }
+
+  void set_genname(const string &_genname)
+  {
+    genname = _genname;
+  }
+
+  virtual void generate_genparameters(ostream &stream, unsigned int indent) = 0;
+
+  void set_genparameters(const string &_genparameters)
+  {
+    genparameters = _genparameters;
+  }
+
+  void generate_genfunction_lua(ostream &stream, unsigned int indent = 0)
+  {
+    string indent_str (indent, ' ');
+    indent = 0;
+  
+    stream << "function generate_";
+    stream << genname;
+    stream << "(stream, record, indent)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local id = {}";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local indent_str = \"\"";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  for i = 1, indent do";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    id[#id + 1] = ' '";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  indent_str = table.concat(id)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  -- save context";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local ctx = io.output()";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  io.output(stream)";
+    stream << "\n";
+    stream << indent_str;
+    indent = 2;
+    if (geninstructions.size () > 0)
+      generate_string (geninstructions, stream, indent + indent_str.length ());
+    else
+      generate_geninstructions (stream, indent + indent_str.length ());
+    indent = 0;
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    stream << "  -- restore context";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  io.output(ctx)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    stream << "function generatep_";
+    stream << genname;
+    stream << "(stream, indent";
+    if (genparameters.size () > 0)
+      generate_string (genparameters, stream, indent + indent_str.length ());
+    else
+      generate_genparameters (stream, indent + indent_str.length ());
+    stream << ")";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  record = {}";
+    stream << "\n";
+    stream << indent_str;
+    indent = 2;
+    stream << "  ";
+    if (assignfields.size () > 0)
+      generate_string (assignfields, stream, indent + indent_str.length ());
+    else
+      generate_assignfields (stream, indent + indent_str.length ());
+    indent = 0;
+    stream << "\n";
+    stream << indent_str;
+    stream << "  generate_";
+    stream << genname;
+    stream << "(stream, record, indent)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "end";
+    stream << "\n";
+    stream << indent_str;
+  }
+};
+
+#endif // GENFUNCTION_LUA_GEN_CLASS_H
diff --git a/src/skels/genfunction_lua.h_skel b/src/skels/genfunction_lua.h_skel
new file mode 100644
index 0000000..defd4d6
--- /dev/null
+++ b/src/skels/genfunction_lua.h_skel
@@ -0,0 +1,21 @@
+function generate_@genname@(stream, record, indent)
+  local id = {}
+  local indent_str = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+  @geninstructions:method{iteration=true}@
+
+  -- restore context
+  io.output(ctx)
+end
+
+function generatep_@genname@(stream, indent@genparameters:method@)
+  record = {}
+  @assignfields:method@
+  generate_@genname@(stream, record, indent)
+end
diff --git a/src/skels/genstrfunction_lua.h b/src/skels/genstrfunction_lua.h
new file mode 100644
index 0000000..cfd3de5
--- /dev/null
+++ b/src/skels/genstrfunction_lua.h
@@ -0,0 +1,168 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef GENSTRFUNCTION_LUA_GEN_CLASS_H
+#define GENSTRFUNCTION_LUA_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class genstrfunction_lua_gen_class
+{
+ protected:
+  string assignfields;
+  string genname;
+  string genparameters;
+  string strgeninstructions;
+
+ public:
+  genstrfunction_lua_gen_class()
+  {
+  }
+  
+  genstrfunction_lua_gen_class(const string &_assignfields, const string &_genname, const string &_genparameters, const string &_strgeninstructions) :
+    assignfields (_assignfields), genname (_genname), genparameters (_genparameters), strgeninstructions (_strgeninstructions)
+  {
+  }
+
+  virtual ~genstrfunction_lua_gen_class()
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  virtual void generate_assignfields(ostream &stream, unsigned int indent) = 0;
+
+  void set_assignfields(const string &_assignfields)
+  {
+    assignfields = _assignfields;
+  }
+
+  void set_genname(const string &_genname)
+  {
+    genname = _genname;
+  }
+
+  virtual void generate_genparameters(ostream &stream, unsigned int indent) = 0;
+
+  void set_genparameters(const string &_genparameters)
+  {
+    genparameters = _genparameters;
+  }
+
+  virtual void generate_strgeninstructions(ostream &stream, unsigned int indent) = 0;
+
+  void set_strgeninstructions(const string &_strgeninstructions)
+  {
+    strgeninstructions = _strgeninstructions;
+  }
+
+  void generate_genstrfunction_lua(ostream &stream, unsigned int indent = 0)
+  {
+    string indent_str (indent, ' ');
+    indent = 0;
+  
+    stream << "\n";
+    stream << indent_str;
+    stream << "function genstring_";
+    stream << genname;
+    stream << "(record, indent)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local id = {}";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local indent_str = \"\"";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local output = \"\"";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  for i = 1, indent do";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    id[#id + 1] = ' '";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  indent_str = table.concat(id)";
+    stream << "\n";
+    stream << indent_str;
+    indent = 2;
+    if (strgeninstructions.size () > 0)
+      generate_string (strgeninstructions, stream, indent + indent_str.length ());
+    else
+      generate_strgeninstructions (stream, indent + indent_str.length ());
+    indent = 0;
+    stream << indent_str;
+    stream << "  return output;";
+    stream << "\n";
+    stream << indent_str;
+    stream << "end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    stream << "function genstringp_";
+    stream << genname;
+    stream << "(indent";
+    if (genparameters.size () > 0)
+      generate_string (genparameters, stream, indent + indent_str.length ());
+    else
+      generate_genparameters (stream, indent + indent_str.length ());
+    stream << ")";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  record = {}";
+    stream << "\n";
+    stream << indent_str;
+    indent = 2;
+    stream << "  ";
+    if (assignfields.size () > 0)
+      generate_string (assignfields, stream, indent + indent_str.length ());
+    else
+      generate_assignfields (stream, indent + indent_str.length ());
+    indent = 0;
+    stream << "\n";
+    stream << indent_str;
+    stream << "  return genstring_";
+    stream << genname;
+    stream << " (record, indent);";
+    stream << "\n";
+    stream << indent_str;
+    stream << "end";
+    stream << "\n";
+    stream << indent_str;
+  }
+};
+
+#endif // GENSTRFUNCTION_LUA_GEN_CLASS_H
diff --git a/src/skels/genstrfunction_lua.h_skel b/src/skels/genstrfunction_lua.h_skel
new file mode 100644
index 0000000..f46b59f
--- /dev/null
+++ b/src/skels/genstrfunction_lua.h_skel
@@ -0,0 +1,18 @@
+
+function genstring_@genname@(record, indent)
+  local id = {}
+  local indent_str = ""
+  local output = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+  @strgeninstructions:method{iteration=true}@
+  return output;
+end
+
+function genstringp_@genname@(indent@genparameters:method@)
+  record = {}
+  @assignfields:method@
+  return genstring_@genname@ (record, indent);
+end
diff --git a/src/skels/genstringfun_lua.h b/src/skels/genstringfun_lua.h
new file mode 100644
index 0000000..710f701
--- /dev/null
+++ b/src/skels/genstringfun_lua.h
@@ -0,0 +1,223 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef GENSTRINGFUN_LUA_GEN_CLASS_H
+#define GENSTRINGFUN_LUA_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class genstringfun_lua_gen_class
+{
+ protected:
+
+ public:
+  genstringfun_lua_gen_class()
+  {
+  }
+  
+
+  void generate_genstringfun_lua(ostream &stream, unsigned int indent = 0)
+  {
+    string indent_str (indent, ' ');
+    indent = 0;
+  
+    stream << "\n";
+    stream << indent_str;
+    stream << "function strchr_tab(tab, char)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local store";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local ret_str = \"\"";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  for w, k in ipairs(tab) do";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    if(k == char) then";
+    stream << "\n";
+    stream << indent_str;
+    stream << "      store = w";
+    stream << "\n";
+    stream << indent_str;
+    stream << "      break";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  if(store == nil) then";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    return nil";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  for i = store, #tab do";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    ret_str = ret_str .. tab[i]";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  return store, ret_str";
+    stream << "\n";
+    stream << indent_str;
+    stream << "end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    stream << "function str_to_tab(str)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  tab = {}";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  for i in string.gmatch(str, \".\") do";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    table.insert(tab, i)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  return tab";
+    stream << "\n";
+    stream << indent_str;
+    stream << "end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    stream << "function generate_string(s, stream, indent)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local subs = s";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local indent_str = \"\"";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local id = {}";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local pos = 0";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local my_tab = str_to_tab(s)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    stream << "  -- save context";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local ctx = io.output()";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  io.output(stream)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    stream << "  if((indent == 0) or (strchr_tab(my_tab, \"\\n\") == nil)) then";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    io.write(s)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    return";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    stream << "  for i = 1, indent do";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    id[#id + 1] = ' '";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  indent_str = table.concat(id)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    stream << "  while(true) do";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    pos, subs = strchr_tab(str_to_tab(s), '\\n')";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    if(subs == nil) then break end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    io.write(table.concat(my_tab, \"\", 1, pos))";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    s = subs:sub(2)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    my_tab = str_to_tab(s)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    if(s ~= \"\") then";
+    stream << "\n";
+    stream << indent_str;
+    stream << "      io.write(indent_str);";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  if(s) then";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    io.write(s)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    stream << "  -- restore context";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  io.output(ctx)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "end";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+  }
+};
+
+#endif // GENSTRINGFUN_LUA_GEN_CLASS_H
diff --git a/src/skels/genstringfun_lua.h_skel b/src/skels/genstringfun_lua.h_skel
new file mode 100644
index 0000000..bf9e128
--- /dev/null
+++ b/src/skels/genstringfun_lua.h_skel
@@ -0,0 +1,66 @@
+
+function strchr_tab(tab, char)
+  local store
+  local ret_str = ""
+  for w, k in ipairs(tab) do
+    if(k == char) then
+      store = w
+      break
+    end
+  end
+  if(store == nil) then
+    return nil
+  end
+  for i = store, #tab do
+    ret_str = ret_str .. tab[i]
+  end
+  return store, ret_str
+end
+
+function str_to_tab(str)
+  tab = {}
+  for i in string.gmatch(str, ".") do
+    table.insert(tab, i)
+  end
+  return tab
+end
+
+function generate_string(s, stream, indent)
+  local subs = s
+  local indent_str = ""
+  local id = {}
+  local pos = 0
+  local my_tab = str_to_tab(s)
+
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+
+  if((indent == 0) or (strchr_tab(my_tab, "\n") == nil)) then
+    io.write(s)
+    return
+  end
+
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+
+  while(true) do
+    pos, subs = strchr_tab(str_to_tab(s), '\n')
+    if(subs == nil) then break end
+    io.write(table.concat(my_tab, "", 1, pos))
+    s = subs:sub(2)
+    my_tab = str_to_tab(s)
+    if(s ~= "") then
+      io.write(indent_str);
+    end
+  end
+  if(s) then
+    io.write(s)
+  end
+
+  -- restore context
+  io.output(ctx)
+end
+
diff --git a/src/skels/ifgen_lua.h b/src/skels/ifgen_lua.h
new file mode 100644
index 0000000..74b930d
--- /dev/null
+++ b/src/skels/ifgen_lua.h
@@ -0,0 +1,120 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef IFGEN_LUA_GEN_CLASS_H
+#define IFGEN_LUA_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class ifgen_lua_gen_class
+{
+ protected:
+  string else_body;
+  string exp;
+  bool skipelse;
+  string then_body;
+
+ public:
+  ifgen_lua_gen_class() :
+    skipelse (false)
+  {
+  }
+  
+  ifgen_lua_gen_class(const string &_else_body, const string &_exp, bool _skipelse, const string &_then_body) :
+    else_body (_else_body), exp (_exp), skipelse (_skipelse), then_body (_then_body)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_else_body(const string &_else_body)
+  {
+    else_body = _else_body;
+  }
+
+  void set_exp(const string &_exp)
+  {
+    exp = _exp;
+  }
+
+  void set_skipelse(bool _skipelse)
+  {
+    skipelse = _skipelse;
+  }
+
+  void set_then_body(const string &_then_body)
+  {
+    then_body = _then_body;
+  }
+
+  void generate_ifgen_lua(ostream &stream, unsigned int indent = 0)
+  {
+    string indent_str (indent, ' ');
+    indent = 0;
+  
+    stream << "if (";
+    generate_string (exp, stream, indent + indent_str.length ());
+    stream << ") then";
+    stream << "\n";
+    stream << indent_str;
+    indent = 2;
+    stream << "  ";
+    generate_string (then_body, stream, indent + indent_str.length ());
+    indent = 0;
+    stream << "\n";
+    stream << indent_str;
+    if (skipelse)
+      {
+        stream << "end";
+      }
+    else
+      {
+        stream << "\n";
+        stream << indent_str;
+        stream << "else";
+        stream << "\n";
+        stream << indent_str;
+        indent = 2;
+        stream << "  ";
+        generate_string (else_body, stream, indent + indent_str.length ());
+        indent = 0;
+        stream << "\n";
+        stream << indent_str;
+        stream << "end";
+      }
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+  }
+};
+
+#endif // IFGEN_LUA_GEN_CLASS_H
diff --git a/src/skels/ifgen_lua.h_skel b/src/skels/ifgen_lua.h_skel
new file mode 100644
index 0000000..3179ee9
--- /dev/null
+++ b/src/skels/ifgen_lua.h_skel
@@ -0,0 +1,7 @@
+if (@exp@) then
+  @then_body@
+@if@ skipelse @then@end@else@
+else
+  @else_body@
+end@endif@
+
diff --git a/src/skels/initstructfun_lua.h b/src/skels/initstructfun_lua.h
new file mode 100644
index 0000000..0f5f1e1
--- /dev/null
+++ b/src/skels/initstructfun_lua.h
@@ -0,0 +1,96 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef INITSTRUCTFUN_LUA_GEN_CLASS_H
+#define INITSTRUCTFUN_LUA_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class initstructfun_lua_gen_class
+{
+ protected:
+  string genfieldinit;
+  string structname;
+
+ public:
+  initstructfun_lua_gen_class()
+  {
+  }
+  
+  initstructfun_lua_gen_class(const string &_genfieldinit, const string &_structname) :
+    genfieldinit (_genfieldinit), structname (_structname)
+  {
+  }
+
+  virtual ~initstructfun_lua_gen_class()
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  virtual void generate_genfieldinit(ostream &stream, unsigned int indent) = 0;
+
+  void set_genfieldinit(const string &_genfieldinit)
+  {
+    genfieldinit = _genfieldinit;
+  }
+
+  void set_structname(const string &_structname)
+  {
+    structname = _structname;
+  }
+
+  void generate_initstructfun_lua(ostream &stream, unsigned int indent = 0)
+  {
+    string indent_str (indent, ' ');
+    indent = 0;
+  
+    stream << "\n";
+    stream << indent_str;
+    stream << "function init_";
+    generate_string (structname, stream, indent + indent_str.length ());
+    stream << "(record)";
+    stream << "\n";
+    stream << indent_str;
+    indent = 2;
+    if (genfieldinit.size () > 0)
+      generate_string (genfieldinit, stream, indent + indent_str.length ());
+    else
+      generate_genfieldinit (stream, indent + indent_str.length ());
+    indent = 0;
+    stream << indent_str;
+    stream << "end";
+    stream << "\n";
+    stream << indent_str;
+  }
+};
+
+#endif // INITSTRUCTFUN_LUA_GEN_CLASS_H
diff --git a/src/skels/initstructfun_lua.h_skel b/src/skels/initstructfun_lua.h_skel
new file mode 100644
index 0000000..c99d057
--- /dev/null
+++ b/src/skels/initstructfun_lua.h_skel
@@ -0,0 +1,4 @@
+
+function init_@structname@(record)
+  @genfieldinit:method{iteration=true}@
+end
diff --git a/src/skels/lua_convert.h b/src/skels/lua_convert.h
new file mode 100644
index 0000000..de13a64
--- /dev/null
+++ b/src/skels/lua_convert.h
@@ -0,0 +1,85 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef LUA_CONVERT_GEN_CLASS_H
+#define LUA_CONVERT_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class lua_convert_gen_class
+{
+ protected:
+  bool hasbools;
+  bool hasints;
+
+ public:
+  lua_convert_gen_class() :
+    hasbools (false), hasints (false)
+  {
+  }
+  
+  lua_convert_gen_class(bool _hasbools, bool _hasints) :
+    hasbools (_hasbools), hasints (_hasints)
+  {
+  }
+
+  void set_hasbools(bool _hasbools)
+  {
+    hasbools = _hasbools;
+  }
+
+  void set_hasints(bool _hasints)
+  {
+    hasints = _hasints;
+  }
+
+  void generate_lua_convert(ostream &stream, unsigned int indent = 0)
+  {
+    string indent_str (indent, ' ');
+    indent = 0;
+  
+    if (hasints)
+      {
+        stream << "\n";
+        stream << indent_str;
+        stream << "function int_to_string(i)";
+        stream << "\n";
+        stream << indent_str;
+        stream << "  return tostring(i)";
+        stream << "\n";
+        stream << indent_str;
+        stream << "end";
+        stream << "\n";
+        stream << indent_str;
+        stream << "\n";
+        stream << indent_str;
+      }
+    stream << "\n";
+    stream << indent_str;
+    if (hasbools)
+      {
+        stream << "\n";
+        stream << indent_str;
+        stream << "function bool_to_string(b)";
+        stream << "\n";
+        stream << indent_str;
+        stream << "  return b";
+        stream << "\n";
+        stream << indent_str;
+        stream << "end";
+        stream << "\n";
+        stream << indent_str;
+        stream << "\n";
+        stream << indent_str;
+      }
+  }
+};
+
+#endif // LUA_CONVERT_GEN_CLASS_H
diff --git a/src/skels/lua_convert.h_skel b/src/skels/lua_convert.h_skel
new file mode 100644
index 0000000..f6d9880
--- /dev/null
+++ b/src/skels/lua_convert.h_skel
@@ -0,0 +1,15 @@
+@IF@ hasints @THEN@
+
+function int_to_string(i)
+  return tostring(i)
+end
+
+@ENDIF@
+
+@IF@ hasbools @THEN@
+
+function bool_to_string(b)
+  return b
+end
+
+@ENDIF@
diff --git a/src/skels/lua_header.h b/src/skels/lua_header.h
new file mode 100644
index 0000000..8c7448d
--- /dev/null
+++ b/src/skels/lua_header.h
@@ -0,0 +1,203 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef LUA_HEADER_GEN_CLASS_H
+#define LUA_HEADER_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class lua_header_gen_class
+{
+ protected:
+  string author;
+  string externfunctions;
+  string fields;
+  string funbody;
+  string genconv;
+  string genstring;
+  string othercomments;
+  string package;
+  string structname;
+  string version;
+
+ public:
+  lua_header_gen_class()
+  {
+  }
+  
+  lua_header_gen_class(const string &_author, const string &_externfunctions, const string &_fields, const string &_funbody, const string &_genconv, const string &_genstring, const string &_othercomments, const string &_package, const string &_structname, const string &_version) :
+    author (_author), externfunctions (_externfunctions), fields (_fields), funbody (_funbody), genconv (_genconv), genstring (_genstring), othercomments (_othercomments), package (_package), structname (_structname), version (_version)
+  {
+  }
+
+  virtual ~lua_header_gen_class()
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_author(const string &_author)
+  {
+    author = _author;
+  }
+
+  virtual void generate_externfunctions(ostream &stream, unsigned int indent) = 0;
+
+  void set_externfunctions(const string &_externfunctions)
+  {
+    externfunctions = _externfunctions;
+  }
+
+  virtual void generate_fields(ostream &stream, unsigned int indent) = 0;
+
+  void set_fields(const string &_fields)
+  {
+    fields = _fields;
+  }
+
+  virtual void generate_funbody(ostream &stream, unsigned int indent) = 0;
+
+  void set_funbody(const string &_funbody)
+  {
+    funbody = _funbody;
+  }
+
+  virtual void generate_genconv(ostream &stream, unsigned int indent) = 0;
+
+  void set_genconv(const string &_genconv)
+  {
+    genconv = _genconv;
+  }
+
+  virtual void generate_genstring(ostream &stream, unsigned int indent) = 0;
+
+  void set_genstring(const string &_genstring)
+  {
+    genstring = _genstring;
+  }
+
+  void set_othercomments(const string &_othercomments)
+  {
+    othercomments = _othercomments;
+  }
+
+  void set_package(const string &_package)
+  {
+    package = _package;
+  }
+
+  void set_structname(const string &_structname)
+  {
+    structname = _structname;
+  }
+
+  void set_version(const string &_version)
+  {
+    version = _version;
+  }
+
+  void generate_lua_header(ostream &stream, unsigned int indent = 0)
+  {
+    string indent_str (indent, ' ');
+    indent = 0;
+  
+    stream << "--[[";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    File automatically generated by";
+    stream << "\n";
+    stream << indent_str;
+    indent = 4;
+    stream << "    ";
+    stream << package;
+    stream << " ";
+    stream << version;
+    stream << " ";
+    stream << author;
+    indent = 0;
+    stream << "\n";
+    stream << indent_str;
+    indent = 4;
+    stream << "    ";
+    stream << othercomments;
+    indent = 0;
+    stream << "\n";
+    stream << indent_str;
+    stream << "--]]";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    stream << "-- Field table";
+    stream << "\n";
+    stream << indent_str;
+    stream << structname;
+    stream << " = {";
+    stream << "\n";
+    stream << indent_str;
+    indent = 2;
+    if (fields.size () > 0)
+      generate_string (fields, stream, indent + indent_str.length ());
+    else
+      generate_fields (stream, indent + indent_str.length ());
+    indent = 0;
+    stream << indent_str;
+    stream << "}";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    if (externfunctions.size () > 0)
+      generate_string (externfunctions, stream, indent + indent_str.length ());
+    else
+      generate_externfunctions (stream, indent + indent_str.length ());
+    stream << indent_str;
+    if (genstring.size () > 0)
+      generate_string (genstring, stream, indent + indent_str.length ());
+    else
+      generate_genstring (stream, indent + indent_str.length ());
+    stream << indent_str;
+    if (genconv.size () > 0)
+      generate_string (genconv, stream, indent + indent_str.length ());
+    else
+      generate_genconv (stream, indent + indent_str.length ());
+    stream << indent_str;
+    if (funbody.size () > 0)
+      generate_string (funbody, stream, indent + indent_str.length ());
+    else
+      generate_funbody (stream, indent + indent_str.length ());
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+  }
+};
+
+#endif // LUA_HEADER_GEN_CLASS_H
diff --git a/src/skels/lua_header.h_skel b/src/skels/lua_header.h_skel
new file mode 100644
index 0000000..ed3846b
--- /dev/null
+++ b/src/skels/lua_header.h_skel
@@ -0,0 +1,16 @@
+--[[
+    File automatically generated by
+    @package@ @version@ @author@
+    @othercomments@
+--]]
+
+-- Field table
+@structname@ = {
+  @fields:method{iteration=true}@
+}
+
+@externfunctions:method{iteration=true}@
+@genstring:method{iteration=true}@
+@genconv:method{iteration=true}@
+@funbody:method{iteration=true}@
+
diff --git a/src/skels/lua_source.h b/src/skels/lua_source.h
new file mode 100644
index 0000000..0eaacc6
--- /dev/null
+++ b/src/skels/lua_source.h
@@ -0,0 +1,169 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef LUA_SOURCE_GEN_CLASS_H
+#define LUA_SOURCE_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class lua_source_gen_class
+{
+ protected:
+  string author;
+  string genconvfun;
+  string genfunbody;
+  string genstringfun;
+  string headerfile;
+  string othercomments;
+  string package;
+  string version;
+
+ public:
+  lua_source_gen_class()
+  {
+  }
+  
+  lua_source_gen_class(const string &_author, const string &_genconvfun, const string &_genfunbody, const string &_genstringfun, const string &_headerfile, const string &_othercomments, const string &_package, const string &_version) :
+    author (_author), genconvfun (_genconvfun), genfunbody (_genfunbody), genstringfun (_genstringfun), headerfile (_headerfile), othercomments (_othercomments), package (_package), version (_version)
+  {
+  }
+
+  virtual ~lua_source_gen_class()
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_author(const string &_author)
+  {
+    author = _author;
+  }
+
+  virtual void generate_genconvfun(ostream &stream, unsigned int indent) = 0;
+
+  void set_genconvfun(const string &_genconvfun)
+  {
+    genconvfun = _genconvfun;
+  }
+
+  virtual void generate_genfunbody(ostream &stream, unsigned int indent) = 0;
+
+  void set_genfunbody(const string &_genfunbody)
+  {
+    genfunbody = _genfunbody;
+  }
+
+  virtual void generate_genstringfun(ostream &stream, unsigned int indent) = 0;
+
+  void set_genstringfun(const string &_genstringfun)
+  {
+    genstringfun = _genstringfun;
+  }
+
+  void set_headerfile(const string &_headerfile)
+  {
+    headerfile = _headerfile;
+  }
+
+  void set_othercomments(const string &_othercomments)
+  {
+    othercomments = _othercomments;
+  }
+
+  void set_package(const string &_package)
+  {
+    package = _package;
+  }
+
+  void set_version(const string &_version)
+  {
+    version = _version;
+  }
+
+  void generate_lua_source(ostream &stream, unsigned int indent = 0)
+  {
+    string indent_str (indent, ' ');
+    indent = 0;
+  
+    stream << "--[[";
+    stream << "\n";
+    stream << indent_str;
+    stream << "    File automatically generated by";
+    stream << "\n";
+    stream << indent_str;
+    indent = 4;
+    stream << "    ";
+    stream << package;
+    stream << " ";
+    stream << version;
+    stream << " ";
+    stream << author;
+    indent = 0;
+    stream << "\n";
+    stream << indent_str;
+    indent = 4;
+    stream << "    ";
+    stream << othercomments;
+    indent = 0;
+    stream << "\n";
+    stream << indent_str;
+    stream << "--]]";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    stream << "dofile(\"";
+    stream << headerfile;
+    stream << "\")";
+    stream << "\n";
+    stream << indent_str;
+    stream << "\n";
+    stream << indent_str;
+    if (genstringfun.size () > 0)
+      generate_string (genstringfun, stream, indent + indent_str.length ());
+    else
+      generate_genstringfun (stream, indent + indent_str.length ());
+    stream << indent_str;
+    if (genconvfun.size () > 0)
+      generate_string (genconvfun, stream, indent + indent_str.length ());
+    else
+      generate_genconvfun (stream, indent + indent_str.length ());
+    stream << indent_str;
+    if (genfunbody.size () > 0)
+      generate_string (genfunbody, stream, indent + indent_str.length ());
+    else
+      generate_genfunbody (stream, indent + indent_str.length ());
+    stream << "\n";
+    stream << indent_str;
+  }
+};
+
+#endif // LUA_SOURCE_GEN_CLASS_H
diff --git a/src/skels/lua_source.h_skel b/src/skels/lua_source.h_skel
new file mode 100644
index 0000000..b5e211e
--- /dev/null
+++ b/src/skels/lua_source.h_skel
@@ -0,0 +1,11 @@
+--[[
+    File automatically generated by
+    @package@ @version@ @author@
+    @othercomments@
+--]]
+
+dofile("@headerfile@")
+
+@genstringfun:method{iteration=true}@
+@genconvfun:method{iteration=true}@
+@genfunbody:method@
diff --git a/src/skels/outputluavar.h b/src/skels/outputluavar.h
new file mode 100644
index 0000000..8652dfb
--- /dev/null
+++ b/src/skels/outputluavar.h
@@ -0,0 +1,74 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef OUTPUTLUAVAR_GEN_CLASS_H
+#define OUTPUTLUAVAR_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class outputluavar_gen_class
+{
+ protected:
+  string name;
+
+ public:
+  outputluavar_gen_class()
+  {
+  }
+  
+  outputluavar_gen_class(const string &_name) :
+    name (_name)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_name(const string &_name)
+  {
+    name = _name;
+  }
+
+  void generate_outputluavar(ostream &stream, unsigned int indent = 0)
+  {
+    string indent_str (indent, ' ');
+    indent = 0;
+  
+    stream << "(record.";
+    generate_string (name, stream, indent + indent_str.length ());
+    stream << ") and record.";
+    generate_string (name, stream, indent + indent_str.length ());
+    stream << " or \"\"";
+    stream << "\n";
+    stream << indent_str;
+  }
+};
+
+#endif // OUTPUTLUAVAR_GEN_CLASS_H
diff --git a/src/skels/outputluavar.h_skel b/src/skels/outputluavar.h_skel
new file mode 100644
index 0000000..51d0f39
--- /dev/null
+++ b/src/skels/outputluavar.h_skel
@@ -0,0 +1 @@
+(record.@name@) and record.@name@ or ""
diff --git a/src/skels/strcntfunction_lua.h b/src/skels/strcntfunction_lua.h
new file mode 100644
index 0000000..975d252
--- /dev/null
+++ b/src/skels/strcntfunction_lua.h
@@ -0,0 +1,112 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef STRCNTFUNCTION_LUA_GEN_CLASS_H
+#define STRCNTFUNCTION_LUA_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class strcntfunction_lua_gen_class
+{
+ protected:
+  string compleninstr;
+  string constlen;
+  string genname;
+
+ public:
+  strcntfunction_lua_gen_class()
+  {
+  }
+  
+  strcntfunction_lua_gen_class(const string &_compleninstr, const string &_constlen, const string &_genname) :
+    compleninstr (_compleninstr), constlen (_constlen), genname (_genname)
+  {
+  }
+
+  virtual ~strcntfunction_lua_gen_class()
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  virtual void generate_compleninstr(ostream &stream, unsigned int indent) = 0;
+
+  void set_compleninstr(const string &_compleninstr)
+  {
+    compleninstr = _compleninstr;
+  }
+
+  void set_constlen(const string &_constlen)
+  {
+    constlen = _constlen;
+  }
+
+  void set_genname(const string &_genname)
+  {
+    genname = _genname;
+  }
+
+  void generate_strcntfunction_lua(ostream &stream, unsigned int indent = 0)
+  {
+    string indent_str (indent, ' ');
+    indent = 0;
+  
+    stream << "\n";
+    stream << indent_str;
+    stream << "function strcnt_";
+    stream << genname;
+    stream << "(record, indent)";
+    stream << "\n";
+    stream << indent_str;
+    stream << "  local length = 0;";
+    stream << "\n";
+    stream << indent_str;
+    indent = 2;
+    stream << "  ";
+    if (compleninstr.size () > 0)
+      generate_string (compleninstr, stream, indent + indent_str.length ());
+    else
+      generate_compleninstr (stream, indent + indent_str.length ());
+    indent = 0;
+    stream << "\n";
+    stream << indent_str;
+    stream << "  return length + ";
+    stream << constlen;
+    stream << ";";
+    stream << "\n";
+    stream << indent_str;
+    stream << "end";
+    stream << "\n";
+    stream << indent_str;
+  }
+};
+
+#endif // STRCNTFUNCTION_LUA_GEN_CLASS_H
diff --git a/src/skels/strcntfunction_lua.h_skel b/src/skels/strcntfunction_lua.h_skel
new file mode 100644
index 0000000..f579dee
--- /dev/null
+++ b/src/skels/strcntfunction_lua.h_skel
@@ -0,0 +1,6 @@
+
+function strcnt_@genname@(record, indent)
+  local length = 0;
+  @compleninstr:method@
+  return length + @constlen@;
+end
diff --git a/src/skelstruct_lua.cpp b/src/skelstruct_lua.cpp
new file mode 100644
index 0000000..bc98a5d
--- /dev/null
+++ b/src/skelstruct_lua.cpp
@@ -0,0 +1,308 @@
+//
+//
+// C++ Implementation: skelstruct_lua
+//
+// Description:
+//
+//
+// Author: Raman Gopalan <ramangopalan@gmail.com>
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "skelstruct_lua.h"
+#include "gengen_globals.h"
+#include "gengen_cmdline_options.h"
+#include "extern_function_lua.h"
+#include "skelstruct_strcnt_lua.h"
+#include "my_sstream.h"
+#include "callextfun_lua.h"
+#include "skelstruct_luastring.h"
+#include "genstringfun_lua.h"
+#include "lua_convert.h"
+#include "outputluavar.h"
+#include "streamstruct.h"
+#include "utils.h"
+#include "fileutil.h"
+
+#define struct_suffix "_gen_table"
+
+using std::endl;
+
+SkelStructLua::SkelStructLua(SkelItems *items,
+                             const string &name, const string &file_name,
+                             StreamStruct &s, bool sep_files) :
+  SkelStruct_Lua_Common (items, name, file_name, s, sep_files), num_of_methods (-1),
+  num_of_normal_strings (-1)
+{
+}
+
+SkelStructLua::~SkelStructLua()
+{
+}
+
+void
+SkelStructLua::generate()
+{
+  if (num_of_methods < 0)
+    analyze_items ();
+
+  string struct_name (name + struct_suffix);
+  string headername_include = struct_name;
+
+  Utils::toUpper(headername_include);
+
+  lua_header_gen_class::set_structname (struct_name);
+  initstructfun_lua_gen_class::set_structname (struct_name);
+
+  string author = "by " AUTHOR " " EMAIL;
+  string other_comments =  HOMEPAGE;
+
+  genfunction_lua_gen_class::set_genname (name);
+  strcntfunction_lua_gen_class::set_genname (name);
+  genstrfunction_lua_gen_class::set_genname (name);
+
+  lua_header_gen_class::set_package (PACKAGE);
+  if (! no_gen_version)
+    lua_header_gen_class::set_version (VERSION);
+  lua_header_gen_class::set_author (author);
+  lua_header_gen_class::set_othercomments (other_comments);
+  lua_source_gen_class::set_package (PACKAGE);
+  if (! no_gen_version)
+    lua_source_gen_class::set_version (VERSION);
+  lua_source_gen_class::set_author (author);
+  lua_source_gen_class::set_othercomments (other_comments);
+
+  // make sure to strip possible path
+  set_headerfile (strip_file_path(file_name));
+
+  generate_lua_header (*streamstruct.header_stream);
+
+  streamstruct.header_stream->flush ();
+}
+
+void
+SkelStructLua::generate_fields(ostream &stream, unsigned int indent)
+{
+  VarSetIterator it, end_it;
+  const VarSet &var_set = skel_struct->getVarSet();
+  string indent_string (indent, ' ');
+  skelitem_type item_type;
+
+  for (it = var_set.begin (); it != var_set.end (); ++it)
+    {
+      item_type = (*it)->getType ();
+      stream << indent_string;
+      stream << **it << ",\n";
+    }
+}
+
+void
+SkelStructLua::generate_genparameters(ostream &stream, unsigned int indent)
+{
+  VarSetIterator it;
+  const VarSet &var_set = skel_struct->getVarSet();
+  skelitem_type item_type;
+
+  for (it = var_set.begin (); it != var_set.end (); ++it)
+    {
+      item_type = (*it)->getType ();
+      stream << ", " << **it;
+    }
+}
+
+void
+SkelStructLua::generate_genstring(ostream &stream, unsigned int indent)
+{
+  if (sep_files)
+    return;
+
+  generate_genstringfun( stream, indent);
+}
+
+void
+SkelStructLua::generate_genstringfun(ostream &stream, unsigned int indent)
+{
+  if (! has_expand_strings ())
+    return;
+
+  genstringfun_lua_gen_class genstring;
+  genstring.generate_genstringfun_lua (stream, indent);
+}
+
+void
+SkelStructLua::generate_genconvfun(ostream &stream, unsigned int indent)
+{
+  if (! has_ints_to_generate() && ! has_booleans_to_generate())
+    return;
+
+  lua_convert_gen_class gen;
+  gen.set_hasints(has_ints_to_generate());
+  gen.set_hasbools(has_booleans_to_generate());
+  gen.generate_lua_convert (stream, indent);
+}
+
+void
+SkelStructLua::generate_genconv(ostream &stream, unsigned int indent)
+{
+  if (sep_files)
+    return;
+
+  generate_genconvfun (stream, indent);
+}
+
+void
+SkelStructLua::generate_genfieldinit(ostream &stream, unsigned int indent)
+{
+  VarSetIterator it;
+  const VarSet &var_set = skel_struct->getVarSet();
+  string indent_string (indent, ' ');
+  skelitem_type item_type;
+
+  for (it = var_set.begin (); it != var_set.end (); ++it)
+    {
+      item_type = (*it)->getType ();
+      if (isVariableType( item_type ))
+        {
+          stream << indent_string;
+          stream << "record." << **it << " = nil\n";
+        }
+    }
+}
+
+void
+SkelStructLua::generate_assignfields(ostream &stream, unsigned int indent)
+{
+  VarSetIterator it;
+  const VarSet &var_set = skel_struct->getVarSet();
+  string indent_string (indent, ' ');
+  skelitem_type item_type;
+
+  stream << endl;
+
+  for (it = var_set.begin (); it != var_set.end (); ++it)
+    {
+      item_type = (*it)->getType ();
+      if (isVariableType( item_type ))
+        {
+          stream << indent_string;
+          stream << "record." << **it << " = " << **it << "\n";
+        }
+    }
+}
+
+void
+SkelStructLua::generate_strgeninstructions(ostream &stream, unsigned int indent)
+{
+  SkelStructLuaString luastring_gen (*this);
+  luastring_gen.start_generation (stream, indent);
+}
+
+void
+SkelStructLua::generate_funbody(ostream &stream, unsigned int indent)
+{
+  if (sep_files)
+    {
+      generate_lua_source (*streamstruct.source_stream, 0);
+
+      streamstruct.source_stream->flush ();
+    }
+  else
+    {
+      generate_genfunction_lua (stream, 0);
+      generate_genstrfunction_lua (stream, 0);
+      generate_strcntfunction_lua (stream, 0);
+      generate_initstructfun_lua (stream, 0);
+    }
+}
+
+void
+SkelStructLua::generate_genfunbody(ostream &stream, unsigned int indent)
+{
+  generate_genfunction_lua (stream, 0);
+  generate_genstrfunction_lua (stream, 0);
+  generate_strcntfunction_lua (stream, 0);
+  generate_initstructfun_lua (stream, 0);
+}
+
+void
+SkelStructLua::generate_externfunctions(ostream &stream, unsigned int indent)
+{
+  VarSetIterator it;
+  const VarSet &var_set = skel_struct->getVarSet();
+  skelitem_type item_type;
+  extern_function_lua_gen_class extfun_gen_lua;
+
+  for (it = var_set.begin (); it != var_set.end (); ++it)
+    {
+      item_type = (*it)->getType ();
+
+      if (item_type == METHOD_TYPE)
+        {
+          extfun_gen_lua.set_name ((*it)->getText ());
+          extfun_gen_lua.generate_extern_function_lua (stream, indent);
+
+          stream << endl;
+          stream << endl;
+        }
+    }
+}
+
+void
+SkelStructLua::generate_geninstructions(ostream &stream, unsigned int indent)
+{
+  gen_generate_instructions (stream, indent);
+}
+
+void
+SkelStructLua::generate_compleninstr(ostream &stream, unsigned int indent)
+{
+  SkelStructStrCntLua strcnt (*this);
+
+  int const_len = strcnt.compute_length (stream, indent);
+
+  ostringstream const_len_s;
+  const_len_s << const_len;
+
+  set_constlen (const_len_s.str ());
+}
+
+void
+SkelStructLua::call_external_function(ostream &stream, const string &name,
+                                      unsigned int indent)
+{
+  callextfun_lua_gen_class callext;
+  callext.set_name (name);
+  callext.generate_callextfun_lua (stream, indent);
+  stream << endl;
+}
+
+void
+SkelStructLua::std_generation(ostream &stream, const string &s)
+{
+  stream << "io.write(" << s << ")\n";
+}
+
+void
+SkelStructLua::variable_generation(ostream &stream, const string &name,
+                                   const skelitem_type &type,
+                                   unsigned int indent)
+{
+  ostringstream luavar;
+
+  if (canBeString( type ) || expand_tabs) {
+    outputluavar_gen_class luavar_gen (name);
+    luavar_gen.generate_outputluavar (luavar);
+  } else {
+    luavar << field_prefix() << name;
+  }
+
+  // instead of relying on the convert functions, since printf
+  // can handle integers, we use this feature directly
+  if (expand_tabs)
+    stream << "generate_string (" + luavar.str () +
+      ", stream, indent + string.len (indent_str))\n";
+  else
+    stream << "io.write(" << luavar.str () << ")\n";
+}
diff --git a/src/skelstruct_lua.h b/src/skelstruct_lua.h
new file mode 100644
index 0000000..57018c4
--- /dev/null
+++ b/src/skelstruct_lua.h
@@ -0,0 +1,81 @@
+//
+//
+// C++ Interface: skelstruct_lua
+//
+// Description:
+//
+//
+// Author: Raman Gopalan <ramangopalan@gmail.com>
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef SKELSTRUCT_LUA_H
+#define SKELSTRUCT_LUA_H
+
+#include "skelstruct_lua_common.h"
+#include "lua_header.h"
+#include "genfunction_lua.h"
+#include "lua_source.h"
+#include "strcntfunction_lua.h"
+#include "initstructfun_lua.h"
+#include "genstrfunction_lua.h"
+
+/**
+ * Class for generation of Lua code
+ */
+class SkelStructLua : public SkelStruct_Lua_Common, public lua_header_gen_class,
+                      public genfunction_lua_gen_class, public lua_source_gen_class,
+                      public strcntfunction_lua_gen_class, public initstructfun_lua_gen_class,
+                      public genstrfunction_lua_gen_class
+{
+ protected:
+  int num_of_methods;
+  int num_of_normal_strings;
+
+ public:
+  // redefined from c_header_gen_class
+  virtual void generate_fields(ostream &stream, unsigned int indent);
+  virtual void generate_funbody(ostream &stream, unsigned int indent);
+  virtual void generate_externfunctions(ostream &stream, unsigned int indent);
+  virtual void generate_genparameters(ostream &stream, unsigned int indent);
+  virtual void generate_genstring(ostream &stream, unsigned int indent);
+  virtual void generate_genconv(ostream &stream, unsigned int indent);
+
+  // redefined from genfunction_gen_class
+  virtual void generate_geninstructions(ostream &stream, unsigned int indent);
+  virtual void generate_assignfields(ostream &stream, unsigned int indent);
+
+  // redefined from c_source_gen_class
+  virtual void generate_genfunbody(ostream &stream, unsigned int indent);
+  virtual void generate_genstringfun(ostream &stream, unsigned int indent);
+  virtual void generate_genconvfun(ostream &stream, unsigned int indent);
+
+  // redefined from strcntfunction_gen_class
+  virtual void generate_compleninstr(ostream &stream, unsigned int indent);
+
+  // redefined from initstructfun_gen_class
+  virtual void generate_genfieldinit(ostream &stream, unsigned int indent);
+
+  // redefined from genstrfunction_gen_class
+  virtual void generate_strgeninstructions(ostream &stream, unsigned int indent);
+
+  // redefined from SkelStruct
+  virtual void call_external_function(ostream &stream, const string &name,
+                                      unsigned int indent);
+  virtual void std_generation(ostream &stream, const string &s);
+  virtual void variable_generation(ostream &stream, const string &name,
+                                   const skelitem_type &t,
+                                   unsigned int indent);
+
+ public:
+  SkelStructLua (SkelItems *items,
+                 const string &n, const string &file_name, StreamStruct &s,
+                 bool sep_files);
+  virtual ~SkelStructLua();
+
+  virtual void generate();
+};
+
+#endif // SKELSTRUCT_LUA_H
diff --git a/src/skelstruct_lua_common.cpp b/src/skelstruct_lua_common.cpp
new file mode 100644
index 0000000..39f2ff9
--- /dev/null
+++ b/src/skelstruct_lua_common.cpp
@@ -0,0 +1,63 @@
+//
+// C++ Implementation: skelstruct_lua_common
+//
+// Description:
+//
+//
+// Author: Raman Gopalan <ramangopalan@gmail.com>
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "skelstruct_lua_common.h"
+#include "ifgen_lua.h"
+#include "expressiongenerator_lua.h"
+
+using std::endl;
+
+SkelStruct_Lua_Common::SkelStruct_Lua_Common(SkelItems* items, const string& n, const string& file, StreamStruct& s, bool sep): SkelStruct(items, n, file, s, sep), expGen (0)
+{
+}
+
+SkelStruct_Lua_Common::~SkelStruct_Lua_Common()
+{
+  if (expGen && !is_copy)
+    delete expGen;
+}
+
+void
+SkelStruct_Lua_Common::if_generation(const string &exp, const string &then_branch,
+                             const string &else_branch, ostream &stream,
+                             unsigned int indent)
+{
+  bool empty_else = (!else_branch.size());
+  
+  ifgen_lua_gen_class ifgen;
+  ifgen.set_exp (exp);
+  ifgen.set_then_body (then_branch);
+  ifgen.set_else_body (else_branch);
+  ifgen.set_skipelse (empty_else);
+
+  ifgen.generate_ifgen_lua (stream, indent);
+
+  stream << endl;
+}
+
+
+void
+SkelStruct_Lua_Common::exp_generation(Expression *exp, ostream &stream)
+{
+  if (!expGen) {
+    expGen = createExpGenLua(stream);
+    expGen->setPrefix( field_prefix() );
+  } else {
+    expGen->setStream( stream );
+  }
+
+  expGen->visit_DB( exp );
+}
+
+ExpressionGeneratorLua *SkelStruct_Lua_Common::createExpGenLua(ostream &stream)
+{
+  return new ExpressionGeneratorLua(stream);
+}
diff --git a/src/skelstruct_lua_common.h b/src/skelstruct_lua_common.h
new file mode 100644
index 0000000..d34f63f
--- /dev/null
+++ b/src/skelstruct_lua_common.h
@@ -0,0 +1,51 @@
+//
+// C++ Interface: skelstruct_lua_common
+//
+// Description:
+//
+//
+// Author: Raman Gopalan <ramangopalan@gmail.com>
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef SKELSTRUCT_LUA_COMMON_H
+#define SKELSTRUCT_LUA_COMMON_H
+
+#include "skelstruct.hpp"
+
+#include "my_sstream.h"
+
+class ExpressionGeneratorLua;
+
+/**
+A base class that contains shared methods for Lua related generation code
+
+@author Raman Gopalan
+*/
+class SkelStruct_Lua_Common : public SkelStruct
+{
+  protected:
+    /// the generator for expressions
+    ExpressionGeneratorLua *expGen;
+
+  public:
+    SkelStruct_Lua_Common(SkelItems* items, const string& n, const string& file, StreamStruct& s, bool sep);
+    virtual ~SkelStruct_Lua_Common();
+
+    virtual void if_generation(const string &exp, const string &then_branch,
+                             const string &else_branch, ostream &stream,
+                             unsigned int indent);
+    virtual const string field_prefix() { return "record."; }
+
+    virtual void exp_generation( Expression *exp, ostream &stream );
+
+    /**
+     * This is the factory method used to create an ExpressionGenerator for Lua
+     *
+     * @return The created ExpressionGenerator
+     */
+    virtual ExpressionGeneratorLua *createExpGenLua(ostream &stream);
+};
+
+#endif // SKELSTRUCT_LUA_COMMON_H
diff --git a/src/skelstruct_luastring.cpp b/src/skelstruct_luastring.cpp
new file mode 100644
index 0000000..404b5fe
--- /dev/null
+++ b/src/skelstruct_luastring.cpp
@@ -0,0 +1,54 @@
+//
+// C++ Implementation: skelstruct_luastring
+//
+// Description: generate into a Lua string instead of into a file
+//
+//
+// Author: Raman Gopalan <ramangopalan@gmail.com>
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "skelstruct_luastring.h"
+
+SkelStructLuaString::SkelStructLuaString(const SkelStruct_Lua_Common &s) :
+  SkelStruct_Lua_Common (s)
+{
+  do_indent_update = false;
+}
+
+void
+SkelStructLuaString::call_external_function(ostream &stream, const string &name,
+                                            unsigned int indent)
+{
+  variable_generation (stream, name, STRING_TYPE, indent);
+}
+
+void
+SkelStructLuaString::std_generation(ostream &stream, const string &s)
+{
+  stream << "output = output .. " << s << "\n";
+}
+
+void
+SkelStructLuaString::variable_generation(ostream &stream, const string &name,
+                                         const skelitem_type &type,
+                                         unsigned int indent)
+{
+  if (canBeString( type )) {
+    stream << "if (record." << name << ") then ";
+    std_generation (stream, "record." + name + " end");
+  } else if (type == BOOL_TYPE) {
+    std_generation (stream, "bool_to_string(record." + name + ")");
+  } else if (type == INT_TYPE) {
+    std_generation (stream, "int_to_string(record." + name + ")");
+  }
+}
+
+void
+SkelStructLuaString::start_generation(ostream &stream, unsigned int indent)
+{
+  gen_generate_instructions (stream, indent);
+}
+
diff --git a/src/skelstruct_luastring.h b/src/skelstruct_luastring.h
new file mode 100644
index 0000000..3e0df69
--- /dev/null
+++ b/src/skelstruct_luastring.h
@@ -0,0 +1,35 @@
+//
+// C++ Interface: skelstruct_luastring
+//
+// Description: generate into a Lua string instead of into a file
+//
+//
+// Author: Raman Gopalan <ramangopalan@gmail.com>
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef SKELSTRUCT_LUASTRING_H
+#define SKELSTRUCT_LUASTRING_H
+
+#include "skelstruct_lua_common.h"
+
+class SkelStructLuaString : public SkelStruct_Lua_Common
+{
+ public:
+  // redefined from SkelStruct
+  virtual void call_external_function(ostream &stream, const string &name,
+                                      unsigned int indent);
+  virtual void std_generation(ostream &stream, const string &s);
+  virtual void variable_generation(ostream &stream, const string &name,
+                                   const skelitem_type &t,
+                                   unsigned int indent);
+
+ public:
+  SkelStructLuaString (const SkelStruct_Lua_Common &s);
+
+  void start_generation (ostream &stream, unsigned int indent);
+};
+
+#endif // SKELSTRUCT_LUASTRING_H
diff --git a/src/skelstruct_strcnt_lua.cpp b/src/skelstruct_strcnt_lua.cpp
new file mode 100644
index 0000000..726cc22
--- /dev/null
+++ b/src/skelstruct_strcnt_lua.cpp
@@ -0,0 +1,88 @@
+//
+//
+// C++ Implementation: skelstruct_strcnt_lua
+//
+// Description: to compute the lenght of the string to be generated
+//
+//
+// Author: Raman Gopalan <ramangopalan@gmail.com>
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "skelstruct_strcnt_lua.h"
+
+SkelStructStrCntLua::SkelStructStrCntLua(const SkelStruct_Lua_Common &s) :
+  SkelStruct_Lua_Common (s), length (0)
+{
+}
+
+void
+SkelStructStrCntLua::call_external_function(ostream &stream, const string &name,
+                                            unsigned int indent)
+{
+  variable_generation (stream, name, STRING_TYPE, indent);
+}
+
+void
+SkelStructStrCntLua::std_generation(ostream &stream, const string &s)
+{
+  int size = s.size();
+  if (s == "\\n" || s == "\\t")
+    size = 1;
+  //std::cerr << "string: \"" << s << "\", length: " << size << std::endl;
+  length += size;
+}
+
+void
+SkelStructStrCntLua::std_indentstr_generation(ostream &stream, const string &s,
+                                              unsigned int indent)
+{
+  //std::cerr << "string: " << s << ", length: " << indent << std::endl;
+  length += indent;
+}
+
+void
+SkelStructStrCntLua::indent_generation(ostream &stream, const string &ind)
+{
+}
+
+void
+SkelStructStrCntLua::variable_generation(ostream &stream, const string &name,
+                                         const skelitem_type &type,
+                                         unsigned int indent)
+{
+  if (examined_variables.find (name) == examined_variables.end ())
+    {
+      string indent_string (indent, ' ');
+      stream << indent_string;
+      stream << "length = length + ";
+      if (canBeString( type )) {
+         stream << "((record." << name << ") " <<
+             "and string.len(record." << name << ") or 0)";
+      } else if (type == BOOL_TYPE) {
+        stream << "string.length(bool_to_string(record." << name
+            << "))";
+      } else if (type == INT_TYPE) {
+        stream << "string.len(int_to_string(record." << name
+            << "))";
+      }
+      stream << " * " <<
+         skel_struct->getVarOccurCnt(name) << ";\n";
+      examined_variables.insert (name);
+    }
+}
+
+void
+SkelStructStrCntLua::indent_update_generation(ostream &stream, int i)
+{
+}
+
+int
+SkelStructStrCntLua::compute_length (ostream &stream, int indent)
+{
+  gen_generate_instructions (stream, indent);
+
+  return length;
+}
diff --git a/src/skelstruct_strcnt_lua.h b/src/skelstruct_strcnt_lua.h
new file mode 100644
index 0000000..7c4e87a
--- /dev/null
+++ b/src/skelstruct_strcnt_lua.h
@@ -0,0 +1,46 @@
+//
+//
+// C++ Interface: skelstruct_strcnt_lua
+//
+// Description: used for computing the length of the string to be generated for Lua
+//
+//
+// Author: Raman Gopalan <ramangopalan@gmail.com>
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef SKELSTRUCT_STRCNT_LUA_H
+#define SKELSTRUCT_STRCNT_LUA_H
+
+#include "skelstruct_lua_common.h"
+
+class SkelStructStrCntLua : public SkelStruct_Lua_Common
+{
+ protected:
+  int length;
+  set<string> examined_variables;
+
+ public:
+  // redefined from SkelStruct
+  virtual void call_external_function(ostream &stream, const string &name,
+                                      unsigned int indent);
+  virtual void std_generation(ostream &stream, const string &s);
+  virtual void std_indentstr_generation(ostream &stream, const string &name,
+                                        unsigned int indent);
+  virtual void variable_generation(ostream &stream, const string &name,
+                                   const skelitem_type &t,
+                                   unsigned int indent);
+  virtual void indent_update_generation(ostream &stream, int i);
+  virtual void indent_generation(ostream &stream, const string &ind);
+  virtual string preformat(const string &item) { return item; }
+  virtual void replace_chars(string &) {}
+
+ public:
+  SkelStructStrCntLua (const SkelStruct_Lua_Common &s);
+
+  int compute_length (ostream &stream, int indent);
+};
+
+#endif // SKELSTRUCT_STRCNT_LUA_H
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e45c4f8..d10b487 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -10,14 +10,16 @@
 
 SUBDIRS = otherdir
 
-SUFFIXES = .err .cc_skel .err_test .cc_skel .h .cc_skel _c.h .cc_skel
+SUFFIXES = .err .cc_skel .err_test .cc_skel .h .cc_skel _c.h .cc_skel _lua.lua
 
 PROGEXE = $(top_builddir)/src/$(PACKAGE)$(EXEEXT)
 PROGEXE_C = $(PROGEXE) --output-format "c"
+PROGEXE_LUA = $(PROGEXE) --output-format "lua"
 PROGNAME = $(PROGEXE) --no-gen-version 2>> $(VERBOSEOUT)
 
 GENERATE = $(PROGNAME)
 GENERATE_C = $(PROGNAME) --output-format "c"
+GENERATE_LUA = $(PROGNAME) --output-format "lua"
 GENERATEERR = $(PROGNAME) --test-mode
 
 TEMP_H = __temp.h
@@ -34,12 +36,18 @@ test_cicle_tabs.h: $(srcdir)/test_cicle_tabs.cc_skel
 test_cicle_tabs_c.h: $(srcdir)/test_cicle_tabs.cc_skel
 	$(GENERATE_C) -i $(srcdir)/test_cicle_tabs.cc_skel --file-name $@ --gen-name test_cicle --expand-tabs
 
+test_cicle_tabs_lua.lua: $(srcdir)/test_cicle_tabs.cc_skel
+	$(GENERATE_LUA) -i $(srcdir)/test_cicle_tabs.cc_skel --file-name $@ --gen-name test_cicle --expand-tabs
+
 .cc_skel.h:
 	$(GENERATE) -i $< --file-name $@ --gen-name $* 
 
 .cc_skel_c.h:
 	$(GENERATE_C) -i $< --file-name $@ --gen-name $* 
 
+.cc_skel_lua.lua:
+	$(GENERATE_LUA) -i $< --file-name $@ --gen-name $*
+
 # the cp is useful when building on a different directory
 # since the sources are also deleted during `make check`
 # see also clean-gen-files:
@@ -55,19 +63,19 @@ notbool.err notbool2.err notbool3.err \
 notsametype.err notsametype2.err
 
 EXTRA_DIST = test_vars.cc_skel test_cicle.cc_skel \
-test_cicle_tabs.cc_skel test_body_loop.cc_skel \
+test_cicle_tabs.cc_skel test_body_loop.cc_skel test_body_loop_lua.skel \
 loop.cc_skel test_subst.cc_skel test_subst.cc_skel test_iter.cc_skel \
 test1.cc_skel example_text.text_skel example_fundef.cc_skel \
-test_vars.cc test_cicle.cc test_cicle_str.cc test_cicle2_main.c \
+test_vars.cc test_cicle.cc test_cicle_str.cc test_cicle2_main.c test_cicle2_main.lua \
 test_iter.cc test_cicle_m.cc test_subst.cc \
-test_subst2_main.cc test1_gen.cc test1_gen_c.c \
-example_text_gen.cc example_text_gen_c.c \
+test_subst2_main.cc test1_gen.cc test1_gen_c.c test1_gen.lua \
+example_text_gen.cc example_text_gen_c.c example_text_gen_lua.lua \
 example_fundef_gen.cc \
-test_cicle_c.c test_cicle_str_c.c test_cicle2_c.c \
+test_cicle_c.c test_cicle_gen_lua.lua test_cicle_str_c.c test_cicle2_c.c test_cicle2_lua.lua \
 test_cicle_cstring.c test_cicle_c_cc.cc \
-test_cicle_tabs.cc test_cicle_tabs_c.c \
-test_if.cc_skel test_if.cc test_if_c.c \
-test_types.cc_skel test_types.cc test_types_c.c \
+test_cicle_tabs.cc test_cicle_tabs_c.c test_cicle_tabs_gen_lua.lua \
+test_if.cc_skel test_if.cc test_if_c.c test_if_gen_lua.lua \
+test_types.cc_skel test_types.cc test_types_c.c test_types_gen_lua.lua \
 $(GENERATED_TESTS) \
 $(ERRFILES) \
 $(ERRFILES_OUTPUT) \
@@ -80,18 +88,18 @@ test_cicle$(EXEEXT) test_cicle_str$(EXEEXT) test_cicle_tabs$(EXEEXT) \
 gen_test_cicle$(EXEEXT) gen_test_cicle_str$(EXEEXT) \
 test_cicle_m$(EXEEXT) gen_test_cicle_m$(EXEEXT) test_subst$(EXEEXT) \
 gen_test_subst$(EXEEXT) test_iter$(EXEEXT) \
-gen_test_iter$(EXEEXT) test_subst2_prog$(EXEEXT) test1_gen$(EXEEXT) test1_gen_c$(EXEEXT) \
-example_text_gen$(EXEEXT) example_text_gen_c$(EXEEXT) \
+gen_test_iter$(EXEEXT) test_subst2_prog$(EXEEXT) test1_gen$(EXEEXT) test1_gen_c$(EXEEXT) test1_gen_lua$(EXEEXT) \
+example_text_gen$(EXEEXT) example_text_gen_c$(EXEEXT) example_text_gen_lua$(EXEEXT) \
 example_fundef_gen$(EXEEXT) \
-test_cicle_c$(EXEEXT) test_cicle_str_c$(EXEEXT) \
-test_cicle2_c$(EXEEXT) test_cicle_c_cc$(EXEEXT) \
-test_cicle_tabs_c$(EXEEXT) \
+test_cicle_c$(EXEEXT) test_cicle_gen_lua$(EXEEXT) test_cicle_str_c$(EXEEXT) \
+test_cicle2_c$(EXEEXT) test_cicle2_lua$(EXEEXT) test_cicle_c_cc$(EXEEXT) \
+test_cicle_tabs_c$(EXEEXT) test_cicle_tabs_gen_lua$(EXEEXT) \
 gen_test_cicle_c$(EXEEXT) gen_test_cicle_str_c$(EXEEXT) \
 gen_test_cicle_c_cc$(EXEEXT) \
 test_cicle_cstring$(EXEEXT) gen_test_cicle_cstring$(EXEEXT) \
 gen_test_cicle_tabs$(EXEEXT) \
-test_if$(EXEEXT) test_if_c$(EXEEXT) \
-test_types$(EXEEXT) test_types_c$(EXEEXT)
+test_if$(EXEEXT) test_if_c$(EXEEXT) test_if_gen_lua$(EXEEXT) \
+test_types$(EXEEXT) test_types_c$(EXEEXT) test_types_gen_lua$(EXEEXT)
 
 # we do not want that generated sources are included in the tar ball
 # so we have to do things manually:
@@ -142,15 +150,16 @@ test_body_loop.h gen_test_cicle.cc gen_test_cicle_str.cc \
 loop.h gen_test_cicle_m.cc \
 test_subst.h gen_test_subst.cc test_iter.h gen_test_iter.cc \
 test_subst2.h test_subst2.cc \
-test1.h test1_c.h \
-example_text.h example_text_c.h example_fundef.h \
-test_cicle_c.h test_cicle2_c.h test_cicle2_c.c test_body_loop_c.h \
-test_cicle_tabs_c.h \
+test1.h test1_c.h test1_lua.lua \
+example_text.h example_text_c.h example_text_lua.lua example_fundef.h \
+test_cicle_c.h test_cicle_lua.lua test_cicle2_c.h test_cicle2_lua.header \
+test_cicle2_c.c test_cicle2_lua.lua test_body_loop_c.h test_body_loop_lua.lua \
+test_cicle_tabs_c.h test_cicle_tabs_lua.lua \
 gen_test_cicle_c.cc gen_test_cicle_str_c.cc \
 gen_test_cicle_cstring.cc gen_test_cicle_c_cc.cc \
 gen_test_cicle_tabs.cc gen_test_cicle_tabs_c.cc \
-test_if.h test_if_c.h \
-test_types.h test_types_c.h
+test_if.h test_if_c.h test_if_lua.lua \
+test_types.h test_types_c.h test_types_lua.lua
 
 # there seem to be problems if using *.test in EXTRA_DIST:
 # it works with `make dist` but not with `make distcheck`
@@ -161,29 +170,29 @@ gen_test_cicle_m.cc.test \
 test_subst.h.test gen_test_subst.cc.test test_iter.h.test \
 gen_test_iter.cc.test \
 test_subst2.h.test test_subst2.cc.test \
-test1.h.test test1_c.h.test example_text.h.test example_text_c.h.test \
+test1.h.test test1_c.h.test test1_lua.lua.test example_text.h.test example_text_c.h.test example_text_lua.lua.test \
 example_fundef.h.test \
-test_cicle_c.h.test \
-test_cicle2_c.h.test \
-test_cicle2_c.c.test \
-test_body_loop_c.h.test \
+test_cicle_c.h.test test_cicle_lua.lua.test \
+test_cicle2_c.h.test test_cicle2_lua.header.test \
+test_cicle2_c.c.test test_cicle2_lua.lua.test \
+test_body_loop_c.h.test test_body_loop_lua.lua.test \
 gen_test_cicle_c.cc.test \
 gen_test_cicle_str_c.cc.test \
 gen_test_cicle_c_cc.cc.test \
 gen_test_cicle_cstring.cc.test \
 test_cicle_tabs.h.test \
 test_cicle_tabs_c.h.test \
+test_cicle_tabs_lua.lua.test \
 gen_test_cicle_tabs.cc.test \
 gen_test_cicle_tabs_c.cc.test \
-test_if.h.test test_if_c.h.test \
-test_types.h.test test_types_c.h.test
+test_if.h.test test_if_c.h.test test_if_lua.lua.test \
+test_types.h.test test_types_c.h.test test_types_lua.lua.test
 
 CXXLD = $(CXX)
 COMPILE_BUILT_EXEC = $(CXXLD) -DHAVE_CONFIG_H $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -I$(top_builddir)/tests/ -I$(top_srcdir)/src/ -I$(top_builddir)/ -o $@ $^
 CCLD = $(CC)
 COMPILE_C_BUILT_EXEC = $(CCLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -I$(top_builddir)/tests/ -o $@ $^
 
-
 test_vars$(EXEEXT): $(test_vars_BUILT_SRC)
 	$(COMPILE_BUILT_EXEC)
 
@@ -251,6 +260,9 @@ example_text.h: example_text.text_skel
 example_text_c.h: example_text.text_skel
 	$(GENERATE) -i $< --file-name $@ --gen-name example_text --output-format=c
 
+example_text_lua.lua: example_text.text_skel
+	$(GENERATE) -i $< --file-name $@ --gen-name example_text --output-format=lua
+
 test_if$(EXEEXT): $(test_if_BUILT_SRC) test_if.h
 	$(COMPILE_BUILT_EXEC)
 
@@ -271,6 +283,10 @@ test_cicle2_c.c: test_cicle2_c.h
 test_cicle2_c.h: test_cicle.cc_skel
 	$(GENERATE_C) -i $< --file-name $@ --gen-name test_cicle --separate-files
 
+test_cicle2_lua.lua: test_cicle2_lua.header
+test_cicle2_lua.header: test_cicle.cc_skel
+	$(GENERATE_LUA) -i $< --file-name $@ --gen-name test_cicle --separate-files
+
 gen_test_vars.cc: test_vars$(EXEEXT)
 	$(top_builddir)/tests/$< > $@
 
@@ -401,6 +417,7 @@ check-valgrind: valgrind_tests.sh
 check-gengen-valgrind: valgrind_gengen_tests.sh
 	$(SHELL) valgrind_gengen_tests.sh $(PROGEXE) -i $(srcdir)/test_cicle_tabs.cc_skel --file-name temp_file --gen-name test_cicle --expand-tabs
 	$(SHELL) valgrind_gengen_tests.sh $(PROGEXE_C) -i $(srcdir)/test_cicle_tabs.cc_skel --file-name temp_file --gen-name test_cicle --expand-tabs
+	$(SHELL) valgrind_gengen_tests.sh $(PROGEXE_LUA) -i $(srcdir)/test_cicle_tabs.cc_skel --file-name temp_file --gen-name test_cicle --expand-tabs
 	rm -f temp_file
 
 CLEANFILES = $(BUILT_SOURCES) $(BUILT_EXECUTABLES) *.err_test $(VERBOSEOUT)
diff --git a/tests/example_text_gen_lua.lua b/tests/example_text_gen_lua.lua
new file mode 100644
index 0000000..3c2f295
--- /dev/null
+++ b/tests/example_text_gen_lua.lua
@@ -0,0 +1,17 @@
+
+require("example_text_lua")
+
+init_example_text_gen_table(example_text_gen_table)
+example_text_gen_table.name = "an example"
+example_text_gen_table.progname = "example_text_gen"
+example_text_gen_table.generator = "Gengen"
+example_text_gen_table.version = "1.0"
+
+generate_example_text(stdout, example_text_gen_table, 0)
+print("\n")
+
+example_text_gen_table.name = "another example"
+io.write("  ")
+
+generate_example_text(stdout, example_text_gen_table, 2)
+io.write("\n")
diff --git a/tests/example_text_lua.lua.test b/tests/example_text_lua.lua.test
new file mode 100644
index 0000000..13e1a73
--- /dev/null
+++ b/tests/example_text_lua.lua.test
@@ -0,0 +1,131 @@
+--[[
+    File automatically generated by
+    gengen 1.4.2 by Lorenzo Bettini 
+    http://www.gnu.org/software/gengen
+--]]
+
+-- Field table
+example_text_gen_table = {
+  generator,
+  name,
+  progname,
+  version,
+}
+
+function generate_example_text(stream, record, indent)
+  local id = {}
+  local indent_str = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+
+  io.write("This is ")
+  io.write((record.name) and record.name or ""
+)
+  io.write(" generated by the program ")
+  io.write((record.progname) and record.progname or ""
+)
+  io.write(".")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("The code of ")
+  io.write((record.progname) and record.progname or ""
+)
+  io.write(" that generated this text was")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("generated by ")
+  io.write((record.generator) and record.generator or ""
+)
+  io.write(" version ")
+  io.write((record.version) and record.version or ""
+)
+  io.write(", made by")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("Lorenzo Bettini <foobar")
+  io.write("@")
+  io.write("foo.org>.")
+
+  -- restore context
+  io.output(ctx)
+end
+
+function generatep_example_text(stream, indent, generator, name, progname, version)
+  record = {}
+  
+  record.generator = generator
+  record.name = name
+  record.progname = progname
+  record.version = version
+
+  generate_example_text(stream, record, indent)
+end
+
+function genstring_example_text(record, indent)
+  local id = {}
+  local indent_str = ""
+  local output = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+
+  output = output .. "This is "
+  if (record.name) then output = output .. record.name end
+  output = output .. " generated by the program "
+  if (record.progname) then output = output .. record.progname end
+  output = output .. "."
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "The code of "
+  if (record.progname) then output = output .. record.progname end
+  output = output .. " that generated this text was"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "generated by "
+  if (record.generator) then output = output .. record.generator end
+  output = output .. " version "
+  if (record.version) then output = output .. record.version end
+  output = output .. ", made by"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "Lorenzo Bettini <foobar"
+  output = output .. "@"
+  output = output .. "foo.org>."
+  return output;
+end
+
+function genstringp_example_text(indent, generator, name, progname, version)
+  record = {}
+  
+  record.generator = generator
+  record.name = name
+  record.progname = progname
+  record.version = version
+
+  return genstring_example_text (record, indent);
+end
+
+function strcnt_example_text(record, indent)
+  local length = 0;
+  
+  length = length + ((record.name) and string.len(record.name) or 0) * 1;
+  length = length + ((record.progname) and string.len(record.progname) or 0) * 2;
+  length = length + ((record.generator) and string.len(record.generator) or 0) * 1;
+  length = length + ((record.version) and string.len(record.version) or 0) * 1;
+
+  return length + 149;
+end
+
+function init_example_text_gen_table(record)
+  record.generator = nil
+  record.name = nil
+  record.progname = nil
+  record.version = nil
+end
+
diff --git a/tests/test1_gen_lua.lua b/tests/test1_gen_lua.lua
new file mode 100644
index 0000000..065500f
--- /dev/null
+++ b/tests/test1_gen_lua.lua
@@ -0,0 +1,9 @@
+
+require ("test1_lua")
+
+test1_gen_table.i = "foo"
+generate_test1(stdout, test1_gen_table, 0)
+print("\n")
+test1_gen_table.i = "bar"
+generate_test1(stdout, test1_gen_table, 0)
+print("\n")
diff --git a/tests/test1_lua.lua.test b/tests/test1_lua.lua.test
new file mode 100644
index 0000000..a910e83
--- /dev/null
+++ b/tests/test1_lua.lua.test
@@ -0,0 +1,90 @@
+--[[
+    File automatically generated by
+    gengen 1.4.2 by Lorenzo Bettini 
+    http://www.gnu.org/software/gengen
+--]]
+
+-- Field table
+test1_gen_table = {
+  i,
+}
+
+function generate_test1(stream, record, indent)
+  local id = {}
+  local indent_str = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+
+  io.write("if (")
+  io.write((record.i) and record.i or ""
+)
+  io.write(" < 10)")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  printf(\"the value of ")
+  io.write((record.i) and record.i or ""
+)
+  io.write(" is %d\", ")
+  io.write((record.i) and record.i or ""
+)
+  io.write(");")
+
+  -- restore context
+  io.output(ctx)
+end
+
+function generatep_test1(stream, indent, i)
+  record = {}
+  
+  record.i = i
+
+  generate_test1(stream, record, indent)
+end
+
+function genstring_test1(record, indent)
+  local id = {}
+  local indent_str = ""
+  local output = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+
+  output = output .. "if ("
+  if (record.i) then output = output .. record.i end
+  output = output .. " < 10)"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  printf(\"the value of "
+  if (record.i) then output = output .. record.i end
+  output = output .. " is %d\", "
+  if (record.i) then output = output .. record.i end
+  output = output .. ");"
+  return output;
+end
+
+function genstringp_test1(indent, i)
+  record = {}
+  
+  record.i = i
+
+  return genstring_test1 (record, indent);
+end
+
+function strcnt_test1(record, indent)
+  local length = 0;
+  
+  length = length + ((record.i) and string.len(record.i) or 0) * 3;
+
+  return length + 47;
+end
+
+function init_test1_gen_table(record)
+  record.i = nil
+end
+
diff --git a/tests/test_body_loop.lua_skel b/tests/test_body_loop.lua_skel
new file mode 100644
index 0000000..4211f39
--- /dev/null
+++ b/tests/test_body_loop.lua_skel
@@ -0,0 +1,7 @@
+cout << "These are the numbers from " << 
+        @my_start@ << " to " << @my_end@ << endl;
+
+for (int i = @my_start@; i <= @my_end@; ++i)
+   cout << i << " ";
+
+cout << endl;
diff --git a/tests/test_body_loop_lua.lua.test b/tests/test_body_loop_lua.lua.test
new file mode 100644
index 0000000..deb5dac
--- /dev/null
+++ b/tests/test_body_loop_lua.lua.test
@@ -0,0 +1,132 @@
+--[[
+    File automatically generated by
+    gengen 1.4.2 by Lorenzo Bettini 
+    http://www.gnu.org/software/gengen
+--]]
+
+-- Field table
+test_body_loop_gen_table = {
+  my_end,
+  my_start,
+}
+
+function generate_test_body_loop(stream, record, indent)
+  local id = {}
+  local indent_str = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+
+  io.write("cout << \"These are the numbers from \" << ")
+  io.write("\n")
+  io.write(indent_str)
+  indent = 8;
+  io.write("        ")
+  io.write((record.my_start) and record.my_start or ""
+)
+  io.write(" << \" to \" << ")
+  io.write((record.my_end) and record.my_end or ""
+)
+  io.write(" << endl;")
+  indent = 0;
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("for (int i = ")
+  io.write((record.my_start) and record.my_start or ""
+)
+  io.write("; i <= ")
+  io.write((record.my_end) and record.my_end or ""
+)
+  io.write("; ++i)")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("   cout << i << \" \";")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("cout << endl;")
+  io.write("\n")
+  io.write(indent_str)
+
+  -- restore context
+  io.output(ctx)
+end
+
+function generatep_test_body_loop(stream, indent, my_end, my_start)
+  record = {}
+  
+  record.my_end = my_end
+  record.my_start = my_start
+
+  generate_test_body_loop(stream, record, indent)
+end
+
+function genstring_test_body_loop(record, indent)
+  local id = {}
+  local indent_str = ""
+  local output = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+
+  output = output .. "cout << \"These are the numbers from \" << "
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "        "
+  if (record.my_start) then output = output .. record.my_start end
+  output = output .. " << \" to \" << "
+  if (record.my_end) then output = output .. record.my_end end
+  output = output .. " << endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "for (int i = "
+  if (record.my_start) then output = output .. record.my_start end
+  output = output .. "; i <= "
+  if (record.my_end) then output = output .. record.my_end end
+  output = output .. "; ++i)"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "   cout << i << \" \";"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "cout << endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  return output;
+end
+
+function genstringp_test_body_loop(indent, my_end, my_start)
+  record = {}
+  
+  record.my_end = my_end
+  record.my_start = my_start
+
+  return genstring_test_body_loop (record, indent);
+end
+
+function strcnt_test_body_loop(record, indent)
+  local length = 0;
+  
+  length = length + ((record.my_start) and string.len(record.my_start) or 0) * 2;
+  length = length + ((record.my_end) and string.len(record.my_end) or 0) * 2;
+
+  return length + 152;
+end
+
+function init_test_body_loop_gen_table(record)
+  record.my_end = nil
+  record.my_start = nil
+end
+
diff --git a/tests/test_cicle2_lua.header.test b/tests/test_cicle2_lua.header.test
new file mode 100644
index 0000000..cbc8227
--- /dev/null
+++ b/tests/test_cicle2_lua.header.test
@@ -0,0 +1,37 @@
+--[[
+    File automatically generated by
+    gengen 1.4.2 by Lorenzo Bettini 
+    http://www.gnu.org/software/gengen
+--]]
+
+-- Field table
+test_cicle_gen_table = {
+  loop,
+  loopnum,
+  printnumloop,
+  printsomething,
+  return_st,
+  zeroloops,
+}
+
+
+generate_loop = function(stream, record, indent)
+--[[
+    This call back function will be executed if 'var'
+    associated with type 'method' is 'nil'. You could
+    add your Lua code here.
+--]]
+end
+
+
+
+generate_return_st = function(stream, record, indent)
+--[[
+    This call back function will be executed if 'var'
+    associated with type 'method' is 'nil'. You could
+    add your Lua code here.
+--]]
+end
+
+
+
diff --git a/tests/test_cicle2_lua.lua.test b/tests/test_cicle2_lua.lua.test
new file mode 100644
index 0000000..c02f877
--- /dev/null
+++ b/tests/test_cicle2_lua.lua.test
@@ -0,0 +1,422 @@
+--[[
+    File automatically generated by
+    gengen 1.4.2 by Lorenzo Bettini 
+    http://www.gnu.org/software/gengen
+--]]
+
+dofile("test_cicle2_lua.header")
+
+
+function strchr_tab(tab, char)
+  local store
+  local ret_str = ""
+  for w, k in ipairs(tab) do
+    if(k == char) then
+      store = w
+      break
+    end
+  end
+  if(store == nil) then
+    return nil
+  end
+  for i = store, #tab do
+    ret_str = ret_str .. tab[i]
+  end
+  return store, ret_str
+end
+
+function str_to_tab(str)
+  tab = {}
+  for i in string.gmatch(str, ".") do
+    table.insert(tab, i)
+  end
+  return tab
+end
+
+function generate_string(s, stream, indent)
+  local subs = s
+  local indent_str = ""
+  local id = {}
+  local pos = 0
+  local my_tab = str_to_tab(s)
+
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+
+  if((indent == 0) or (strchr_tab(my_tab, "\n") == nil)) then
+    io.write(s)
+    return
+  end
+
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+
+  while(true) do
+    pos, subs = strchr_tab(str_to_tab(s), '\n')
+    if(subs == nil) then break end
+    io.write(table.concat(my_tab, "", 1, pos))
+    s = subs:sub(2)
+    my_tab = str_to_tab(s)
+    if(s ~= "") then
+      io.write(indent_str);
+    end
+  end
+  if(s) then
+    io.write(s)
+  end
+
+  -- restore context
+  io.output(ctx)
+end
+
+function generate_test_cicle(stream, record, indent)
+  local id = {}
+  local indent_str = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+
+  io.write("#include <iostream>")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("using std::cout;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("using std::endl;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("#define NUM_OF_LOOPS ")
+  io.write((record.loopnum) and record.loopnum or ""
+)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("int")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("main()")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("{")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  cout << \"The val of NUM_OF_LOOPS is \";")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  cout << ")
+  io.write((record.loopnum) and record.loopnum or ""
+)
+  io.write(" << endl;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  if (record.zeroloops) then
+    io.write("  /*")
+    io.write("\n")
+    io.write(indent_str)
+    io.write("   * No loop generated since NUM_OF_LOOPS is 0")
+    io.write("\n")
+    io.write(indent_str)
+    io.write("   */")
+    io.write("\n")
+    io.write(indent_str)
+  
+  else
+    if (record.printsomething) then
+      if (record.printnumloop) then
+        io.write("  cout << \"zero loops: \" << ")
+        io.write((record.loopnum) and record.loopnum or ""
+        )
+        io.write(" << endl;")
+        io.write("\n")
+        io.write(indent_str)
+      
+      else
+        io.write("  cout << \"zero loops!\" << endl;")
+        io.write("\n")
+        io.write(indent_str)
+      end
+    
+    else
+      indent = 2;
+      io.write("  ")
+      
+      if(record.loop) then
+        generate_string(record.loop, stream, indent + string.len(indent_str))
+      else
+        generate_loop(stream, record, indent + string.len(indent_str))
+      end
+      
+      indent = 0;
+      io.write("\n")
+      io.write(indent_str)
+      if (record.zeroloops) then
+        
+      
+      
+      else
+        
+      
+      end
+      
+      
+      if (record.zeroloops) then
+        
+      
+      
+      else
+        
+      
+      end
+      
+      
+      if (record.zeroloops) then
+        
+      
+      end
+    end
+  end
+  
+  
+  io.write("\n")
+  io.write(indent_str)
+  indent = 2;
+  io.write("  ")
+  
+  if(record.return_st) then
+    generate_string(record.return_st, stream, indent + string.len(indent_str))
+  else
+    generate_return_st(stream, record, indent + string.len(indent_str))
+  end
+  
+  indent = 0;
+  io.write("\n")
+  io.write(indent_str)
+  io.write("}")
+  io.write("\n")
+  io.write(indent_str)
+
+  -- restore context
+  io.output(ctx)
+end
+
+function generatep_test_cicle(stream, indent, loop, loopnum, printnumloop, printsomething, return_st, zeroloops)
+  record = {}
+  
+  record.loop = loop
+  record.loopnum = loopnum
+  record.printnumloop = printnumloop
+  record.printsomething = printsomething
+  record.return_st = return_st
+  record.zeroloops = zeroloops
+
+  generate_test_cicle(stream, record, indent)
+end
+
+function genstring_test_cicle(record, indent)
+  local id = {}
+  local indent_str = ""
+  local output = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+
+  output = output .. "#include <iostream>"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "using std::cout;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "using std::endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "#define NUM_OF_LOOPS "
+  if (record.loopnum) then output = output .. record.loopnum end
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "int"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "main()"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "{"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  cout << \"The val of NUM_OF_LOOPS is \";"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  cout << "
+  if (record.loopnum) then output = output .. record.loopnum end
+  output = output .. " << endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  if (record.zeroloops) then
+    output = output .. "  /*"
+    output = output .. "\n"
+    output = output .. indent_str
+    output = output .. "   * No loop generated since NUM_OF_LOOPS is 0"
+    output = output .. "\n"
+    output = output .. indent_str
+    output = output .. "   */"
+    output = output .. "\n"
+    output = output .. indent_str
+  
+  else
+    if (record.printsomething) then
+      if (record.printnumloop) then
+        output = output .. "  cout << \"zero loops: \" << "
+        if (record.loopnum) then output = output .. record.loopnum end
+        output = output .. " << endl;"
+        output = output .. "\n"
+        output = output .. indent_str
+      
+      else
+        output = output .. "  cout << \"zero loops!\" << endl;"
+        output = output .. "\n"
+        output = output .. indent_str
+      end
+    
+    else
+      output = output .. "  "
+      if (record.loop) then output = output .. record.loop end
+      output = output .. "\n"
+      output = output .. indent_str
+      if (record.zeroloops) then
+        
+      
+      
+      else
+        
+      
+      end
+      
+      
+      if (record.zeroloops) then
+        
+      
+      
+      else
+        
+      
+      end
+      
+      
+      if (record.zeroloops) then
+        
+      
+      end
+    end
+  end
+  
+  
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  "
+  if (record.return_st) then output = output .. record.return_st end
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "}"
+  output = output .. "\n"
+  output = output .. indent_str
+  return output;
+end
+
+function genstringp_test_cicle(indent, loop, loopnum, printnumloop, printsomething, return_st, zeroloops)
+  record = {}
+  
+  record.loop = loop
+  record.loopnum = loopnum
+  record.printnumloop = printnumloop
+  record.printsomething = printsomething
+  record.return_st = return_st
+  record.zeroloops = zeroloops
+
+  return genstring_test_cicle (record, indent);
+end
+
+function strcnt_test_cicle(record, indent)
+  local length = 0;
+  
+  length = length + ((record.loopnum) and string.len(record.loopnum) or 0) * 3;
+if (record.zeroloops) then
+    
+
+  
+  else
+    if (record.printsomething) then
+      if (record.printnumloop) then
+        
+      
+      
+      else
+        
+      
+      end
+    
+    else
+      length = length + ((record.loop) and string.len(record.loop) or 0) * 1;
+      if (record.zeroloops) then
+        
+      
+      
+      else
+        
+      
+      end
+      
+      
+      if (record.zeroloops) then
+        
+      
+      
+      else
+        
+      
+      end
+      
+      
+      if (record.zeroloops) then
+        
+      
+      end
+    end
+  end
+  
+  
+  length = length + ((record.return_st) and string.len(record.return_st) or 0) * 1;
+
+  return length + 324;
+end
+
+function init_test_cicle_gen_table(record)
+  record.loop = nil
+  record.loopnum = nil
+  record.printnumloop = nil
+  record.printsomething = nil
+  record.return_st = nil
+  record.zeroloops = nil
+end
+
diff --git a/tests/test_cicle2_main.lua b/tests/test_cicle2_main.lua
new file mode 100644
index 0000000..d3c4e99
--- /dev/null
+++ b/tests/test_cicle2_main.lua
@@ -0,0 +1,16 @@
+
+require("test_cicle2_lua.lua")
+require("test_body_loop_lua.lua")
+
+function generate_loop(stream, table, indent)
+  table.my_start = "1"
+  table.my_end = "10"
+  generate_test_body_loop (stream, table, indent)
+end
+
+function generate_return_st(stream, table, indent)
+end
+
+test_cicle_gen_table.loopnum = "10"
+test_cicle_gen_table.return_st = "return 0;"
+generate_test_cicle (stdout, test_cicle_gen_table, 0);
diff --git a/tests/test_cicle_gen_lua.lua b/tests/test_cicle_gen_lua.lua
new file mode 100644
index 0000000..00b2115
--- /dev/null
+++ b/tests/test_cicle_gen_lua.lua
@@ -0,0 +1,16 @@
+
+require("test_cicle_lua.lua")
+require("test_body_loop_lua.lua")
+
+function generate_loop(stream, table, indent)
+  table.my_start = "1"
+  table.my_end = "10"
+  generate_test_body_loop (stream, table, indent)
+end
+
+function generate_return_st(stream, table, indent)
+end
+
+test_cicle_gen_table.loopnum = "10"
+test_cicle_gen_table.return_st = "return 0;"
+generate_test_cicle (stdout, test_cicle_gen_table, 0);
diff --git a/tests/test_cicle_lua.lua.test b/tests/test_cicle_lua.lua.test
new file mode 100644
index 0000000..af4e78f
--- /dev/null
+++ b/tests/test_cicle_lua.lua.test
@@ -0,0 +1,450 @@
+--[[
+    File automatically generated by
+    gengen 1.4.2 by Lorenzo Bettini 
+    http://www.gnu.org/software/gengen
+--]]
+
+-- Field table
+test_cicle_gen_table = {
+  loop,
+  loopnum,
+  printnumloop,
+  printsomething,
+  return_st,
+  zeroloops,
+}
+
+
+generate_loop = function(stream, record, indent)
+--[[
+    This call back function will be executed if 'var'
+    associated with type 'method' is 'nil'. You could
+    add your Lua code here.
+--]]
+end
+
+
+
+generate_return_st = function(stream, record, indent)
+--[[
+    This call back function will be executed if 'var'
+    associated with type 'method' is 'nil'. You could
+    add your Lua code here.
+--]]
+end
+
+
+
+function strchr_tab(tab, char)
+  local store
+  local ret_str = ""
+  for w, k in ipairs(tab) do
+    if(k == char) then
+      store = w
+      break
+    end
+  end
+  if(store == nil) then
+    return nil
+  end
+  for i = store, #tab do
+    ret_str = ret_str .. tab[i]
+  end
+  return store, ret_str
+end
+
+function str_to_tab(str)
+  tab = {}
+  for i in string.gmatch(str, ".") do
+    table.insert(tab, i)
+  end
+  return tab
+end
+
+function generate_string(s, stream, indent)
+  local subs = s
+  local indent_str = ""
+  local id = {}
+  local pos = 0
+  local my_tab = str_to_tab(s)
+
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+
+  if((indent == 0) or (strchr_tab(my_tab, "\n") == nil)) then
+    io.write(s)
+    return
+  end
+
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+
+  while(true) do
+    pos, subs = strchr_tab(str_to_tab(s), '\n')
+    if(subs == nil) then break end
+    io.write(table.concat(my_tab, "", 1, pos))
+    s = subs:sub(2)
+    my_tab = str_to_tab(s)
+    if(s ~= "") then
+      io.write(indent_str);
+    end
+  end
+  if(s) then
+    io.write(s)
+  end
+
+  -- restore context
+  io.output(ctx)
+end
+
+function generate_test_cicle(stream, record, indent)
+  local id = {}
+  local indent_str = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+
+  io.write("#include <iostream>")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("using std::cout;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("using std::endl;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("#define NUM_OF_LOOPS ")
+  io.write((record.loopnum) and record.loopnum or ""
+)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("int")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("main()")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("{")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  cout << \"The val of NUM_OF_LOOPS is \";")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  cout << ")
+  io.write((record.loopnum) and record.loopnum or ""
+)
+  io.write(" << endl;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  if (record.zeroloops) then
+    io.write("  /*")
+    io.write("\n")
+    io.write(indent_str)
+    io.write("   * No loop generated since NUM_OF_LOOPS is 0")
+    io.write("\n")
+    io.write(indent_str)
+    io.write("   */")
+    io.write("\n")
+    io.write(indent_str)
+  
+  else
+    if (record.printsomething) then
+      if (record.printnumloop) then
+        io.write("  cout << \"zero loops: \" << ")
+        io.write((record.loopnum) and record.loopnum or ""
+        )
+        io.write(" << endl;")
+        io.write("\n")
+        io.write(indent_str)
+      
+      else
+        io.write("  cout << \"zero loops!\" << endl;")
+        io.write("\n")
+        io.write(indent_str)
+      end
+    
+    else
+      indent = 2;
+      io.write("  ")
+      
+      if(record.loop) then
+        generate_string(record.loop, stream, indent + string.len(indent_str))
+      else
+        generate_loop(stream, record, indent + string.len(indent_str))
+      end
+      
+      indent = 0;
+      io.write("\n")
+      io.write(indent_str)
+      if (record.zeroloops) then
+        
+      
+      
+      else
+        
+      
+      end
+      
+      
+      if (record.zeroloops) then
+        
+      
+      
+      else
+        
+      
+      end
+      
+      
+      if (record.zeroloops) then
+        
+      
+      end
+    end
+  end
+  
+  
+  io.write("\n")
+  io.write(indent_str)
+  indent = 2;
+  io.write("  ")
+  
+  if(record.return_st) then
+    generate_string(record.return_st, stream, indent + string.len(indent_str))
+  else
+    generate_return_st(stream, record, indent + string.len(indent_str))
+  end
+  
+  indent = 0;
+  io.write("\n")
+  io.write(indent_str)
+  io.write("}")
+  io.write("\n")
+  io.write(indent_str)
+
+  -- restore context
+  io.output(ctx)
+end
+
+function generatep_test_cicle(stream, indent, loop, loopnum, printnumloop, printsomething, return_st, zeroloops)
+  record = {}
+  
+  record.loop = loop
+  record.loopnum = loopnum
+  record.printnumloop = printnumloop
+  record.printsomething = printsomething
+  record.return_st = return_st
+  record.zeroloops = zeroloops
+
+  generate_test_cicle(stream, record, indent)
+end
+
+function genstring_test_cicle(record, indent)
+  local id = {}
+  local indent_str = ""
+  local output = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+
+  output = output .. "#include <iostream>"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "using std::cout;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "using std::endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "#define NUM_OF_LOOPS "
+  if (record.loopnum) then output = output .. record.loopnum end
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "int"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "main()"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "{"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  cout << \"The val of NUM_OF_LOOPS is \";"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  cout << "
+  if (record.loopnum) then output = output .. record.loopnum end
+  output = output .. " << endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  if (record.zeroloops) then
+    output = output .. "  /*"
+    output = output .. "\n"
+    output = output .. indent_str
+    output = output .. "   * No loop generated since NUM_OF_LOOPS is 0"
+    output = output .. "\n"
+    output = output .. indent_str
+    output = output .. "   */"
+    output = output .. "\n"
+    output = output .. indent_str
+  
+  else
+    if (record.printsomething) then
+      if (record.printnumloop) then
+        output = output .. "  cout << \"zero loops: \" << "
+        if (record.loopnum) then output = output .. record.loopnum end
+        output = output .. " << endl;"
+        output = output .. "\n"
+        output = output .. indent_str
+      
+      else
+        output = output .. "  cout << \"zero loops!\" << endl;"
+        output = output .. "\n"
+        output = output .. indent_str
+      end
+    
+    else
+      output = output .. "  "
+      if (record.loop) then output = output .. record.loop end
+      output = output .. "\n"
+      output = output .. indent_str
+      if (record.zeroloops) then
+        
+      
+      
+      else
+        
+      
+      end
+      
+      
+      if (record.zeroloops) then
+        
+      
+      
+      else
+        
+      
+      end
+      
+      
+      if (record.zeroloops) then
+        
+      
+      end
+    end
+  end
+  
+  
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  "
+  if (record.return_st) then output = output .. record.return_st end
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "}"
+  output = output .. "\n"
+  output = output .. indent_str
+  return output;
+end
+
+function genstringp_test_cicle(indent, loop, loopnum, printnumloop, printsomething, return_st, zeroloops)
+  record = {}
+  
+  record.loop = loop
+  record.loopnum = loopnum
+  record.printnumloop = printnumloop
+  record.printsomething = printsomething
+  record.return_st = return_st
+  record.zeroloops = zeroloops
+
+  return genstring_test_cicle (record, indent);
+end
+
+function strcnt_test_cicle(record, indent)
+  local length = 0;
+  
+  length = length + ((record.loopnum) and string.len(record.loopnum) or 0) * 3;
+if (record.zeroloops) then
+    
+
+  
+  else
+    if (record.printsomething) then
+      if (record.printnumloop) then
+        
+      
+      
+      else
+        
+      
+      end
+    
+    else
+      length = length + ((record.loop) and string.len(record.loop) or 0) * 1;
+      if (record.zeroloops) then
+        
+      
+      
+      else
+        
+      
+      end
+      
+      
+      if (record.zeroloops) then
+        
+      
+      
+      else
+        
+      
+      end
+      
+      
+      if (record.zeroloops) then
+        
+      
+      end
+    end
+  end
+  
+  
+  length = length + ((record.return_st) and string.len(record.return_st) or 0) * 1;
+
+  return length + 324;
+end
+
+function init_test_cicle_gen_table(record)
+  record.loop = nil
+  record.loopnum = nil
+  record.printnumloop = nil
+  record.printsomething = nil
+  record.return_st = nil
+  record.zeroloops = nil
+end
+
diff --git a/tests/test_cicle_tabs_gen_lua.lua b/tests/test_cicle_tabs_gen_lua.lua
new file mode 100644
index 0000000..fed32da
--- /dev/null
+++ b/tests/test_cicle_tabs_gen_lua.lua
@@ -0,0 +1,17 @@
+--[[
+     rely on the generate_string method that expands tabs for strings
+     in this case, the loop field
+--]]
+
+dofile("test_cicle_tabs_lua.lua")
+dofile("test_body_loop_lua.lua")
+
+test_body_loop_gen_table.my_start = "1"
+test_body_loop_gen_table.my_end = "10"
+loop_str = genstring_test_body_loop(test_body_loop_gen_table, 0)
+
+test_cicle_gen_table.loopnum = "10"
+test_cicle_gen_table.return_st = "return 0;"
+test_cicle_gen_table.loop = loop_str
+
+generate_test_cicle(stdout, test_cicle_gen_table, 0)
diff --git a/tests/test_cicle_tabs_lua.lua.test b/tests/test_cicle_tabs_lua.lua.test
new file mode 100644
index 0000000..f167878
--- /dev/null
+++ b/tests/test_cicle_tabs_lua.lua.test
@@ -0,0 +1,253 @@
+--[[
+    File automatically generated by
+    gengen 1.4.2 by Lorenzo Bettini 
+    http://www.gnu.org/software/gengen
+--]]
+
+-- Field table
+test_cicle_gen_table = {
+  loop,
+  loopnum,
+  return_st,
+}
+
+
+function strchr_tab(tab, char)
+  local store
+  local ret_str = ""
+  for w, k in ipairs(tab) do
+    if(k == char) then
+      store = w
+      break
+    end
+  end
+  if(store == nil) then
+    return nil
+  end
+  for i = store, #tab do
+    ret_str = ret_str .. tab[i]
+  end
+  return store, ret_str
+end
+
+function str_to_tab(str)
+  tab = {}
+  for i in string.gmatch(str, ".") do
+    table.insert(tab, i)
+  end
+  return tab
+end
+
+function generate_string(s, stream, indent)
+  local subs = s
+  local indent_str = ""
+  local id = {}
+  local pos = 0
+  local my_tab = str_to_tab(s)
+
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+
+  if((indent == 0) or (strchr_tab(my_tab, "\n") == nil)) then
+    io.write(s)
+    return
+  end
+
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+
+  while(true) do
+    pos, subs = strchr_tab(str_to_tab(s), '\n')
+    if(subs == nil) then break end
+    io.write(table.concat(my_tab, "", 1, pos))
+    s = subs:sub(2)
+    my_tab = str_to_tab(s)
+    if(s ~= "") then
+      io.write(indent_str);
+    end
+  end
+  if(s) then
+    io.write(s)
+  end
+
+  -- restore context
+  io.output(ctx)
+end
+
+function generate_test_cicle(stream, record, indent)
+  local id = {}
+  local indent_str = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+
+  io.write("#include <iostream>")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("using std::cout;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("using std::endl;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("#define NUM_OF_LOOPS ")
+  generate_string ((record.loopnum) and record.loopnum or ""
+, stream, indent + string.len (indent_str))
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("int")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("main()")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("{")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  cout << \"The val of NUM_OF_LOOPS is \";")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  cout << ")
+  generate_string ((record.loopnum) and record.loopnum or ""
+, stream, indent + string.len (indent_str))
+  io.write(" << endl;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  indent = 2;
+  io.write("  ")
+  generate_string ((record.loop) and record.loop or ""
+, stream, indent + string.len (indent_str))
+  indent = 0;
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  indent = 2;
+  io.write("  ")
+  generate_string ((record.return_st) and record.return_st or ""
+, stream, indent + string.len (indent_str))
+  indent = 0;
+  io.write("\n")
+  io.write(indent_str)
+  io.write("}")
+  io.write("\n")
+  io.write(indent_str)
+
+  -- restore context
+  io.output(ctx)
+end
+
+function generatep_test_cicle(stream, indent, loop, loopnum, return_st)
+  record = {}
+  
+  record.loop = loop
+  record.loopnum = loopnum
+  record.return_st = return_st
+
+  generate_test_cicle(stream, record, indent)
+end
+
+function genstring_test_cicle(record, indent)
+  local id = {}
+  local indent_str = ""
+  local output = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+
+  output = output .. "#include <iostream>"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "using std::cout;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "using std::endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "#define NUM_OF_LOOPS "
+  if (record.loopnum) then output = output .. record.loopnum end
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "int"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "main()"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "{"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  cout << \"The val of NUM_OF_LOOPS is \";"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  cout << "
+  if (record.loopnum) then output = output .. record.loopnum end
+  output = output .. " << endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  "
+  if (record.loop) then output = output .. record.loop end
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  "
+  if (record.return_st) then output = output .. record.return_st end
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "}"
+  output = output .. "\n"
+  output = output .. indent_str
+  return output;
+end
+
+function genstringp_test_cicle(indent, loop, loopnum, return_st)
+  record = {}
+  
+  record.loop = loop
+  record.loopnum = loopnum
+  record.return_st = return_st
+
+  return genstring_test_cicle (record, indent);
+end
+
+function strcnt_test_cicle(record, indent)
+  local length = 0;
+  
+  length = length + ((record.loopnum) and string.len(record.loopnum) or 0) * 2;
+  length = length + ((record.loop) and string.len(record.loop) or 0) * 1;
+  length = length + ((record.return_st) and string.len(record.return_st) or 0) * 1;
+
+  return length + 197;
+end
+
+function init_test_cicle_gen_table(record)
+  record.loop = nil
+  record.loopnum = nil
+  record.return_st = nil
+end
+
diff --git a/tests/test_if_gen_lua.lua b/tests/test_if_gen_lua.lua
new file mode 100644
index 0000000..b224598
--- /dev/null
+++ b/tests/test_if_gen_lua.lua
@@ -0,0 +1,11 @@
+
+require("test_if_lua")
+
+test_if_gen_table.myvar = "\"fooval\""
+test_if_gen_table.mydef = "foodef";
+test_if_gen_table.boolvar = 0;
+test_if_gen_table.intvar = 0;
+test_if_gen_table.intvarcomp = 0;
+test_if_gen_table.stringvar = "bar";
+test_if_gen_table.stringvarcomp = "ba";
+generate_test_if(stdout, test_if_gen_table, 0);
diff --git a/tests/test_if_lua.lua.test b/tests/test_if_lua.lua.test
new file mode 100644
index 0000000..43ab7b7
--- /dev/null
+++ b/tests/test_if_lua.lua.test
@@ -0,0 +1,167 @@
+--[[
+    File automatically generated by
+    gengen 1.4.2 by Lorenzo Bettini 
+    http://www.gnu.org/software/gengen
+--]]
+
+-- Field table
+test_types_gen_table = {
+  mybool,
+  myint,
+  mystring,
+}
+
+
+function int_to_string(i)
+  return tostring(i)
+end
+
+
+
+function bool_to_string(b)
+  return b
+end
+
+function generate_test_types(stream, record, indent)
+  local id = {}
+  local indent_str = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+
+  io.write("#include <iostream>")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("using namespace std;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("int main()")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("{")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  cout << \"this is a string: \" << ")
+  io.write((record.mystring) and record.mystring or ""
+)
+  io.write(" << endl;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  cout << \"this is an int: \" << ")
+  io.write(record.myint)
+  io.write(" << endl;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  cout << \"this is a bool: \" << ")
+  io.write(record.mybool)
+  io.write(" << endl;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  return 0;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("}")
+  io.write("\n")
+  io.write(indent_str)
+
+  -- restore context
+  io.output(ctx)
+end
+
+function generatep_test_types(stream, indent, mybool, myint, mystring)
+  record = {}
+  
+  record.mybool = mybool
+  record.myint = myint
+  record.mystring = mystring
+
+  generate_test_types(stream, record, indent)
+end
+
+function genstring_test_types(record, indent)
+  local id = {}
+  local indent_str = ""
+  local output = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+
+  output = output .. "#include <iostream>"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "using namespace std;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "int main()"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "{"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  cout << \"this is a string: \" << "
+  if (record.mystring) then output = output .. record.mystring end
+  output = output .. " << endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  cout << \"this is an int: \" << "
+  output = output .. int_to_string(record.myint)
+  output = output .. " << endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  cout << \"this is a bool: \" << "
+  output = output .. bool_to_string(record.mybool)
+  output = output .. " << endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  return 0;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "}"
+  output = output .. "\n"
+  output = output .. indent_str
+  return output;
+end
+
+function genstringp_test_types(indent, mybool, myint, mystring)
+  record = {}
+  
+  record.mybool = mybool
+  record.myint = myint
+  record.mystring = mystring
+
+  return genstring_test_types (record, indent);
+end
+
+function strcnt_test_types(record, indent)
+  local length = 0;
+  
+  length = length + ((record.mystring) and string.len(record.mystring) or 0) * 1;
+  length = length + string.len(int_to_string(record.myint)) * 1;
+  length = length + string.length(bool_to_string(record.mybool)) * 1;
+
+  return length + 223;
+end
+
+function init_test_types_gen_table(record)
+  record.mybool = nil
+  record.myint = nil
+  record.mystring = nil
+end
+
diff --git a/tests/test_types_gen_lua.lua b/tests/test_types_gen_lua.lua
new file mode 100644
index 0000000..a939f52
--- /dev/null
+++ b/tests/test_types_gen_lua.lua
@@ -0,0 +1,7 @@
+
+require("test_types_lua")
+
+test_types_gen_table.mystring = "hello_world"
+test_types_gen_table.myint = 1971
+test_types_gen_table.mybool = 1
+generate_test_types(stdout, test_types_gen_table, 0)
diff --git a/tests/test_types_lua.lua.test b/tests/test_types_lua.lua.test
new file mode 100644
index 0000000..43ab7b7
--- /dev/null
+++ b/tests/test_types_lua.lua.test
@@ -0,0 +1,167 @@
+--[[
+    File automatically generated by
+    gengen 1.4.2 by Lorenzo Bettini 
+    http://www.gnu.org/software/gengen
+--]]
+
+-- Field table
+test_types_gen_table = {
+  mybool,
+  myint,
+  mystring,
+}
+
+
+function int_to_string(i)
+  return tostring(i)
+end
+
+
+
+function bool_to_string(b)
+  return b
+end
+
+function generate_test_types(stream, record, indent)
+  local id = {}
+  local indent_str = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+  -- save context
+  local ctx = io.output()
+  io.output(stream)
+
+  io.write("#include <iostream>")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("using namespace std;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("int main()")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("{")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  cout << \"this is a string: \" << ")
+  io.write((record.mystring) and record.mystring or ""
+)
+  io.write(" << endl;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  cout << \"this is an int: \" << ")
+  io.write(record.myint)
+  io.write(" << endl;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  cout << \"this is a bool: \" << ")
+  io.write(record.mybool)
+  io.write(" << endl;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("\n")
+  io.write(indent_str)
+  io.write("  return 0;")
+  io.write("\n")
+  io.write(indent_str)
+  io.write("}")
+  io.write("\n")
+  io.write(indent_str)
+
+  -- restore context
+  io.output(ctx)
+end
+
+function generatep_test_types(stream, indent, mybool, myint, mystring)
+  record = {}
+  
+  record.mybool = mybool
+  record.myint = myint
+  record.mystring = mystring
+
+  generate_test_types(stream, record, indent)
+end
+
+function genstring_test_types(record, indent)
+  local id = {}
+  local indent_str = ""
+  local output = ""
+  for i = 1, indent do
+    id[#id + 1] = ' '
+  end
+  indent_str = table.concat(id)
+
+  output = output .. "#include <iostream>"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "using namespace std;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "int main()"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "{"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  cout << \"this is a string: \" << "
+  if (record.mystring) then output = output .. record.mystring end
+  output = output .. " << endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  cout << \"this is an int: \" << "
+  output = output .. int_to_string(record.myint)
+  output = output .. " << endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  cout << \"this is a bool: \" << "
+  output = output .. bool_to_string(record.mybool)
+  output = output .. " << endl;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "  return 0;"
+  output = output .. "\n"
+  output = output .. indent_str
+  output = output .. "}"
+  output = output .. "\n"
+  output = output .. indent_str
+  return output;
+end
+
+function genstringp_test_types(indent, mybool, myint, mystring)
+  record = {}
+  
+  record.mybool = mybool
+  record.myint = myint
+  record.mystring = mystring
+
+  return genstring_test_types (record, indent);
+end
+
+function strcnt_test_types(record, indent)
+  local length = 0;
+  
+  length = length + ((record.mystring) and string.len(record.mystring) or 0) * 1;
+  length = length + string.len(int_to_string(record.myint)) * 1;
+  length = length + string.length(bool_to_string(record.mybool)) * 1;
+
+  return length + 223;
+end
+
+function init_test_types_gen_table(record)
+  record.mybool = nil
+  record.myint = nil
+  record.mystring = nil
+end
+
