Synopsis - Cross-Reference

File: /tests/Cxx/src/ConstEvaluator.cc
  1#include <Synopsis/Trace.hh>
  2#include <Synopsis/Buffer.hh>
  3#include <Synopsis/Lexer.hh>
  4#include <Synopsis/SymbolFactory.hh>
  5#include <Synopsis/Parser.hh>
  6#include <Synopsis/PTree.hh>
  7#include <Synopsis/PTree/Display.hh>
  8#include <Synopsis/PTree/Writer.hh>
  9#include <Synopsis/SymbolLookup.hh>
 10#include <Synopsis/TypeAnalysis.hh>
 11#include <iostream>
 12#include <iomanip>
 13#include <fstream>
 14
 15using namespace Synopsis;
 16
 17class InitializerFinder : private SymbolLookup::Walker
 18{
 19public:
 20  InitializerFinder(SymbolLookup::Scope *global, std::ostream &os)
 21    : SymbolLookup::Walker(global), my_os(os) {}
 22  void find(PTree::Node *node) { node->accept(this);}
 23private:
 24  virtual void visit(PTree::List *node)
 25  {
 26    for (PTree::Node *n = node; n; n = n->cdr())
 27      if (n->car()) n->car()->accept(this);
 28  }
 29  virtual void visit(PTree::EnumSpec *node)
 30  {
 31    PTree::Node *body = third(node);
 32
 33    long value = -1;
 34    for (PTree::Node *e = PTree::second(body);
 35	 e;
 36	 e = PTree::rest(rest(e)))
 37    {
 38      PTree::Node *enumerator = e->car();
 39      if (enumerator->is_atom()) ++value;
 40      else  // [identifier = initializer]
 41      {
 42	PTree::Node *initializer = PTree::third(enumerator);
 43	enumerator = enumerator->car();
 44	if (!TypeAnalysis::evaluate_const(current_scope(), initializer, value))
 45	{
 46	  std::cerr << "Error in evaluating enum initializer :\n"
 47		    << "Expression doesn't evaluate to a constant integral value" << std::endl;
 48	}
 49      }
 50      assert(enumerator->is_atom());
 51      std::string name(enumerator->position(), enumerator->length());
 52      my_os << "enumerator : " << name << ", "
 53	    << "value : " << value << std::endl;
 54    }
 55  }
 56  virtual void visit(PTree::Declaration *node)
 57  {
 58    PTree::Node *type = PTree::second(node);
 59    type->accept(this);
 60    PTree::Node *rest = PTree::third(node);
 61    if (rest->is_atom()) return; // ';'
 62    for (; rest; rest = rest->cdr())
 63    {
 64      PTree::Node *p = rest->car();
 65      p->accept(this);
 66    }
 67  }
 68  virtual void visit(PTree::Declarator *node) 
 69  {
 70    if (PTree::length(node) == 3)
 71    {
 72      PTree::Node *initializer = PTree::third(node);
 73      my_os << "initializer : " << PTree::reify(initializer) << std::endl;
 74      long value;
 75      if (TypeAnalysis::evaluate_const(current_scope(), initializer, value))
 76	my_os << "value : " << value << std::endl;
 77      else
 78	my_os << "value : none" << std::endl;
 79    }
 80  }
 81
 82  std::ostream &my_os;
 83};
 84
 85int main(int argc, char **argv)
 86{
 87  if (argc < 3)
 88  {
 89    std::cerr << "Usage: " << argv[0] << " [-d] <output> <input>" << std::endl;
 90    exit(-1);
 91  }
 92  try
 93  {
 94    std::string output;
 95    std::string input;
 96    if (argv[1] == std::string("-d"))
 97    {
 98      Trace::enable(Trace::ALL);
 99      output = argv[2];
100      input = argv[3];
101    }
102    else
103    {
104      output = argv[1];
105      input = argv[2];
106    }
107    std::ofstream ofs(output.c_str());
108    std::ifstream ifs(input.c_str());
109    Buffer buffer(ifs.rdbuf(), input);
110    Lexer lexer(&buffer);
111    SymbolFactory symbols;
112    Parser parser(lexer, symbols);
113    PTree::Node *node = parser.parse();
114    InitializerFinder finder(symbols.current_scope(), ofs);
115    finder.find(node);
116  }
117  catch (std::exception const &e)
118  {
119    std::cerr << "Caught exception : " << e.what() << std::endl;
120  }
121}