tying to deal with a flex problem
[proto.git] / src / compiler / compiler-utils.h
blob64c6418c669b7ebfafbd400d0c0f2d746c2dfc39
1 /* Proto compiler utilities
2 Copyright (C) 2005-2008, Jonathan Bachrach, Jacob Beal, and contributors
3 listed in the AUTHORS file in the MIT Proto distribution's top directory.
5 This file is part of MIT Proto, and is distributed under the terms of
6 the GNU General Public License, with a linking exception, as described
7 in the file LICENSE in the MIT Proto distribution's top directory. */
9 // Note: compiler will leak memory like mad, so it needs to be run
10 // as a sub-application, then discarded.
12 #ifndef __COMPILER_UTILS__
13 #define __COMPILER_UTILS__
15 #include <map>
16 #include <iostream>
17 #include <utility>
18 #include <string>
19 #include <sstream>
21 using namespace std;
23 extern ostream *cpout, *cperr, *cplog; // Compiler output streams
25 /****** OUTPUT HANDLING ******/
26 struct CompilationElement;
28 // Report a compiler internal error (i.e. not caused by user)
29 void ierror(string msg);
30 void ierror(CompilationElement *where, string msg);
31 // pretty-print indenting
32 void pp_push(int n=1);
33 void pp_pop();
34 string pp_indent();
36 /****** COMPILATION ELEMENTS & ATTRIBUTES ******/
37 struct Attribute {
38 virtual Attribute* inherited() { return NULL; }
39 virtual void merge(Attribute *addition) {
40 ierror("Attempt to merge incompatible attributes: " + this->to_str()
41 + ", " + addition->to_str());
43 string to_str() { ostringstream s; print(&s); return s.str(); }
44 virtual void print(ostream *out=cpout) = 0;
48 struct Context : Attribute {
49 map<string, pair<int,int>*> places; // file, <start,end>
51 Context(string file_name,int line)
52 { places[file_name] = new pair<int,int>(line,line); }
54 Attribute* inherited() { return new Context(*this); }
55 void merge(Attribute *_addition) {
56 Context *addition = (Context*)_addition;
57 map<string,pair<int,int>*>::iterator i;
58 for(i=addition->places.begin(); i != addition->places.end(); i++) {
59 if(places.find(i->first) != places.end()) {
60 places[i->first]->first=min(places[i->first]->first,i->second->first);
61 places[i->first]->second=max(places[i->first]->second,i->second->second);
62 } else {
63 places[i->first] = i->second;
68 void print(ostream *out=cpout) {
69 map<string,pair<int,int>*>::iterator i;
70 for(i=places.begin(); i != places.end(); i++) {
71 if(i!=places.begin()) *out << ", ";
72 *out << i->first << ":" << i->second->first;
73 if(i->second->first!=i->second->second) *out << "-" << i->second->second;
79 // By default, attributes that are passed around are *not* duplicated
80 struct CompilationElement {
81 map<string,Attribute*> attributes; // should end up with null in default
82 typedef map<string,Attribute*>::iterator att_iter;
84 virtual void inherit_attributes(CompilationElement* src) {
85 for(att_iter i=src->attributes.begin(); i!=src->attributes.end(); i++) {
86 Attribute *a = src->attributes[i->first]->inherited();
87 if(a!=NULL) {
88 if(attributes.find(i->first)!=attributes.end()) {
89 attributes[i->first]->merge(a);
90 } else {
91 attributes[i->first] = a;
96 virtual string type_of() { return "CompilationElement"; }
97 string to_str() { ostringstream s; print(&s); return s.str(); }
98 virtual void print(ostream *out=cpout) {
99 *out << pp_indent() << "Attributes [" << attributes.size() << "]\n";
100 pp_push(2);
101 for(att_iter i=attributes.begin(); i!=attributes.end(); i++) {
102 *out<< pp_indent() << i->first <<": "; i->second->print(out); *out<<"\n";
104 pp_pop();
108 #endif // __COMPILER_UTILS__