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/UserInput.cpp b/lib/ExecutionEngine/Interpreter/UserInput.cpp
new file mode 100644
index 0000000..cfa74f1
--- /dev/null
+++ b/lib/ExecutionEngine/Interpreter/UserInput.cpp
@@ -0,0 +1,147 @@
+//===-- UserInput.cpp - Interpreter Input Loop support --------------------===//
+// 
+//  This file implements the interpreter Input I/O loop.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Interpreter.h"
+#include "llvm/Assembly/Writer.h"
+#include <algorithm>
+
+enum CommandID {
+  Quit, Help,                           // Basics
+  Print, List, StackTrace, Up, Down,    // Inspection
+  Next, Step, Run, Finish, Call,        // Control flow changes
+  Break, Watch,                         // Debugging
+  Load, Flush
+};
+
+// CommandTable - Build a lookup table for the commands available to the user...
+static struct CommandTableElement {
+  const char *Name;
+  enum CommandID CID;
+
+  inline bool operator<(const CommandTableElement &E) const {
+    return string(Name) < string(E.Name);
+  }
+  inline bool operator==(const string &S) const { 
+    return string(Name) == S;
+  }
+} CommandTable[] = {
+  { "quit"     , Quit       }, { "q", Quit }, { "", Quit }, // Empty str = eof
+  { "help"     , Help       }, { "h", Help },
+
+  { "print"    , Print      }, { "p", Print },
+  { "list"     , List       },
+  { "backtrace", StackTrace }, { "bt", StackTrace }, { "where", StackTrace },
+  { "up"       , Up         },
+  { "down"     , Down       },
+
+  { "next"     , Next       }, { "n", Next },
+  { "step"     , Step       }, { "s", Step },
+  { "run"      , Run        },
+  { "finish"   , Finish     },
+  { "call"     , Call       },
+
+  { "break"    , Break      }, { "b", Break },
+  { "watch"    , Watch      },
+
+  { "load"     , Load       },
+  { "flush"    , Flush      },
+};
+static CommandTableElement *CommandTableEnd = 
+   CommandTable+sizeof(CommandTable)/sizeof(CommandTable[0]);
+
+
+//===----------------------------------------------------------------------===//
+// handleUserInput - Enter the input loop for the interpreter.  This function
+// returns when the user quits the interpreter.
+//
+void Interpreter::handleUserInput() {
+  bool UserQuit = false;
+
+  // Sort the table...
+  sort(CommandTable, CommandTableEnd);
+
+  // Print the instruction that we are stopped at...
+  printCurrentInstruction();
+
+  do {
+    string Command;
+    cout << "lli> " << flush;
+    cin >> Command;
+
+    CommandTableElement *E = find(CommandTable, CommandTableEnd, Command);
+
+    if (E == CommandTableEnd) {
+      cout << "Error: '" << Command << "' not recognized!\n";
+      continue;
+    }
+
+    switch (E->CID) {
+    case Quit:       UserQuit = true;   break;
+    case Print:
+      cin >> Command;
+      printValue(Command);
+      break;
+    case List:       list();            break;
+    case StackTrace: printStackTrace(); break;
+    case Up: 
+      if (CurFrame > 0) --CurFrame;
+      else cout << "Error: Already at root of stack!\n";
+      break;
+    case Down:
+      if ((unsigned)CurFrame < ECStack.size()-1) ++CurFrame;
+      else cout << "Error: Already at bottom of stack!\n";
+      break;
+    case Next:       nextInstruction(); break;
+    case Step:       stepInstruction(); break;
+    case Run:        run();             break;
+    case Finish:     finish();          break;
+    case Call:
+      cin >> Command;
+      callMethod(Command);    // Enter the specified method
+      finish();               // Run until it's complete
+      break;
+
+    default:
+      cout << "Command '" << Command << "' unimplemented!\n";
+      break;
+    }
+
+  } while (!UserQuit);
+}
+
+
+//===----------------------------------------------------------------------===//
+// setBreakpoint - Enable a breakpoint at the specified location
+//
+void Interpreter::setBreakpoint(const string &Name) {
+  Value *PickedVal = ChooseOneOption(Name, LookupMatchingNames(Name));
+  // TODO: Set a breakpoint on PickedVal
+}
+
+//===----------------------------------------------------------------------===//
+// callMethod - Enter the specified method...
+//
+bool Interpreter::callMethod(const string &Name) {
+  vector<Value*> Options = LookupMatchingNames(Name);
+
+  for (unsigned i = 0; i < Options.size(); ++i) { // Remove nonmethod matches...
+    if (!Options[i]->isMethod()) {
+      Options.erase(Options.begin()+i);
+      --i;
+    }
+  }
+
+  Value *PickedMeth = ChooseOneOption(Name, Options);
+  if (PickedMeth == 0)
+    return true;
+
+  callMethod(PickedMeth->castMethodAsserting());  // Start executing it...
+
+  // Reset the current frame location to the top of stack
+  CurFrame = ECStack.size()-1;
+
+  return false;
+}