Changes in src/main.cc [e6955b1:35f9114]
- File:
- 
      - 1 edited
 
 - 
          
  src/main.cc (modified) (12 diffs)
 
Legend:
- Unmodified
- Added
- Removed
- 
      src/main.ccre6955b1 r35f9114 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 20 12:52:22201613 // Update Count : 40312 // Last Modified On : Sat Aug 6 16:17:41 2016 13 // Update Count : 210 14 14 // 15 15 16 16 #include <iostream> 17 17 #include <fstream> 18 #include <signal.h> // signal 19 #include <getopt.h> // getopt 20 #include <execinfo.h> // backtrace, backtrace_symbols_fd 21 #include <cxxabi.h> // __cxa_demangle 22 23 using namespace std; 24 25 #include "Parser/lex.h" 26 #include "Parser/parser.h" 27 #include "Parser/TypedefTable.h" 18 #include <cstdlib> 19 #include <cstdio> 20 #include <getopt.h> 21 #include "Parser/Parser.h" 22 #include "Parser/ParseNode.h" 23 #include "Parser/LinkageSpec.h" 24 #include "SynTree/Declaration.h" 25 #include "SynTree/Visitor.h" 28 26 #include "GenPoly/Lvalue.h" 29 27 #include "GenPoly/Specialize.h" … … 34 32 #include "CodeGen/FixNames.h" 35 33 #include "ControlStruct/Mutate.h" 34 #include "Tuples/Mutate.h" 35 #include "Tuples/FunctionChecker.h" 36 #include "SymTab/Mangler.h" 37 #include "SymTab/Indexer.h" 36 38 #include "SymTab/Validate.h" 37 39 #include "ResolvExpr/AlternativePrinter.h" 38 40 #include "ResolvExpr/Resolver.h" 39 41 #include "MakeLibCfa.h" 42 #include "InitTweak/Mutate.h" 40 43 #include "InitTweak/GenInit.h" 41 44 #include "InitTweak/FixInit.h" 45 //#include "Explain/GenProlog.h" 46 //#include "Try/Visit.h" 47 48 #include "Common/SemanticError.h" 42 49 #include "Common/UnimplementedError.h" 50 43 51 #include "../config.h" 44 52 45 53 using namespace std; 46 54 47 #define OPTPRINT(x) if ( errorp ) cerr << x << endl; 48 49 50 LinkageSpec::Spec linkage = LinkageSpec::Cforall; 51 TypedefTable typedefTable; 52 DeclarationNode * parseTree = nullptr; // program parse tree 53 54 extern int yydebug; // set for -g flag (Grammar) 55 #define OPTPRINT(x) \ 56 if ( errorp ) std::cerr << x << std::endl; 57 58 static void parse( FILE * input, LinkageSpec::Type t, bool shouldExit = false ); 59 static void dump( std::list< Declaration * > & translationUnit, std::ostream & out = std::cout ); 60 55 61 bool 56 62 astp = false, … … 60 66 exprp = false, 61 67 expraltp = false, 68 grammarp = false, 62 69 libcfap = false, 63 70 nopreludep = false, … … 71 78 codegenp = false; 72 79 73 static void parse_cmdline( int argc, char *argv[], const char *& filename ); 74 static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit = false ); 75 static void dump( list< Declaration * > & translationUnit, ostream & out = cout ); 76 77 void sigSegvBusHandler( int sig_num ) { 78 enum { Frames = 50 }; 79 void * array[Frames]; 80 int size = backtrace( array, Frames ); 81 82 cerr << "*CFA runtime error* program cfa-cpp terminated with " 83 << (sig_num == SIGSEGV ? "segment fault" : "bus error") 84 << " backtrace:" << endl; 85 86 char ** messages = backtrace_symbols( array, size ); 87 88 // skip first stack frame (points here) 89 for ( int i = 2; i < size - 2 && messages != nullptr; i += 1 ) { 90 char * mangled_name = nullptr, * offset_begin = nullptr, * offset_end = nullptr; 91 for ( char *p = messages[i]; *p; ++p ) { // find parantheses and +offset 92 if (*p == '(') { 93 mangled_name = p; 94 } else if (*p == '+') { 95 offset_begin = p; 96 } else if (*p == ')') { 97 offset_end = p; 98 break; 99 } // if 100 } // for 101 102 // if line contains symbol, attempt to demangle 103 if ( mangled_name && offset_begin && offset_end && mangled_name < offset_begin ) { 104 *mangled_name++ = '\0'; 105 *offset_begin++ = '\0'; 106 *offset_end++ = '\0'; 107 108 int status; 109 char * real_name = __cxxabiv1::__cxa_demangle( mangled_name, 0, 0, &status ); 110 if ( status == 0 ) { // demangling successful ? 111 cerr << "(" << i - 2 << ") " << messages[i] << " : " 112 << real_name << "+" << offset_begin << offset_end << endl; 113 114 } else { // otherwise, output mangled name 115 cerr << "(" << i - 2 << ") " << messages[i] << " : " 116 << mangled_name << "+" << offset_begin << offset_end << endl; 117 } // if 118 free( real_name ); 119 } else { // otherwise, print the whole line 120 cerr << "(" << i - 2 << ") " << messages[i] << endl; 121 } // if 122 } // for 123 free( messages ); 124 exit( EXIT_FAILURE ); 125 } // sigSegvBusHandler 126 127 int main( int argc, char * argv[] ) { 128 FILE * input; // use FILE rather than istream because yyin is FILE 129 ostream *output = & cout; 130 const char *filename = nullptr; 131 list< Declaration * > translationUnit; 132 133 signal( SIGSEGV, sigSegvBusHandler ); 134 signal( SIGBUS, sigSegvBusHandler ); 135 136 parse_cmdline( argc, argv, filename ); // process command-line arguments 80 enum { Ast, Bbox, Bresolver, CtorInitFix, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, }; 81 82 static struct option long_opts[] = { 83 { "ast", no_argument, 0, Ast }, 84 { "before-box", no_argument, 0, Bbox }, 85 { "before-resolver", no_argument, 0, Bresolver }, 86 { "ctorinitfix", no_argument, 0, CtorInitFix }, 87 { "expr", no_argument, 0, Expr }, 88 { "expralt", no_argument, 0, ExprAlt }, 89 { "grammar", no_argument, 0, Grammar }, 90 { "libcfa", no_argument, 0, LibCFA }, 91 { "no-preamble", no_argument, 0, Nopreamble }, 92 { "parse", no_argument, 0, Parse }, 93 { "no-prototypes", no_argument, 0, Prototypes }, 94 { "resolver", no_argument, 0, Resolver }, 95 { "symbol", no_argument, 0, Symbol }, 96 { "tree", no_argument, 0, Tree }, 97 { "validate", no_argument, 0, Validate }, 98 { 0, 0, 0, 0 } 99 }; 100 101 int main( int argc, char *argv[] ) { 102 FILE *input; 103 std::ostream *output = &std::cout; 104 int long_index; 105 std::list< Declaration * > translationUnit; 106 const char *filename = NULL; 107 108 opterr = 0; // prevent getopt from printing error messages 109 110 int c; 111 while ( (c = getopt_long( argc, argv, "abBcefglnpqrstvyzD:F:", long_opts, &long_index )) != -1 ) { 112 switch ( c ) { 113 case Ast: 114 case 'a': // dump AST 115 astp = true; 116 break; 117 case Bresolver: 118 case 'b': // print before resolver steps 119 bresolvep = true; 120 break; 121 case 'B': // print before resolver steps 122 bboxp = true; 123 break; 124 case CtorInitFix: 125 case 'c': 126 ctorinitp = true; 127 break; 128 case Expr: 129 case 'e': // dump AST after expression analysis 130 exprp = true; 131 break; 132 case ExprAlt: 133 case 'f': // print alternatives for expressions 134 expraltp = true; 135 break; 136 case Grammar: 137 case 'g': // bison debugging info (grammar rules) 138 grammarp = true; 139 break; 140 case LibCFA: 141 case 'l': // generate libcfa.c 142 libcfap = true; 143 break; 144 case Nopreamble: 145 case 'n': // do not read preamble 146 nopreludep = true; 147 break; 148 case Prototypes: 149 case 'p': // generate prototypes for preamble functions 150 noprotop = true; 151 break; 152 case Parse: 153 case 'q': // dump parse tree 154 parsep = true; 155 break; 156 case Resolver: 157 case 'r': // print resolver steps 158 resolvep = true; 159 break; 160 case Symbol: 161 case 's': // print symbol table events 162 symtabp = true; 163 break; 164 case Tree: 165 case 't': // build in tree 166 treep = true; 167 break; 168 case 'v': // dump AST after decl validation pass 169 validp = true; 170 break; 171 case 'y': 172 errorp = true; 173 break; 174 case 'z': 175 codegenp = true; 176 break; 177 case 'D': // ignore -Dxxx 178 break; 179 case 'F': // source file-name without suffix 180 filename = optarg; 181 break; 182 case '?': 183 cout << "Unknown option: '" << (char)optopt << "'" << endl; 184 exit( EXIT_FAILURE ); 185 default: 186 abort(); 187 } // switch 188 } // while 137 189 138 190 try { 139 191 // choose to read the program from a file or stdin 140 if ( optind < argc ) { // any commands after the flags ? => input file name192 if ( optind < argc ) { 141 193 input = fopen( argv[ optind ], "r" ); 142 assertf( input, "cannot open %s\n", argv[ optind ] ); 194 if ( ! input ) { 195 std::cout << "Error: cannot open " << argv[ optind ] << std::endl; 196 exit( EXIT_FAILURE ); 197 } // if 143 198 // if running cfa-cpp directly, might forget to pass -F option (and really shouldn't have to) 144 if ( filename == nullptr) filename = argv[ optind ];199 if ( filename == NULL ) filename = argv[ optind ]; 145 200 // prelude filename comes in differently 146 201 if ( libcfap ) filename = "prelude.cf"; 147 202 optind += 1; 148 } else { // no input file name203 } else { 149 204 input = stdin; 150 205 // if running cfa-cpp directly, might forget to pass -F option. Since this takes from stdin, pass 151 206 // a fake name along 152 if ( filename == nullptr) filename = "stdin";153 } // if 154 155 if ( optind < argc ) { // any commands after the flags and input file ? => output file name207 if ( filename == NULL ) filename = "stdin"; 208 } // if 209 210 if ( optind < argc ) { 156 211 output = new ofstream( argv[ optind ] ); 157 212 } // if 213 214 Parser::get_parser().set_debug( grammarp ); 158 215 159 216 // read in the builtins, extras, and the prelude … … 161 218 // -l is for initial build ONLY and builtins.cf is not in the lib directory so access it here. 162 219 FILE * builtins = fopen( libcfap | treep ? "builtins.cf" : CFA_LIBDIR "/builtins.cf", "r" ); 163 assertf( builtins, "cannot open builtins.cf\n" ); 220 if ( builtins == NULL ) { 221 std::cerr << "Error: cannot open builtins.cf" << std::endl; 222 exit( EXIT_FAILURE ); 223 } // if 164 224 parse( builtins, LinkageSpec::Compiler ); 165 225 166 226 // read the extra prelude in, if not generating the cfa library 167 227 FILE * extras = fopen( libcfap | treep ? "extras.cf" : CFA_LIBDIR "/extras.cf", "r" ); 168 assertf( extras, "cannot open extras.cf\n" ); 228 if ( extras == NULL ) { 229 std::cerr << "Error: cannot open extras.cf" << std::endl; 230 exit( EXIT_FAILURE ); 231 } // if 169 232 parse( extras, LinkageSpec::C ); 170 233 … … 172 235 // read the prelude in, if not generating the cfa library 173 236 FILE * prelude = fopen( treep ? "prelude.cf" : CFA_LIBDIR "/prelude.cf", "r" ); 174 assertf( prelude, "cannot open prelude.cf\n" ); 237 if ( prelude == NULL ) { 238 std::cerr << "Error: cannot open prelude.cf" << std::endl; 239 exit( EXIT_FAILURE ); 240 } // if 241 175 242 parse( prelude, LinkageSpec::Intrinsic ); 176 243 } // if 177 244 } // if 178 245 179 parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, yydebug);246 parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp ); 180 247 181 248 if ( parsep ) { 182 parseTree->printList( cout ); 183 delete parseTree; 184 return 0; 185 } // if 186 187 buildList( parseTree, translationUnit ); 188 delete parseTree; 189 parseTree = nullptr; 190 249 Parser::get_parser().get_parseTree()->printList( std::cout ); 250 Parser::get_parser().freeTree(); 251 return 0; 252 } // if 253 254 buildList( Parser::get_parser().get_parseTree(), translationUnit ); 255 256 Parser::get_parser().freeTree(); 191 257 if ( astp ) { 192 258 dump( translationUnit ); … … 202 268 203 269 if ( expraltp ) { 204 ResolvExpr::AlternativePrinter printer( cout );270 ResolvExpr::AlternativePrinter printer( std::cout ); 205 271 acceptAll( translationUnit, printer ); 206 272 return 0; … … 234 300 dump( translationUnit ); 235 301 return 0; 236 } // if302 } 237 303 238 304 // fix ObjectDecl - replaces ConstructorInit nodes … … 242 308 dump ( translationUnit ); 243 309 return 0; 244 } // if310 } 245 311 246 312 OPTPRINT("instantiateGenerics") … … 256 322 dump( translationUnit ); 257 323 return 0; 258 } // if324 } 259 325 OPTPRINT( "box" ) 260 326 GenPoly::box( translationUnit ); … … 268 334 CodeGen::generate( translationUnit, *output, ! noprotop ); 269 335 270 if ( output != & cout ) {336 if ( output != &std::cout ) { 271 337 delete output; 272 338 } // if 273 339 } catch ( SemanticError &e ) { 274 340 if ( errorp ) { 275 cerr << "---AST at error:---" <<endl;276 dump( translationUnit, cerr );277 cerr << endl << "---End of AST, begin error message:---\n" <<endl;278 } // if279 e.print( cerr );280 if ( output != & cout ) {341 std::cerr << "---AST at error:---" << std::endl; 342 dump( translationUnit, std::cerr ); 343 std::cerr << std::endl << "---End of AST, begin error message:---\n" << std::endl; 344 } 345 e.print( std::cerr ); 346 if ( output != &std::cout ) { 281 347 delete output; 282 348 } // if 283 349 return 1; 284 350 } catch ( UnimplementedError &e ) { 285 cout << "Sorry, " << e.get_what() << " is not currently implemented" <<endl;286 if ( output != & cout ) {351 std::cout << "Sorry, " << e.get_what() << " is not currently implemented" << std::endl; 352 if ( output != &std::cout ) { 287 353 delete output; 288 354 } // if 289 355 return 1; 290 356 } catch ( CompilerError &e ) { 291 cerr << "Compiler Error: " << e.get_what() <<endl;292 cerr << "(please report bugs to " <<endl;293 if ( output != & cout ) {357 std::cerr << "Compiler Error: " << e.get_what() << std::endl; 358 std::cerr << "(please report bugs to " << std::endl; 359 if ( output != &std::cout ) { 294 360 delete output; 295 361 } // if … … 301 367 } // main 302 368 303 void parse_cmdline( int argc, char * argv[], const char *& filename ) { 304 enum { Ast, Bbox, Bresolver, CtorInitFix, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, }; 305 306 static struct option long_opts[] = { 307 { "ast", no_argument, 0, Ast }, 308 { "before-box", no_argument, 0, Bbox }, 309 { "before-resolver", no_argument, 0, Bresolver }, 310 { "ctorinitfix", no_argument, 0, CtorInitFix }, 311 { "expr", no_argument, 0, Expr }, 312 { "expralt", no_argument, 0, ExprAlt }, 313 { "grammar", no_argument, 0, Grammar }, 314 { "libcfa", no_argument, 0, LibCFA }, 315 { "no-preamble", no_argument, 0, Nopreamble }, 316 { "parse", no_argument, 0, Parse }, 317 { "no-prototypes", no_argument, 0, Prototypes }, 318 { "resolver", no_argument, 0, Resolver }, 319 { "symbol", no_argument, 0, Symbol }, 320 { "tree", no_argument, 0, Tree }, 321 { "validate", no_argument, 0, Validate }, 322 { 0, 0, 0, 0 } 323 }; // long_opts 324 int long_index; 325 326 opterr = 0; // (global) prevent getopt from printing error messages 327 328 int c; 329 while ( (c = getopt_long( argc, argv, "abBcefglnpqrstvyzD:F:", long_opts, &long_index )) != -1 ) { 330 switch ( c ) { 331 case Ast: 332 case 'a': // dump AST 333 astp = true; 334 break; 335 case Bresolver: 336 case 'b': // print before resolver steps 337 bresolvep = true; 338 break; 339 case 'B': // print before resolver steps 340 bboxp = true; 341 break; 342 case CtorInitFix: 343 case 'c': 344 ctorinitp = true; 345 break; 346 case Expr: 347 case 'e': // dump AST after expression analysis 348 exprp = true; 349 break; 350 case ExprAlt: 351 case 'f': // print alternatives for expressions 352 expraltp = true; 353 break; 354 case Grammar: 355 case 'g': // bison debugging info (grammar rules) 356 yydebug = true; 357 break; 358 case LibCFA: 359 case 'l': // generate libcfa.c 360 libcfap = true; 361 break; 362 case Nopreamble: 363 case 'n': // do not read preamble 364 nopreludep = true; 365 break; 366 case Prototypes: 367 case 'p': // generate prototypes for preamble functions 368 noprotop = true; 369 break; 370 case Parse: 371 case 'q': // dump parse tree 372 parsep = true; 373 break; 374 case Resolver: 375 case 'r': // print resolver steps 376 resolvep = true; 377 break; 378 case Symbol: 379 case 's': // print symbol table events 380 symtabp = true; 381 break; 382 case Tree: 383 case 't': // build in tree 384 treep = true; 385 break; 386 case 'v': // dump AST after decl validation pass 387 validp = true; 388 break; 389 case 'y': 390 errorp = true; 391 break; 392 case 'z': 393 codegenp = true; 394 break; 395 case 'D': // ignore -Dxxx 396 break; 397 case 'F': // source file-name without suffix 398 filename = optarg; 399 break; 400 case '?': 401 assertf( false, "Unknown option: '%c'\n", (char)optopt ); 402 default: 403 abort(); 404 } // switch 405 } // while 406 } // parse_cmdline 407 408 static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit ) { 409 extern int yyparse( void ); 410 extern FILE * yyin; 411 extern int yylineno; 412 413 ::linkage = linkage; // set globals 414 yyin = input; 415 yylineno = 1; 416 typedefTable.enterScope(); 417 int parseStatus = yyparse(); 369 static void parse( FILE * input, LinkageSpec::Type linkage, bool shouldExit ) { 370 Parser::get_parser().set_linkage( linkage ); 371 Parser::get_parser().parse( input ); 418 372 419 373 fclose( input ); 420 if ( shouldExit || parseStatus!= 0 ) {421 exit( parseStatus);374 if ( shouldExit || Parser::get_parser().get_parseStatus() != 0 ) { 375 exit( Parser::get_parser().get_parseStatus() ); 422 376 } // if 423 } // parse377 } 424 378 425 379 static bool notPrelude( Declaration * decl ) { 426 380 return ! LinkageSpec::isBuiltin( decl->get_linkage() ); 427 } // notPrelude 428 429 static void dump( list< Declaration * > & translationUnit, ostream & out ) { 430 list< Declaration * > decls; 431 381 } 382 383 static void dump( std::list< Declaration * > & translationUnit, std::ostream & out ) { 384 std::list< Declaration * > decls; 432 385 if ( noprotop ) { 433 filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), notPrelude ); 386 filter( translationUnit.begin(), translationUnit.end(), 387 std::back_inserter( decls ), notPrelude ); 434 388 } else { 435 389 decls = translationUnit; 436 } // if390 } 437 391 438 392 printAll( decls, out ); 439 393 deleteAll( translationUnit ); 440 } // dump 394 } 395 441 396 442 397 // Local Variables: // 
  Note:
 See   TracChangeset
 for help on using the changeset viewer.
  