[llvm-commits] [hlvm] r38404 - in /hlvm/trunk: hlvm/AST/AST.cpp hlvm/AST/AST.h hlvm/AST/Arithmetic.cpp hlvm/AST/Arithmetic.h hlvm/AST/Bundle.cpp hlvm/AST/Bundle.h hlvm/AST/IntrinsicTypes.rng hlvm/AST/MemoryOps.h hlvm/AST/Node.h hlvm/AST/StringOps.cpp hlvm/AST/StringOps.h hlvm/AST/Type.cpp hlvm/AST/Type.h hlvm/CodeGen/LLVMGenerator.cpp hlvm/Pass/Validate.cpp hlvm/Reader/HLVM.rng hlvm/Reader/XMLReader.cpp hlvm/Writer/XMLWriter.cpp tools/hlvm-config/hlvm-config.cpp tools/hlvm-gentestcase/Generate.cpp

Reid Spencer reid at x10sys.com
Sat Jul 7 17:03:04 PDT 2007


Author: reid
Date: Sat Jul  7 19:03:04 2007
New Revision: 38404

URL: http://llvm.org/viewvc/llvm-project?rev=38404&view=rev
Log:
Several changes to start making the code generated by the test case generator
work:
1. No need for NInf, PInf, NaN value operators, they are generated at runtime
2. Fill in the missing code generation for Pointers, Vectors, Structures.
3. Making Types be an operand via a GetOp is a bad idea. The type hierarchy
   gets broken and it causes havoc with code gen. Just use the Type directlry
   in the ConvertOp.
4. Implement the string operators (insert, erase, replace, concat)
5. Implement code gen shell for the math operators (requires runtime support)
6. Start to support the Rational Type.
7. Implement the Length operator.

Modified:
    hlvm/trunk/hlvm/AST/AST.cpp
    hlvm/trunk/hlvm/AST/AST.h
    hlvm/trunk/hlvm/AST/Arithmetic.cpp
    hlvm/trunk/hlvm/AST/Arithmetic.h
    hlvm/trunk/hlvm/AST/Bundle.cpp
    hlvm/trunk/hlvm/AST/Bundle.h
    hlvm/trunk/hlvm/AST/IntrinsicTypes.rng
    hlvm/trunk/hlvm/AST/MemoryOps.h
    hlvm/trunk/hlvm/AST/Node.h
    hlvm/trunk/hlvm/AST/StringOps.cpp
    hlvm/trunk/hlvm/AST/StringOps.h
    hlvm/trunk/hlvm/AST/Type.cpp
    hlvm/trunk/hlvm/AST/Type.h
    hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp
    hlvm/trunk/hlvm/Pass/Validate.cpp
    hlvm/trunk/hlvm/Reader/HLVM.rng
    hlvm/trunk/hlvm/Reader/XMLReader.cpp
    hlvm/trunk/hlvm/Writer/XMLWriter.cpp
    hlvm/trunk/tools/hlvm-config/hlvm-config.cpp
    hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp

Modified: hlvm/trunk/hlvm/AST/AST.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/AST.cpp?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/AST.cpp (original)
+++ hlvm/trunk/hlvm/AST/AST.cpp Sat Jul  7 19:03:04 2007
@@ -41,6 +41,7 @@
 #include <hlvm/AST/Arithmetic.h>
 #include <hlvm/AST/BooleanOps.h>
 #include <hlvm/AST/RealMath.h>
+#include <hlvm/AST/StringOps.h>
 #include <hlvm/AST/SymbolTable.h>
 #include <hlvm/Base/Assert.h>
 #include <hlvm/Base/Pool.h>
@@ -751,20 +752,30 @@
 }
 
 GetOp* 
