Thrift: Added support for double type across all languages

Summary: Just for completeness cause I'm crazy. Let's never use these!

Notes: Also made thrift grammar support # style comments, so you can do this at the top of your files

#!/usr/local/bin/thrift --cpp

/**
 * This is a thrift def file youc an invoke directly and gen code!
 */

blah


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664789 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc
index b43ee16..56980e4 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/generate/t_cpp_generator.cc
@@ -1125,6 +1125,9 @@
       case t_base_type::TYPE_I64:
         out << "readI64(itrans, " << name << ");";
         break;
+      case t_base_type::TYPE_DOUBLE:
+        out << "readDouble(itrans, " << name << ");";
+        break;
       default:
         throw "compiler error: no C++ reader for base type " + tbase + name;
       }
@@ -1331,6 +1334,9 @@
       case t_base_type::TYPE_I64:
         out << "writeI64(otrans, " << name << ");";
         break;
+      case t_base_type::TYPE_DOUBLE:
+        out << "writeDouble(otrans, " << name << ");";
+        break;
       default:
         throw "compiler error: no C++ writer for base type " + tbase + name;
       }
@@ -1540,6 +1546,8 @@
     return "int32_t";
   case t_base_type::TYPE_I64:
     return "int64_t";
+  case t_base_type::TYPE_DOUBLE:
+    return "double";
   default:
     throw "compiler error: no C++ base type name for base type " + tbase;
   }
@@ -1576,6 +1584,9 @@
       case t_base_type::TYPE_I64:
         result += " = 0";
         break;
+      case t_base_type::TYPE_DOUBLE:
+        result += " = (double)0";
+        break;
       default:
         throw "compiler error: no C++ initializer for base type " + tbase;
       }
@@ -1645,6 +1656,8 @@
       return "facebook::thrift::protocol::T_I32";
     case t_base_type::TYPE_I64:
       return "facebook::thrift::protocol::T_I64";
+    case t_base_type::TYPE_DOUBLE:
+      return "facebook::thrift::protocol::T_DOUBLE";
     }
   } else if (type->is_enum()) {
     return "facebook::thrift::protocol::T_I32";
diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc
index 390c563..6d12dce 100644
--- a/compiler/cpp/src/generate/t_java_generator.cc
+++ b/compiler/cpp/src/generate/t_java_generator.cc
@@ -867,6 +867,9 @@
       case t_base_type::TYPE_I64:
         out << "readI64(_itrans);";
         break;
+      case t_base_type::TYPE_DOUBLE:
+        out << "readDouble(_itrans);";
+        break;
       default:
         throw "compiler error: no Java name for base type " + tbase;
       }
@@ -1068,6 +1071,9 @@
       case t_base_type::TYPE_I64:
         out << "writeI64(_otrans, " << name << ");";
         break;
+      case t_base_type::TYPE_DOUBLE:
+        out << "writeDouble(_otrans, " << name << ");";
+        break;
       default:
         throw "compiler error: no Java name for base type " + tbase;
       }
@@ -1256,6 +1262,8 @@
     return (in_container ? "Integer" : "int");
   case t_base_type::TYPE_I64:
     return (in_container ? "Long" : "long");
+  case t_base_type::TYPE_DOUBLE:
+    return (in_container ? "Double" : "double");
   default:
     throw "compiler error: no C++ name for base type " + tbase;
   }
@@ -1292,6 +1300,9 @@
       case t_base_type::TYPE_I64:
         result += " = 0";
         break;
+      case t_base_type::TYPE_DOUBLE:
+        result += " = (double)0";
+        break;
     }
 
     } else if (ttype->is_enum()) {
@@ -1372,6 +1383,8 @@
       return "TType.I32";
     case t_base_type::TYPE_I64:
       return "TType.I64";
+    case t_base_type::TYPE_DOUBLE:
+      return "TType.DOUBLE";
     }
   } else if (type->is_enum()) {
     return "TType.I32";
diff --git a/compiler/cpp/src/generate/t_php_generator.cc b/compiler/cpp/src/generate/t_php_generator.cc
index 8b05f70..6ac0b33 100644
--- a/compiler/cpp/src/generate/t_php_generator.cc
+++ b/compiler/cpp/src/generate/t_php_generator.cc
@@ -622,7 +622,7 @@
           "return;" << endl;
       } else {
         f_service_ <<
-          indent() << "throw Exception(\"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl;
+          indent() << "throw new Exception(\"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl;
       }     
     }      
 
@@ -722,6 +722,11 @@
             indent() << "  $" << name << " = $_arr[1]*4294967296 + $_arr[2];" << endl <<
             indent() << "}" << endl;
           break;
+        case t_base_type::TYPE_DOUBLE:
+          out <<
+            indent() << "$_arr = unpack('d', strrev(" << itrans << "->readAll(8)));" << endl <<
+            indent() << "$" << name << " = $_arr[1];" << endl;
+          break;
         default:
           throw "compiler error: no PHP name for base type " + tbase + tfield->get_name();
         }
@@ -764,6 +769,9 @@
         case t_base_type::TYPE_I64:
           out << "readI64($itrans, $" << name << ");";
           break;
+        case t_base_type::TYPE_DOUBLE:
+          out << "readDouble($itrans, $" << name << ");";
+          break;
         default:
           throw "compiler error: no PHP name for base type " + tbase;
         }
@@ -808,9 +816,9 @@
   t_field fvtype(g_program->get_byte_type(), vtype);
   t_field fetype(g_program->get_byte_type(), etype);
 
-  indent(out) <<
-    prefix << " = array();" << endl <<
-    "$" << size << " = 0;" << endl;
+  out <<
+    indent() << "$" << prefix << " = array();" << endl <<
+    indent() << "$" << size << " = 0;" << endl;
   
   // Declare variables, read header
   if (ttype->is_map()) {
@@ -1000,6 +1008,10 @@
           out << 
             indent() << "$_output .= pack('N2', $" << name << " >> 32, $" << name << " & 0xFFFFFFFF);" << endl;
           break;
+        case t_base_type::TYPE_DOUBLE:
+          out << 
+            indent() << "$_output .= strrev(pack('d', $" << name << "));" << endl;
+          break;
         default:
           throw "compiler error: no PHP name for base type " + tbase;
         }
@@ -1037,6 +1049,9 @@
         case t_base_type::TYPE_I64:
           out << "writeI64($otrans, $" << name << ");";
           break;
+        case t_base_type::TYPE_DOUBLE:
+          out << "writeDouble($otrans, $" << name << ");";
+          break;
         default:
           throw "compiler error: no PHP name for base type " + tbase;
         }
@@ -1247,6 +1262,8 @@
     return "Int32";
   case t_base_type::TYPE_I64:
     return "Int64";
+  case t_base_type::TYPE_DOUBLE:
+    return "Double";
   default:
     throw "compiler error: no PHP name for base type " + tbase;
   }
@@ -1281,6 +1298,9 @@
       case t_base_type::TYPE_I64:
         result += " = 0";
         break;
+      case t_base_type::TYPE_DOUBLE:
+        result += " = 0.0";
+        break;
       default:
         throw "compiler error: no PHP initializer for base type " + tbase;
       }
@@ -1357,6 +1377,8 @@
       return "TType::I32";
     case t_base_type::TYPE_I64:
       return "TType::I64";
+    case t_base_type::TYPE_DOUBLE:
+      return "TType::DOUBLE";
     }
   } else if (type->is_enum()) {
     return "TType::I32";
diff --git a/compiler/cpp/src/generate/t_py_generator.cc b/compiler/cpp/src/generate/t_py_generator.cc
index 53e5b3b..522ce38 100644
--- a/compiler/cpp/src/generate/t_py_generator.cc
+++ b/compiler/cpp/src/generate/t_py_generator.cc
@@ -784,6 +784,9 @@
       case t_base_type::TYPE_I64:
         out << "readI64(itrans);";
         break;
+      case t_base_type::TYPE_DOUBLE:
+        out << "readDouble(itrans);";
+        break;
       default:
         throw "compiler error: no PHP name for base type " + tbase;
       }
@@ -988,6 +991,9 @@
       case t_base_type::TYPE_I64:
         out << "writeI64(otrans, " << name << ")";
         break;
+      case t_base_type::TYPE_DOUBLE:
+        out << "writeDouble(otrans, " << name << ")";
+        break;
       default:
         throw "compiler error: no PHP name for base type " + tbase;
       }
@@ -1161,6 +1167,8 @@
     return "Int32";
   case t_base_type::TYPE_I64:
     return "Int64";
+  case t_base_type::TYPE_DOUBLE:
+    return "Double";
   default:
     throw "compiler error: no PHP name for base type " + tbase;
   }
@@ -1195,6 +1203,9 @@
       case t_base_type::TYPE_I64:
         result += " = 0";
         break;
+      case t_base_type::TYPE_DOUBLE:
+        result += " = 0.0";
+        break;
       default:
         throw "compiler error: no PHP initializer for base type " + tbase;
       }
@@ -1275,6 +1286,8 @@
       return "TType.I32";
     case t_base_type::TYPE_I64:
       return "TType.I64";
+    case t_base_type::TYPE_DOUBLE:
+      return "TType.DOUBLE";
     }
   } else if (type->is_enum()) {
     return "TType.I32";
diff --git a/compiler/cpp/src/parse/t_base_type.h b/compiler/cpp/src/parse/t_base_type.h
index 1429d1c..0e97207 100644
--- a/compiler/cpp/src/parse/t_base_type.h
+++ b/compiler/cpp/src/parse/t_base_type.h
@@ -10,7 +10,9 @@
  */
 class t_base_type : public t_type {
  public:
-  /** Enumeration of thrift base types */
+  /**
+   * Enumeration of thrift base types
+   */
   enum t_base {
     TYPE_VOID,
     TYPE_STRING,
@@ -18,7 +20,8 @@
     TYPE_BYTE,
     TYPE_I16,
     TYPE_I32,
-    TYPE_I64
+    TYPE_I64,
+    TYPE_DOUBLE
   };
 
   t_base_type(std::string name, t_base base) :
diff --git a/compiler/cpp/src/parse/t_program.h b/compiler/cpp/src/parse/t_program.h
index abb368b..9fa4271 100644
--- a/compiler/cpp/src/parse/t_program.h
+++ b/compiler/cpp/src/parse/t_program.h
@@ -37,6 +37,7 @@
     type_i16    = new t_base_type("i16",    t_base_type::TYPE_I16);
     type_i32    = new t_base_type("i32",    t_base_type::TYPE_I32);
     type_i64    = new t_base_type("i64",    t_base_type::TYPE_I64);
+    type_double = new t_base_type("double", t_base_type::TYPE_DOUBLE);
   }
 
   ~t_program() {
@@ -46,6 +47,7 @@
     delete type_i16;
     delete type_i32;
     delete type_i64;
+    delete type_double;
   }
 
   // Name accessor
@@ -69,6 +71,7 @@
   t_type* get_i16_type()    const { return type_i16;    }
   t_type* get_i32_type()    const { return type_i32;    }
   t_type* get_i64_type()    const { return type_i64;    }
+  t_type* get_double_type() const { return type_double; }
 
   // Custom data type lookup
   t_type* get_custom_type(std::string name) {
@@ -130,6 +133,7 @@
   t_type* type_i16;
   t_type* type_i32;
   t_type* type_i64;
+  t_type* type_double;
 };
 
 #endif
diff --git a/compiler/cpp/src/thrift.l b/compiler/cpp/src/thrift.l
index 1ff7708..484e43b 100644
--- a/compiler/cpp/src/thrift.l
+++ b/compiler/cpp/src/thrift.l
@@ -23,6 +23,7 @@
 whitespace   ([ \t\r\n]*)
 multicomm    ("/*""/"*([^*/]|[^*]"/"|"*"[^/])*"*"*"*/")
 comment      ("//"[^\n]*)
+unixcomment  ("#"[^\n]*)
 symbol       ([\,\{\}\(\)\=<>])
 
 %%
@@ -30,6 +31,7 @@
 {whitespace}  { /* do nothing */ }
 {multicomm}   { /* do nothing */ }
 {comment}     { /* do nothing */ }
+{unixcomment} { /* do nothing */ }
 
 {symbol}      { return yytext[0]; }
 
diff --git a/compiler/cpp/src/thrift.y b/compiler/cpp/src/thrift.y
index e738180..f2fd790 100644
--- a/compiler/cpp/src/thrift.y
+++ b/compiler/cpp/src/thrift.y
@@ -394,6 +394,11 @@
       pdebug("BaseType -> tok_i64");
       $$ = g_program->get_i64_type();
     }
+| tok_double
+    {
+      pdebug("BaseType -> tok_double");
+      $$ = g_program->get_double_type();
+    }
 
 ContainerType:
   MapType