1 ///////////////////////////////////////////////////////////////////////////////
4 // // // ////// ///// ///////
5 // //////// // // // // //
10 // Allen Leung (leunga@cs.nyu.edu)
11 ///////////////////////////////////////////////////////////////////////////////
13 // This is the driver routine for the translator
27 ///////////////////////////////////////////////////////////////////////////////
29 // Various global data.
31 ///////////////////////////////////////////////////////////////////////////////
34 std::istream
* input_stream
= 0;
35 std::ostream
* output_stream
= 0;
36 std::ostream
* log_stream
= 0;
37 Compiler
* error_log
= 0;
40 ///////////////////////////////////////////////////////////////////////////////
42 // Memory pool and string pool
44 ///////////////////////////////////////////////////////////////////////////////
45 MemPool
mem_pool(4096); // 4K page size
46 MemPool
global_pool(4096); // 4K page size
47 MemPool
* current_pool
= &mem_pool
;
48 StringPool
str_pool(4096); // 4K page size
49 static int globals
= 0;
50 void MEM::use_global_pools() { current_pool
= &global_pool
; globals
++; }
51 void MEM::use_local_pools() { if (--globals
== 0) current_pool
= &mem_pool
;}
52 void * MEM::operator new(size_t n
) { return (*current_pool
)[n
]; }
54 ///////////////////////////////////////////////////////////////////////////////
56 // Current source location variables.
58 ///////////////////////////////////////////////////////////////////////////////
62 ///////////////////////////////////////////////////////////////////////////////
64 // Source location methods
66 ///////////////////////////////////////////////////////////////////////////////
67 Loc::Loc() { begin_line
= first_line
; end_line
= line
; file_name
= file
;
69 Loc::Loc(int a
, int b
)
70 { begin_line
= a
; end_line
= b
; file_name
= file
;
73 void Loc::set_loc() const { line
= begin_line
; file
= file_name
; }
75 const char * my_strrchr(const char * s
, char c
)
76 { register const char * p
;
77 for (p
= s
+ strlen(s
) - 1; p
!= s
; p
--)
78 if (*p
== c
) return p
;
82 ///////////////////////////////////////////////////////////////////////////////
84 // Compute the output file name from the input file name
86 ///////////////////////////////////////////////////////////////////////////////
87 void PropOptions::compute_output_file_name ()
88 { // Locate the . in the file name and
89 // Cut out the directory prefix.
90 const char * dot
= my_strrchr(input_file_name
,'.');
91 const char * slash
= my_strrchr(input_file_name
,PATH_SEPARATOR
);
92 if (dot
== 0 || ! (dot
[1] == 'p' || dot
[1] == 'P')) {
93 std::cerr
<< '"' << input_file_name
94 << "\" is not a valid source file name. "
95 "It must be of the form \"*.p*\".\n";
98 if (slash
== 0) slash
= input_file_name
-1;
99 memcpy(file_prefix
, slash
+1, dot
- slash
);
100 file_prefix
[dot
- slash
] = '\0';
101 if (output_file_name
[0] == '\0') {
102 strcpy(output_file_name
,file_prefix
);
103 strcat(output_file_name
, dot
+2);
105 encode_string(mangled_file_prefix
,file_prefix
);
106 encode_string(mangled_file_name
,output_file_name
);
109 ///////////////////////////////////////////////////////////////////////////////
111 // Function to emit the proper headers
113 ///////////////////////////////////////////////////////////////////////////////
114 static void emit_headers(Compiler
& C
)
118 "%^// This file is generated automatically using Prop (version %s.%s),"
119 "%^// last updated on %s."
120 "%^// The original source file is \"%s\"."
122 VERSION
, PATCH_LEVEL
, LAST_UPDATED
, options
.input_file_name
125 C
.emit_header_text();
127 /////////////////////////////////////////////////////////////////////////
129 /////////////////////////////////////////////////////////////////////////
131 if (Used::rewriting
) { C
.pr ("#define PROP_REWRITING_USED\n"); inc
= true; }
132 if (Used::infer
) { C
.pr ("#define PROP_INFERENCE_USED\n"); inc
= true; }
133 if (Used::gc
) { C
.pr ("#define PROP_GARBAGE_COLLECTION_USED\n"); inc
= true; }
134 if (Used::refcount
) { C
.pr ("#define PROP_REFCOUNT_USED\n"); inc
= true; }
135 if (Used::printer
) { C
.pr ("#define PROP_PRINTER_USED\n"); inc
= true; }
136 if (Used::persistence
) { C
.pr ("#define PROP_PERSISTENCE_USED\n"); inc
= true; }
137 if (Used::objc
) { C
.pr ("#define PROP_OBJC_USED\n"); inc
= true; }
138 if (Used::regexp
) { C
.pr ("#define PROP_REGEXP_MATCHING_USED\n"); inc
= true; }
139 if (Used::string_match
) { C
.pr ("#define PROP_STRCMP_USED\n"); inc
= true; }
140 if (Used::equality
) { C
.pr ("#define PROP_EQUALITY_USED\n"); inc
= true; }
141 if (Used::unification
) { C
.pr ("#define PROP_UNIFICATION_USED\n"); inc
= true; }
142 if (Used::vector
) { C
.pr ("#define PROP_VECTOR_USED\n"); inc
= true; }
143 if (Used::parser
) { C
.pr ("#define PROP_PARSER_USED\n"); inc
= true; }
144 if (Used::quark
) { C
.pr ("#define PROP_QUARK_USED\n"); inc
= true; }
145 if (Used::bigint
) { C
.pr ("#define PROP_BIGINT_USED\n"); inc
= true; }
146 if (Used::graph_type
) { C
.pr ("#define PROP_GRAPHTYPE_USED\n"); inc
= true; }
147 if (options
.trace
) { C
.pr ("#define PROP_TRACE_ON\n"); inc
= true; }
148 for (int i
= 2; i
< MAX_TUPLE_ARITY
; i
++)
149 { if (Used::tuple
[i
])
150 { C
.pr("#define PROP_TUPLE%i_USED\n", i
);
154 if (inc
) C
.pr ("#include <propdefs.h>\n");
157 ///////////////////////////////////////////////////////////////////////////////
161 ///////////////////////////////////////////////////////////////////////////////
162 int process_input(PropOptions
& options
)
164 ////////////////////////////////////////////////////////////////////////////
166 ////////////////////////////////////////////////////////////////////////////
167 { input_stream
= new std::ifstream(options
.input_file_name
);
168 if (! *input_stream
) { perror(options
.input_file_name
); return 1; }
171 ////////////////////////////////////////////////////////////////////////////
173 ////////////////////////////////////////////////////////////////////////////
174 Compiler
C(options
.tagged_pointer
? OPTtaggedpointer
: OPTnone
,
175 options
.max_embedded_tags
);
177 ////////////////////////////////////////////////////////////////////////////
179 ////////////////////////////////////////////////////////////////////////////
181 { extern void front_end(const char *, Compiler
&);
182 front_end(options
.input_file_name
,C
);
185 ////////////////////////////////////////////////////////////////////////////
187 ////////////////////////////////////////////////////////////////////////////
188 if (errors
> 0) options
.emit_code
= false;
190 ////////////////////////////////////////////////////////////////////////////
192 ////////////////////////////////////////////////////////////////////////////
193 Bool clean_up_file
= false;
194 if (! options
.gen_dependences
)
195 { if (options
.to_stdout
) {
196 output_stream
= &std::cout
;
198 output_stream
= options
.emit_code
?
199 (new std::ofstream(options
.output_file_name
)) : (new std::ofstream
);
200 if (! (*output_stream
)) {
201 perror(options
.output_file_name
); return 1;
203 clean_up_file
= true;
205 C
.set_stream(*output_stream
);
207 /////////////////////////////////////////////////////////////////////////
209 /////////////////////////////////////////////////////////////////////////
212 /////////////////////////////////////////////////////////////////////////
214 /////////////////////////////////////////////////////////////////////////
217 C
.print_report(*output_stream
);
220 /////////////////////////////////////////////////////////////////////////
222 /////////////////////////////////////////////////////////////////////////
223 if (clean_up_file
) delete output_stream
;
224 if (errors
> 0 && options
.emit_code
&& options
.output_file_name
[0])
225 remove(options
.output_file_name
);
228 ////////////////////////////////////////////////////////////////////////////
230 ////////////////////////////////////////////////////////////////////////////
231 if (errors
> 0) return 1;
232 if (options
.gen_dependences
) IncludeDependency::print_dependences();
233 else std::cerr
<< options
.output_file_name
<< '\n';
237 ///////////////////////////////////////////////////////////////////////////////
239 // Print messages on the console
241 ///////////////////////////////////////////////////////////////////////////////
242 std::ostream
& pr_msg(const char * fmt
, va_list arg
)
243 { if (error_log
== 0) error_log
= new Compiler(0,0);
244 return error_log
->outv(fmt
,arg
).flush();
247 ///////////////////////////////////////////////////////////////////////////////
251 ///////////////////////////////////////////////////////////////////////////////
252 std::ostream
& msg (const char * fmt
, ...)
255 std::ostream
& f
= pr_msg(fmt
,arg
);
260 ///////////////////////////////////////////////////////////////////////////////
262 // Print debugging messages
264 ///////////////////////////////////////////////////////////////////////////////
265 std::ostream
& debug_msg (const char * fmt
, ...)
268 if (options
.debug
) pr_msg(fmt
,arg
);
273 ///////////////////////////////////////////////////////////////////////////////
275 // Print error message
277 ///////////////////////////////////////////////////////////////////////////////
278 std::ostream
& error (const char * fmt
, ...)
281 std::ostream
& f
= pr_msg(fmt
,arg
);
287 ///////////////////////////////////////////////////////////////////////////////
291 ///////////////////////////////////////////////////////////////////////////////
292 void bug (const char * fmt
, ...)
298 std::cerr
<< "\nPlease send bug report to " << EMAIL
<< '\n';
302 //////////////////////////////////////////////////////////////////////////////
304 // Routine to open a file for reading, using the search path as
305 // starting point. Returns NIL if none can be found.
307 //////////////////////////////////////////////////////////////////////////////
308 std::istream
* PropOptions::open_input_file(const char file_name
[])
310 register const char * p
;
313 for (p
= search_paths
; *p
!= '\0' && *p
!= FILE_SEPARATOR
; p
++) {
314 for (q
= current_file_path
; *p
!= '\0' && *p
!= FILE_SEPARATOR
; )
316 *q
++ = PATH_SEPARATOR
; *q
= '\0';
317 strcat(current_file_path
,file_name
);
318 debug_msg("[Opening file %s]\n",current_file_path
);
319 std::ifstream
* f
= new std::ifstream(current_file_path
);
326 //////////////////////////////////////////////////////////////////////////////
328 // Routine to open a file for write and returns the handle
330 //////////////////////////////////////////////////////////////////////////////
331 std::ostream
* open_output_file(const char file_name
[])
333 std::ofstream
* F
= new std::ofstream(file_name
);
334 if (! *F
) { perror(file_name
); exit(1); }
338 //////////////////////////////////////////////////////////////////////////////
340 // Routine to open a log file and returns the handle.
342 //////////////////////////////////////////////////////////////////////////////
343 std::ostream
& open_logfile()
344 { if (log_stream
) return *log_stream
;
345 if (! options
.generate_report
)
346 { log_stream
= new std::ofstream
;
349 { char log_file_name
[256];
350 strcpy(log_file_name
,options
.file_prefix
);
351 strcat(log_file_name
,"report");
352 log_stream
= open_output_file(log_file_name
);