#include #include #include #include #include #include "Parser/Parser.h" #include "Parser/ParseNode.h" #include "Parser/LinkageSpec.h" #include "SynTree/Declaration.h" #include "SynTree/Visitor.h" #include "GenPoly/Lvalue.h" #include "GenPoly/Specialize.h" #include "GenPoly/Box.h" #include "GenPoly/CopyParams.h" #include "CodeGen/Generate.h" #include "CodeGen/FixNames.h" #include "ControlStruct/Mutate.h" #include "Tuples/Mutate.h" #include "Tuples/FunctionChecker.h" #include "SymTab/Mangler.h" #include "SymTab/Indexer.h" #include "SymTab/Validate.h" #include "ResolvExpr/AlternativePrinter.h" #include "ResolvExpr/Resolver.h" #include "MakeLibCfa.h" #include "InitTweak/Mutate.h" #include "InitTweak/RemoveInit.h" //#include "Explain/GenProlog.h" //#include "Try/Visit.h" #include "SemanticError.h" #include "UnimplementedError.h" #include "utility.h" #include "../config.h" using namespace std; extern "C"{ #include } // extern FILE *open_prelude(); FILE *open_builtins(); bool beVerbose = false; bool resolveVerbose = false; int main( int argc, char *argv[] ) { bool debugp = false, treep = false, astp = false, manglep = false, symtabp = false, validp = false; bool preludep = true, protop = false, libp = false; bool exprp = false, codegenp = false; int c; FILE *input, *prelude, *builtins; std::ostream *output = &std::cout; opterr = 0; while ( (c = getopt( argc, argv, "dtsgmvxcenprlDz:" )) != -1 ) { switch (c) { case 'd': /* bison debugging info */ debugp = true; break; case 't': /* dump parse tree */ treep = true; break; case 's': /* dump AST */ astp = true; break; case 'g': /* print alternatives for expressions */ manglep = true; break; case 'm': /* print symbol table events */ symtabp = true; break; case 'r': /* print resolver steps */ resolveVerbose = true; break; case 'x': /* dump AST after decl validation pass */ validp = true; break; case 'e': /* dump AST after expression analysis */ exprp = true; break; case 'z': codegenp = true; break; case 'n': /* don't read preamble */ preludep = false; break; case 'p': /* generate prototypes for preamble functions */ protop = true; break; case 'l': /* generate libcfa.c */ libp = true; break; case 'v': /* verbose */ beVerbose = true; break; case 'D': /* ignore -Dxxx */ break; case '?': cout << "Unknown option: '" << (char)optopt << "'" << endl; exit(1); default: abort(); } // switch } // while try { if ( optind < argc ) { input = fopen( argv[ optind ], "r" ); if ( ! input ) { std::cout << "Error: can't open " << argv[optind] << std::endl; exit( 1 ); } // if optind++; } else { input = stdin; } // if if ( optind < argc ) { output = new ofstream( argv[ optind ] ); } // if Parser::get_parser().set_debug( debugp ); if ( preludep ) { // include gcc builtins builtins = open_builtins(); if ( !builtins ) { std::cout << "Error: can't open builtins" << std::endl; exit( 1 ); } // if Parser::get_parser().set_linkage( LinkageSpec::Compiler ); Parser::get_parser().parse( builtins ); if ( Parser::get_parser().get_parseStatus() != 0 ) { return Parser::get_parser().get_parseStatus(); } // if fclose( builtins ); // include cfa prelude if ( libp ) { prelude = input; } else { prelude = open_prelude(); } // if if ( !prelude ) { std::cout << "Error: can't open prelude" << std::endl; exit( 1 ); } // if Parser::get_parser().set_linkage( LinkageSpec::Intrinsic ); Parser::get_parser().parse( prelude ); if ( Parser::get_parser().get_parseStatus() != 0 ) { return Parser::get_parser().get_parseStatus(); } // if fclose( prelude ); } // if if ( libp ) { std::list< Declaration* > translationUnit; buildList( Parser::get_parser().get_parseTree(), translationUnit ); Parser::get_parser().freeTree(); SymTab::validate( translationUnit, false ); CodeGen::fixNames( translationUnit ); LibCfa::makeLibCfa( translationUnit ); ResolvExpr::resolve( translationUnit ); GenPoly::convertLvalue( translationUnit ); GenPoly::box( translationUnit ); CodeGen::generate( translationUnit, *output, true ); if ( output != &std::cout ) { delete output; } // if return 0; } // if Parser::get_parser().set_linkage( LinkageSpec::Cforall ); Parser::get_parser().parse( input ); if ( debugp || Parser::get_parser().get_parseStatus() != 0 ) { return Parser::get_parser().get_parseStatus(); } // if fclose( input ); if ( treep ) { Parser::get_parser().get_parseTree()->printList( std::cout ); Parser::get_parser().freeTree(); return 0; } // if std::list< Declaration* > translationUnit; buildList( Parser::get_parser().get_parseTree(), translationUnit ); Parser::get_parser().freeTree(); if ( astp ) { printAll( translationUnit, std::cout ); return 0; } // if if ( manglep ) { SymTab::validate( translationUnit, false ); ResolvExpr::AlternativePrinter printer( std::cout ); acceptAll( translationUnit, printer ); return 0; } // if if ( symtabp ) { SymTab::validate( translationUnit, true ); return 0; } // if if ( validp ) { SymTab::validate( translationUnit, false ); printAll( translationUnit, std::cout ); return 0; } // if if ( exprp ) { SymTab::validate( translationUnit, false ); ResolvExpr::resolve( translationUnit ); printAll( translationUnit, std::cout ); return 0; } // if if ( codegenp ) { // print the tree right before code generation... // InitTweak::mutate( translationUnit ); // InitTweak::tweak( translationUnit ); //printAll( translationUnit, std::cout ); // std::cerr << "finished tweaking" << std::endl; SymTab::validate( translationUnit, false ); ControlStruct::mutate( translationUnit ); CodeGen::fixNames( translationUnit ); ResolvExpr::resolve( translationUnit ); GenPoly::copyParams( translationUnit ); GenPoly::convertSpecializations( translationUnit ); GenPoly::convertLvalue( translationUnit ); GenPoly::box( translationUnit ); printAll( translationUnit, std::cout ); return 0; } // if // add the assignment statement after the // initialization of a type parameter InitTweak::tweak( translationUnit ); //std::cerr << "before validate" << std::endl; SymTab::validate( translationUnit, false ); //Try::visit( translationUnit ); //Tuples::mutate( translationUnit ); //InitTweak::mutate( translationUnit ); //std::cerr << "before mutate" << std::endl; ControlStruct::mutate( translationUnit ); //std::cerr << "before fixNames" << std::endl; CodeGen::fixNames( translationUnit ); //std::cerr << "before resolve" << std::endl; ResolvExpr::resolve( translationUnit ); //Tuples::checkFunctions( translationUnit ); // std::cerr << "Finished tuple checkfunctions" << std::endl; //printAll( translationUnit, std::cerr ); //std::cerr << "before copyParams" << std::endl; GenPoly::copyParams( translationUnit ); //std::cerr << "before convertSpecializations" << std::endl; GenPoly::convertSpecializations( translationUnit ); //std::cerr << "before convertLvalue" << std::endl; GenPoly::convertLvalue( translationUnit ); //std::cerr << "before box" << std::endl; GenPoly::box( translationUnit ); //Tuples::mutate( translationUnit ); CodeGen::generate( translationUnit, *output, protop ); if ( output != &std::cout ) { delete output; } // if } catch ( SemanticError &e ) { e.print( cout ); if ( output != &std::cout ) { delete output; } // if return 1; } catch ( UnimplementedError &e ) { std::cout << "Sorry, " << e.get_what() << " is not currently implemented" << std::endl; if ( output != &std::cout ) { delete output; } // if return 1; } catch ( CompilerError &e ) { std::cerr << "Compiler Error: " << e.get_what() << std::endl; std::cerr << "(please report bugs to " << std::endl; if ( output != &std::cout ) { delete output; } // if return 1; } // try return 0; } // main FILE *open_prelude() { FILE *ret; const string name("prelude.cf"), full_name = string(CFA_LIBDIR) + "/" + name; if ( beVerbose ) { cout << "Reading from " << full_name << endl; } // if if ( ! (ret = fopen(full_name.c_str(), "r" ) ) ) return fopen(name.c_str(), "r" ); // trying current directory else return ret; } // open_prelude FILE *open_builtins() { FILE *ret; const char *name = "builtins.cf"; const char *full_name = CFA_LIBDIR "/builtins.cf"; if ( beVerbose ) { cout << "Reading from " << full_name << endl; } // if if ( ! (ret = fopen(full_name, "r" ) ) ) return fopen(name, "r" ); // trying current directory else return ret; } // open_builtins // Local Variables: // // compile-command: "make" // // End: //