2013-12-31 23:43:49 -06:00
# include "Importer.h"
2015-03-15 18:41:55 -04:00
Importer : : Importer ( Parser * parserIn , std : : vector < std : : string > includePaths , std : : string outputNameIn ) {
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
if ( mkdir ( ( " ./ " + outputName ) . c_str ( ) , 0755 ) ) {
std : : cerr < < " \n \n =====IMPORTER===== \n \n " < < std : : endl ;
std : : cerr < < " Could not make directory " < < outputName < < std : : endl ;
}
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 ) ) ;
2014-12-19 18:29:33 -05:00
//removeSymbols.push_back(Symbol("::", true));
2015-04-04 01:32:40 -04:00
//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 ) ) ;
2014-01-07 13:14:58 -05:00
removeSymbols . push_back ( Symbol ( " typedef " , true ) ) ;
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 ) ) ;
collapseSymbols . push_back ( Symbol ( " opt_import_list " , false ) ) ;
collapseSymbols . push_back ( Symbol ( " import_list " , false ) ) ;
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 ) ) ;
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 ) ) ;
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 ) {
2014-05-19 20:00:35 -04:00
std : : cout < < " \n \n Importing " < < 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 ( ) ) {
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
}
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
ast = ASTTransformer - > firstPass ( fileName , parseTree ) ; //This firstPass will register itself
}
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.
std : : cout < < " \n \n =====FIRST PASS===== \n \n " < < std : : endl ;
importFirstPass ( fileName ) ; //First pass defines all objects
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-03-24 18:29:21 -04:00
for ( importTriplet i : importedTrips ) //Third pass finishes up by doing all function bodies
std : : cout < < " \n \n Fourth pass for: " < < i . name < < std : : endl , ASTTransformer - > thirdPass ( i . ast , i . syntaxTree ) ; //With that, we're done
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 ) {
outFileAST < < i . ast - > DOTGraphString ( ) < < std : : endl ;
} 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 ;
2014-05-24 14:04:32 -04:00
std : : ofstream outFile , outFileTransformed ;
2013-12-31 23:43:49 -06:00
2015-03-15 18:41:55 -04:00
std : : cout < < " outputName " < < outputName < < std : : endl ;
std : : cout < < " fileName " < < fileName < < std : : endl ;
auto pathPieces = split ( fileName , ' / ' ) ;
std : : string outputFileName = outputName + " / " + pathPieces [ pathPieces . size ( ) - 1 ] + " out " ;
std : : cout < < " outputFileName " < < outputFileName < < std : : endl ;
2014-06-17 00:10:57 -07:00
2014-05-01 01:18:01 -04:00
for ( auto i : includePaths ) {
programInFile . open ( i + fileName ) ;
if ( programInFile . is_open ( ) )
break ;
2014-05-03 20:46:10 -04:00
else
std : : cout < < i + fileName < < " is no good " < < std : : endl ;
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-03-15 18:41:55 -04:00
outFile . open ( outputFileName ) ;
2013-12-31 23:43:49 -06:00
if ( ! outFile . is_open ( ) ) {
2015-03-15 18:41:55 -04:00
std : : cout < < " Probelm opening output file " < < outputFileName < < " \n " ;
2013-12-31 23:43:49 -06:00
return NULL ;
}
2015-03-15 18:41:55 -04:00
outFileTransformed . open ( ( outputFileName + " .transformed.dot " ) . c_str ( ) ) ;
2013-12-31 23:43:49 -06:00
if ( ! outFileTransformed . is_open ( ) ) {
2015-03-15 18:41:55 -04:00
std : : cout < < " Probelm opening second output file " < < outputFileName + " .transformed.dot " < < " \n " ;
2013-12-31 23:43:49 -06:00
return NULL ;
}
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;
2013-12-31 23:43:49 -06:00
NodeTree < Symbol > * parseTree = parser - > parseInput ( programInputFileString ) ;
if ( parseTree ) {
//std::cout << parseTree->DOTGraphString() << std::endl;
outFile < < parseTree - > DOTGraphString ( ) < < std : : endl ;
} else {
2014-06-17 00:10:57 -07:00
std : : cout < < " ParseTree returned from parser for " < < fileName < < " is NULL! " < < std : : endl ;
2014-06-30 01:57:50 -07: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 ;
}
2013-12-31 23:43:49 -06:00
outFile . close ( ) ;
//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 ) {
outFileTransformed < < parseTree - > DOTGraphString ( ) < < std : : endl ;
} else {
std : : cout < < " Tree returned from transformation is NULL! " < < std : : endl ;
}
outFileTransformed . close ( ) ;
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 ;
}