| //===-- 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]; |
| } |