137 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "mcg.h"
 | |
| #include <errno.h>
 | |
| #include <unistd.h>
 | |
| 
 | |
| static const char* tracechars = NULL;
 | |
| 
 | |
| FILE* outputfile = NULL;
 | |
| FILE* dominance_dot_file = NULL;
 | |
| FILE* cfg_dot_file = NULL;
 | |
| 
 | |
| bool tracing(char k)
 | |
| {
 | |
|     if (k == '!')
 | |
|         return true;
 | |
|     if (!tracechars)
 | |
|         return false;
 | |
| 
 | |
|     return index(tracechars, k);
 | |
| }
 | |
| 
 | |
| void tracef(char k, const char* fmt, ...)
 | |
| {
 | |
|     va_list ap;
 | |
| 
 | |
|     if (tracing(k))
 | |
|     {
 | |
|         va_start(ap, fmt);
 | |
|         vfprintf(stderr, fmt, ap);
 | |
|         va_end(ap);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static bool find_procedures_cb(struct symbol* symbol, void* user)
 | |
| {
 | |
|     if (symbol->proc)
 | |
|         procedure_compile(symbol->proc);
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| int main(int argc, char* const argv[])
 | |
| {
 | |
|     const char* inputfilename = NULL;
 | |
|     const char* outputfilename = NULL;
 | |
|     FILE* output;
 | |
| 
 | |
|     program_name = argv[0];
 | |
| 
 | |
|     opterr = 1;
 | |
|     for (;;)
 | |
|     {
 | |
|         int c = getopt(argc, argv, "-d:D:C:o:");
 | |
|         if (c == -1)
 | |
|             break;
 | |
| 
 | |
|         switch (c)
 | |
|         {
 | |
|             case 'C':
 | |
|                 cfg_dot_file = fopen(optarg, "w");
 | |
|                 if (!cfg_dot_file)
 | |
|                     fatal("couldn't open output file '%s': %s",
 | |
|                         optarg, strerror(errno));
 | |
|                 fprintf(cfg_dot_file, "digraph {\n");
 | |
|                 break;
 | |
| 
 | |
|             case 'D':
 | |
|                 dominance_dot_file = fopen(optarg, "w");
 | |
|                 if (!dominance_dot_file)
 | |
|                     fatal("couldn't open output file '%s': %s",
 | |
|                         optarg, strerror(errno));
 | |
|                 fprintf(dominance_dot_file, "digraph {\n");
 | |
|                 break;
 | |
| 
 | |
|             case 'd':
 | |
|                 tracechars = optarg;
 | |
|                 break;
 | |
| 
 | |
|             case 'o':
 | |
|                 if (outputfilename)
 | |
|                     fatal("already specified an output file");
 | |
|                 outputfilename = optarg;
 | |
|                 break;
 | |
| 
 | |
|             case 1:
 | |
|                 if (inputfilename)
 | |
|                     fatal("unexpected argument '%s'", optarg);
 | |
|                 inputfilename = optarg;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     symbol_init();
 | |
| 
 | |
| 	if (!EM_open((char*) inputfilename))
 | |
| 		fatal("couldn't open input '%s': %s",
 | |
|             inputfilename ? inputfilename : "<stdin>", EM_error);
 | |
| 	
 | |
|     if (outputfilename)
 | |
|     {
 | |
|         outputfile = fopen(outputfilename, "w");
 | |
|         if (!outputfile)
 | |
|             fatal("couldn't open output '%s': %s",
 | |
|                 outputfilename, strerror(errno));
 | |
|     }
 | |
|     else
 | |
|         outputfile = stdout;
 | |
| 
 | |
|     fprintf(outputfile, ".sect .text\n.sect .rom\n.sect .data\n.sect .bss\n");
 | |
| 
 | |
|     /* Reads in the EM, outputs the data sections, parses any code and
 | |
|      * generates IR trees. */
 | |
| 
 | |
|     parse_em();
 | |
| 
 | |
|     /* For every procedure, go ahead and do the compilation proper. We do this
 | |
|      * now so that we know that all the data has been read correctly and our
 | |
|      * symbol table is complete (we may need to refer to it). */
 | |
| 
 | |
|     symbol_walk(find_procedures_cb, NULL);
 | |
| 
 | |
|     if (outputfilename)
 | |
|         fclose(outputfile);
 | |
| 	EM_close();
 | |
| 
 | |
|     if (cfg_dot_file)
 | |
|     {
 | |
|         fprintf(cfg_dot_file, "}\n");
 | |
|         fclose(cfg_dot_file);
 | |
|     }
 | |
|     if (dominance_dot_file)
 | |
|     {
 | |
|         fprintf(dominance_dot_file, "}\n");
 | |
|         fclose(dominance_dot_file);
 | |
|     }
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /* vim: set sw=4 ts=4 expandtab : */
 |