-AST::new_GetOp(const Documentable* D, const Locator*loc)
+AST::new_GetOp(const Value* V, const Locator*loc)
 {
-  hlvmAssert(D != 0 && "GetOp must have a Value to reference");
+  hlvmAssert(V != 0 && "GetOp must have a Value to reference");
   GetOp* result = new GetOp();
-  if (llvm::isa<AutoVarOp>(D) || 
-      llvm::isa<Argument>(D) ||
-      llvm::isa<Constant>(D)) {
-    result->setType(llvm::cast<Value>(D)->getType());
-  } else if (llvm::isa<Type>(D)) {
-    result->setType(llvm::cast<Type>(D));
+  if (llvm::isa<AutoVarOp>(V) || 
+      llvm::isa<Argument>(V) ||
+      llvm::isa<Constant>(V)) {
+    result->setType(llvm::cast<Value>(V)->getType());
   } else
     hlvmAssert(!"Invalid referent type");
   result->setLocator(loc);
-  result->setReferent(D);
+  result->setReferent(V);
+  return result;
+}
+
+ConvertOp*
+AST::new_ConvertOp(Operator* V, const Type* Ty, const Locator* loc)
+{
+  hlvmAssert(V != 0 && "ConvertOp must have a Value to convert");
+  hlvmAssert(Ty != 0 && "ConvertOp must have a type to convert the value");
+  ConvertOp* result = new ConvertOp();
+  result->setType(Ty);
+  result->setOperand(V);
+  result->setLocator(loc);
   return result;
 }
 
@@ -945,22 +956,10 @@
 template SizeOfOp*
 AST::new_UnaryOp<SizeOfOp>(Operator* op1, Bundle* B, const Locator* loc);
 
-template ConvertOp*
-AST::new_BinaryOp<ConvertOp>(
-    const Type* Ty, Operator* op1, Operator* op2, const Locator* loc);
-
-template<> ConvertOp*
-AST::new_BinaryOp(
-  Operator* oprnd1,  ///< The first operand
-  Operator* oprnd2,  ///< The second operand
-  Bundle* B,         ///< The bundle, for type lookup
-  const Locator* loc ///< The source locator
-)
-{
-  GetOp* get = llvm::cast<GetOp>(oprnd2);
-  const Type*  Ty = llvm::cast<Type>(get->getReferent());
-  return new_BinaryOp<ConvertOp>(Ty,oprnd1,oprnd2,loc);
-}
+template LengthOp*
+AST::new_UnaryOp<LengthOp>(const Type* Ty, Operator* op1, const Locator* loc);
+template LengthOp*
+AST::new_UnaryOp<LengthOp>(Operator* op1, Bundle* B, const Locator* loc);
 
 template AddOp*
 AST::new_BinaryOp<AddOp>(
@@ -1212,6 +1211,28 @@
   return AST::new_BinaryOp<InequalityOp>(Ty,op1,op2,loc);
 }
 
+// String Operators
+template StrInsertOp*
+AST::new_TernaryOp<StrInsertOp>(const Type* Ty, Operator*op1,Operator*op2,Operator*op3,const Locator* loc);
+template StrInsertOp*
+AST::new_TernaryOp<StrInsertOp>(Operator*op1,Operator*op2,Operator*op3,Bundle* B,const Locator* loc);
+
+template StrEraseOp*
+AST::new_TernaryOp<StrEraseOp>(const Type* Ty, Operator*op1,Operator*op2,Operator*op3,const Locator* loc);
+template StrEraseOp*
+AST::new_TernaryOp<StrEraseOp>(Operator*op1,Operator*op2,Operator*op3,Bundle* B,const Locator* loc);
+
+template StrReplaceOp* 
+AST::new_MultiOp<StrReplaceOp>(
+    const Type* Ty, const std::vector<Operator*>& ops, const Locator*loc);
+template StrReplaceOp* 
+AST::new_MultiOp<StrReplaceOp>(const std::vector<Operator*>& ops, Bundle* B, const Locator*loc);
+
+template StrConcatOp*
+AST::new_BinaryOp<StrConcatOp>(const Type* Ty, Operator* op1, Operator* op2, const Locator* loc);
+template StrConcatOp*
+AST::new_BinaryOp<StrConcatOp>(Operator* op1, Operator* op2, Bundle* B, const Locator* loc);
+
 // Control Flow Operators
 template Block* 
 AST::new_MultiOp<Block>(
@@ -1373,6 +1394,14 @@
     case intTy:    result = new IntegerType(32,true); break;
     case longTy:   result = new IntegerType(64,true); break;
     case octetTy:  result = new IntegerType(8,false); break;
+    case qs16Ty:   result = new RationalType(true,8,8); break;
+    case qs32Ty:   result = new RationalType(true,16,16); break;
+    case qs64Ty:   result = new RationalType(true,32,32); break;
+    case qs128Ty:  result = new RationalType(true,64,64); break;
+    case qu16Ty:   result = new RationalType(false,8,8); break;
+    case qu32Ty:   result = new RationalType(false,16,16); break;
+    case qu64Ty:   result = new RationalType(false,32,32); break;
+    case qu128Ty:  result = new RationalType(false,64,64); break;
     case r8Ty:     result = new RangeType(INT8_MIN,INT8_MAX); break;
     case r16Ty:    result = new RangeType(INT16_MIN,INT16_MAX); break;
     case r32Ty:    result = new RangeType(INT32_MIN,INT32_MAX); break;

Modified: hlvm/trunk/hlvm/AST/AST.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/AST.h?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/AST.h (original)
+++ hlvm/trunk/hlvm/AST/AST.h Sat Jul  7 19:03:04 2007
@@ -56,6 +56,7 @@
 class Operator;
 class AutoVarOp;
 class GetOp;
+class ConvertOp;
 class URI;
 
 /// This class is used to hold or contain an Abstract Syntax Tree. It forms the
@@ -504,10 +505,17 @@
 
     /// Create a new GetOp.
     GetOp* new_GetOp(
-      const Documentable* D,///< The value or type being referenced
+      const Value* V,       ///< The value being referenced
       const Locator*loc = 0 ///< The source locator
     );
 
+    /// Create a new ConvertOp.
+    ConvertOp* new_ConvertOp(
+      Operator* oprnd,    ///< The operand to be converted
+      const Type* Ty,     ///< The Type to convert \p V to
+      const Locator* loc  ///< THe source locator
+    );
+
     /// Provide a template function for creating standard nilary operators
     template<class OpClass>
     OpClass* new_NilaryOp(

Modified: hlvm/trunk/hlvm/AST/Arithmetic.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Arithmetic.cpp?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Arithmetic.cpp (original)
+++ hlvm/trunk/hlvm/AST/Arithmetic.cpp Sat Jul  7 19:03:04 2007
@@ -42,6 +42,7 @@
 PreDecrOp::~PreDecrOp() {}
 PostDecrOp::~PostDecrOp() {}
 SizeOfOp::~SizeOfOp() {}
+LengthOp::~LengthOp() {}
 ConvertOp::~ConvertOp() {}
 AddOp::~AddOp() {}
 SubtractOp::~SubtractOp() {}

Modified: hlvm/trunk/hlvm/AST/Arithmetic.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Arithmetic.h?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Arithmetic.h (original)
+++ hlvm/trunk/hlvm/AST/Arithmetic.h Sat Jul  7 19:03:04 2007
@@ -177,7 +177,7 @@
 
 /// This class provides an Abstract Syntax Tree node that represents a 
 /// SizeOf operator. The SizeOfOp is a unary operator that returns the size, in
-/// bytes, of its operand. The value returned is a constant.
+/// bytes, of its operand. The value returned is a constant s32
 /// @brief AST SizeOf Operator Node   
 class SizeOfOp : public UnaryOperator
 {
@@ -199,16 +199,42 @@
 };
 
 /// This class provides an Abstract Syntax Tree node that represents a 
+/// length operator. The LengthOp is a unary operator that returns the logical
+/// length of its operand. The value returned is a u64. This operator may be
+/// applied to any type of object. For most types, it returns 1. For arrays,
+/// it returns the actual (dynamic) size of the array. Same for Text and String
+/// type objects. For Structures it returns the number of fields.
+/// @brief AST SizeOf Operator Node   
+class LengthOp : public UnaryOperator
+{
+  /// @name Constructors
+  /// @{
+  protected:
+    LengthOp() : UnaryOperator(LengthOpID)  {}
+    virtual ~LengthOp();
+
+  /// @}
+  /// @name Accessors
+  /// @{
+  public:
+    static inline bool classof(const LengthOp*) { return true; }
+    static inline bool classof(const Node* N) { return N->is(LengthOpID); }
+
+  /// @}
+  friend class AST;
+};
+
+/// This class provides an Abstract Syntax Tree node that represents a 
 /// conversion operator. The ConvertOp is a binary operator that converts its
 /// first operand to the type provided in its second operand (which must be
 /// a reference operator to the type).
 /// @brief AST Conversion Operator Node   
-class ConvertOp : public BinaryOperator
+class ConvertOp : public UnaryOperator
 {
   /// @name Constructors
   /// @{
   protected:
-    ConvertOp() : BinaryOperator(ConvertOpID)  {}
+    ConvertOp() : UnaryOperator(ConvertOpID)  {}
     virtual ~ConvertOp();
 
   /// @}

Modified: hlvm/trunk/hlvm/AST/Bundle.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Bundle.cpp?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Bundle.cpp (original)
+++ hlvm/trunk/hlvm/AST/Bundle.cpp Sat Jul  7 19:03:04 2007
@@ -134,6 +134,14 @@
     case HLVM_AST::TKN_int:             return intTy; break;
     case HLVM_AST::TKN_long:            return longTy; break;
     case HLVM_AST::TKN_octet:           return octetTy; break;
+    case HLVM_AST::TKN_qs16:            return qs16Ty; break;
+    case HLVM_AST::TKN_qs32:            return qs32Ty; break;
+    case HLVM_AST::TKN_qs64:            return qs64Ty; break;
+    case HLVM_AST::TKN_qs128:           return qs128Ty; break;
+    case HLVM_AST::TKN_qu16:            return qu16Ty; break;
+    case HLVM_AST::TKN_qu32:            return qu32Ty; break;
+    case HLVM_AST::TKN_qu64:            return qu64Ty; break;
+    case HLVM_AST::TKN_qu128:           return qu128Ty; break;
     case HLVM_AST::TKN_r8:              return r8Ty; break;
     case HLVM_AST::TKN_r16:             return r16Ty; break;
     case HLVM_AST::TKN_r32:             return r32Ty; break;

Modified: hlvm/trunk/hlvm/AST/Bundle.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Bundle.h?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Bundle.h (original)
+++ hlvm/trunk/hlvm/AST/Bundle.h Sat Jul  7 19:03:04 2007
@@ -61,6 +61,14 @@
   intTy,      ///< Signed 32-bit integer quantity
   longTy,     ///< Signed 64-bit integer quantity
   octetTy,    ///< Unsigned 8-bit integer quantity, not computable
+  qs16Ty,     ///< Signed 16-bit rational quantity
+  qs32Ty,     ///< Signed 32-bit rational quantity
+  qs64Ty,     ///< Signed 64-bit rational quantity
+  qs128Ty,    ///< Signed 8-bit rational quantity
+  qu16Ty,     ///< Unsigned 16-bit rational quantity
+  qu32Ty,     ///< Unsigned 32-bit rational quantity
+  qu64Ty,     ///< Unsigned 64-bit rational quantity
+  qu128Ty,    ///< Unsigned 8-bit rational quantity
   r8Ty,       ///< Range checked signed 8-bit integer quantity
   r16Ty,      ///< Range checked signed 16-bit integer quantity
   r32Ty,      ///< Range checked signed 32-bit integer quantity

Modified: hlvm/trunk/hlvm/AST/IntrinsicTypes.rng
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/IntrinsicTypes.rng?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/IntrinsicTypes.rng (original)
+++ hlvm/trunk/hlvm/AST/IntrinsicTypes.rng Sat Jul  7 19:03:04 2007
@@ -58,6 +58,14 @@
       <value>int</value>
       <value>long</value>
       <value>octet</value>
+      <value>qs16</value>
+      <value>qs32</value>
+      <value>qs64</value>
+      <value>qs128</value>
+      <value>qu16</value>
+      <value>qu32</value>
+      <value>qu64</value>
+      <value>qu128</value>
       <value>r8</value>
       <value>r16</value>
       <value>r32</value>

Modified: hlvm/trunk/hlvm/AST/MemoryOps.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/MemoryOps.h?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/MemoryOps.h (original)
+++ hlvm/trunk/hlvm/AST/MemoryOps.h Sat Jul  7 19:03:04 2007
@@ -230,7 +230,7 @@
   /// @name Accessors
   /// @{
   public:
-    const Documentable* getReferent() const { return referent; }
+    const Value* getReferent() const { return referent; }
     static inline bool classof(const GetOp*) { return true; }
     static inline bool classof(const Node* N) { 
       return N->is(GetOpID); 
@@ -240,13 +240,13 @@
   /// @name Mutators
   /// @{
   public:
-    void setReferent(const Documentable* ref) { referent = ref; }
+    void setReferent(const Value* ref) { referent = ref; }
 
   /// @}
   /// @name Data
   /// @{
   protected:
-    const Documentable* referent;
+    const Value* referent;
   /// @}
   friend class AST;
 };

Modified: hlvm/trunk/hlvm/AST/Node.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Node.h?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Node.h (original)
+++ hlvm/trunk/hlvm/AST/Node.h Sat Jul  7 19:03:04 2007
@@ -146,9 +146,6 @@
 FirstNilaryOperatorID = BreakOpID,
   ContinueOpID,            ///< Continue from start of enclosing loop
   ReturnOpID,              ///< Return to the function's caller
-  PInfOpID,                ///< Constant Positive Infinity Real Value
-  NInfOpID,                ///< Constant Negative Infinity Real Value
-  NaNOpID,                 ///< Constant Not-A-Number Real Value
   GetOpID,                 ///< Obtain value of Variable/Function/Constant
 LastNilaryOperatorID = GetOpID,
 
@@ -248,9 +245,10 @@
   // Ternary Operators
   SelectOpID,                  ///< The select an alternate operator
 FirstTernaryOperatorID = SelectOpID,
-  StrInsertOpID,           ///< Insert(str,where,what)
+  StrInsertOpID,           ///< Insert(str1,where,str2)
   StrEraseOpID,            ///< Erase(str,at,len)
   StrReplaceOpID,          ///< Replace(str,at,len,what)
+  StrConcatOpID,           ///< str3 = Concat(str1,str2)
   PositionOpID,            ///< Position a stream (stream,where,relative-to)
   LoopOpID,                ///< The General Purpose Loop Operator
 LastTernaryOperatorID = LoopOpID,

Modified: hlvm/trunk/hlvm/AST/StringOps.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/StringOps.cpp?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/StringOps.cpp (original)
+++ hlvm/trunk/hlvm/AST/StringOps.cpp Sat Jul  7 19:03:04 2007
@@ -31,5 +31,9 @@
 
 namespace hlvm {
 
+StrInsertOp::~StrInsertOp() {}
+StrEraseOp::~StrEraseOp() {}
+StrReplaceOp::~StrReplaceOp() {}
+StrConcatOp::~StrConcatOp() {}
 
 }

Modified: hlvm/trunk/hlvm/AST/StringOps.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/StringOps.h?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/StringOps.h (original)
+++ hlvm/trunk/hlvm/AST/StringOps.h Sat Jul  7 19:03:04 2007
@@ -35,7 +35,10 @@
 namespace hlvm
 {
 
-/// Represents the String insert operator.
+/// Represents an Abstract Syntax Tree node for a string insert operator. This
+/// operator provides editing on a string value. It takes three arguments that
+/// specify the string to be modified, the location of the insertion, and the
+/// string to insert.
 /// @brief HLVM AST String Insert Node
 class StrInsertOp : public TernaryOperator
 {
@@ -53,20 +56,79 @@
     static inline bool classof(const Node* N) { return N->is(StrInsertOpID); }
 
   /// @}
-  /// @name Mutators
+  friend class AST;
+};
+
+/// Represents an Abstract Syntax Tree node for a string insert operator. This
+/// operator provides editing on a string value. It takes three arguments that
+/// specify the string to be modified, the location of the insertion, and the
+/// string to insert.
+/// @brief HLVM AST String Insert Node
+class StrEraseOp : public TernaryOperator
+{
+  /// @name Constructors
+  /// @{
+  protected:
+    StrEraseOp() : TernaryOperator(StrEraseOpID) {}
+    virtual ~StrEraseOp();
+
+  /// @}
+  /// @name Accessors
   /// @{
   public:
+    static inline bool classof(const StrEraseOp*) { return true; }
+    static inline bool classof(const Node* N) { return N->is(StrEraseOpID); }
 
   /// @}
-  /// @name Data
+  friend class AST;
+};
+
+/// Represents an Abstract Syntax Tree node for a string insert operator. This
+/// operator provides editing on a string value. It takes four arguments that
+/// specify the string to be modified, the location of the replacement, and the
+/// replacement string.
+/// @brief HLVM AST String Replace Node
+class StrReplaceOp : public MultiOperator
+{
+  /// @name Constructors
   /// @{
   protected:
+    StrReplaceOp() : MultiOperator(StrReplaceOpID) {}
+    virtual ~StrReplaceOp();
+
+  /// @}
+  /// @name Accessors
+  /// @{
+  public:
+    static inline bool classof(const StrReplaceOp*) { return true; }
+    static inline bool classof(const Node* N) { return N->is(StrReplaceOpID); }
+
+  /// @}
+  friend class AST;
+};
+
+/// Represents an Abstract Syntax Tree node for a string concatentation 
+/// operator. This operator creates a new string that is the concatenation of
+/// its two operand strings. 
+/// @brief HLVM AST String Concatenation Node
+class StrConcatOp : public BinaryOperator
+{
+  /// @name Constructors
+  /// @{
+  protected:
+    StrConcatOp() : BinaryOperator(StrConcatOpID) {}
+    virtual ~StrConcatOp();
+
+  /// @}
+  /// @name Accessors
+  /// @{
+  public:
+    static inline bool classof(const StrConcatOp*) { return true; }
+    static inline bool classof(const Node* N) { return N->is(StrConcatOpID); }
+
   /// @}
   friend class AST;
 };
 
 } // hlvm
 #endif
-namespace hlvm {
-
-}

Modified: hlvm/trunk/hlvm/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Type.cpp?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Type.cpp (original)
+++ hlvm/trunk/hlvm/AST/Type.cpp Sat Jul  7 19:03:04 2007
@@ -225,6 +225,37 @@
   return 0;
 }
 
+RationalType::~RationalType()
+{
+}
+
+const char* 
+RationalType::getPrimitiveName() const
+{
+  if (numer_bits == 32 && denom_bits == 32) {
+    if (isSigned())
+      return "qs64";
+    else
+      return "qu64";
+  } else if (numer_bits == 16 && denom_bits == 16) {
+    if (isSigned())
+      return "qs32";
+    else
+      return "qu32";
+  } else if (numer_bits == 8 && denom_bits == 8) {
+    if (isSigned())
+      return "qs16";
+    else
+      return "qu16";
+  } else if (numer_bits == 64 && denom_bits == 64) {
+    if (isSigned())
+      return "qs128";
+    else
+      return "qu128";
+  }
+  return 0;
+}
+
 OpaqueType::~OpaqueType()
 {
 }

Modified: hlvm/trunk/hlvm/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Type.h?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Type.h (original)
+++ hlvm/trunk/hlvm/AST/Type.h Sat Jul  7 19:03:04 2007
@@ -461,6 +461,73 @@
   friend class AST;
 };
 
+/// This class provides an Abstract Syntax Tree node that represents a rational
+/// number. All rational numbers are represented by a pair of integers, one for
+/// the numerator and one for the denominator. All integer arithmetic operations
+/// are available on rational numbers. This provides an alternate (and perhaps
+/// more accurate) form of dealing with the subset of real numbers that are
+/// rational.
+/// @brief AST Rational Number Type
+class RationalType : public Type
+{
+  /// @name Constructors
+  /// @{
+  protected:
+    RationalType(bool isSigned = true, uint16_t numer=32, uint16_t denom=32) 
+      : Type(RationalTypeID), numer_bits(numer), denom_bits(denom) 
+    {
+      setSigned(isSigned);
+    }
+    virtual ~RationalType();
+
+  /// @}
+  /// @name Accessors
+  /// @{
+  public:
+    virtual const char* getPrimitiveName() const;
+
+    /// @brief Return the signedness of this type
+    bool isSigned() const { return flags & SignedTF; }
+
+    /// Get the number of numerator bits
+    uint16_t getNumeratorBits() const { return numer_bits; }
+
+    /// Get the number of denominator bits
+    uint16_t getDenominatorBits() const { return denom_bits; }
+
+    /// Get the total number of bits
+    uint32_t getBits() const { 
+      return getNumeratorBits() + getDenominatorBits();
+    }
+
+    // Methods to support type inquiry via is, cast, dyn_cast
+    static inline bool classof(const RationalType*) { return true; }
+    static inline bool classof(const Node* T) { return T->is(RationalTypeID); }
+
+  /// @}
+  /// @name Mutators
+  /// @{
+  public:
+    /// @brief Set the signedness of the type
+    void setSigned(bool isSigned) { 
+      if (isSigned) flags |= SignedTF; else flags &= ~SignedTF; }
+
+    /// Set the mantissa bits
+    void setNumeratorBits(uint16_t bits) { numer_bits = bits; }
+
+    /// Set the exponent bits
+    void setDenominatorBits(uint16_t bits) { denom_bits = bits; }
+
+  /// @}
+  /// @name Data
+  /// @{
+  protected:
+    uint16_t numer_bits; ///< Number of bits in numerator
+    uint16_t denom_bits; ///< Number of bits in denominator
+  /// @}
+  friend class AST;
+};
+
 /// This class provides an Abstract Syntax Tree node that represents an opaque
 /// type. Opaque types are those whose definition is not known. Opaque types are
 /// used to handle forward type references and recursion within container types.

Modified: hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp (original)
+++ hlvm/trunk/hlvm/CodeGen/LLVMGenerator.cpp Sat Jul  7 19:03:04 2007
@@ -564,7 +564,7 @@
 llvm::Value* 
 LLVMGeneratorPass::getReferent(hlvm::GetOp* r)
 {
-  const hlvm::Documentable* referent = r->getReferent();
+  const hlvm::Value* referent = r->getReferent();
   llvm::Value* v = 0;
   if (llvm::isa<AutoVarOp>(referent)) {
     AutoVarMap::const_iterator I = 
@@ -893,9 +893,7 @@
   llvm::Value* v1 = popOperand(op1);
   
   // Get the target type
-  hlvm::GetOp* op2 = llvm::cast<GetOp>(op->getOperand(1));
-  const hlvm::Type* tgtTy = llvm::cast<const hlvm::Type>(op2->getReferent());
-  llvm::Value* v2 = popOperand(op2);
+  const hlvm::Type* tgtTy = op->getType();
 
   // Get the source and target types as an llvm type
   const llvm::Type* lsrcTy = getType(srcTy);
@@ -1118,6 +1116,113 @@
 }
 
 template<> void
+LLVMGeneratorPass::gen(IsPInfOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  llvm::Value* op2 = popOperand(op->getOperand(1)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(IsNInfOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(IsNanOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(TruncOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(RoundOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(FloorOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(CeilingOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(LogEOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(Log2Op* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(Log10Op* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(SquareRootOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(CubeRootOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(FactorialOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(PowerOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  llvm::Value* op2 = popOperand(op->getOperand(1)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(RootOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  llvm::Value* op2 = popOperand(op->getOperand(1)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(GCDOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  llvm::Value* op2 = popOperand(op->getOperand(1)); 
+}
+
+template<> void
+LLVMGeneratorPass::gen(LCMOp* op)
+{
+  llvm::Value* op1 = popOperand(op->getOperand(0)); 
+  llvm::Value* op2 = popOperand(op->getOperand(1)); 
+}
+
+template<> void
 LLVMGeneratorPass::gen(SelectOp* op)
 {
   // If none of the operands are blocks then we can use LLVM's select
@@ -1393,6 +1498,9 @@
 {
   // Get the result operand
   llvm::Value* src = popOperand(r->getOperand(0));
+  if (llvm::isa<llvm::AllocaInst>(src))
+    src = em.emitLoad(src,src->getName() + "_load");
+
   // Get the block this result applies to
   hlvm::Block* B = llvm::cast<hlvm::Block>(r->getParent());
   // Get the location into which we will store the result
@@ -1490,7 +1598,7 @@
   hlvm::Operator* loc = i->getOperand(0);
   hlvm::Operator* field = i->getOperand(1);
   if (hlvm::GetOp* Ref = llvm::dyn_cast<GetOp>(field)) 
-    if (const hlvm::Documentable* referent = Ref->getReferent())
+    if (const hlvm::Value* referent = Ref->getReferent())
       if (const hlvm::ConstantString* CS = 
            llvm::dyn_cast<ConstantString>(referent)) {
         const std::string& fldName = CS->getValue();
@@ -1799,6 +1907,23 @@
       case GreaterThanOpID:         gen(llvm::cast<GreaterThanOp>(n)); break;
       case GreaterEqualOpID:        gen(llvm::cast<GreaterEqualOp>(n)); break;
       case LessEqualOpID:           gen(llvm::cast<LessEqualOp>(n)); break;
+      case IsPInfOpID:              gen(llvm::cast<IsPInfOp>(n)); break;
+      case IsNInfOpID:              gen(llvm::cast<IsNInfOp>(n)); break;
+      case IsNanOpID:               gen(llvm::cast<IsNanOp>(n)); break;
+      case TruncOpID:               gen(llvm::cast<TruncOp>(n)); break;
+      case RoundOpID:               gen(llvm::cast<RoundOp>(n)); break;
+      case FloorOpID:               gen(llvm::cast<FloorOp>(n)); break;
+      case CeilingOpID:             gen(llvm::cast<CeilingOp>(n)); break;
+      case LogEOpID:                gen(llvm::cast<LogEOp>(n)); break;
+      case Log2OpID:                gen(llvm::cast<Log2Op>(n)); break;
+      case Log10OpID:               gen(llvm::cast<Log10Op>(n)); break;
+      case SquareRootOpID:          gen(llvm::cast<SquareRootOp>(n)); break;
+      case CubeRootOpID:            gen(llvm::cast<CubeRootOp>(n)); break;
+      case FactorialOpID:           gen(llvm::cast<FactorialOp>(n)); break;
+      case PowerOpID:               gen(llvm::cast<PowerOp>(n)); break;
+      case RootOpID:                gen(llvm::cast<RootOp>(n)); break;
+      case GCDOpID:                 gen(llvm::cast<GCDOp>(n)); break;
+      case LCMOpID:                 gen(llvm::cast<LCMOp>(n)); break;
       case SelectOpID:              gen(llvm::cast<SelectOp>(n)); break;
       case SwitchOpID:              gen(llvm::cast<SwitchOp>(n)); break;
       case WhileOpID:               gen(llvm::cast<WhileOp>(n)); break;

Modified: hlvm/trunk/hlvm/Pass/Validate.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Pass/Validate.cpp?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Pass/Validate.cpp (original)
+++ hlvm/trunk/hlvm/Pass/Validate.cpp Sat Jul  7 19:03:04 2007
@@ -37,6 +37,7 @@
 #include <hlvm/AST/Arithmetic.h>
 #include <hlvm/AST/RealMath.h>
 #include <hlvm/AST/BooleanOps.h>
+#include <hlvm/AST/StringOps.h>
 #include <hlvm/AST/Linkables.h>
 #include <hlvm/AST/Constants.h>
 #include <llvm/Support/Casting.h>
@@ -398,6 +399,14 @@
 }
 
 template<> inline void
+ValidateImpl::validate(RationalType* n)
+{
+  if (checkNode(n))
+    if (!n->is(RationalTypeID))
+      error(n,"Bad ID for RationalType");
+}
+
+template<> inline void
 ValidateImpl::validate(StringType* n)
 {
   checkType(n,StringTypeID);
@@ -1175,7 +1184,14 @@
 template<> inline void
 ValidateImpl::validate(SizeOfOp* n)
 {
-  if (checkOperator(n,SizeOfOpID,2))
+  if (checkOperator(n,SizeOfOpID,1))
+    ;
+}
+
+template<> inline void
+ValidateImpl::validate(LengthOp* n)
+{
+  if (checkOperator(n,LengthOpID,1))
     ;
 }
 
@@ -1184,12 +1200,7 @@
 {
   if (checkOperator(n,ConvertOpID,2)) {
     const Operator* Oprnd1 = n->getOperand(0);
-    const Operator* Oprnd2 = n->getOperand(1);
-    if (const GetOp* RO = dyn_cast<GetOp>(Oprnd2)) {
-      if (!isa<Type>(RO->getReferent()))
-        error(n,"Second operand must be a reference to atype");
-    } else
-      error(n,"Second operand must be a GetOp");
+    /// FIXME: assure type of Oprnd1 is convertible to n->getType();
   }
 }
 
@@ -1404,7 +1415,7 @@
   if (checkOperator(n,IsNInfOpID,1)) {
     const Type* Ty1 = n->getOperand(0)->getType();
     if (!Ty1->is(RealTypeID))
-      error(n,"IsPInfoOp requires real number operand");
+      error(n,"IsNInfoOp requires real number operand");
   }
 }
 
@@ -1563,6 +1574,34 @@
 }
 
 template<> inline void
+ValidateImpl::validate(StrInsertOp* n)
+{
+  if (checkOperator(n,StrInsertOpID,3))
+    ;
+}
+
+template<> inline void
+ValidateImpl::validate(StrEraseOp* n)
+{
+  if (checkOperator(n,StrEraseOpID,3))
+    ;
+}
+
+template<> inline void
+ValidateImpl::validate(StrReplaceOp* n)
+{
+  if (checkOperator(n,StrReplaceOpID,4))
+    ;
+}
+
+template<> inline void
+ValidateImpl::validate(StrConcatOp* n)
+{
+  if (checkOperator(n,StrConcatOpID,2))
+    ;
+}
+
+template<> inline void
 ValidateImpl::validate(OpenOp* n)
 {
   if (checkOperator(n,OpenOpID,1)) {
@@ -1642,7 +1681,7 @@
     case RangeTypeID:            validate(cast<RangeType>(n)); break;
     case EnumerationTypeID:      validate(cast<EnumerationType>(n)); break;
     case RealTypeID:             validate(cast<RealType>(n)); break;
-    case RationalTypeID:         /*validate(cast<RationalType>(n));*/ break;
+    case RationalTypeID:         validate(cast<RationalType>(n)); break;
     case TextTypeID:             validate(cast<TextType>(n)); break;
     case StringTypeID:           validate(cast<StringType>(n)); break;
     case StreamTypeID:           validate(cast<StreamType>(n)); break;
@@ -1734,15 +1773,16 @@
     case RootOpID:               validate(cast<RootOp>(n)); break;
     case GCDOpID:                validate(cast<GCDOp>(n)); break;
     case LCMOpID:                validate(cast<LCMOp>(n)); break;
-    case LengthOpID:             /*validate(cast<LengthOp>(n)); */ break;
+    case StrInsertOpID:          validate(cast<StrInsertOp>(n)); break;
+    case StrEraseOpID:           validate(cast<StrEraseOp>(n)); break;
+    case StrReplaceOpID:         validate(cast<StrReplaceOp>(n)); break;
+    case StrConcatOpID:          validate(cast<StrConcatOp>(n)); break;
+    case LengthOpID:             validate(cast<LengthOp>(n)); break;
     case OpenOpID:               validate(cast<OpenOp>(n)); break;
     case CloseOpID:              validate(cast<CloseOp>(n)); break;
     case ReadOpID:               validate(cast<ReadOp>(n)); break;
     case WriteOpID:              validate(cast<WriteOp>(n)); break;
     case PositionOpID:           /*validate(cast<PositionOp>(n));*/ break;
-    case PInfOpID:               /*validate(cast<PInfOp>(n)); */ break;
-    case NInfOpID:               /*validate(cast<NInfoOp>(n)); */ break;
-    case NaNOpID:                /*validate(cast<NaNOp>(n)); */ break;
     case ConstantAnyID:          validate(cast<ConstantAny>(n)); break;
     case ConstantBooleanID:      validate(cast<ConstantBoolean>(n)); break;
     case ConstantCharacterID:    validate(cast<ConstantCharacter>(n)); break;

Modified: hlvm/trunk/hlvm/Reader/HLVM.rng
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Reader/HLVM.rng?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Reader/HLVM.rng (original)
+++ hlvm/trunk/hlvm/Reader/HLVM.rng Sat Jul  7 19:03:04 2007
@@ -1044,8 +1044,9 @@
 
   <define name="convert.elem">
     <element name="convert">
+      <ref name="Typed_Element.pat"/>
+      <ref name="Documentation.pat"/>
       <ref name="Operators.pat"/>
-      <ref name="Location.pat"/>
     </element>
   </define>
 
@@ -1264,6 +1265,54 @@
     </element>
   </define>
 
+  <!-- String Operators -->
+  <define name="StringOperators.pat">
+    <choice>
+      <ref name="sinsert.elem"/>
+      <ref name="serase.elem"/>
+      <ref name="sreplace.elem"/>
+      <ref name="sconcat.elem"/>
+    </choice>
+  </define>
+
+  <define name="sinsert.elem">
+    <element name="sinsert">
+      <ref name="Documentation.pat"/>
+      <ref name="Operators.pat"/>
+      <ref name="Operators.pat"/>
+      <ref name="Operators.pat"/>
+    </element>
+  </define>
+
+  <define name="serase.elem">
+    <element name="serase">
+      <ref name="Documentation.pat"/>
+      <ref name="Operators.pat"/>
+      <ref name="Operators.pat"/>
+      <ref name="Operators.pat"/>
+    </element>
+  </define>
+
+  <define name="sreplace.elem">
+    <element name="sreplace">
+      <ref name="Documentation.pat"/>
+      <ref name="Operators.pat"/>
+      <ref name="Operators.pat"/>
+      <ref name="Operators.pat"/>
+      <ref name="Operators.pat"/>
+    </element>
+  </define>
+
+  <define name="sconcat.elem">
+    <element name="sconcat">
+      <ref name="Documentation.pat"/>
+      <ref name="Operators.pat"/>
+      <ref name="Operators.pat"/>
+    </element>
+  </define>
+
+  <!-- Control Flow Operators -->
+
   <define name="ControlFlowOps.pat">
     <choice>
       <ref name="select.elem"/>

Modified: hlvm/trunk/hlvm/Reader/XMLReader.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Reader/XMLReader.cpp?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Reader/XMLReader.cpp (original)
+++ hlvm/trunk/hlvm/Reader/XMLReader.cpp Sat Jul  7 19:03:04 2007
@@ -43,6 +43,7 @@
 #include <hlvm/AST/Arithmetic.h>
 #include <hlvm/AST/BooleanOps.h>
 #include <hlvm/AST/RealMath.h>
+#include <hlvm/AST/StringOps.h>
 #include <hlvm/Base/Assert.h>
 #include <llvm/ADT/StringExtras.h>
 #include <libxml/parser.h>
@@ -957,7 +958,7 @@
   Locator* loc = getLocator(cur);
 
   // Find the referrent variable in a block
-  Documentable* referent = 0;
+  Value* referent = 0;
   for (BlockStack::reverse_iterator I = blocks.rbegin(), E = blocks.rend(); 
        I != E; ++I )
   {
@@ -977,11 +978,7 @@
   if (!referent)
     referent= bundle->getConst(id);
     
-  // Didn't find a linkable? Try a type.
-  if (!referent)
-    referent = bundle->getType(id);
-  
-  // Didn't find a type? Try an error message for size
+  // Didn't find an constant? Try an error message for size
   if (!referent)
       error(loc,std::string("Referent '") + id + "' not found");
 
@@ -990,6 +987,25 @@
   return refop;
 }
 
+template<> ConvertOp*
+XMLReaderImpl::parse<ConvertOp>(xmlNodePtr& cur)
+{
+  Locator* loc = getLocator(cur);
+  std::string typeName (getAttribute(cur,"type",true));
+  Type* Ty = getType(typeName);
+  xmlNodePtr child = cur->children;
+  Documentation* doc = parse<Documentation>(child); 
+  if (child && skipBlanks(child)) {
+    Operator* oprnd1 = parseOperator(child);
+    ConvertOp* cnvrt = ast->new_ConvertOp(oprnd1,Ty,loc);
+    if (doc)
+      cnvrt->setDoc(doc);
+    return cnvrt;
+  }
+  hlvmDeadCode("Invalid ConvertOp");
+  return 0;
+}
+
 template<class OpClass>
 OpClass*
 XMLReaderImpl::parseNilaryOp(xmlNodePtr& cur)
@@ -1299,7 +1315,10 @@
       case TKN_root:         op = parseBinaryOp<RootOp>(cur); break;
       case TKN_GCD:          op = parseBinaryOp<GCDOp>(cur); break;
       case TKN_LCM:          op = parseBinaryOp<LCMOp>(cur); break;
-      case TKN_convert:      op = parseBinaryOp<ConvertOp>(cur); break;
+      case TKN_sinsert:      op = parseTernaryOp<StrInsertOp>(cur); break;
+      case TKN_serase:       op = parseTernaryOp<StrEraseOp>(cur); break;
+      case TKN_sreplace:     op = parseMultiOp<StrReplaceOp>(cur); break;
+      case TKN_sconcat:      op = parseBinaryOp<StrConcatOp>(cur); break;
       case TKN_select:       op = parseTernaryOp<SelectOp>(cur); break;
       case TKN_switch:       op = parseMultiOp<SwitchOp>(cur); break;
       case TKN_while:        op = parseBinaryOp<WhileOp>(cur); break;
@@ -1319,6 +1338,7 @@
       case TKN_write:        op = parseBinaryOp<WriteOp>(cur); break;
       case TKN_close:        op = parseUnaryOp<CloseOp>(cur); break;
       case TKN_get:          op = parse<GetOp>(cur); break;
+      case TKN_convert:      op = parse<ConvertOp>(cur); break;
       case TKN_autovar:      op = parse<AutoVarOp>(cur); break;
       case TKN_block:        op = parse<Block>(cur); break;
       default:

Modified: hlvm/trunk/hlvm/Writer/XMLWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Writer/XMLWriter.cpp?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Writer/XMLWriter.cpp (original)
+++ hlvm/trunk/hlvm/Writer/XMLWriter.cpp Sat Jul  7 19:03:04 2007
@@ -41,6 +41,7 @@
 #include <hlvm/AST/Arithmetic.h>
 #include <hlvm/AST/BooleanOps.h>
 #include <hlvm/AST/RealMath.h>
+#include <hlvm/AST/StringOps.h>
 #include <hlvm/Base/Assert.h>
 #include <hlvm/Pass/Pass.h>
 #include <llvm/ADT/StringExtras.h>
@@ -1159,9 +1160,39 @@
 XMLWriterImpl::WriterPass::put(const ConvertOp* r)
 {
   startElement("convert");
+  writeAttribute("type",r->getType()->getName());
   putDoc(r);
 }
 
+template<> void
+XMLWriterImpl::WriterPass::put(const StrInsertOp* r)
+{
+  startElement("sinsert");
+  putDoc(r);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const StrEraseOp* r) 
+{
+  startElement("serase");
+  putDoc(r);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const StrReplaceOp* r) 
+{
+  startElement("sreplace");
+  putDoc(r);
+}
+
+template<> void
+XMLWriterImpl::WriterPass::put(const StrConcatOp* r) 
+{
+  startElement("sconcat");
+  putDoc(r);
+}
+
+
 template<> void 
 XMLWriterImpl::WriterPass::put(const Bundle* b)
 {
@@ -1264,6 +1295,10 @@
       case CloseOpID:              put(cast<CloseOp>(n)); break;
       case WriteOpID:              put(cast<WriteOp>(n)); break;
       case ConvertOpID:            put(cast<ConvertOp>(n)); break;
+      case StrInsertOpID:          put(cast<StrInsertOp>(n)); break;
+      case StrEraseOpID:           put(cast<StrEraseOp>(n)); break;
+      case StrReplaceOpID:         put(cast<StrReplaceOp>(n)); break;
+      case StrConcatOpID:          put(cast<StrConcatOp>(n)); break;
       case IsPInfOpID:             put(cast<IsPInfOp>(n)); break;
       case IsNInfOpID:             put(cast<IsNInfOp>(n)); break;
       case IsNanOpID:              put(cast<IsNanOp>(n)); break;

Modified: hlvm/trunk/tools/hlvm-config/hlvm-config.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/tools/hlvm-config/hlvm-config.cpp?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/tools/hlvm-config/hlvm-config.cpp (original)
+++ hlvm/trunk/tools/hlvm-config/hlvm-config.cpp Sat Jul  7 19:03:04 2007
@@ -90,9 +90,6 @@
   "BreakOp",
   "ContinueOp",
   "ReturnOp",
-  "PInfOp",
-  "NInfOp",
-  "NaNOp",
   "GetOp",
   "ResultOp",
   "ThrowOp",
@@ -163,6 +160,7 @@
   "StrInsertOp",
   "StrEraseOp",
   "StrReplaceOp",
+  "StrConcatOp",
   "PositionOp",
   "LoopOp",
   "CallOp",

Modified: hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp?rev=38404&r1=38403&r2=38404&view=diff

==============================================================================
--- hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp (original)
+++ hlvm/trunk/tools/hlvm-gentestcase/Generate.cpp Sat Jul  7 19:03:04 2007
@@ -37,6 +37,7 @@
 #include <hlvm/AST/MemoryOps.h>
 #include <hlvm/AST/InputOutput.h>
 #include <hlvm/AST/RealMath.h>
+#include <hlvm/AST/StringOps.h>
 #include <hlvm/AST/Bundle.h>
 #include <llvm/Support/CommandLine.h>
 #include <llvm/ADT/StringExtras.h>
@@ -534,6 +535,10 @@
   return 0;
 }
 
+static Operator* genExpression(Operator* Val, unsigned depth);
+static Operator* genUnaryExpression(Operator* Val);
+static Operator* genBinaryExpression(Operator* V1, Operator*V2);
+
 static Operator*
 genBooleanUnary(Operator* V1) 
 {
@@ -635,8 +640,8 @@
 static Operator*
 genIntegerBinary(Operator* V1, Operator* V2)
 {
-  hlvmAssert(V1->getType()->getID() == IntegerTypeID);
-  hlvmAssert(V2->getType()->getID() == IntegerTypeID);
+  hlvmAssert(V1->getType()->isIntegralType());
+  hlvmAssert(V2->getType()->isIntegralType());
   Operator* result = 0;
   NodeIDs id = NodeIDs(randRange(AddOpID, BNorOpID));
   switch (id) {
@@ -748,148 +753,260 @@
 static Operator*
 genStringUnary(Operator* V1)
 {
-  hlvmAssert(V1->getType()->getID() == RealTypeID);
-  return 0;
+  hlvmAssert(isa<StringType>(V1));
+  Operator* str = genValueAsOperator(bundle->getIntrinsicType(stringTy));
+  return ast->new_BinaryOp<StrConcatOp>(V1,str,bundle,getLocator());
 }
 
 static Operator*
 genStringBinary(Operator* V1, Operator* V2)
 {
-  return 0;
+  hlvmAssert(isa<StringType>(V1));
+  hlvmAssert(isa<StringType>(V2));
+  ConstantInteger* CI = getConstantInteger(0);
+  GetOp* get = ast->new_GetOp(CI,getLocator());
+  return ast->new_BinaryOp<StrConcatOp>(V1,V2,bundle,getLocator());
 }
 
 static Operator*
-genPointerUnary(Operator* V1)
+genArrayUnary(Operator* V1)
 {
-  hlvmAssert(V1->getType()->getID() == RealTypeID);
+  hlvmAssert(isa<ArrayType>(V1));
+  const ArrayType* Ty = cast<ArrayType>(V1->getType());
   return 0;
 }
 
 static Operator*
-genPointerBinary(Operator* V1, Operator* V2)
+genArrayBinary(Operator* V1, Operator* V2)
 {
+  hlvmAssert(isa<ArrayType>(V1));
+  hlvmAssert(isa<ArrayType>(V2));
+  hlvmAssert(V1->getType() == V2->getType());
+  const ArrayType* Ty = cast<ArrayType>(V1->getType());
   return 0;
 }
 
 static Operator*
-genArrayUnary(Operator* V1)
+genVectorUnary(Operator* V1)
 {
-  hlvmAssert(V1->getType()->getID() == RealTypeID);
-  return 0;
+  hlvmAssert(isa<VectorType>(V1));
+  const VectorType* Ty = cast<VectorType>(V1->getType());
+  Block* blk = ast->new_Block(getLocator());
+  AutoVarOp* autovar = ast->new_AutoVarOp("result",Ty,getLocator());
+  for (unsigned i = 0; i < Ty->getSize(); ++i) {
+    ConstantInteger* cst = getConstantInteger(i);
+    GetOp* index = ast->new_GetOp(cst,getLocator());
+    GetIndexOp* elem = 
+      ast->new_BinaryOp<GetIndexOp>(V1,index,bundle,getLocator());
+    LoadOp* load1 = ast->new_UnaryOp<LoadOp>(elem,bundle,getLocator());
+    Operator* expr = genUnaryExpression(load1);
+    GetOp* get = ast->new_GetOp(autovar,getLocator());
+    GetIndexOp* elem2 =
+      ast->new_BinaryOp<GetIndexOp>(get,index,bundle,getLocator());
+    StoreOp* store = 
+      ast->new_BinaryOp<StoreOp>(elem2,expr,bundle,getLocator());
+    blk->addOperand(store);
+  }
+  GetOp* get = ast->new_GetOp(autovar,getLocator());
+  ResultOp* result = ast->new_UnaryOp<ResultOp>(get,bundle,getLocator());
+  blk->addOperand(result);
+  return blk;
 }
 
 static Operator*
-genArrayBinary(Operator* V1, Operator* V2)
+genVectorBinary(Operator* V1, Operator* V2)
 {
-  return 0;
+  hlvmAssert(isa<StructureType>(V1));
+  hlvmAssert(isa<StructureType>(V2));
+  hlvmAssert(V1->getType() == V2->getType());
+  const VectorType* Ty = llvm::cast<VectorType>(V1->getType());
+  Block* blk = ast->new_Block(getLocator());
+  AutoVarOp* autovar = ast->new_AutoVarOp("result",Ty,getLocator());
+  for (unsigned i = 0; i < Ty->getSize(); ++i)
+  {
+    ConstantInteger* cst = getConstantInteger(i);
+    GetOp* index = ast->new_GetOp(cst,getLocator());
+    GetFieldOp* elem1 = 
+      ast->new_BinaryOp<GetFieldOp>(V1,index,bundle,getLocator());
+    LoadOp* load1 = ast->new_UnaryOp<LoadOp>(elem1,bundle,getLocator());
+    GetFieldOp* elem2 = 
+      ast->new_BinaryOp<GetFieldOp>(V2,index,bundle,getLocator());
+    LoadOp* load2 = ast->new_UnaryOp<LoadOp>(elem1,bundle,getLocator());
+    Operator* expr = genBinaryExpression(load1,load2);
+    GetOp* get = ast->new_GetOp(autovar,getLocator());
+    GetFieldOp* elem3 = 
+      ast->new_BinaryOp<GetFieldOp>(get,index,bundle,getLocator());
+    StoreOp* store = 
+      ast->new_BinaryOp<StoreOp>(elem3,expr,bundle,getLocator());
+    blk->addOperand(store);
+  }
+  GetOp* get = ast->new_GetOp(autovar,getLocator());
+  ResultOp* result = ast->new_UnaryOp<ResultOp>(get,bundle,getLocator());
+  blk->addOperand(result);
+  return blk;
 }
 
 static Operator*
-genVectorUnary(Operator* V1)
+genStructureUnary(Operator* V1)
 {
-  hlvmAssert(V1->getType()->getID() == RealTypeID);
-  return 0;
+  hlvmAssert(V1->getType()->getID() == StructureTypeID);
+  Block* blk = ast->new_Block(getLocator());
+  AutoVarOp* autovar = ast->new_AutoVarOp("result",V1->getType(),getLocator());
+  const StructureType* Ty = llvm::cast<StructureType>(V1->getType());
+  for (StructureType::const_iterator I = Ty->begin(), E = Ty->end(); 
+       I != E; ++I)
+  {
+    ConstantString* cst = getConstantString((*I)->getName());
+    GetOp* fldName = ast->new_GetOp(cst,getLocator());
+    GetFieldOp* getField1 = 
+      ast->new_BinaryOp<GetFieldOp>(V1,fldName,bundle,getLocator());
+    LoadOp* load1 = ast->new_UnaryOp<LoadOp>(getField1,bundle,getLocator());
+    Operator* expr = genUnaryExpression(load1);
+    GetOp* get = ast->new_GetOp(autovar,getLocator());
+    GetFieldOp* getField3 =
+      ast->new_BinaryOp<GetFieldOp>(get,fldName,bundle,getLocator());
+    StoreOp* store = 
+      ast->new_BinaryOp<StoreOp>(getField3,expr,bundle,getLocator());
+    blk->addOperand(store);
+  }
+  GetOp* get = ast->new_GetOp(autovar,getLocator());
+  ResultOp* result = ast->new_UnaryOp<ResultOp>(get,bundle,getLocator());
+  blk->addOperand(result);
+  return blk;
 }
 
 static Operator*
-genVectorBinary(Operator* V1, Operator* V2)
+genStructureBinary(Operator* V1, Operator* V2)
 {
-  return 0;
+  hlvmAssert(V1->getType()->getID() == StructureTypeID);
+  hlvmAssert(V2->getType()->getID() == StructureTypeID);
+  hlvmAssert(V1->getType() == V2->getType());
+  Block* blk = ast->new_Block(getLocator());
+  AutoVarOp* autovar = ast->new_AutoVarOp("result",V1->getType(),getLocator());
+  const StructureType* Ty = llvm::cast<StructureType>(V1->getType());
+  for (StructureType::const_iterator I = Ty->begin(), E = Ty->end(); 
+       I != E; ++I)
+  {
+    ConstantString* cst = getConstantString((*I)->getName());
+    GetOp* fldName = ast->new_GetOp(cst,getLocator());
+    GetFieldOp* getField1 = 
+      ast->new_BinaryOp<GetFieldOp>(V1,fldName,bundle,getLocator());
+    LoadOp* load1 = ast->new_UnaryOp<LoadOp>(getField1,bundle,getLocator());
+    GetFieldOp* getField2 = 
+      ast->new_BinaryOp<GetFieldOp>(V2,fldName,bundle,getLocator());
+    LoadOp* load2 = ast->new_UnaryOp<LoadOp>(getField2,bundle,getLocator());
+    Operator* expr = genBinaryExpression(load1,load2);
+    GetOp* get = ast->new_GetOp(autovar,getLocator());
+    GetFieldOp* getField3 = 
+      ast->new_BinaryOp<GetFieldOp>(get,fldName,bundle,getLocator());
+    StoreOp* store = 
+      ast->new_BinaryOp<StoreOp>(getField3,expr,bundle,getLocator());
+    blk->addOperand(store);
+  }
+  GetOp* get = ast->new_GetOp(autovar,getLocator());
+  ResultOp* result = ast->new_UnaryOp<ResultOp>(get,bundle,getLocator());
+  blk->addOperand(result);
+  return blk;
 }
 
 static Operator*
-genStructureUnary(Operator* V1)
+genPointerUnary(Operator* V1)
 {
-  hlvmAssert(V1->getType()->getID() == RealTypeID);
-  return 0;
+  hlvmAssert(V1->getType()->getID() == PointerTypeID);
+  LoadOp* load = ast->new_UnaryOp<LoadOp>(V1,bundle,getLocator());
+  return genUnaryExpression(load);
 }
 
 static Operator*
-genStructureBinary(Operator* V1, Operator* V2)
+genPointerBinary(Operator* V1, Operator* V2)
 {
-  return 0;
+  hlvmAssert(V1->getType()->getID() == PointerTypeID);
+  hlvmAssert(V2->getType()->getID() == PointerTypeID);
+  hlvmAssert(V1->getType() == V2->getType());
+  LoadOp* load1 = ast->new_UnaryOp<LoadOp>(V1,bundle,getLocator());
+  LoadOp* load2 = ast->new_UnaryOp<LoadOp>(V2,bundle,getLocator());
+  return genBinaryExpression(load1,load2);
+}
+
+static Operator*
+genUnaryExpression(Operator* Val)
+{
+  switch(Val->getType()->getID()) {
+    case BooleanTypeID:      return genBooleanUnary(Val); break;
+    case CharacterTypeID:    return genCharacterUnary(Val); break;
+    case AnyTypeID:         
+    case BufferTypeID:
+    case StreamTypeID:
+    case TextTypeID:
+    case SignatureTypeID:
+    case RationalTypeID:
+      // FALL THROUGH: Not Implemented
+    case RangeTypeID:
+    case IntegerTypeID:
+    case EnumerationTypeID:  return genIntegerUnary(Val); break;
+    case RealTypeID:         return genRealUnary(Val); break;
+    case StringTypeID:       return genStringUnary(Val); break;
+    case PointerTypeID:      return genPointerUnary(Val); break;
+    case ArrayTypeID:        return genArrayUnary(Val); break;
+    case VectorTypeID:       return genVectorUnary(Val); break;
+    case OpaqueTypeID:
+    case ContinuationTypeID:
+    case StructureTypeID:    return genStructureUnary(Val); break;
+    default:
+      hlvmDeadCode("Invalid type?");
+      return 0;
+      break;
+  }
+}
+
+static Operator*
+genBinaryExpression(Operator* V1, Operator*V2)
+{
+  switch (V1->getType()->getID()) {
+    case BooleanTypeID:     return genBooleanBinary(V1,V2); break;
+    case CharacterTypeID:   return genCharacterBinary(V1,V2); break;
+    case AnyTypeID:         
+    case BufferTypeID:
+    case StreamTypeID:
+    case TextTypeID:
+    case SignatureTypeID:
+    case RationalTypeID:
+      // FALL THROUGH: Not Implemented
+    case RangeTypeID:
+    case IntegerTypeID:
+    case EnumerationTypeID: return genIntegerBinary(V1,V2);break;
+    case RealTypeID:        return genRealBinary(V1,V2); break;
+    case StringTypeID:      return  genStringBinary(V1,V2); break;
+    case PointerTypeID:     return  genPointerBinary(V1,V2); break;
+    case ArrayTypeID:       return  genArrayBinary(V1,V2); break;
+    case VectorTypeID:      return  genVectorBinary(V1,V2); break;
+    case OpaqueTypeID:
+    case ContinuationTypeID:
+    case StructureTypeID:   return  genStructureBinary(V1,V2);break;
+    default:                hlvmDeadCode("Invalid Type");
+                            return 0;
+  }
 }
 
 // Forward declare
 static Function* genFunction(const Type* resultType, unsigned depth);
 
 static Operator*
-genExpression(Operator* Val, const Type* Ty, unsigned depth)
+genExpression(Operator* Val, unsigned depth)
 {
-  hlvmAssert(Val->getType() == Ty);
   if (depth > 0) {
     // Generate a function
-    Function* F = genFunction(Ty, depth-1);
+    Function* F = genFunction(Val->getType(), depth-1);
     // Generate a call to that function
     return genCallTo(F);
   }
 
-  Operator* result = 0;
+  // 50% Randomly generate a unary expression
+  if (5 <= randRange(1,10))
+    return genUnaryExpression(Val);
 
-  // Determine whether to generate a binary or unary expression
-  if (5 <= randRange(1,10)) {
-    switch (Ty->getID()) {
-      case BooleanTypeID: result = genBooleanUnary(Val); break;
-      case CharacterTypeID: result = genCharacterUnary(Val); break;
-      case AnyTypeID:         
-      case BufferTypeID:
-      case StreamTypeID:
-      case TextTypeID:
-      case SignatureTypeID:
-      case RationalTypeID:
-        // FALL THROUGH: Not Implemented
-      case RangeTypeID:
-      case IntegerTypeID:
-      case EnumerationTypeID: result = genIntegerUnary(Val); break;
-      case RealTypeID: result = genRealUnary(Val); break;
-      case StringTypeID: result = genStringUnary(Val); break;
-      case PointerTypeID: result = genPointerUnary(Val); break;
-      case ArrayTypeID: result = genArrayUnary(Val); break;
-      case VectorTypeID: result = genVectorUnary(Val); break;
-      case OpaqueTypeID:
-      case ContinuationTypeID:
-      case StructureTypeID: result = genStructureUnary(Val); break;
-      default:
-        hlvmAssert(!"Invalid type?");
-        break;
-    }
-  } else {
-    switch (Ty->getID()) {
-      case BooleanTypeID: 
-        result = genBooleanBinary(Val,genValueAsOperator(Ty)); break;
-      case CharacterTypeID:
-        result = genCharacterBinary(Val,genValueAsOperator(Ty)); break;
-      case AnyTypeID:         
-      case BufferTypeID:
-      case StreamTypeID:
-      case TextTypeID:
-      case SignatureTypeID:
-      case RationalTypeID:
-        // FALL THROUGH: Not Implemented
-      case RangeTypeID:
-      case IntegerTypeID:
-      case EnumerationTypeID: 
-        result = genIntegerBinary(Val,genValueAsOperator(Ty));break;
-      case RealTypeID: 
-        result = genRealBinary(Val,genValueAsOperator(Ty)); break;
-      case StringTypeID: 
-        result = genStringBinary(Val,genValueAsOperator(Ty)); break;
-      case PointerTypeID: 
-        result = genPointerBinary(Val,genValueAsOperator(Ty)); break;
-      case ArrayTypeID: 
-        result = genArrayBinary(Val,genValueAsOperator(Ty)); break;
-      case VectorTypeID: 
-        result = genVectorBinary(Val,genValueAsOperator(Ty)); break;
-      case OpaqueTypeID:
-      case ContinuationTypeID:
-      case StructureTypeID: 
-        result = genStructureBinary(Val,genValueAsOperator(Ty));break;
-      default:
-        hlvmAssert(!"Invalid type?");
-        break;
-    }
-  }
-  return result;
+  // Otherwise generate a binary expression
+  return genBinaryExpression(Val,genValueAsOperator(Val->getType()));
 }
 
 static void
@@ -963,7 +1080,7 @@
     }
 
     // Generate the expression
-    Operator* expr = genExpression(theValue,F->getResultType(),depth-1);
+    Operator* expr = genExpression(theValue,depth-1);
 
     // Merge the current value of the autovar result with the generated
     // expression.
@@ -1071,10 +1188,8 @@
     // Coalesce the result of the random function into the autovar we
     // created for the result of this block.
     if (Ty->isNumericType()) {
-      Operator* get = 
-        ast->new_GetOp(program->getResultType(),getLocator());
       Operator* cvt = 
-        ast->new_BinaryOp<ConvertOp>(call,get,bundle,getLocator());
+        ast->new_ConvertOp(call,program->getResultType(),getLocator());
       genMergeExpression(result,cvt,B);
     }
   }





More information about the llvm-commits mailing list