2013-12-31 23:43:49 -06:00
# include "Importer.h"
2015-07-03 18:34:46 -04:00
Importer : : Importer ( Parser * parserIn , std : : vector < std : : string > includePaths , std : : string outputNameIn , bool only_parseIn ) {
only_parse = only_parseIn ;
2013-12-31 23:43:49 -06:00
//constructor
2015-03-15 18:41:55 -04:00
outputName = outputNameIn ;
2015-03-24 19:33:31 -04:00
2015-07-03 18:34:46 -04:00
if ( ! only_parse ) {
if ( mkdir ( ( " ./ " + outputName ) . c_str ( ) , 0755 ) ) {
//std::cerr << "\n\n =====IMPORTER===== \n\n" << std::endl;
//std::cerr << "Could not make directory " << outputName << std::endl;
}
2015-03-24 19:33:31 -04:00
}
2013-12-31 23:43:49 -06:00
parser = parserIn ;
2014-05-01 01:18:01 -04:00
this - > includePaths = includePaths ;
2014-05-24 14:04:32 -04:00
ASTTransformer = new ASTTransformation ( this ) ;
2013-12-31 23:43:49 -06:00
2014-05-24 14:04:32 -04:00
removeSymbols . push_back ( Symbol ( " $NULL$ " , true ) ) ;
2013-12-31 23:43:49 -06:00
removeSymbols . push_back ( Symbol ( " WS " , false ) ) ;
removeSymbols . push_back ( Symbol ( " \\ ( " , true ) ) ;
removeSymbols . push_back ( Symbol ( " \\ ) " , true ) ) ;
2015-04-14 16:08:36 -04:00
removeSymbols . push_back ( Symbol ( " var " , true ) ) ;
removeSymbols . push_back ( Symbol ( " fun " , true ) ) ;
2013-12-31 23:43:49 -06:00
removeSymbols . push_back ( Symbol ( " ; " , true ) ) ;
2015-05-09 03:13:40 -04:00
removeSymbols . push_back ( Symbol ( " line_end " , false ) ) ;
2013-12-31 23:43:49 -06:00
removeSymbols . push_back ( Symbol ( " { " , true ) ) ;
removeSymbols . push_back ( Symbol ( " } " , true ) ) ;
removeSymbols . push_back ( Symbol ( " ( " , true ) ) ;
removeSymbols . push_back ( Symbol ( " ) " , true ) ) ;
2014-05-07 02:33:04 -04:00
removeSymbols . push_back ( Symbol ( " import " , true ) ) ;
2013-12-31 23:43:49 -06:00
removeSymbols . push_back ( Symbol ( " interpreter_directive " , false ) ) ;
removeSymbols . push_back ( Symbol ( " if " , true ) ) ;
removeSymbols . push_back ( Symbol ( " while " , true ) ) ;
removeSymbols . push_back ( Symbol ( " __if_comp__ " , true ) ) ;
2015-04-04 01:32:40 -04:00
removeSymbols . push_back ( Symbol ( " simple_passthrough " , true ) ) ;
2013-12-31 23:43:49 -06:00
removeSymbols . push_back ( Symbol ( " comp_simple_passthrough " , true ) ) ;
2015-05-16 12:05:23 -04:00
removeSymbols . push_back ( Symbol ( " def_nonterm " , false ) ) ;
removeSymbols . push_back ( Symbol ( " obj_nonterm " , false ) ) ;
2015-08-29 21:45:55 -04:00
removeSymbols . push_back ( Symbol ( " adt_nonterm " , false ) ) ;
2014-05-07 02:33:04 -04:00
removeSymbols . push_back ( Symbol ( " template " , true ) ) ;
2014-08-01 00:45:48 -07:00
removeSymbols . push_back ( Symbol ( " \\ | " , true ) ) ;
2014-12-19 18:29:33 -05:00
//collapseSymbols.push_back(Symbol("scoped_identifier", false));
2015-04-10 00:37:31 -04:00
collapseSymbols . push_back ( Symbol ( " opt_param_assign_list " , false ) ) ;
collapseSymbols . push_back ( Symbol ( " param_assign_list " , false ) ) ;
2013-12-31 23:43:49 -06:00
collapseSymbols . push_back ( Symbol ( " opt_typed_parameter_list " , false ) ) ;
collapseSymbols . push_back ( Symbol ( " opt_parameter_list " , false ) ) ;
2015-08-29 21:45:55 -04:00
collapseSymbols . push_back ( Symbol ( " identifier_list " , false ) ) ;
2013-12-31 23:43:49 -06:00
collapseSymbols . push_back ( Symbol ( " statement_list " , false ) ) ;
collapseSymbols . push_back ( Symbol ( " parameter_list " , false ) ) ;
collapseSymbols . push_back ( Symbol ( " typed_parameter_list " , false ) ) ;
collapseSymbols . push_back ( Symbol ( " unorderd_list_part " , false ) ) ;
collapseSymbols . push_back ( Symbol ( " if_comp_pred " , false ) ) ;
2014-01-19 18:20:52 -05:00
collapseSymbols . push_back ( Symbol ( " declaration_block " , false ) ) ;
2014-06-17 00:10:57 -07:00
collapseSymbols . push_back ( Symbol ( " type_list " , false ) ) ;
2015-05-22 22:30:25 -04:00
collapseSymbols . push_back ( Symbol ( " opt_type_list " , false ) ) ;
2014-07-06 23:42:25 -07:00
collapseSymbols . push_back ( Symbol ( " template_param_list " , false ) ) ;
2014-07-18 08:52:15 -07:00
collapseSymbols . push_back ( Symbol ( " trait_list " , false ) ) ;
2014-08-01 00:45:48 -07:00
collapseSymbols . push_back ( Symbol ( " dec_type " , false ) ) ;
2015-07-14 19:32:54 -04:00
//collapseSymbols.push_back(Symbol("pre_reffed", false));
2013-12-31 23:43:49 -06:00
}
Importer : : ~ Importer ( ) {
//destructor
2014-05-24 14:04:32 -04:00
delete ASTTransformer ;
2013-12-31 23:43:49 -06:00
}
2014-05-24 14:04:32 -04:00
void Importer : : registerAST ( std : : string name , NodeTree < ASTData > * ast , NodeTree < Symbol > * syntaxTree ) {
imported [ name ] = ast ;
importedTrips . push_back ( { name , ast , syntaxTree } ) ;
std : : cout < < " REGISTERD " < < name < < std : : endl ;
}
2014-05-19 20:00:35 -04:00
2014-05-24 14:04:32 -04:00
NodeTree < ASTData > * Importer : : getUnit ( std : : string fileName ) {
2015-07-03 18:34:46 -04:00
//std::cout << "\n\nImporting " << fileName << " ";
2014-01-01 17:29:19 -06:00
//Check to see if we've already done it
2014-05-19 20:00:35 -04:00
if ( imported . find ( fileName ) ! = imported . end ( ) ) {
2015-07-03 18:34:46 -04:00
//std::cout << "Already Imported!" << std::endl;
2014-01-01 17:29:19 -06:00
return imported [ fileName ] ;
2014-05-19 20:00:35 -04:00
}
2015-07-03 18:34:46 -04:00
//std::cout << "Not yet imported" << std::endl;
2014-01-01 17:29:19 -06:00
2014-05-24 14:04:32 -04:00
return NULL ;
}
NodeTree < ASTData > * Importer : : importFirstPass ( std : : string fileName ) {
NodeTree < ASTData > * ast = getUnit ( fileName ) ;
if ( ast = = NULL ) {
NodeTree < Symbol > * parseTree = parseAndTrim ( fileName ) ;
2014-06-30 01:57:50 -07:00
if ( ! parseTree )
return NULL ;
2014-05-24 14:04:32 -04:00
//Call with ourself to allow the transformation to call us to import files that it needs
2015-07-03 18:34:46 -04:00
if ( ! only_parse )
ast = ASTTransformer - > firstPass ( fileName , parseTree ) ; //This firstPass will register itself
2014-05-24 14:04:32 -04:00
}
return ast ;
}
void Importer : : import ( std : : string fileName ) {
//Start the ball rolling by importing and running the first pass on the first file.
//This will import, first pass and register all the other files too.
2015-07-03 18:34:46 -04:00
//std::cout << "\n\n =====FIRST PASS===== \n\n" << std::endl;
2014-05-24 14:04:32 -04:00
importFirstPass ( fileName ) ; //First pass defines all objects
2015-07-03 18:34:46 -04:00
if ( only_parse )
return ;
2014-05-24 14:04:32 -04:00
std : : cout < < " \n \n =====SECOND PASS===== \n \n " < < std : : endl ;
for ( importTriplet i : importedTrips ) //Second pass defines data inside objects, outside declaration statements,
std : : cout < < " \n \n Second pass for: " < < i . name < < std : : endl , ASTTransformer - > secondPass ( i . ast , i . syntaxTree ) ; //function prototypes, and identifiers (as we now have all type defs)
std : : cout < < " \n \n =====THIRD PASS===== \n \n " < < std : : endl ;
2015-06-28 14:27:48 -04:00
for ( importTriplet i : importedTrips ) //Third pass does all function bodies
std : : cout < < " \n \n Third pass for: " < < i . name < < std : : endl , ASTTransformer - > thirdPass ( i . ast , i . syntaxTree ) ;
std : : cout < < " \n \n =====FOURTH PASS===== \n \n " < < std : : endl ;
bool changed = true ;
while ( changed ) {
changed = false ;
for ( importTriplet i : importedTrips ) { //Fourth pass finishes up by doing all template classes
std : : cout < < " \n \n Fourth pass for: " < < i . name < < std : : endl ;
changed = changed ? changed : ASTTransformer - > fourthPass ( i . ast , i . syntaxTree ) ;
}
}
2014-05-24 14:04:32 -04:00
2015-03-24 18:29:21 -04:00
//Note that class template instantiation can happen in the second or third passes and that function template instantion
//can happen in the third pass.
2014-05-24 14:04:32 -04:00
std : : ofstream outFileAST ;
for ( importTriplet i : importedTrips ) {
2015-03-15 18:41:55 -04:00
std : : string outputFileName = outputName + " / " + i . name + " out " ;
outFileAST . open ( ( outputFileName + " .AST.dot " ) . c_str ( ) ) ;
2014-05-24 14:04:32 -04:00
if ( ! outFileAST . is_open ( ) ) {
2015-03-15 18:41:55 -04:00
std : : cout < < " Problem opening second output file " < < outputFileName + " .AST.dot " < < " \n " ;
2014-05-24 14:04:32 -04:00
return ;
}
if ( i . ast ) {
2015-06-29 01:03:51 -04:00
//outFileAST << i.ast->DOTGraphString() << std::endl;
2014-05-24 14:04:32 -04:00
} else {
2014-06-17 00:10:57 -07:00
std : : cout < < " Tree returned from ASTTransformation for " < < fileName < < " is NULL! " < < std : : endl ;
2014-05-24 14:04:32 -04:00
}
outFileAST . close ( ) ;
}
}
NodeTree < Symbol > * Importer : : parseAndTrim ( std : : string fileName ) {
2013-12-31 23:43:49 -06:00
std : : ifstream programInFile ;
2015-07-03 18:34:46 -04:00
//std::ofstream outFile, outFileTransformed;
2013-12-31 23:43:49 -06:00
2015-07-03 18:34:46 -04:00
//std::cout << "outputName " << outputName << std::endl;
//std::cout << "fileName " << fileName << std::endl;
2015-03-15 18:41:55 -04:00
auto pathPieces = split ( fileName , ' / ' ) ;
std : : string outputFileName = outputName + " / " + pathPieces [ pathPieces . size ( ) - 1 ] + " out " ;
2015-07-03 18:34:46 -04:00
//std::cout << "outputFileName " << outputFileName << std::endl;
2014-06-17 00:10:57 -07:00
2015-07-03 18:34:46 -04:00
std : : string inputFileName ;
2014-05-01 01:18:01 -04:00
for ( auto i : includePaths ) {
programInFile . open ( i + fileName ) ;
2015-07-03 18:34:46 -04:00
if ( programInFile . is_open ( ) ) {
inputFileName = i + fileName ;
2014-05-01 01:18:01 -04:00
break ;
2015-07-03 18:34:46 -04:00
} else {
2014-05-03 20:46:10 -04:00
std : : cout < < i + fileName < < " is no good " < < std : : endl ;
2015-07-03 18:34:46 -04:00
}
2014-05-01 01:18:01 -04:00
}
2013-12-31 23:43:49 -06:00
if ( ! programInFile . is_open ( ) ) {
std : : cout < < " Problem opening programInFile " < < fileName < < " \n " ;
return NULL ;
}
2015-07-03 18:34:46 -04:00
//outFile.open(outputFileName);
//if (!outFile.is_open()) {
//std::cout << "Probelm opening output file " << outputFileName << "\n";
//return NULL;
//}
2013-12-31 23:43:49 -06:00
2015-07-03 18:34:46 -04:00
//outFileTransformed.open((outputFileName + ".transformed.dot").c_str());
//if (!outFileTransformed.is_open()) {
//std::cout << "Probelm opening second output file " << outputFileName + ".transformed.dot" << "\n";
//return NULL;
//}
2013-12-31 23:43:49 -06:00
std : : string programInputFileString , line ;
while ( programInFile . good ( ) ) {
getline ( programInFile , line ) ;
programInputFileString . append ( line + " \n " ) ;
}
programInFile . close ( ) ;
2014-01-01 17:29:19 -06:00
//std::cout << programInputFileString << std::endl;
2015-07-03 18:34:46 -04:00
NodeTree < Symbol > * parseTree = parser - > parseInput ( programInputFileString , inputFileName ) ;
2013-12-31 23:43:49 -06:00
if ( parseTree ) {
2015-06-29 01:03:51 -04:00
//std::cout << parseTree->DOTGraphString() << std::endl;
//outFile << parseTree->DOTGraphString() << std::endl;
2013-12-31 23:43:49 -06:00
} else {
2014-06-17 00:10:57 -07:00
std : : cout < < " ParseTree returned from parser for " < < fileName < < " is NULL! " < < std : : endl ;
2015-07-03 18:34:46 -04:00
//outFile.close(); outFileTransformed.close();
2015-03-11 01:58:10 -04:00
throw " unexceptablblllll " ;
2014-06-30 01:57:50 -07:00
return NULL ;
}
2015-07-03 18:34:46 -04:00
//outFile.close();
2013-12-31 23:43:49 -06:00
//Remove Transformations
for ( int i = 0 ; i < removeSymbols . size ( ) ; i + + )
parseTree = RemovalTransformation < Symbol > ( removeSymbols [ i ] ) . transform ( parseTree ) ;
//Collapse Transformations
for ( int i = 0 ; i < collapseSymbols . size ( ) ; i + + )
parseTree = CollapseTransformation < Symbol > ( collapseSymbols [ i ] ) . transform ( parseTree ) ;
if ( parseTree ) {
2015-06-29 01:03:51 -04:00
//outFileTransformed << parseTree->DOTGraphString() << std::endl;
2013-12-31 23:43:49 -06:00
} else {
std : : cout < < " Tree returned from transformation is NULL! " < < std : : endl ;
}
2015-07-03 18:34:46 -04:00
//outFileTransformed.close();
2013-12-31 23:43:49 -06:00
2015-03-15 18:41:55 -04:00
std : : cout < < " Returning parse tree " < < std : : endl ;
2014-05-24 14:04:32 -04:00
return parseTree ;
2014-01-01 17:29:19 -06:00
}
std : : map < std : : string , NodeTree < ASTData > * > Importer : : getASTMap ( ) {
return imported ;
}