2013-09-26 15:16:58 -04:00
# include "ASTTransformation.h"
2013-12-31 23:43:49 -06:00
ASTTransformation : : ASTTransformation ( Importer * importerIn ) {
importer = importerIn ;
2014-03-06 13:13:40 -05:00
//Set up language level special scope. (the final scope checked)
//Note the NULL type
languageLevelScope [ " + " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " + " , true ) , NULL ) ) ) ;
languageLevelScope [ " - " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " - " , true ) , NULL ) ) ) ;
languageLevelScope [ " * " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " * " , true ) , NULL ) ) ) ;
languageLevelScope [ " & " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " & " , true ) , NULL ) ) ) ;
languageLevelScope [ " -- " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " -- " , true ) , NULL ) ) ) ;
languageLevelScope [ " ++ " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " ++ " , true ) , NULL ) ) ) ;
languageLevelScope [ " == " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " == " , true ) , NULL ) ) ) ;
languageLevelScope [ " <= " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " <= " , true ) , NULL ) ) ) ;
languageLevelScope [ " >= " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " >= " , true ) , NULL ) ) ) ;
languageLevelScope [ " < " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " < " , true ) , NULL ) ) ) ;
languageLevelScope [ " > " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " > " , true ) , NULL ) ) ) ;
languageLevelScope [ " && " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " && " , true ) , NULL ) ) ) ;
languageLevelScope [ " || " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " || " , true ) , NULL ) ) ) ;
languageLevelScope [ " ! " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " ! " , true ) , NULL ) ) ) ;
languageLevelScope [ " *= " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " *= " , true ) , NULL ) ) ) ;
languageLevelScope [ " += " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " += " , true ) , NULL ) ) ) ;
languageLevelScope [ " -= " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " -= " , true ) , NULL ) ) ) ;
languageLevelScope [ " . " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " . " , true ) , NULL ) ) ) ;
languageLevelScope [ " -> " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " -> " , true ) , NULL ) ) ) ;
2014-05-06 13:54:53 -04:00
languageLevelScope [ " [] " ] . push_back ( new NodeTree < ASTData > ( " function " , ASTData ( function , Symbol ( " [] " , true ) , NULL ) ) ) ;
2013-09-26 15:16:58 -04:00
}
ASTTransformation : : ~ ASTTransformation ( ) {
//
}
2013-10-02 03:15:20 -04:00
NodeTree < ASTData > * ASTTransformation : : transform ( NodeTree < Symbol > * from ) {
2013-12-27 13:05:07 -06:00
//Set up top scope
2014-05-09 02:56:55 -04:00
return transform ( from , NULL , std : : vector < Type > ( ) , std : : map < std : : string , Type * > ( ) ) ;
2013-12-27 13:05:07 -06:00
}
2014-05-09 02:56:55 -04:00
NodeTree < ASTData > * ASTTransformation : : transform ( NodeTree < Symbol > * from , NodeTree < ASTData > * scope , std : : vector < Type > types , std : : map < std : : string , Type * > templateTypeReplacements ) {
2013-10-16 01:43:18 -04:00
Symbol current = from - > getData ( ) ;
std : : string name = current . getName ( ) ;
2014-02-03 11:41:25 -05:00
NodeTree < ASTData > * newNode = NULL ;
2013-10-16 01:43:18 -04:00
std : : vector < NodeTree < Symbol > * > children = from - > getChildren ( ) ;
2013-10-26 11:47:34 -04:00
std : : set < int > skipChildren ;
2013-10-16 01:43:18 -04:00
if ( name = = " translation_unit " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( translation_unit ) ) ;
2013-12-27 13:05:07 -06:00
scope = newNode ;
2013-10-26 11:47:34 -04:00
} else if ( name = = " interpreter_directive " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( interpreter_directive ) ) ;
2013-10-16 01:43:18 -04:00
} else if ( name = = " import " & & ! current . isTerminal ( ) ) {
2013-12-31 23:43:49 -06:00
std : : string toImport = concatSymbolTree ( children [ 0 ] ) ;
newNode = new NodeTree < ASTData > ( name , ASTData ( import , Symbol ( toImport , true ) ) ) ;
//Do the imported file too
NodeTree < ASTData > * outsideTranslationUnit = importer - > import ( toImport + " .krak " ) ;
2014-03-06 13:13:40 -05:00
scope - > getDataRef ( ) - > scope [ toImport ] . push_back ( outsideTranslationUnit ) ; //Put this transation_unit in the scope as it's files name
2013-12-31 23:43:49 -06:00
//Now add it to scope
for ( auto i = outsideTranslationUnit - > getDataRef ( ) - > scope . begin ( ) ; i ! = outsideTranslationUnit - > getDataRef ( ) - > scope . end ( ) ; i + + )
2014-03-06 13:13:40 -05:00
for ( auto j : i - > second )
scope - > getDataRef ( ) - > scope [ i - > first ] . push_back ( j ) ;
2013-10-16 01:43:18 -04:00
return newNode ; // Don't need children of import
2013-10-26 11:47:34 -04:00
} else if ( name = = " identifier " ) {
2014-01-19 18:20:52 -05:00
//Make sure we get the entire name
std : : string lookupName = concatSymbolTree ( from ) ;
2014-03-06 13:13:40 -05:00
std : : cout < < " Looking up: " < < lookupName < < std : : endl ;
newNode = scopeLookup ( scope , lookupName , types ) ;
2013-12-27 13:05:07 -06:00
if ( newNode = = NULL ) {
2014-02-03 11:41:25 -05:00
std : : cout < < " scope lookup error! Could not find " < < lookupName < < " in identifier " < < std : : endl ;
2013-12-27 13:05:07 -06:00
throw " LOOKUP ERROR: " + lookupName ;
2014-01-19 18:20:52 -05:00
} else if ( newNode - > getDataRef ( ) - > symbol . getName ( ) ! = lookupName ) {
//This happens when the lookup name denotes a member of an object, i.e. obj.foo
//The newNode points to obj, not foo.
2013-12-27 13:05:07 -06:00
}
//newNode = new NodeTree<ASTData>(name, ASTData(identifier, Symbol(concatSymbolTree(children[0]), true)));
2014-01-07 13:14:58 -05:00
} else if ( name = = " type_def " ) {
2014-01-19 18:20:52 -05:00
//If it is an alisis of a type
2014-05-07 02:33:04 -04:00
std : : string typeAlias ;
2014-01-19 18:20:52 -05:00
if ( children [ 1 ] - > getData ( ) . getName ( ) = = " type " ) {
2014-05-07 02:33:04 -04:00
typeAlias = concatSymbolTree ( children [ 0 ] ) ;
2014-05-09 02:56:55 -04:00
newNode = new NodeTree < ASTData > ( name , ASTData ( type_def , Symbol ( typeAlias , true , typeAlias ) , typeFromTypeNode ( children [ 1 ] , scope , templateTypeReplacements ) ) ) ;
2014-05-08 01:07:57 -04:00
skipChildren . insert ( 0 ) ; //Don't want any children, it's unnecessary for ailising
skipChildren . insert ( 1 ) ;
2014-01-19 18:20:52 -05:00
} else { //Is a struct or class
2014-05-07 02:33:04 -04:00
Type * objectType = NULL ;
if ( children [ 0 ] - > getData ( ) . getName ( ) = = " template_dec " ) {
typeAlias = concatSymbolTree ( children [ 1 ] ) ;
2014-05-09 02:56:55 -04:00
std : : cout < < " Template Type! " < < std : : endl ;
2014-05-08 01:07:57 -04:00
newNode = new NodeTree < ASTData > ( name , ASTData ( type_def , Symbol ( typeAlias , true , typeAlias ) ) ) ;
2014-05-09 02:56:55 -04:00
//So we give this typedef its name without any template types and make its type template_type, and point to this from node.
//Then, when this template is instantiated, it will run transform on from with the types filled in.
objectType = new Type ( template_type , from ) ;
// skipChildren.insert(0); //Don't try to transform the template
// skipChildren.insert(1); //Identifier lookup will be ourselves, as we just added ourselves to the scope
2014-05-07 02:33:04 -04:00
} else {
typeAlias = concatSymbolTree ( children [ 0 ] ) ;
2014-05-08 01:07:57 -04:00
newNode = new NodeTree < ASTData > ( name , ASTData ( type_def , Symbol ( typeAlias , true , typeAlias ) ) ) ;
2014-05-07 02:33:04 -04:00
objectType = new Type ( newNode ) ;
skipChildren . insert ( 0 ) ; //Identifier lookup will be ourselves, as we just added ourselves to the scope
}
newNode - > getDataRef ( ) - > valueType = objectType ; //Type is self-referential since this is the definition
2014-01-19 18:20:52 -05:00
}
2014-03-06 13:13:40 -05:00
scope - > getDataRef ( ) - > scope [ typeAlias ] . push_back ( newNode ) ;
newNode - > getDataRef ( ) - > scope [ " ~enclosing_scope " ] . push_back ( scope ) ;
2014-05-09 02:56:55 -04:00
//Templates are done here. No need to go farther
if ( children [ 0 ] - > getData ( ) . getName ( ) = = " template_dec " )
return newNode ;
2014-02-03 11:41:25 -05:00
scope = newNode ;
2014-01-19 18:20:52 -05:00
//return newNode;
2013-10-16 01:43:18 -04:00
} else if ( name = = " function " ) {
2013-12-27 13:05:07 -06:00
std : : string functionName = concatSymbolTree ( children [ 1 ] ) ;
2014-05-09 02:56:55 -04:00
newNode = new NodeTree < ASTData > ( name , ASTData ( function , Symbol ( functionName , true ) , typeFromTypeNode ( children [ 0 ] , scope , templateTypeReplacements ) ) ) ;
2013-10-26 11:47:34 -04:00
skipChildren . insert ( 0 ) ;
skipChildren . insert ( 1 ) ;
2014-03-06 13:13:40 -05:00
scope - > getDataRef ( ) - > scope [ functionName ] . push_back ( newNode ) ;
newNode - > getDataRef ( ) - > scope [ " ~enclosing_scope " ] . push_back ( scope ) ;
2013-12-27 13:05:07 -06:00
scope = newNode ;
2014-03-06 13:13:40 -05:00
// auto transChildren = transformChildren(children, skipChildren, scope, types);
// std::cout << functionName << " ";
// for (auto i : transChildren)
// std::cout << "||" << i->getDataRef()->toString() << "|| ";
// std::cout << "??||" << std::endl;
// newNode->addChildren(transChildren);
// return newNode;
2014-02-03 11:41:25 -05:00
std : : cout < < " finished function " < < functionName < < std : : endl ;
2013-10-26 11:47:34 -04:00
} else if ( name = = " code_block " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( code_block ) ) ;
2014-03-06 13:13:40 -05:00
newNode - > getDataRef ( ) - > scope [ " ~enclosing_scope " ] . push_back ( scope ) ;
2013-12-27 13:05:07 -06:00
scope = newNode ;
2013-10-26 11:47:34 -04:00
} else if ( name = = " typed_parameter " ) {
2013-12-27 13:05:07 -06:00
//newNode = transform(children[1]); //Transform to get the identifier
std : : string parameterName = concatSymbolTree ( children [ 1 ] ) ;
2014-05-07 02:33:04 -04:00
//std::string typeString = concatSymbolTree(children[0]);//Get the type (left child) and set our new identifer to be that type
2014-05-09 02:56:55 -04:00
newNode = new NodeTree < ASTData > ( " identifier " , ASTData ( identifier , Symbol ( parameterName , true ) , typeFromTypeNode ( children [ 0 ] , scope , templateTypeReplacements ) ) ) ;
2014-03-06 13:13:40 -05:00
scope - > getDataRef ( ) - > scope [ parameterName ] . push_back ( newNode ) ;
newNode - > getDataRef ( ) - > scope [ " ~enclosing_scope " ] . push_back ( scope ) ;
2013-11-01 02:52:18 -04:00
return newNode ;
2013-12-27 13:05:07 -06:00
} else if ( name = = " boolean_expression " | | name = = " and_boolean_expression " | | name = = " bool_exp " ) {
2013-11-07 22:19:33 -05:00
//If this is an actual part of an expression, not just a premoted term
if ( children . size ( ) > 1 ) {
2014-03-06 13:13:40 -05:00
//We do children first so we can do appropriate scope searching with types (yay operator overloading!)
skipChildren . insert ( 1 ) ;
2014-05-09 02:56:55 -04:00
std : : vector < NodeTree < ASTData > * > transformedChildren = transformChildren ( children , skipChildren , scope , types , templateTypeReplacements ) ;
2014-02-03 11:41:25 -05:00
std : : string functionCallString = concatSymbolTree ( children [ 1 ] ) ;
2014-05-09 02:56:55 -04:00
NodeTree < ASTData > * function = doFunction ( scope , functionCallString , transformedChildren , templateTypeReplacements ) ;
2013-12-27 13:05:07 -06:00
if ( function = = NULL ) {
2014-02-03 11:41:25 -05:00
std : : cout < < " scope lookup error! Could not find " < < functionCallString < < " in boolean stuff " < < std : : endl ;
throw " LOOKUP ERROR: " + functionCallString ;
2013-12-27 13:05:07 -06:00
}
2014-04-27 02:48:57 -04:00
newNode = function ;
// newNode = new NodeTree<ASTData>(functionCallString, ASTData(function_call, function->getDataRef()->valueType));
// newNode->addChild(function); // First child of function call is a link to the function
// newNode->addChildren(transformedChildren);
2013-11-07 22:19:33 -05:00
} else {
2014-01-01 17:29:19 -06:00
//std::cout << children.size() << std::endl;
2013-12-27 13:05:07 -06:00
if ( children . size ( ) = = 0 )
return new NodeTree < ASTData > ( ) ;
2014-05-09 02:56:55 -04:00
return transform ( children [ 0 ] , scope , types , templateTypeReplacements ) ; //Just a promoted term, so do child
2013-11-07 22:19:33 -05:00
}
2013-12-18 18:05:21 -06:00
//Here's the order of ops stuff
2014-01-19 18:20:52 -05:00
} else if ( name = = " expression " | | name = = " shiftand " | | name = = " term " | | name = = " unarad " | | name = = " access_operation " ) { //unarad can ride through, it should always just be a promoted child
2013-12-18 18:05:21 -06:00
//If this is an actual part of an expression, not just a premoted child
2013-12-23 01:26:24 -06:00
if ( children . size ( ) > 2 ) {
2014-05-09 02:56:55 -04:00
NodeTree < ASTData > * lhs = transform ( children [ 0 ] , scope , std : : vector < Type > ( ) , templateTypeReplacements ) ; //LHS does not inherit types
2014-03-06 13:13:40 -05:00
NodeTree < ASTData > * rhs ;
2014-05-09 02:56:55 -04:00
if ( name = = " access_operation " ) {
std : : cout < < " lhs is: " < < lhs - > getDataRef ( ) - > toString ( ) < < std : : endl ;
rhs = transform ( children [ 2 ] , lhs - > getDataRef ( ) - > valueType - > typeDefinition , types , templateTypeReplacements ) ; //If an access operation, then the right side will be in the lhs's type's scope
}
2014-03-06 13:13:40 -05:00
else
2014-05-09 02:56:55 -04:00
rhs = transform ( children [ 2 ] , scope , types , templateTypeReplacements ) ;
2014-03-06 13:13:40 -05:00
2013-10-26 15:05:42 -04:00
std : : string functionCallName = concatSymbolTree ( children [ 1 ] ) ;
2014-01-01 17:29:19 -06:00
//std::cout << "scope lookup from expression or similar" << std::endl;
2014-03-06 13:13:40 -05:00
std : : vector < NodeTree < ASTData > * > transformedChildren ; transformedChildren . push_back ( lhs ) ; transformedChildren . push_back ( rhs ) ;
2014-05-09 02:56:55 -04:00
NodeTree < ASTData > * function = doFunction ( scope , functionCallName , transformedChildren , templateTypeReplacements ) ;
2013-12-27 13:05:07 -06:00
if ( function = = NULL ) {
2014-02-03 11:41:25 -05:00
std : : cout < < " scope lookup error! Could not find " < < functionCallName < < " in expression " < < std : : endl ;
2013-12-27 13:05:07 -06:00
throw " LOOKUP ERROR: " + functionCallName ;
}
2014-04-27 02:48:57 -04:00
newNode = function ;
// newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
// newNode->addChild(function); // First child of function call is a link to the function definition
// newNode->addChild(lhs);
// newNode->addChild(rhs);
2014-02-03 11:41:25 -05:00
2014-04-27 02:48:57 -04:00
// if (name == "access_operation")
// std::cout << "Access Operation: " << lhs->getDataRef()->symbol.getName() << " : " << rhs->getDataRef()->symbol.getName() << std::endl;
// std::cout << functionCallName << " - " << function->getName() << " has value type " << function->getDataRef()->valueType << " and rhs " << rhs->getDataRef()->valueType << std::endl;
// //Set the value of this function call
2014-02-18 21:55:00 -05:00
if ( function - > getDataRef ( ) - > valueType )
newNode - > getDataRef ( ) - > valueType = function - > getDataRef ( ) - > valueType ;
else if ( rhs - > getDataRef ( ) - > valueType )
newNode - > getDataRef ( ) - > valueType = rhs - > getDataRef ( ) - > valueType ;
else
newNode - > getDataRef ( ) - > valueType = NULL ;
std : : cout < < " function call to " < < functionCallName < < " - " < < function - > getName ( ) < < " is now " < < newNode - > getDataRef ( ) - > valueType < < std : : endl ;
2014-02-03 11:41:25 -05:00
return newNode ;
//skipChildren.insert(1);
2013-10-26 15:05:42 -04:00
} else {
2014-05-09 02:56:55 -04:00
return transform ( children [ 0 ] , scope , types , templateTypeReplacements ) ; //Just a promoted child, so do it instead
2013-10-26 11:47:34 -04:00
}
2013-12-23 01:26:24 -06:00
} else if ( name = = " factor " ) { //Do factor here, as it has all the weird unary operators
2014-03-06 13:13:40 -05:00
//If this is an actual part of an expression, not just a premoted child
2013-12-23 01:26:24 -06:00
//NO SUPPORT FOR CASTING YET
2014-05-06 13:54:53 -04:00
std : : string funcName ;
2013-12-23 01:26:24 -06:00
if ( children . size ( ) = = 2 ) {
2014-05-06 13:54:53 -04:00
funcName = concatSymbolTree ( children [ 0 ] ) ;
2014-02-18 21:55:00 -05:00
NodeTree < ASTData > * param ;
2013-12-23 01:26:24 -06:00
if ( funcName = = " * " | | funcName = = " & " | | funcName = = " ++ " | | funcName = = " -- " | | funcName = = " - " | | funcName = = " ! " | | funcName = = " ~ " )
2014-05-09 02:56:55 -04:00
param = transform ( children [ 1 ] , scope , types , templateTypeReplacements ) ;
2013-12-23 01:26:24 -06:00
else
2014-05-09 02:56:55 -04:00
funcName = concatSymbolTree ( children [ 1 ] ) , param = transform ( children [ 0 ] , scope , types , templateTypeReplacements ) ;
2013-12-23 01:26:24 -06:00
2014-01-01 17:29:19 -06:00
//std::cout << "scope lookup from factor" << std::endl;
2014-03-06 13:13:40 -05:00
std : : vector < NodeTree < ASTData > * > transformedChildren ; transformedChildren . push_back ( param ) ;
2014-05-09 02:56:55 -04:00
NodeTree < ASTData > * function = doFunction ( scope , funcName , transformedChildren , templateTypeReplacements ) ;
2013-12-27 13:05:07 -06:00
if ( function = = NULL ) {
2014-02-03 11:41:25 -05:00
std : : cout < < " scope lookup error! Could not find " < < funcName < < " in factor " < < std : : endl ;
2013-12-27 13:05:07 -06:00
throw " LOOKUP ERROR: " + funcName ;
}
2014-02-18 21:55:00 -05:00
2014-05-06 13:54:53 -04:00
return function ;
} else if ( children . size ( ) > = 4 ) { //Array brackets []
funcName = " [] " ;
std : : vector < NodeTree < ASTData > * > transformedChildren ;
2014-05-09 02:56:55 -04:00
transformedChildren . push_back ( transform ( children [ 0 ] , scope , types , templateTypeReplacements ) ) ;
transformedChildren . push_back ( transform ( children [ 2 ] , scope , types , templateTypeReplacements ) ) ;
NodeTree < ASTData > * function = doFunction ( scope , funcName , transformedChildren , templateTypeReplacements ) ;
2014-05-06 13:54:53 -04:00
if ( function = = NULL ) {
std : : cout < < " scope lookup error! Could not find " < < funcName < < " in factor " < < std : : endl ;
throw " LOOKUP ERROR: " + funcName ;
}
return function ;
2013-12-23 01:26:24 -06:00
} else {
2014-05-09 02:56:55 -04:00
return transform ( children [ 0 ] , scope , types , templateTypeReplacements ) ; //Just a promoted child, so do it instead
2013-12-23 01:26:24 -06:00
}
2013-10-26 11:47:34 -04:00
} else if ( name = = " statement " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( statement ) ) ;
} else if ( name = = " if_statement " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( if_statement ) ) ;
2013-12-18 18:05:21 -06:00
} else if ( name = = " while_loop " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( while_loop ) ) ;
} else if ( name = = " for_loop " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( for_loop ) ) ;
2013-10-26 11:47:34 -04:00
} else if ( name = = " return_statement " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( return_statement ) ) ;
} else if ( name = = " assignment_statement " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( assignment_statement ) ) ;
2013-12-18 18:05:21 -06:00
std : : string assignFuncName = concatSymbolTree ( children [ 1 ] ) ;
if ( assignFuncName = = " = " ) {
2014-05-09 02:56:55 -04:00
newNode - > addChild ( transform ( children [ 0 ] , scope , types , templateTypeReplacements ) ) ;
newNode - > addChild ( transform ( children [ 2 ] , scope , types , templateTypeReplacements ) ) ;
2013-12-18 18:05:21 -06:00
} else {
//For assignments like += or *=, expand the syntatic sugar.
2014-05-09 02:56:55 -04:00
NodeTree < ASTData > * lhs = transform ( children [ 0 ] , scope , types , templateTypeReplacements ) ;
NodeTree < ASTData > * rhs = transform ( children [ 2 ] , scope , types , templateTypeReplacements ) ;
2014-03-06 13:13:40 -05:00
std : : vector < NodeTree < ASTData > * > transformedChildren ; transformedChildren . push_back ( lhs ) ; transformedChildren . push_back ( rhs ) ;
2013-12-27 13:05:07 -06:00
std : : string functionName = assignFuncName . substr ( 0 , 1 ) ;
2014-05-09 02:56:55 -04:00
NodeTree < ASTData > * operatorCall = doFunction ( scope , functionName , transformedChildren , templateTypeReplacements ) ;
2014-04-27 02:48:57 -04:00
if ( operatorCall = = NULL ) {
2014-02-03 11:41:25 -05:00
std : : cout < < " scope lookup error! Could not find " < < functionName < < " in assignment_statement " < < std : : endl ;
2013-12-27 13:05:07 -06:00
throw " LOOKUP ERROR: " + functionName ;
}
2013-12-18 18:05:21 -06:00
newNode - > addChild ( lhs ) ;
2014-04-27 02:48:57 -04:00
newNode - > addChild ( operatorCall ) ;
2013-12-18 18:05:21 -06:00
}
return newNode ;
2013-11-01 02:52:18 -04:00
} else if ( name = = " declaration_statement " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( declaration_statement ) ) ;
2013-12-27 13:05:07 -06:00
// NodeTree<ASTData>* newIdentifier = transform(children[1], scope); //Transform the identifier
// newIdentifier->getDataRef()->valueType = Type(concatSymbolTree(children[0]));//set the type of the identifier
std : : string newIdentifierStr = concatSymbolTree ( children [ 1 ] ) ;
2014-05-09 02:56:55 -04:00
Type * identifierType = typeFromTypeNode ( children [ 0 ] , scope , templateTypeReplacements ) ;
std : : cout < < " Declaring an identifier " < < newIdentifierStr < < " to be of type " < < identifierType - > toString ( ) < < std : : endl ;
2014-01-19 18:20:52 -05:00
NodeTree < ASTData > * newIdentifier = new NodeTree < ASTData > ( " identifier " , ASTData ( identifier , Symbol ( newIdentifierStr , true ) , identifierType ) ) ;
2014-03-06 13:13:40 -05:00
scope - > getDataRef ( ) - > scope [ newIdentifierStr ] . push_back ( newIdentifier ) ;
newNode - > getDataRef ( ) - > scope [ " ~enclosing_scope " ] . push_back ( scope ) ;
2013-11-01 02:52:18 -04:00
newNode - > addChild ( newIdentifier ) ;
2014-05-07 02:33:04 -04:00
2013-11-01 02:52:18 -04:00
skipChildren . insert ( 0 ) ; //These, the type and the identifier, have been taken care of.
skipChildren . insert ( 1 ) ;
2013-12-22 01:34:59 -06:00
} else if ( name = = " if_comp " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( if_comp ) ) ;
2013-12-27 13:05:07 -06:00
newNode - > addChild ( new NodeTree < ASTData > ( " identifier " , ASTData ( identifier , Symbol ( concatSymbolTree ( children [ 0 ] ) , true ) ) ) ) ;
skipChildren . insert ( 0 ) ; //Don't do the identifier. The identifier lookup will fail. That's why we do it here.
2013-12-22 01:34:59 -06:00
} else if ( name = = " simple_passthrough " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( simple_passthrough ) ) ;
2013-10-26 11:47:34 -04:00
} else if ( name = = " function_call " ) {
2014-01-19 18:20:52 -05:00
std : : string functionCallName = concatSymbolTree ( children [ 0 ] ) ;
2013-10-26 15:05:42 -04:00
newNode = new NodeTree < ASTData > ( functionCallName , ASTData ( function_call , Symbol ( functionCallName , true ) ) ) ;
2014-03-06 13:13:40 -05:00
// if (function == NULL) {
// std::cout << "scope lookup error! Could not find " << functionCallName << " in function_call " << std::endl;
// throw "LOOKUP ERROR: " + functionCallName;
// }
skipChildren . insert ( 0 ) ;
2014-05-09 02:56:55 -04:00
std : : vector < NodeTree < ASTData > * > transformedChildren = transformChildren ( children , skipChildren , scope , types , templateTypeReplacements ) ;
2014-02-03 11:41:25 -05:00
std : : cout < < " scope lookup from function_call: " < < functionCallName < < std : : endl ;
for ( auto i : children )
std : : cout < < i < < " : " < < i - > getName ( ) < < " : " < < i - > getDataRef ( ) - > getName ( ) < < std : : endl ;
2014-03-06 13:13:40 -05:00
2014-05-09 02:56:55 -04:00
NodeTree < ASTData > * function = transform ( children [ 0 ] , scope , mapNodesToTypes ( transformedChildren ) , templateTypeReplacements ) ;
2014-02-03 11:41:25 -05:00
std : : cout < < " The thing: " < < function < < " : " < < function - > getName ( ) < < std : : endl ;
for ( auto i : function - > getChildren ( ) )
std : : cout < < i - > getName ( ) < < " " ;
std : : cout < < std : : endl ;
2013-12-27 13:05:07 -06:00
newNode - > addChild ( function ) ;
2014-02-18 21:55:00 -05:00
newNode - > getDataRef ( ) - > valueType = function - > getDataRef ( ) - > valueType ;
2014-03-06 13:13:40 -05:00
newNode - > addChildren ( transformedChildren ) ;
return newNode ;
2013-10-26 15:05:42 -04:00
} else if ( name = = " parameter " ) {
2014-05-09 02:56:55 -04:00
return transform ( children [ 0 ] , scope , types , templateTypeReplacements ) ; //Don't need a parameter node, just the value
2013-12-23 01:26:24 -06:00
} else if ( name = = " type " ) {
std : : string theConcat = concatSymbolTree ( from ) ; //We have no symbol, so this will concat our children
2014-05-09 02:56:55 -04:00
newNode = new NodeTree < ASTData > ( name , ASTData ( value , Symbol ( theConcat , true ) , typeFromTypeNode ( from , scope , templateTypeReplacements ) ) ) ;
2013-10-26 15:05:42 -04:00
} else if ( name = = " number " ) {
2014-05-09 02:56:55 -04:00
return transform ( children [ 0 ] , scope , types , templateTypeReplacements ) ;
2013-10-26 15:05:42 -04:00
} else if ( name = = " integer " ) {
2014-01-07 13:14:58 -05:00
newNode = new NodeTree < ASTData > ( name , ASTData ( value , Symbol ( concatSymbolTree ( from ) , true ) , new Type ( integer ) ) ) ;
2013-10-26 15:05:42 -04:00
} else if ( name = = " float " ) {
2014-01-07 13:14:58 -05:00
newNode = new NodeTree < ASTData > ( name , ASTData ( value , Symbol ( concatSymbolTree ( from ) , true ) , new Type ( floating ) ) ) ;
2013-10-26 15:05:42 -04:00
} else if ( name = = " double " ) {
2014-01-07 13:14:58 -05:00
newNode = new NodeTree < ASTData > ( name , ASTData ( value , Symbol ( concatSymbolTree ( from ) , true ) , new Type ( double_percision ) ) ) ;
2014-05-03 20:46:10 -04:00
} else if ( name = = " char " ) { //Is this correct? This might be a useless old thing
2014-01-07 13:14:58 -05:00
newNode = new NodeTree < ASTData > ( name , ASTData ( value , Symbol ( concatSymbolTree ( children [ 0 ] ) , true ) , new Type ( character , 1 ) ) ) ; //Indirection of 1 for array
2013-12-22 01:34:59 -06:00
} else if ( name = = " string " | | name = = " triple_quoted_string " ) {
2014-01-07 13:14:58 -05:00
newNode = new NodeTree < ASTData > ( name , ASTData ( value , Symbol ( concatSymbolTree ( children [ 0 ] ) , true ) , new Type ( character , 1 ) ) ) ; //Indirection of 1 for array
2014-05-03 20:46:10 -04:00
} else if ( name = = " character " ) {
newNode = new NodeTree < ASTData > ( name , ASTData ( value , Symbol ( concatSymbolTree ( children [ 0 ] ) , true ) , new Type ( character , 0 ) ) ) ; //Indirection of 0 for character
2013-10-16 01:43:18 -04:00
} else {
return new NodeTree < ASTData > ( ) ;
}
2014-03-06 13:13:40 -05:00
//Do all children but the ones we skip
2013-10-16 01:43:18 -04:00
for ( int i = 0 ; i < children . size ( ) ; i + + ) {
2013-10-26 11:47:34 -04:00
if ( skipChildren . find ( i ) = = skipChildren . end ( ) ) {
2014-05-09 02:56:55 -04:00
NodeTree < ASTData > * transChild = transform ( children [ i ] , scope , types , templateTypeReplacements ) ;
2013-12-27 13:05:07 -06:00
if ( transChild - > getDataRef ( ) - > type ) //Only add the children that have a real ASTData::ASTType, that is, legit ASTData.
2013-10-26 11:47:34 -04:00
newNode - > addChild ( transChild ) ;
else
delete transChild ;
}
2013-10-16 01:43:18 -04:00
}
return newNode ;
}
2014-03-06 13:13:40 -05:00
//We use this functionality a lot at different places
2014-05-09 02:56:55 -04:00
std : : vector < NodeTree < ASTData > * > ASTTransformation : : transformChildren ( std : : vector < NodeTree < Symbol > * > children , std : : set < int > skipChildren , NodeTree < ASTData > * scope , std : : vector < Type > types , std : : map < std : : string , Type * > templateTypeReplacements ) {
2014-03-06 13:13:40 -05:00
std : : vector < NodeTree < ASTData > * > transformedChildren ;
// In general, iterate through children and do them. Might not do this for all children.
for ( int i = 0 ; i < children . size ( ) ; i + + ) {
if ( skipChildren . find ( i ) = = skipChildren . end ( ) ) {
2014-05-09 02:56:55 -04:00
NodeTree < ASTData > * transChild = transform ( children [ i ] , scope , types , templateTypeReplacements ) ;
2014-03-06 13:13:40 -05:00
if ( transChild - > getDataRef ( ) - > type ) //Only add the children that have a real ASTData::ASTType, that is, legit ASTData.
transformedChildren . push_back ( transChild ) ;
else
delete transChild ;
}
}
return transformedChildren ;
}
2014-05-09 02:56:55 -04:00
//Extract types from already transformed nodes
2014-03-06 13:13:40 -05:00
std : : vector < Type > ASTTransformation : : mapNodesToTypes ( std : : vector < NodeTree < ASTData > * > nodes ) {
std : : vector < Type > types ;
2014-05-05 13:52:12 -04:00
for ( auto i : nodes ) {
std : : cout < < i - > getDataRef ( ) - > toString ( ) < < std : : endl ;
2014-03-06 13:13:40 -05:00
types . push_back ( * ( i - > getDataRef ( ) - > valueType ) ) ;
2014-05-05 13:52:12 -04:00
}
2014-03-06 13:13:40 -05:00
return types ;
}
2014-05-09 02:56:55 -04:00
//Simple way to extract strings from syntax trees. Used often for identifiers, strings, types
2013-10-16 01:43:18 -04:00
std : : string ASTTransformation : : concatSymbolTree ( NodeTree < Symbol > * root ) {
std : : string concatString ;
2013-12-27 13:05:07 -06:00
std : : string ourValue = root - > getDataRef ( ) - > getValue ( ) ;
2013-10-16 01:43:18 -04:00
if ( ourValue ! = " NoValue " )
concatString + = ourValue ;
std : : vector < NodeTree < Symbol > * > children = root - > getChildren ( ) ;
for ( int i = 0 ; i < children . size ( ) ; i + + ) {
2013-12-23 01:26:24 -06:00
concatString + = concatSymbolTree ( children [ i ] ) ;
2013-10-16 01:43:18 -04:00
}
return concatString ;
2013-09-26 15:16:58 -04:00
}
2013-12-27 13:05:07 -06:00
2014-05-09 02:56:55 -04:00
//We pass in the actual children (parameters) to allow us to handle overloaded operator methods (where a parameter is actually the scope of the method)
NodeTree < ASTData > * ASTTransformation : : doFunction ( NodeTree < ASTData > * scope , std : : string lookup , std : : vector < NodeTree < ASTData > * > nodes , std : : map < std : : string , Type * > templateTypeReplacements ) {
2014-03-14 15:55:45 -04:00
auto LLElementIterator = languageLevelScope . find ( lookup ) ;
2014-04-27 02:48:57 -04:00
NodeTree < ASTData > * newNode ;
2014-03-14 15:55:45 -04:00
if ( LLElementIterator ! = languageLevelScope . end ( ) ) {
std : : cout < < " Checking for early method level operator overload " < < std : : endl ;
std : : string lookupOp = " operator " + lookup ;
for ( auto i : nodes )
std : : cout < < i - > getDataRef ( ) - > toString ( ) < < " " ;
std : : cout < < std : : endl ;
NodeTree < ASTData > * operatorMethod = NULL ;
if ( nodes [ 0 ] - > getDataRef ( ) - > valueType & & nodes [ 0 ] - > getDataRef ( ) - > valueType - > typeDefinition )
operatorMethod = scopeLookup ( nodes [ 0 ] - > getDataRef ( ) - > valueType - > typeDefinition , lookupOp , mapNodesToTypes ( slice ( nodes , 1 , - 1 ) ) ) ;
if ( operatorMethod ) {
//Ok, so we construct
std : : cout < < " Early method level operator was found " < < std : : endl ;
//return operatorMethod;
2014-04-27 02:48:57 -04:00
NodeTree < ASTData > * newNode = new NodeTree < ASTData > ( lookupOp , ASTData ( function_call , Symbol ( lookupOp , true ) ) ) ;
NodeTree < ASTData > * dotFunctionCall = new NodeTree < ASTData > ( " . " , ASTData ( function_call , Symbol ( " . " , true ) ) ) ;
dotFunctionCall - > addChild ( languageLevelScope [ " . " ] [ 0 ] ) ; //function definition
dotFunctionCall - > addChild ( nodes [ 0 ] ) ; // The object whose method we're calling
dotFunctionCall - > addChild ( operatorMethod ) ; //The method we're calling
newNode - > addChild ( dotFunctionCall ) ; // First child of function call is a link to the function definition
newNode - > addChildren ( slice ( nodes , 1 , - 1 ) ) ; //The rest of the parameters to the operator
2014-03-14 15:55:45 -04:00
//Set the value of this function call
2014-04-27 02:48:57 -04:00
newNode - > getDataRef ( ) - > valueType = operatorMethod - > getDataRef ( ) - > valueType ;
return newNode ;
2014-03-14 15:55:45 -04:00
}
std : : cout < < " Early method level operator was NOT found " < < std : : endl ;
}
2014-04-27 02:48:57 -04:00
newNode = new NodeTree < ASTData > ( lookup , ASTData ( function_call , Symbol ( lookup , true ) ) ) ;
NodeTree < ASTData > * function = scopeLookup ( scope , lookup , mapNodesToTypes ( nodes ) ) ;
newNode - > addChild ( function ) ;
newNode - > addChildren ( nodes ) ;
2014-05-05 13:52:12 -04:00
//Specially handle dereference and address of to assign the correct type
//We need some significant other type corrections here, maybe to the point of being their own function. (int + float, etc.)
for ( auto i : nodes )
std : : cout < < i - > getDataRef ( ) - > toString ( ) < < " " ;
std : : cout < < std : : endl ;
std : : vector < Type > oldTypes = mapNodesToTypes ( nodes ) ;
2014-05-06 13:54:53 -04:00
if ( lookup = = " * " | | lookup = = " & " | | lookup = = " [] " ) {
2014-05-05 13:52:12 -04:00
Type * newType = oldTypes [ 0 ] . clone ( ) ;
2014-05-06 13:54:53 -04:00
lookup = = " * " | | lookup = = " [] " ? newType - > indirection - - : newType - > indirection + + ;
newNode - > getDataRef ( ) - > valueType = newType , std : : cout < < " Operator " + lookup < < " is altering indirection " < < std : : endl ;
2014-05-05 13:52:12 -04:00
} else {
newNode - > getDataRef ( ) - > valueType = function - > getDataRef ( ) - > valueType , std : : cout < < " Some other || " < < lookup < < " || " < < std : : endl ;
}
2014-04-27 02:48:57 -04:00
return newNode ;
2014-03-14 15:55:45 -04:00
}
2014-05-09 02:56:55 -04:00
//Search recursively through levels of scope (each ASTData, that is, every node, has its own scope)
//We pass in types so that if we're searching for a function we can find the right overloaded one
2014-03-06 13:13:40 -05:00
NodeTree < ASTData > * ASTTransformation : : scopeLookup ( NodeTree < ASTData > * scope , std : : string lookup , std : : vector < Type > types ) {
2014-03-14 15:55:45 -04:00
//We first search the languageLevelScope to see if it's an operator. If so, we modifiy the lookup with a preceding "operator"
auto LLElementIterator = languageLevelScope . find ( lookup ) ;
if ( LLElementIterator ! = languageLevelScope . end ( ) )
lookup = " operator " + lookup ;
2014-01-19 18:20:52 -05:00
//Search the map
2013-12-27 13:05:07 -06:00
auto scopeMap = scope - > getDataRef ( ) - > scope ;
auto elementIterator = scopeMap . find ( lookup ) ;
2014-03-14 15:55:45 -04:00
for ( auto i : scopeMap )
std : : cout < < i . first < < " " ;
std : : cout < < std : : endl ;
2014-03-06 13:13:40 -05:00
//
2013-12-27 13:05:07 -06:00
if ( elementIterator ! = scopeMap . end ( ) ) {
2014-03-06 13:13:40 -05:00
for ( auto i = elementIterator - > second . begin ( ) ; i ! = elementIterator - > second . end ( ) ; i + + ) {
//Types and functions cannot have the same name, and types very apparently do not have parameter types, so check and short-circuit
if ( ( * i ) - > getDataRef ( ) - > type = = type_def )
return * i ;
2014-05-09 02:56:55 -04:00
2014-03-06 13:13:40 -05:00
std : : vector < NodeTree < ASTData > * > children = ( * i ) - > getChildren ( ) ;
2014-03-14 15:55:45 -04:00
if ( types . size ( ) ! = ( ( children . size ( ) > 0 ) ? children . size ( ) - 1 : 0 ) ) {
2014-03-06 13:13:40 -05:00
std : : cout < < " Type sizes do not match between two " < < lookup < < " ( " < < types . size ( ) < < " , " < < ( ( children . size ( ) > 0 ) ? children . size ( ) - 1 : 0 ) < < " ), types are: " ;
for ( auto j : types )
std : : cout < < j . toString ( ) < < " " ;
std : : cout < < std : : endl ;
continue ;
}
bool typesMatch = true ;
for ( int j = 0 ; j < types . size ( ) ; j + + ) {
if ( types [ j ] ! = * ( children [ j ] - > getDataRef ( ) - > valueType ) ) {
typesMatch = false ;
2014-05-05 13:52:12 -04:00
std : : cout < < " Types do not match between two " < < lookup < < " " < < types [ j ] . toString ( ) < < " vs " < < children [ j ] - > getDataRef ( ) - > valueType - > toString ( ) < < std : : endl ;
2014-03-06 13:13:40 -05:00
break ;
}
}
if ( typesMatch )
return * i ;
}
2013-12-27 13:05:07 -06:00
}
2014-03-06 13:13:40 -05:00
2013-12-27 13:05:07 -06:00
//if it doesn't exist, try the enclosing scope if it exists.
auto enclosingIterator = scopeMap . find ( " ~enclosing_scope " ) ;
if ( enclosingIterator ! = scopeMap . end ( ) ) {
2013-12-28 21:54:22 -05:00
// std::cout << "upper scope exists, searching it for " << lookup << std::endl;
2014-03-14 15:55:45 -04:00
NodeTree < ASTData > * upperResult = scopeLookup ( enclosingIterator - > second [ 0 ] , lookup , types ) ;
if ( upperResult )
return upperResult ;
2013-12-27 13:05:07 -06:00
}
2013-12-28 21:54:22 -05:00
//std::cout << "upper scope does not exist" << std::endl;
2014-03-06 13:13:40 -05:00
std : : cout < < " could not find " < < lookup < < " in standard scope, checking for operator " < < std : : endl ;
//Note that we don't check for types. At some point we should, as we don't know how to add objects/structs without overloaded operators, etc
2014-03-14 15:55:45 -04:00
//Also, we've already searched for the element because this is also how we keep track of operator overloading
if ( LLElementIterator ! = languageLevelScope . end ( ) ) {
2014-03-06 13:13:40 -05:00
std : : cout < < " found it at language level as operator. " < < std : : endl ;
2014-03-14 15:55:45 -04:00
return LLElementIterator - > second [ 0 ] ;
2014-03-06 13:13:40 -05:00
}
2014-03-14 15:55:45 -04:00
std : : cout < < " Did not find, returning NULL " < < std : : endl ;
2013-12-27 13:05:07 -06:00
return NULL ;
}
2014-01-07 13:14:58 -05:00
2014-05-09 02:56:55 -04:00
//Create a type from a syntax tree. This can get complicated with templates
Type * ASTTransformation : : typeFromTypeNode ( NodeTree < Symbol > * typeNode , NodeTree < ASTData > * scope , std : : map < std : : string , Type * > templateTypeReplacements ) {
2014-05-07 02:33:04 -04:00
std : : string typeIn ;
2014-05-09 02:56:55 -04:00
typeIn = concatSymbolTree ( typeNode ) ;
2014-05-07 02:33:04 -04:00
2014-01-07 13:14:58 -05:00
int indirection = 0 ;
ValueType baseType ;
NodeTree < ASTData > * typeDefinition = NULL ;
while ( typeIn [ typeIn . size ( ) - indirection - 1 ] = = ' * ' ) indirection + + ;
std : : string edited = strSlice ( typeIn , 0 , - ( indirection + 1 ) ) ;
if ( edited = = " void " )
baseType = void_type ;
else if ( edited = = " bool " )
baseType = boolean ;
else if ( edited = = " int " )
baseType = integer ;
else if ( edited = = " float " )
2014-05-07 02:33:04 -04:00
baseType = floating ;
else if ( edited = = " double " )
2014-01-07 13:14:58 -05:00
baseType = double_percision ;
else if ( edited = = " char " )
baseType = character ;
else {
baseType = none ;
typeDefinition = scopeLookup ( scope , edited ) ;
2014-05-09 02:56:55 -04:00
//So, if this is a template class type and it has already been instantiated, then the above scope lookup will take care of it.
//So either this is an uninstatiated template class type, or this is literally a template type T, and we should get it from our
//templateTypeReplacements map. We try this first
if ( templateTypeReplacements . find ( edited ) ! = templateTypeReplacements . end ( ) ) {
std : : cout < < " Template type T! ( " < < edited < < " ) " < < std : : endl ;
Type * templateTypeReplacement = templateTypeReplacements [ edited ] - > clone ( ) ;
templateTypeReplacement - > indirection + = indirection ;
return templateTypeReplacement ;
}
//If not, we better instantiate it and then add it to the scope
//Note that this means the template instantiation is scoped, which is inefficient, though it has a nice correctness about it
if ( typeDefinition = = NULL & & typeNode - > getChildren ( ) . size ( ) > 1 & & typeNode - > getChildren ( ) [ 1 ] - > getData ( ) . getName ( ) = = " template_inst " ) {
std : : cout < < " Template type: " < < edited < < " not yet instantiated " < < std : : endl ;
//Look up this template's plain definition. It's type has the syntax tree that we need to parse
NodeTree < ASTData > * templateDefinition = scopeLookup ( scope , concatSymbolTree ( typeNode - > getChildren ( ) [ 0 ] ) ) ;
if ( templateDefinition = = NULL )
std : : cout < < " Template definition is null! " < < std : : endl ;
else
std : : cout < < " Template definition is not null! " < < std : : endl ;
NodeTree < Symbol > * templateSyntaxTree = templateDefinition - > getDataRef ( ) - > valueType - > templateDefinition ;
//Create a new map of template type names to actual types.
std : : map < std : : string , Type * > newTemplateTypeReplacement ;
std : : string templateParameterName = concatSymbolTree ( templateSyntaxTree - > getChildren ( ) [ 0 ] - > getChildren ( ) [ 1 ] ) ;
Type * replacementType = typeFromTypeNode ( typeNode - > getChildren ( ) [ 1 ] - > getChildren ( ) [ 1 ] , scope , templateTypeReplacements ) ;
newTemplateTypeReplacement [ templateParameterName ] = replacementType ;
std : : string classNameWithoutTemplate = concatSymbolTree ( typeNode - > getChildren ( ) [ 0 ] ) ;
std : : string fullyInstantiatedName = classNameWithoutTemplate + " < " + replacementType - > toString ( ) + " > " ;
typeDefinition = new NodeTree < ASTData > ( " type_def " , ASTData ( type_def , Symbol ( fullyInstantiatedName , true , fullyInstantiatedName ) ) ) ;
typeDefinition - > getDataRef ( ) - > valueType = new Type ( typeDefinition ) ; ; //Type is self-referential since this is the definition
scope - > getDataRef ( ) - > scope [ fullyInstantiatedName ] . push_back ( typeDefinition ) ;
//Note that the instantiated template's scope is the template's definition.
typeDefinition - > getDataRef ( ) - > scope [ " ~enclosing_scope " ] . push_back ( templateDefinition ) ;
std : : set < int > skipChildren ;
skipChildren . insert ( 0 ) ; //Don't do the template part
skipChildren . insert ( 1 ) ; //Identifier lookup will be ourselves, as we just added ourselves to the scope
typeDefinition - > addChildren ( transformChildren ( templateSyntaxTree - > getChildren ( ) , skipChildren , typeDefinition , std : : vector < Type > ( ) , newTemplateTypeReplacement ) ) ;
std : : cout < < " Done instantating " < < fullyInstantiatedName < < " that had template parameter " < < templateParameterName < < " with " < < replacementType - > toString ( ) < < std : : endl ;
} else {
std : : cout < < " Type: " < < edited < < " already instantiated! " < < std : : endl ;
}
2014-01-07 13:14:58 -05:00
}
2014-05-09 02:56:55 -04:00
Type * toReturn = new Type ( baseType , typeDefinition , indirection ) ;
std : : cout < < " Returning type " < < toReturn - > toString ( ) < < std : : endl ;
return toReturn ;
2014-01-07 13:14:58 -05:00
}