// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // main.cc -- // // Author : Richard C. Bilson // Created On : Fri May 15 23:12:02 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Thu Dec 17 12:59:06 2015 // Update Count : 179 // #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/InstantiateGeneric.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 "../config.h" using namespace std; #define OPTPRINT(x) \ if ( errorp ) std::cerr << x << std::endl; static void parse( FILE * input, LinkageSpec::Type t, bool shouldExit = false ); static void dump( std::list< Declaration * > & translationUnit ); bool astp = false, bresolvep = false, exprp = false, expraltp = false, grammarp = false, libcfap = false, nopreludep = false, noprotop = false, parsep = false, resolvep = false, // used in AlternativeFinder symtabp = false, validp = false, errorp = false, codegenp = false; enum { Ast, Bresolver, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Validate, }; static struct option long_opts[] = { { "ast", no_argument, 0, Ast }, { "before-resolver", no_argument, 0, Bresolver }, { "expr", no_argument, 0, Expr }, { "expralt", no_argument, 0, ExprAlt }, { "grammar", no_argument, 0, Grammar }, { "libcfa", no_argument, 0, LibCFA }, { "no-preamble", no_argument, 0, Nopreamble }, { "parse", no_argument, 0, Parse }, { "no-prototypes", no_argument, 0, Prototypes }, { "resolver", no_argument, 0, Resolver }, { "symbol", no_argument, 0, Symbol }, { "validate", no_argument, 0, Validate }, { 0, 0, 0, 0 } }; int main( int argc, char *argv[] ) { FILE *input; std::ostream *output = &std::cout; int long_index; std::list< Declaration* > translationUnit; opterr = 0; // prevent getopt from printing error messages int c; while ( (c = getopt_long( argc, argv, "abefglnpqrsvyzD:", long_opts, &long_index )) != -1 ) { switch ( c ) { case Ast: case 'a': // dump AST astp = true; break; case Bresolver: case 'b': // print before resolver steps bresolvep = true; break; case Expr: case 'e': // dump AST after expression analysis exprp = true; break; case ExprAlt: case 'f': // print alternatives for expressions expraltp = true; break; case Grammar: case 'g': // bison debugging info (grammar rules) grammarp = true; break; case LibCFA: case 'l': // generate libcfa.c libcfap = true; break; case Nopreamble: case 'n': // do not read preamble nopreludep = true; break; case Prototypes: case 'p': // generate prototypes for preamble functions noprotop = true; break; case Parse: case 'q': // dump parse tree parsep = true; break; case Resolver: case 'r': // print resolver steps resolvep = true; break; case Symbol: case 's': // print symbol table events symtabp = true; break; case 'v': // dump AST after decl validation pass validp = true; break; case 'y': errorp = true; break; case 'z': codegenp = true; break; case 'D': // ignore -Dxxx break; case '?': cout << "Unknown option: '" << (char)optopt << "'" << endl; exit(1); default: abort(); } // switch } // while try { // choose to read the program from a file or stdin if ( optind < argc ) { input = fopen( argv[ optind ], "r" ); if ( ! input ) { std::cout << "Error: can't open " << argv[optind] << std::endl; exit( 1 ); } // if optind += 1; } else { input = stdin; } // if if ( optind < argc ) { output = new ofstream( argv[ optind ] ); } // if Parser::get_parser().set_debug( grammarp ); // read in the builtins and the prelude if ( ! nopreludep ) { // include gcc builtins // -l is for initial build ONLY and builtins.cf is not in the lib directory so access it here. FILE * builtins = fopen( libcfap ? "./builtins.cf" : CFA_LIBDIR "/builtins.cf", "r" ); if ( builtins == NULL ) { std::cerr << "Error: can't open builtins" << std::endl; exit( 1 ); } // if parse( builtins, LinkageSpec::Compiler ); if ( ! libcfap ) { // read the prelude in, if not generating the cfa library FILE * prelude = fopen( CFA_LIBDIR "/prelude.cf", "r" ); if ( prelude == NULL ) { std::cerr << "Error: can't open prelude" << std::endl; exit( 1 ); } // if parse( prelude, LinkageSpec::Intrinsic ); } // if } // if parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp ); if ( parsep ) { Parser::get_parser().get_parseTree()->printList( std::cout ); Parser::get_parser().freeTree(); return 0; } // if buildList( Parser::get_parser().get_parseTree(), translationUnit ); Parser::get_parser().freeTree(); if ( astp ) { dump( translationUnit ); return 0; } // if // add the assignment statement after the initialization of a type parameter OPTPRINT( "validate" ) SymTab::validate( translationUnit, symtabp ); if ( symtabp ) { return 0; } // if if ( expraltp ) { ResolvExpr::AlternativePrinter printer( std::cout ); acceptAll( translationUnit, printer ); return 0; } // if if ( validp ) { dump( translationUnit ); return 0; } // if OPTPRINT( "mutate" ) ControlStruct::mutate( translationUnit ); OPTPRINT( "fixNames" ) CodeGen::fixNames( translationUnit ); OPTPRINT( "tweak" ) InitTweak::tweak( translationUnit ); if ( libcfap ) { // generate the bodies of cfa library functions LibCfa::makeLibCfa( translationUnit ); } // if if ( bresolvep ) { dump( translationUnit ); return 0; } // if OPTPRINT( "resolve" ) ResolvExpr::resolve( translationUnit ); if ( exprp ) { dump( translationUnit ); } OPTPRINT( "copyParams" ); GenPoly::copyParams( translationUnit ); OPTPRINT( "convertSpecializations" ) GenPoly::convertSpecializations( translationUnit ); OPTPRINT( "convertLvalue" ) GenPoly::convertLvalue( translationUnit ); OPTPRINT( "box" ) GenPoly::box( translationUnit ); OPTPRINT( "instantiateGeneric" ) GenPoly::instantiateGeneric( translationUnit ); // print tree right before code generation if ( codegenp ) { dump( translationUnit ); return 0; } // if CodeGen::generate( translationUnit, *output, ! noprotop ); if ( output != &std::cout ) { delete output; } // if } catch ( SemanticError &e ) { if ( errorp ) { dump( translationUnit ); } e.print( std::cerr ); 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 static void parse( FILE * input, LinkageSpec::Type linkage, bool shouldExit ) { Parser::get_parser().set_linkage( linkage ); Parser::get_parser().parse( input ); fclose( input ); if ( shouldExit || Parser::get_parser().get_parseStatus() != 0 ) { exit( Parser::get_parser().get_parseStatus() ); } // if } static bool notPrelude( Declaration * decl ) { return ! LinkageSpec::isBuiltin( decl->get_linkage() ); } static void dump( std::list< Declaration * > & translationUnit ) { std::list< Declaration * > decls; if ( noprotop ) { filter( translationUnit.begin(), translationUnit.end(), std::back_inserter( decls ), notPrelude ); } else { decls = translationUnit; } printAll( decls, std::cout ); deleteAll( translationUnit ); } // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //