Synopsis - Cross-Reference
File: /tests/Cxx/src/ConstEvaluator.cc1#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}