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__
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);
36 /****** COMPILATION ELEMENTS & ATTRIBUTES ******/
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
);
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();
88 if(attributes
.find(i
->first
)!=attributes
.end()) {
89 attributes
[i
->first
]->merge(a
);
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";
101 for(att_iter i
=attributes
.begin(); i
!=attributes
.end(); i
++) {
102 *out
<< pp_indent() << i
->first
<<": "; i
->second
->print(out
); *out
<<"\n";
108 #endif // __COMPILER_UTILS__