Synopsis - Cross-Reference

File: /tests/Cxx/src/TypeAnalysis.cc
  1#include <Synopsis/Trace.hh>
  2#include <Synopsis/Buffer.hh>
  3#include <Synopsis/Lexer.hh>
  4#include <Synopsis/Parser.hh>
  5#include <Synopsis/PTree.hh>
  6#include <Synopsis/PTree/Display.hh>
  7#include <Synopsis/PTree/Writer.hh>
  8#include <Synopsis/SymbolLookup.hh>
  9#include <Synopsis/TypeAnalysis.hh>
 10#include <iostream>
 11#include <iomanip>
 12#include <fstream>
 13
 14using namespace Synopsis;
 15
 16//. Evaluating types of expressions may involve
 17//. overload resolution, if the types of the subexpressions
 18//. are user defined (enums, classes).
 19//. As this is a unit test for type evaluation, not overload
 20//. resolution, we restrict ourselfs to builtin types.
 21//.
 22//. Test input should be a set of declarations where
 23//. the initializers are expressions which we look up
 24//. the type for.
 25class InitializerFinder : private SymbolLookup::Walker
 26{
 27public:
 28  InitializerFinder(SymbolLookup::Scope *scope, std::ostream &os)
 29    : SymbolLookup::Walker(scope), my_os(os) {}
 30  void find(PTree::Node *node) { node->accept(this);}
 31
 32private:
 33  virtual void visit(PTree::Declaration *node)
 34  {
 35    PTree::Node *type = PTree::second(node);
 36    type->accept(this);
 37    PTree::Node *rest = PTree::third(node);
 38    if (rest->is_atom()) return; // ';'
 39    for (; rest; rest = rest->cdr())
 40    {
 41      PTree::Node *p = rest->car();
 42      p->accept(this);
 43    }
 44  }
 45  virtual void visit(PTree::Declarator *decl)
 46  {
 47    size_t length = PTree::length(decl);
 48    if (length >= 2 && *PTree::nth(decl, length - 2) == '=')
 49    {
 50      PTree::Node *init = PTree::tail(decl, length - 1)->car();
 51      // do the type evaluation here...
 52      std::cout << "Expression : " << PTree::reify(init) << std::endl;
 53      TypeAnalysis::Type const *type = TypeAnalysis::type_of(init, current_scope());
 54//       std::cout << "Type : " << type << std::endl;
 55//       std::cout << "Type : " << type.is_const() << std::endl;
 56//       std::cout << "Type : " << type.is_builtin_type() << std::endl;
 57//       std::cout << "Type : " << type << std::endl;
 58    }
 59  }
 60
 61  std::ostream &my_os;
 62};
 63
 64int main(int argc, char **argv)
 65{
 66  if (argc < 3)
 67  {
 68    std::cerr << "Usage: " << argv[0] << " [-d] <output> <input>" << std::endl;
 69    exit(-1);
 70  }
 71  try
 72  {
 73    std::string output;
 74    std::string input;
 75    if (argv[1] == std::string("-d"))
 76    {
 77      Trace::enable(Trace::ALL);
 78      output = argv[2];
 79      input = argv[3];
 80    }
 81    else
 82    {
 83      output = argv[1];
 84      input = argv[2];
 85    }
 86    std::ofstream ofs(output.c_str());
 87    std::ifstream ifs(input.c_str());
 88    Buffer buffer(ifs.rdbuf(), input);
 89    Lexer lexer(&buffer);
 90    SymbolFactory symbols;
 91    Parser parser(lexer, symbols);
 92    PTree::Node *node = parser.parse();
 93    InitializerFinder finder(symbols.current_scope(), ofs);
 94    finder.find(node);
 95  }
 96  catch (std::exception const &e)
 97  {
 98    std::cerr << "Caught exception : " << e.what() << std::endl;
 99  }
100}