Initial checkin of interpreter


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ExecutionEngine/Interpreter/Support.cpp b/lib/ExecutionEngine/Interpreter/Support.cpp
new file mode 100644
index 0000000..a619304
--- /dev/null
+++ b/lib/ExecutionEngine/Interpreter/Support.cpp
@@ -0,0 +1,78 @@
+//===-- Support.cpp - Support routines for interpreter --------------------===//
+// 
+//  This file contains support routines for the interpreter core.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Interpreter.h"
+#include "llvm/SymbolTable.h"
+#include "llvm/Assembly/Writer.h"
+
+//===----------------------------------------------------------------------===//
+//
+// LookupMatchingNames helper - Search a symbol table for values matching Name.
+//
+static inline void LookupMatchingNames(const string &Name, SymTabValue &STV,
+				       vector<Value*> &Results) {
+  SymbolTable *SymTab = STV.getSymbolTable();
+  if (SymTab == 0) return;                         // No symbolic values :(
+
+  // Loop over all of the type planes in the symbol table...
+  for (SymbolTable::iterator I = SymTab->begin(), E = SymTab->end();
+       I != E; ++I) {
+    SymbolTable::VarMap &Plane = I->second;
+    
+    // Search the symbol table plane for this name...
+    SymbolTable::VarMap::iterator Val = Plane.find(Name);
+    if (Val != Plane.end())
+      Results.push_back(Val->second);                    // Found a name match!
+  }
+}
+
+// LookupMatchingNames - Search the current method namespace, then the global
+// namespace looking for values that match the specified name.  Return ALL
+// matches to that name.  This is obviously slow, and should only be used for
+// user interaction.
+//
+vector<Value*> Interpreter::LookupMatchingNames(const string &Name) {
+  vector<Value*> Results;
+  Method *CurMeth = getCurrentMethod();
+  
+  if (CurMeth) ::LookupMatchingNames(Name, *CurMeth, Results);
+  if (CurMod ) ::LookupMatchingNames(Name, *CurMod , Results);
+  return Results;
+}
+
+// ChooseOneOption - Prompt the user to choose among the specified options to
+// pick one value.  If no options are provided, emit an error.  If a single 
+// option is provided, just return that option.
+//
+Value *Interpreter::ChooseOneOption(const string &Name,
+				    const vector<Value*> &Opts) {
+  switch (Opts.size()) {
+  case 1: return Opts[0];
+  case 0: 
+    cout << "Error: no entities named '" << Name << "' found!\n";
+    return 0;
+  default: break;  // Must prompt user...
+  }
+
+  cout << "Multiple entities named '" << Name << "' found!  Please choose:\n";
+  cout << "  0. Cancel operation\n";
+  for (unsigned i = 0; i < Opts.size(); ++i) {
+    cout << "  " << (i+1) << ".";
+    WriteAsOperand(cout, Opts[i]) << endl;
+  }
+
+  unsigned Option;
+  do {
+    cout << "lli> " << flush;
+    cin >> Option;
+    if (Option > Opts.size())
+      cout << "Invalid selection: Please choose from 0 to " << Opts.size()
+	   << endl;
+  } while (Option > Opts.size());
+
+  if (Option == 0) return 0;
+  return Opts[Option-1];
+}