// // 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 May 21 21:15:54 2015 // Update Count : 9 // #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 "../config.h" using namespace std; bool astp = false, exprp = false, expraltp = false, grammarp = false, libcfap = false, resolvep = false, // used in AlternativeFinder symtabp = false, parsep = false, validp = false, preludep = true, protop = false, codegenp = false, errorp = false; enum { Ast, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Prototypes, Resolver, Symbol, Parse, }; static struct option long_opts[] = { { "ast", no_argument, 0, Ast }, { "expr", no_argument, 0, Expr }, { "expralt", no_argument, 0, ExprAlt }, { "grammar", no_argument, 0, Grammar }, { "libcfa", no_argument, 0, LibCFA }, { "nopreamble", no_argument, 0, Nopreamble }, { "prototypes", no_argument, 0, Prototypes }, { "resolver", no_argument, 0, Resolver }, { "symbol", no_argument, 0, Symbol }, { "parse", no_argument, 0, Parse }, { 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, "aefglnpqrsxyzD:", long_opts, &long_index )) != -1 ) { switch ( c ) { case Ast: case 'a': // dump AST astp = 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 preludep = false; break; case Prototypes: case 'p': // generate prototypes for preamble functions protop = 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 'x': // 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 { 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 ); if ( preludep ) { // include gcc builtins FILE *builtins = fopen( CFA_LIBDIR "/builtins.cf", "r" ); if ( builtins == NULL ) { 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 ); FILE *prelude; if ( libcfap ) { // include cfa prelude prelude = input; } else { prelude = fopen( CFA_LIBDIR "/prelude.cf", "r" ); } // if if ( prelude == NULL ) { 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 ( libcfap ) { 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 ( grammarp || Parser::get_parser().get_parseStatus() != 0 ) { return Parser::get_parser().get_parseStatus(); } // if fclose( input ); 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 ) { printAll( translationUnit, std::cout ); return 0; } // if if ( expraltp ) { 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 ) { InitTweak::tweak( translationUnit ); SymTab::validate( translationUnit, false ); ControlStruct::mutate( translationUnit ); CodeGen::fixNames( translationUnit ); ResolvExpr::resolve( translationUnit ); printAll( translationUnit, std::cout ); return 0; } // if if ( codegenp ) { // print the tree right before code generation cerr << "tweak" << endl; InitTweak::tweak( translationUnit ); cerr << "validate" << endl; SymTab::validate( translationUnit, false ); cerr << "mutate" << endl; ControlStruct::mutate( translationUnit ); cerr << "fixNames" << endl; CodeGen::fixNames( translationUnit ); cerr << "resolve" << endl; ResolvExpr::resolve( translationUnit ); cerr << "copyParams" << endl; GenPoly::copyParams( translationUnit ); cerr << "convertSpecializations" << endl; GenPoly::convertSpecializations( translationUnit ); cerr << "convertLvalue" << endl; GenPoly::convertLvalue( translationUnit ); cerr << "box" << endl; GenPoly::box( translationUnit ); if ( errorp ) { 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 ) { if ( errorp ) { printAll( translationUnit, std::cout ); } 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 // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //