Fixed quite a few bugs, including makeing find template functions check for trait subset, not trait equality, and add the number required to the satisfied count. Based on what is now breaking, it looks like it's time to give the builtin functions types.
This commit is contained in:
@@ -34,21 +34,21 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
|
|||||||
|
|
||||||
//The fourth pass finishes up by doing all function bodies
|
//The fourth pass finishes up by doing all function bodies
|
||||||
void fourthPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* parseTree);
|
void fourthPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* parseTree);
|
||||||
NodeTree<ASTData>* seachScopeForFunctionDef(NodeTree<ASTData>* scope, NodeTree<Symbol>* parseTree, std::map<std::string, Type*> templateTypeReplacements);
|
NodeTree<ASTData>* searchScopeForFunctionDef(NodeTree<ASTData>* scope, NodeTree<Symbol>* parseTree, std::map<std::string, Type*> templateTypeReplacements);
|
||||||
void fourthPassFunction(NodeTree<Symbol>* from, NodeTree<ASTData>* functionDef, std::map<std::string, Type*> templateTypeReplacements);
|
void fourthPassFunction(NodeTree<Symbol>* from, NodeTree<ASTData>* functionDef, std::map<std::string, Type*> templateTypeReplacements);
|
||||||
|
|
||||||
virtual NodeTree<ASTData>* transform(NodeTree<Symbol>* from);
|
virtual NodeTree<ASTData>* transform(NodeTree<Symbol>* from);
|
||||||
NodeTree<ASTData>* transform(NodeTree<Symbol>* from, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements, bool instantiateTemplates);
|
NodeTree<ASTData>* transform(NodeTree<Symbol>* from, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements);
|
||||||
std::vector<NodeTree<ASTData>*> transformChildren(std::vector<NodeTree<Symbol>*> children, std::set<int> skipChildren, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements, bool instantiateTemplates);
|
std::vector<NodeTree<ASTData>*> transformChildren(std::vector<NodeTree<Symbol>*> children, std::set<int> skipChildren, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements);
|
||||||
std::vector<Type> mapNodesToTypes(std::vector<NodeTree<ASTData>*> nodes);
|
std::vector<Type> mapNodesToTypes(std::vector<NodeTree<ASTData>*> nodes);
|
||||||
std::string concatSymbolTree(NodeTree<Symbol>* root);
|
std::string concatSymbolTree(NodeTree<Symbol>* root);
|
||||||
NodeTree<ASTData>* doFunction(NodeTree<ASTData>* scope, std::string lookup, std::vector<NodeTree<ASTData>*> nodes, std::map<std::string, Type*> templateTypeReplacements);
|
NodeTree<ASTData>* doFunction(NodeTree<ASTData>* scope, std::string lookup, std::vector<NodeTree<ASTData>*> nodes, std::map<std::string, Type*> templateTypeReplacements);
|
||||||
|
|
||||||
NodeTree<ASTData>* functionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types);
|
NodeTree<ASTData>* functionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types);
|
||||||
NodeTree<ASTData>* templateFunctionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type*> templateInstantiationTypes, std::vector<Type> types);
|
NodeTree<ASTData>* templateFunctionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type*> templateInstantiationTypes, std::vector<Type> types);
|
||||||
std::vector<NodeTree<ASTData>*> scopeLookup(NodeTree<ASTData>* scope, std::string lookup);
|
std::vector<NodeTree<ASTData>*> scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules = false);
|
||||||
|
|
||||||
Type* typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<ASTData>* scope, std::map<std::string, Type*> templateTypeReplacements, bool instantiateTemplates);
|
Type* typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<ASTData>* scope, std::map<std::string, Type*> templateTypeReplacements);
|
||||||
NodeTree<ASTData>* templateClassLookup(NodeTree<ASTData>* scope, std::string name, std::vector<Type*> templateInstantiationTypes);
|
NodeTree<ASTData>* templateClassLookup(NodeTree<ASTData>* scope, std::string name, std::vector<Type*> templateInstantiationTypes);
|
||||||
NodeTree<ASTData>* findOrInstantiateFunctionTemplate(std::vector<NodeTree<Symbol>*> children, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements);
|
NodeTree<ASTData>* findOrInstantiateFunctionTemplate(std::vector<NodeTree<Symbol>*> children, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements);
|
||||||
std::map<std::string, Type*> makeTemplateFunctionTypeMap(NodeTree<Symbol>* templateNode, std::vector<Type*> types);
|
std::map<std::string, Type*> makeTemplateFunctionTypeMap(NodeTree<Symbol>* templateNode, std::vector<Type*> types);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@@ -40,6 +41,14 @@ std::vector<T> slice(std::vector<T> vec, int begin, int end, int step = 1) {
|
|||||||
toReturn.push_back(vec[i]);
|
toReturn.push_back(vec[i]);
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool subset(std::set<T> a, std::set<T> b) {
|
||||||
|
for (auto i : a)
|
||||||
|
if (b.find(i) == b.end())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
std::vector<std::string> split(std::string str, char delim) {
|
std::vector<std::string> split(std::string str, char delim) {
|
||||||
std::stringstream stream(str);
|
std::stringstream stream(str);
|
||||||
|
|||||||
+1
-1
@@ -79,7 +79,7 @@ function_call = unarad "\(" WS opt_parameter_list WS "\)" ;
|
|||||||
|
|
||||||
boolean_expression = boolean_expression WS "\|\|" WS and_boolean_expression | and_boolean_expression ;
|
boolean_expression = boolean_expression WS "\|\|" WS and_boolean_expression | and_boolean_expression ;
|
||||||
and_boolean_expression = and_boolean_expression "&&" bool_exp | bool_exp ;
|
and_boolean_expression = and_boolean_expression "&&" bool_exp | bool_exp ;
|
||||||
bool_exp = expression WS comparator WS expression | bool | expression ;
|
bool_exp = expression WS comparator WS expression | expression ;
|
||||||
comparator = "==" | "<=" | ">=" | "!=" | "<" | ">" ;
|
comparator = "==" | "<=" | ">=" | "!=" | "<" | ">" ;
|
||||||
|
|
||||||
expression = expression WS "<<" WS term | expression WS right_shift WS shiftand | shiftand ;
|
expression = expression WS "<<" WS term | expression WS right_shift WS shiftand | shiftand ;
|
||||||
|
|||||||
+133
-91
@@ -118,7 +118,7 @@ void ASTTransformation::secondPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
|
|||||||
|
|
||||||
//It's an alias. Note that if typedefChildren.size() == 1 it's because its a regular class with no body, i.e. {}
|
//It's an alias. Note that if typedefChildren.size() == 1 it's because its a regular class with no body, i.e. {}
|
||||||
if (typedefChildren.size() > 1 && typedefChildren[1]->getData().getName() == "type") {
|
if (typedefChildren.size() > 1 && typedefChildren[1]->getData().getName() == "type") {
|
||||||
Type* aliasedType = typeFromTypeNode(typedefChildren[1], ast, std::map<std::string, Type*>(), false); //false - don't fully instantiate templates
|
Type* aliasedType = typeFromTypeNode(typedefChildren[1], ast, std::map<std::string, Type*>());
|
||||||
typeDef->getDataRef()->valueType = aliasedType;
|
typeDef->getDataRef()->valueType = aliasedType;
|
||||||
typeDef->getDataRef()->scope["~enclosing_scope"][0] = aliasedType->typeDefinition; //So that object lookups find the right member. Note that this overrides translation_unit as a parent scope
|
typeDef->getDataRef()->scope["~enclosing_scope"][0] = aliasedType->typeDefinition; //So that object lookups find the right member. Note that this overrides translation_unit as a parent scope
|
||||||
// std::cout << name << " alias's to " << aliasedType->typeDefinition << std::endl;
|
// std::cout << name << " alias's to " << aliasedType->typeDefinition << std::endl;
|
||||||
@@ -155,7 +155,7 @@ NodeTree<ASTData>* ASTTransformation::secondPassDeclaration(NodeTree<Symbol>* fr
|
|||||||
//Check here for method call (an error here)
|
//Check here for method call (an error here)
|
||||||
NodeTree<ASTData>* decStmt = new NodeTree<ASTData>("declaration_statement", ASTData(declaration_statement));
|
NodeTree<ASTData>* decStmt = new NodeTree<ASTData>("declaration_statement", ASTData(declaration_statement));
|
||||||
std::string newIdentifierStr = concatSymbolTree(from->getChildren()[1]);
|
std::string newIdentifierStr = concatSymbolTree(from->getChildren()[1]);
|
||||||
Type* identifierType = typeFromTypeNode(from->getChildren()[0], scope, templateTypeReplacements, false);
|
Type* identifierType = typeFromTypeNode(from->getChildren()[0], scope, templateTypeReplacements);
|
||||||
std::cout << "Declaring an identifier " << newIdentifierStr << " to be of type " << identifierType->toString() << std::endl;
|
std::cout << "Declaring an identifier " << newIdentifierStr << " to be of type " << identifierType->toString() << std::endl;
|
||||||
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), identifierType));
|
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), identifierType));
|
||||||
scope->getDataRef()->scope[newIdentifierStr].push_back(newIdentifier);
|
scope->getDataRef()->scope[newIdentifierStr].push_back(newIdentifier);
|
||||||
@@ -184,7 +184,7 @@ NodeTree<ASTData>* ASTTransformation::secondPassFunction(NodeTree<Symbol>* from,
|
|||||||
else //has traits
|
else //has traits
|
||||||
yetToBeInstantiatedTemplateTypes[concatSymbolTree(i->getChildren()[0])] = new Type(template_type_type, parseTraits(i->getChildren()[1])); //This may have to be combined with templateTypeReplacements if we do templated member functions inside of templated classes
|
yetToBeInstantiatedTemplateTypes[concatSymbolTree(i->getChildren()[0])] = new Type(template_type_type, parseTraits(i->getChildren()[1])); //This may have to be combined with templateTypeReplacements if we do templated member functions inside of templated classes
|
||||||
}
|
}
|
||||||
auto transChildren = transformChildren(slice(children,3,-2), std::set<int>(), functionDef, std::vector<Type>(), yetToBeInstantiatedTemplateTypes, false);
|
auto transChildren = transformChildren(slice(children,3,-2), std::set<int>(), functionDef, std::vector<Type>(), yetToBeInstantiatedTemplateTypes);
|
||||||
std::cout << "Template function " << functionName << " has these parameters: ";
|
std::cout << "Template function " << functionName << " has these parameters: ";
|
||||||
for (auto i : transChildren)
|
for (auto i : transChildren)
|
||||||
std::cout << "||" << i->getDataRef()->toString() << "|| ";
|
std::cout << "||" << i->getDataRef()->toString() << "|| ";
|
||||||
@@ -195,11 +195,11 @@ NodeTree<ASTData>* ASTTransformation::secondPassFunction(NodeTree<Symbol>* from,
|
|||||||
return functionDef;
|
return functionDef;
|
||||||
}
|
}
|
||||||
functionName = concatSymbolTree(children[1]);
|
functionName = concatSymbolTree(children[1]);
|
||||||
functionDef = new NodeTree<ASTData>("function", ASTData(function, Symbol(functionName, true), typeFromTypeNode(children[0], scope, templateTypeReplacements, false)));
|
functionDef = new NodeTree<ASTData>("function", ASTData(function, Symbol(functionName, true), typeFromTypeNode(children[0], scope, templateTypeReplacements)));
|
||||||
scope->getDataRef()->scope[functionName].push_back(functionDef);
|
scope->getDataRef()->scope[functionName].push_back(functionDef);
|
||||||
functionDef->getDataRef()->scope["~enclosing_scope"].push_back(scope);
|
functionDef->getDataRef()->scope["~enclosing_scope"].push_back(scope);
|
||||||
//We only do the parameter nodes. We don't do the body yet, as this is the secondPass
|
//We only do the parameter nodes. We don't do the body yet, as this is the secondPass
|
||||||
auto transChildren = transformChildren(slice(children,2,-2), std::set<int>(), functionDef, std::vector<Type>(), templateTypeReplacements, false);
|
auto transChildren = transformChildren(slice(children,2,-2), std::set<int>(), functionDef, std::vector<Type>(), templateTypeReplacements);
|
||||||
|
|
||||||
// std::cout << "REGULAR function " << functionName << " has " << transChildren.size() << " parameters: ";
|
// std::cout << "REGULAR function " << functionName << " has " << transChildren.size() << " parameters: ";
|
||||||
// for (auto i : transChildren)
|
// for (auto i : transChildren)
|
||||||
@@ -240,22 +240,6 @@ void ASTTransformation::fourthPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
|
|||||||
topScope = ast; //Top scope is maintained for templates, which need to add themselves to the top scope from where ever they are instantiated
|
topScope = ast; //Top scope is maintained for templates, which need to add themselves to the top scope from where ever they are instantiated
|
||||||
std::vector<NodeTree<Symbol>*> children = parseTree->getChildren();
|
std::vector<NodeTree<Symbol>*> children = parseTree->getChildren();
|
||||||
|
|
||||||
//First copy unfinished class templates into a new list and do them before anything else, so we know exactly which ones we need to do.
|
|
||||||
std::vector<NodeTree<ASTData>*> classTemplates;
|
|
||||||
for (auto i : ast->getDataRef()->scope) {
|
|
||||||
if (i.second[0]->getDataRef()->type == type_def && i.second[0]->getDataRef()->valueType->templateTypeReplacement.size()) {
|
|
||||||
classTemplates.push_back(i.second[0]);
|
|
||||||
std::cout << "Saving " << i.second[0]->getDataRef()->toString() << " to instantiate." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto i : classTemplates) {
|
|
||||||
Type* classTemplateType = i->getDataRef()->valueType;
|
|
||||||
std::cout << "Instantiating template " << i->getDataRef()->toString() << std::endl;
|
|
||||||
for (NodeTree<Symbol>* j : classTemplateType->templateDefinition->getChildren())
|
|
||||||
if (j->getDataRef()->getName() == "function")
|
|
||||||
fourthPassFunction(j, seachScopeForFunctionDef(i, j, classTemplateType->templateTypeReplacement), classTemplateType->templateTypeReplacement); //do member method
|
|
||||||
}
|
|
||||||
|
|
||||||
//Go through and finish both regular functions and class methods
|
//Go through and finish both regular functions and class methods
|
||||||
//Note that this pass can instantiate class AND function templates
|
//Note that this pass can instantiate class AND function templates
|
||||||
for (NodeTree<Symbol>* i : children) {
|
for (NodeTree<Symbol>* i : children) {
|
||||||
@@ -273,20 +257,44 @@ void ASTTransformation::fourthPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
|
|||||||
//Do the inside of classes here
|
//Do the inside of classes here
|
||||||
for (NodeTree<Symbol>* j : typedefChildren) {
|
for (NodeTree<Symbol>* j : typedefChildren) {
|
||||||
if (j->getDataRef()->getName() == "function") {
|
if (j->getDataRef()->getName() == "function") {
|
||||||
fourthPassFunction(j, seachScopeForFunctionDef(typeDef, j, std::map<std::string, Type*>()), std::map<std::string, Type*>()); //do member method
|
fourthPassFunction(j, searchScopeForFunctionDef(typeDef, j, std::map<std::string, Type*>()), std::map<std::string, Type*>()); //do member method
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (i->getDataRef()->getName() == "function") {
|
} else if (i->getDataRef()->getName() == "function") {
|
||||||
//Do prototypes of functions
|
//Do prototypes of functions
|
||||||
if (i->getChildren()[0]->getData().getName() == "template_dec")
|
if (i->getChildren()[0]->getData().getName() == "template_dec")
|
||||||
continue; //We've already set up function templates
|
continue; //We've already set up function templates
|
||||||
fourthPassFunction(i, seachScopeForFunctionDef(ast, i, std::map<std::string, Type*>()), std::map<std::string, Type*>());
|
fourthPassFunction(i, searchScopeForFunctionDef(ast, i, std::map<std::string, Type*>()), std::map<std::string, Type*>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We do these here, in a loop, so that we can do mututally recursive definitions
|
||||||
|
// even inside of class templates. As its methods may cause partial instantiation of
|
||||||
|
// other class templates, we need to do this until the size no longer changes.
|
||||||
|
std::vector<NodeTree<ASTData>*> classTemplates;
|
||||||
|
int lastSize = 0;
|
||||||
|
while (lastSize != ast->getDataRef()->scope.size()) {
|
||||||
|
lastSize = ast->getDataRef()->scope.size();
|
||||||
|
classTemplates.clear();
|
||||||
|
for (auto i : ast->getDataRef()->scope) {
|
||||||
|
if (i.second[0]->getDataRef()->type == type_def && i.second[0]->getDataRef()->valueType->templateTypeReplacement.size()) {
|
||||||
|
classTemplates.push_back(i.second[0]);
|
||||||
|
std::cout << "Saving " << i.second[0]->getDataRef()->toString() << " to instantiate." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto i : classTemplates) {
|
||||||
|
Type* classTemplateType = i->getDataRef()->valueType;
|
||||||
|
std::cout << "Instantiating template " << i->getDataRef()->toString() << std::endl;
|
||||||
|
for (NodeTree<Symbol>* j : classTemplateType->templateDefinition->getChildren())
|
||||||
|
if (j->getDataRef()->getName() == "function")
|
||||||
|
fourthPassFunction(j, searchScopeForFunctionDef(i, j, classTemplateType->templateTypeReplacement), classTemplateType->templateTypeReplacement); //do member method
|
||||||
|
classTemplateType->templateTypeReplacement.clear(); // This template has been fully instantiated, clear it's map so it won't be instantiated again
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//This function finds the right AST definition in a scope given its parseTree
|
//This function finds the right AST definition in a scope given its parseTree
|
||||||
NodeTree<ASTData>* ASTTransformation::seachScopeForFunctionDef(NodeTree<ASTData>* scope, NodeTree<Symbol>* parseTree, std::map<std::string, Type*> templateTypeReplacements) {
|
NodeTree<ASTData>* ASTTransformation::searchScopeForFunctionDef(NodeTree<ASTData>* scope, NodeTree<Symbol>* parseTree, std::map<std::string, Type*> templateTypeReplacements) {
|
||||||
std::string functionName = concatSymbolTree(parseTree->getChildren()[1]);
|
std::string functionName = concatSymbolTree(parseTree->getChildren()[1]);
|
||||||
std::vector<Type> types;
|
std::vector<Type> types;
|
||||||
std::vector<NodeTree<Symbol>*> children = parseTree->getChildren();
|
std::vector<NodeTree<Symbol>*> children = parseTree->getChildren();
|
||||||
@@ -294,11 +302,11 @@ NodeTree<ASTData>* ASTTransformation::seachScopeForFunctionDef(NodeTree<ASTData>
|
|||||||
std::cout << "\n Searching scope for function def, function is :" << concatSymbolTree(children[1]) << ", children size is " << children.size() << std::endl;
|
std::cout << "\n Searching scope for function def, function is :" << concatSymbolTree(children[1]) << ", children size is " << children.size() << std::endl;
|
||||||
for (int i = 2; i < children.size()-1; i+=2) { //Skip over commas
|
for (int i = 2; i < children.size()-1; i+=2) { //Skip over commas
|
||||||
std::cout << "Making type for lookup ||" << concatSymbolTree(children[i]) << "||" << std::endl;
|
std::cout << "Making type for lookup ||" << concatSymbolTree(children[i]) << "||" << std::endl;
|
||||||
Type type = *typeFromTypeNode(children[i]->getChildren()[0], scope, templateTypeReplacements, true);
|
Type type = *typeFromTypeNode(children[i]->getChildren()[0], scope, templateTypeReplacements);
|
||||||
std::cout << "Type made: " << type.toString() << std::endl;
|
std::cout << "Type made: " << type.toString() << std::endl;
|
||||||
types.push_back(type);
|
types.push_back(type);
|
||||||
}
|
}
|
||||||
std::cout << "About to seach scope about " << concatSymbolTree(children[1]) << std::endl;
|
std::cout << "About to search scope about " << concatSymbolTree(children[1]) << std::endl;
|
||||||
NodeTree<ASTData>* result = functionLookup(scope, functionName, types);
|
NodeTree<ASTData>* result = functionLookup(scope, functionName, types);
|
||||||
std::cout << "Done searching scope about " << concatSymbolTree(children[1]) << std::endl;
|
std::cout << "Done searching scope about " << concatSymbolTree(children[1]) << std::endl;
|
||||||
return result;
|
return result;
|
||||||
@@ -309,15 +317,15 @@ NodeTree<ASTData>* ASTTransformation::seachScopeForFunctionDef(NodeTree<ASTData>
|
|||||||
//Note that it may instantiate class OR function templates, which need to be fully instantiated
|
//Note that it may instantiate class OR function templates, which need to be fully instantiated
|
||||||
void ASTTransformation::fourthPassFunction(NodeTree<Symbol>* from, NodeTree<ASTData>* functionDef, std::map<std::string, Type*> templateTypeReplacements) {
|
void ASTTransformation::fourthPassFunction(NodeTree<Symbol>* from, NodeTree<ASTData>* functionDef, std::map<std::string, Type*> templateTypeReplacements) {
|
||||||
NodeTree<Symbol>* codeBlock = from->getChildren()[from->getChildren().size()-1];
|
NodeTree<Symbol>* codeBlock = from->getChildren()[from->getChildren().size()-1];
|
||||||
functionDef->addChild(transform(codeBlock, functionDef, std::vector<Type>(), templateTypeReplacements, true));
|
functionDef->addChild(transform(codeBlock, functionDef, std::vector<Type>(), templateTypeReplacements));
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
|
NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
|
||||||
//Set up top scope
|
//Set up top scope
|
||||||
return transform(from, NULL, std::vector<Type>(), std::map<std::string, Type*>(), false);
|
return transform(from, NULL, std::vector<Type>(), std::map<std::string, Type*>());
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements, bool instantiateTemplates) {
|
NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements) {
|
||||||
Symbol current = from->getData();
|
Symbol current = from->getData();
|
||||||
std::string name = current.getName();
|
std::string name = current.getName();
|
||||||
NodeTree<ASTData>* newNode = NULL;
|
NodeTree<ASTData>* newNode = NULL;
|
||||||
@@ -351,8 +359,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
newNode = scope->getDataRef()->scope[typeAlias][0]; //The node for this type_def has already been made by translation_unit.
|
newNode = scope->getDataRef()->scope[typeAlias][0]; //The node for this type_def has already been made by translation_unit.
|
||||||
//This is done so that types that reference each other can be declared in any order
|
//This is done so that types that reference each other can be declared in any order
|
||||||
|
|
||||||
//newNode = new NodeTree<ASTData>(name, ASTData(type_def, Symbol(typeAlias, true, typeAlias), typeFromTypeNode(children[1], scope, templateTypeReplacements)));
|
newNode->getDataRef()->valueType = typeFromTypeNode(children[1], scope, templateTypeReplacements);
|
||||||
newNode->getDataRef()->valueType = typeFromTypeNode(children[1], scope, templateTypeReplacements, instantiateTemplates);
|
|
||||||
skipChildren.insert(0); //Don't want any children, it's unnecessary for ailising
|
skipChildren.insert(0); //Don't want any children, it's unnecessary for ailising
|
||||||
skipChildren.insert(1);
|
skipChildren.insert(1);
|
||||||
} else { //Is a struct or class
|
} else { //Is a struct or class
|
||||||
@@ -364,7 +371,6 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
//This is done so that types that reference each other can be declared in any order
|
//This is done so that types that reference each other can be declared in any order
|
||||||
// std::cout << "typeAlias is " << typeAlias << " and newNode is " << newNode << std::endl;
|
// std::cout << "typeAlias is " << typeAlias << " and newNode is " << newNode << std::endl;
|
||||||
|
|
||||||
//newNode = new NodeTree<ASTData>(name, ASTData(type_def, Symbol(typeAlias, true, typeAlias)));
|
|
||||||
//So we give this typedef its name without any template types and make its type template_type, and point to this from node.
|
//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.
|
//Then, when this template is instantiated, it will run transform on from with the types filled in.
|
||||||
objectType = new Type(template_type, from);
|
objectType = new Type(template_type, from);
|
||||||
@@ -374,7 +380,6 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
newNode = scope->getDataRef()->scope[typeAlias][0]; //The node for this type_def has already been made by translation_unit.
|
newNode = scope->getDataRef()->scope[typeAlias][0]; //The node for this type_def has already been made by translation_unit.
|
||||||
//This is done so that types that reference each other can be declared in any order
|
//This is done so that types that reference each other can be declared in any order
|
||||||
|
|
||||||
//newNode = new NodeTree<ASTData>(name, ASTData(type_def, Symbol(typeAlias, true, typeAlias)));
|
|
||||||
objectType = new Type(newNode);
|
objectType = new Type(newNode);
|
||||||
skipChildren.insert(0); //Identifier lookup will be ourselves, as we just added ourselves to the scope
|
skipChildren.insert(0); //Identifier lookup will be ourselves, as we just added ourselves to the scope
|
||||||
}
|
}
|
||||||
@@ -400,7 +405,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
for (auto i : slice(children[0]->getChildren(), 1, -1, 2)) //skip commas
|
for (auto i : slice(children[0]->getChildren(), 1, -1, 2)) //skip commas
|
||||||
yetToBeInstantiatedTemplateTypes[concatSymbolTree(i)] = new Type(template_type_type); //This may have to be combined with templateTypeReplacements if we do templated member functions inside of templated classes
|
yetToBeInstantiatedTemplateTypes[concatSymbolTree(i)] = new Type(template_type_type); //This may have to be combined with templateTypeReplacements if we do templated member functions inside of templated classes
|
||||||
|
|
||||||
auto transChildren = transformChildren(slice(children,3,-2), std::set<int>(), newNode, types, yetToBeInstantiatedTemplateTypes, instantiateTemplates);
|
auto transChildren = transformChildren(slice(children,3,-2), std::set<int>(), newNode, types, yetToBeInstantiatedTemplateTypes);
|
||||||
std::cout << "Template function " << functionName << " has these parameters: ";
|
std::cout << "Template function " << functionName << " has these parameters: ";
|
||||||
for (auto i : transChildren)
|
for (auto i : transChildren)
|
||||||
std::cout << "||" << i->getDataRef()->toString() << "|| ";
|
std::cout << "||" << i->getDataRef()->toString() << "|| ";
|
||||||
@@ -411,7 +416,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
functionName = concatSymbolTree(children[1]);
|
functionName = concatSymbolTree(children[1]);
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(function, Symbol(functionName, true), typeFromTypeNode(children[0], scope, templateTypeReplacements, instantiateTemplates)));
|
newNode = new NodeTree<ASTData>(name, ASTData(function, Symbol(functionName, true), typeFromTypeNode(children[0], scope, templateTypeReplacements)));
|
||||||
skipChildren.insert(0);
|
skipChildren.insert(0);
|
||||||
skipChildren.insert(1);
|
skipChildren.insert(1);
|
||||||
scope->getDataRef()->scope[functionName].push_back(newNode);
|
scope->getDataRef()->scope[functionName].push_back(newNode);
|
||||||
@@ -436,7 +441,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
std::string parameterName = concatSymbolTree(children[1]);
|
std::string parameterName = concatSymbolTree(children[1]);
|
||||||
std::cout << "Doing typed parameter " << parameterName << std::endl;
|
std::cout << "Doing typed parameter " << parameterName << std::endl;
|
||||||
//std::string typeString = concatSymbolTree(children[0]);//Get the type (left child) and set our new identifer to be that type
|
//std::string typeString = concatSymbolTree(children[0]);//Get the type (left child) and set our new identifer to be that type
|
||||||
newNode = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(parameterName, true), typeFromTypeNode(children[0], scope, templateTypeReplacements, instantiateTemplates)));
|
newNode = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(parameterName, true), typeFromTypeNode(children[0], scope, templateTypeReplacements)));
|
||||||
scope->getDataRef()->scope[parameterName].push_back(newNode);
|
scope->getDataRef()->scope[parameterName].push_back(newNode);
|
||||||
newNode->getDataRef()->scope["~enclosing_scope"].push_back(scope);
|
newNode->getDataRef()->scope["~enclosing_scope"].push_back(scope);
|
||||||
std::cout << "Done doing typed_parameter " << parameterName << std::endl;
|
std::cout << "Done doing typed_parameter " << parameterName << std::endl;
|
||||||
@@ -446,7 +451,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
if (children.size() > 1) {
|
if (children.size() > 1) {
|
||||||
//We do children first so we can do appropriate scope searching with types (yay operator overloading!)
|
//We do children first so we can do appropriate scope searching with types (yay operator overloading!)
|
||||||
skipChildren.insert(1);
|
skipChildren.insert(1);
|
||||||
std::vector<NodeTree<ASTData>*> transformedChildren = transformChildren(children, skipChildren, scope, types, templateTypeReplacements, instantiateTemplates);
|
std::vector<NodeTree<ASTData>*> transformedChildren = transformChildren(children, skipChildren, scope, types, templateTypeReplacements);
|
||||||
std::string functionCallString = concatSymbolTree(children[1]);
|
std::string functionCallString = concatSymbolTree(children[1]);
|
||||||
NodeTree<ASTData>* function = doFunction(scope, functionCallString, transformedChildren, templateTypeReplacements);
|
NodeTree<ASTData>* function = doFunction(scope, functionCallString, transformedChildren, templateTypeReplacements);
|
||||||
if (function == NULL) {
|
if (function == NULL) {
|
||||||
@@ -461,20 +466,20 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
//std::cout << children.size() << std::endl;
|
//std::cout << children.size() << std::endl;
|
||||||
if (children.size() == 0)
|
if (children.size() == 0)
|
||||||
return new NodeTree<ASTData>();
|
return new NodeTree<ASTData>();
|
||||||
return transform(children[0], scope, types, templateTypeReplacements, instantiateTemplates); //Just a promoted term, so do child
|
return transform(children[0], scope, types, templateTypeReplacements); //Just a promoted term, so do child
|
||||||
}
|
}
|
||||||
//Here's the order of ops stuff
|
//Here's the order of ops stuff
|
||||||
} else if (name == "expression" || name == "shiftand" || name == "term" || name == "unarad" || name == "access_operation") {
|
} else if (name == "expression" || name == "shiftand" || name == "term" || name == "unarad" || name == "access_operation") {
|
||||||
//If this is an actual part of an expression, not just a premoted child
|
//If this is an actual part of an expression, not just a premoted child
|
||||||
if (children.size() > 2) {
|
if (children.size() > 2) {
|
||||||
NodeTree<ASTData>* lhs = transform(children[0], scope, std::vector<Type>(), templateTypeReplacements, instantiateTemplates); //LHS does not inherit types
|
NodeTree<ASTData>* lhs = transform(children[0], scope, std::vector<Type>(), templateTypeReplacements); //LHS does not inherit types
|
||||||
NodeTree<ASTData>* rhs;
|
NodeTree<ASTData>* rhs;
|
||||||
if (name == "access_operation") {
|
if (name == "access_operation") {
|
||||||
std::cout << "lhs is: " << lhs->getDataRef()->toString() << std::endl;
|
std::cout << "lhs is: " << lhs->getDataRef()->toString() << std::endl;
|
||||||
rhs = transform(children[2], lhs->getDataRef()->valueType->typeDefinition, types, templateTypeReplacements, instantiateTemplates); //If an access operation, then the right side will be in the lhs's type's scope
|
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
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
rhs = transform(children[2], scope, types, templateTypeReplacements, instantiateTemplates);
|
rhs = transform(children[2], scope, types, templateTypeReplacements);
|
||||||
|
|
||||||
std::string functionCallName = concatSymbolTree(children[1]);
|
std::string functionCallName = concatSymbolTree(children[1]);
|
||||||
if (functionCallName == "[")
|
if (functionCallName == "[")
|
||||||
@@ -501,7 +506,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
//Is template instantiation
|
//Is template instantiation
|
||||||
return findOrInstantiateFunctionTemplate(children, scope, types, templateTypeReplacements);
|
return findOrInstantiateFunctionTemplate(children, scope, types, templateTypeReplacements);
|
||||||
} else {
|
} else {
|
||||||
return transform(children[0], scope, types, templateTypeReplacements, instantiateTemplates); //Just a promoted child, so do it instead
|
return transform(children[0], scope, types, templateTypeReplacements); //Just a promoted child, so do it instead
|
||||||
}
|
}
|
||||||
} else if (name == "factor") { //Do factor here, as it has all the weird unary operators
|
} else if (name == "factor") { //Do factor here, as it has all the weird unary operators
|
||||||
//If this is an actual part of an expression, not just a premoted child
|
//If this is an actual part of an expression, not just a premoted child
|
||||||
@@ -511,9 +516,9 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
funcName = concatSymbolTree(children[0]);
|
funcName = concatSymbolTree(children[0]);
|
||||||
NodeTree<ASTData>* param;
|
NodeTree<ASTData>* param;
|
||||||
if (funcName == "*" || funcName == "&" || funcName == "++" || funcName == "--" || funcName == "-" || funcName == "!" || funcName == "~")
|
if (funcName == "*" || funcName == "&" || funcName == "++" || funcName == "--" || funcName == "-" || funcName == "!" || funcName == "~")
|
||||||
param = transform(children[1], scope, types, templateTypeReplacements, instantiateTemplates);
|
param = transform(children[1], scope, types, templateTypeReplacements);
|
||||||
else
|
else
|
||||||
funcName = concatSymbolTree(children[1]), param = transform(children[0], scope, types, templateTypeReplacements, instantiateTemplates);
|
funcName = concatSymbolTree(children[1]), param = transform(children[0], scope, types, templateTypeReplacements);
|
||||||
|
|
||||||
//std::cout << "scope lookup from factor" << std::endl;
|
//std::cout << "scope lookup from factor" << std::endl;
|
||||||
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(param);
|
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(param);
|
||||||
@@ -525,7 +530,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
|
|
||||||
return function;
|
return function;
|
||||||
} else {
|
} else {
|
||||||
return transform(children[0], scope, types, templateTypeReplacements, instantiateTemplates); //Just a promoted child, so do it instead
|
return transform(children[0], scope, types, templateTypeReplacements); //Just a promoted child, so do it instead
|
||||||
}
|
}
|
||||||
} else if (name == "statement") {
|
} else if (name == "statement") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(statement));
|
newNode = new NodeTree<ASTData>(name, ASTData(statement));
|
||||||
@@ -541,12 +546,12 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
newNode = new NodeTree<ASTData>(name, ASTData(assignment_statement));
|
newNode = new NodeTree<ASTData>(name, ASTData(assignment_statement));
|
||||||
std::string assignFuncName = concatSymbolTree(children[1]);
|
std::string assignFuncName = concatSymbolTree(children[1]);
|
||||||
if (assignFuncName == "=") {
|
if (assignFuncName == "=") {
|
||||||
newNode->addChild(transform(children[0], scope, types, templateTypeReplacements, instantiateTemplates));
|
newNode->addChild(transform(children[0], scope, types, templateTypeReplacements));
|
||||||
newNode->addChild(transform(children[2], scope, types, templateTypeReplacements, instantiateTemplates));
|
newNode->addChild(transform(children[2], scope, types, templateTypeReplacements));
|
||||||
} else {
|
} else {
|
||||||
//For assignments like += or *=, expand the syntatic sugar.
|
//For assignments like += or *=, expand the syntatic sugar.
|
||||||
NodeTree<ASTData>* lhs = transform(children[0], scope, types, templateTypeReplacements, instantiateTemplates);
|
NodeTree<ASTData>* lhs = transform(children[0], scope, types, templateTypeReplacements);
|
||||||
NodeTree<ASTData>* rhs = transform(children[2], scope, types, templateTypeReplacements, instantiateTemplates);
|
NodeTree<ASTData>* rhs = transform(children[2], scope, types, templateTypeReplacements);
|
||||||
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(lhs); transformedChildren.push_back(rhs);
|
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(lhs); transformedChildren.push_back(rhs);
|
||||||
std::string functionName = assignFuncName.substr(0,1);
|
std::string functionName = assignFuncName.substr(0,1);
|
||||||
NodeTree<ASTData>* operatorCall = doFunction(scope, functionName, transformedChildren, templateTypeReplacements);
|
NodeTree<ASTData>* operatorCall = doFunction(scope, functionName, transformedChildren, templateTypeReplacements);
|
||||||
@@ -564,7 +569,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
// NodeTree<ASTData>* newIdentifier = transform(children[1], scope); //Transform the identifier
|
// NodeTree<ASTData>* newIdentifier = transform(children[1], scope); //Transform the identifier
|
||||||
// newIdentifier->getDataRef()->valueType = Type(concatSymbolTree(children[0]));//set the type of the identifier
|
// newIdentifier->getDataRef()->valueType = Type(concatSymbolTree(children[0]));//set the type of the identifier
|
||||||
std::string newIdentifierStr = concatSymbolTree(children[1]);
|
std::string newIdentifierStr = concatSymbolTree(children[1]);
|
||||||
Type* identifierType = typeFromTypeNode(children[0], scope, templateTypeReplacements, instantiateTemplates);
|
Type* identifierType = typeFromTypeNode(children[0], scope, templateTypeReplacements);
|
||||||
std::cout << "Declaring an identifier " << newIdentifierStr << " to be of type " << identifierType->toString() << std::endl;
|
std::cout << "Declaring an identifier " << newIdentifierStr << " to be of type " << identifierType->toString() << std::endl;
|
||||||
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), identifierType));
|
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), identifierType));
|
||||||
scope->getDataRef()->scope[newIdentifierStr].push_back(newIdentifier);
|
scope->getDataRef()->scope[newIdentifierStr].push_back(newIdentifier);
|
||||||
@@ -577,8 +582,8 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
//This code is a simplified version of the code in function_call with respect to access_operation.
|
//This code is a simplified version of the code in function_call with respect to access_operation.
|
||||||
//Note that in this case, what is lhs there is our newIdentifier here (the declaration of the left side of the access operation)
|
//Note that in this case, what is lhs there is our newIdentifier here (the declaration of the left side of the access operation)
|
||||||
auto sliced = slice(children, 4, -1);
|
auto sliced = slice(children, 4, -1);
|
||||||
std::vector<NodeTree<ASTData>*> initPositionFuncParams = transformChildren(sliced, std::set<int>(), scope, types, templateTypeReplacements, instantiateTemplates);
|
std::vector<NodeTree<ASTData>*> initPositionFuncParams = transformChildren(sliced, std::set<int>(), scope, types, templateTypeReplacements);
|
||||||
NodeTree<ASTData>* rhs = transform(children[3], identifierType->typeDefinition, mapNodesToTypes(initPositionFuncParams), templateTypeReplacements, instantiateTemplates); //If an access operation, then the right side will be in the lhs's type's scope
|
NodeTree<ASTData>* rhs = transform(children[3], identifierType->typeDefinition, mapNodesToTypes(initPositionFuncParams), templateTypeReplacements); //If an access operation, then the right side will be in the lhs's type's scope
|
||||||
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(newIdentifier); transformedChildren.push_back(rhs);
|
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(newIdentifier); transformedChildren.push_back(rhs);
|
||||||
NodeTree<ASTData>* accessFuncCall = doFunction(scope, ".", transformedChildren, templateTypeReplacements);
|
NodeTree<ASTData>* accessFuncCall = doFunction(scope, ".", transformedChildren, templateTypeReplacements);
|
||||||
accessFuncCall->getDataRef()->valueType = rhs->getDataRef()->valueType;
|
accessFuncCall->getDataRef()->valueType = rhs->getDataRef()->valueType;
|
||||||
@@ -595,7 +600,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
|
|
||||||
skipChildren.insert(0); //These, the type and the identifier, have been taken care of.
|
skipChildren.insert(0); //These, the type and the identifier, have been taken care of.
|
||||||
skipChildren.insert(1);
|
skipChildren.insert(1);
|
||||||
newNode->addChildren(transformChildren(children, skipChildren, scope, types, templateTypeReplacements, instantiateTemplates));
|
newNode->addChildren(transformChildren(children, skipChildren, scope, types, templateTypeReplacements));
|
||||||
return newNode;
|
return newNode;
|
||||||
} else if (name == "if_comp") {
|
} else if (name == "if_comp") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(if_comp));
|
newNode = new NodeTree<ASTData>(name, ASTData(if_comp));
|
||||||
@@ -608,12 +613,12 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
|
newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
|
||||||
|
|
||||||
skipChildren.insert(0);
|
skipChildren.insert(0);
|
||||||
std::vector<NodeTree<ASTData>*> transformedChildren = transformChildren(children, skipChildren, scope, types, templateTypeReplacements, instantiateTemplates);
|
std::vector<NodeTree<ASTData>*> transformedChildren = transformChildren(children, skipChildren, scope, types, templateTypeReplacements);
|
||||||
std::cout << "scope lookup from function_call: " << functionCallName << std::endl;
|
std::cout << "scope lookup from function_call: " << functionCallName << std::endl;
|
||||||
for (auto i : children)
|
for (auto i : children)
|
||||||
std::cout << i << " : " << i->getName() << " : " << i->getDataRef()->getName() << std::endl;
|
std::cout << i << " : " << i->getName() << " : " << i->getDataRef()->getName() << std::endl;
|
||||||
|
|
||||||
NodeTree<ASTData>* function = transform(children[0], scope, mapNodesToTypes(transformedChildren), templateTypeReplacements, instantiateTemplates);
|
NodeTree<ASTData>* function = transform(children[0], scope, mapNodesToTypes(transformedChildren), templateTypeReplacements);
|
||||||
std::cout << "The thing: " << function << " : " << function->getName() << std::endl;
|
std::cout << "The thing: " << function << " : " << function->getName() << std::endl;
|
||||||
for (auto i : function->getChildren())
|
for (auto i : function->getChildren())
|
||||||
std::cout << i->getName() << " ";
|
std::cout << i->getName() << " ";
|
||||||
@@ -623,12 +628,12 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
newNode->addChildren(transformedChildren);
|
newNode->addChildren(transformedChildren);
|
||||||
return newNode;
|
return newNode;
|
||||||
} else if (name == "parameter") {
|
} else if (name == "parameter") {
|
||||||
return transform(children[0], scope, types, templateTypeReplacements, instantiateTemplates); //Don't need a parameter node, just the value
|
return transform(children[0], scope, types, templateTypeReplacements); //Don't need a parameter node, just the value
|
||||||
} else if (name == "type") {
|
} else if (name == "type") {
|
||||||
std::string theConcat = concatSymbolTree(from); //We have no symbol, so this will concat our children
|
std::string theConcat = concatSymbolTree(from); //We have no symbol, so this will concat our children
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(theConcat, true), typeFromTypeNode(from, scope, templateTypeReplacements, instantiateTemplates)));
|
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(theConcat, true), typeFromTypeNode(from, scope, templateTypeReplacements)));
|
||||||
} else if (name == "number") {
|
} else if (name == "number") {
|
||||||
return transform(children[0], scope, types, templateTypeReplacements, instantiateTemplates);
|
return transform(children[0], scope, types, templateTypeReplacements);
|
||||||
} else if (name == "integer") {
|
} else if (name == "integer") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(from), true), new Type(integer)));
|
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(from), true), new Type(integer)));
|
||||||
} else if (name == "floating_literal") {
|
} else if (name == "floating_literal") {
|
||||||
@@ -648,22 +653,27 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), new Type(character, 1))); //Indirection of 1 for array
|
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), new Type(character, 1))); //Indirection of 1 for array
|
||||||
}else if (name == "character") {
|
}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
|
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), new Type(character, 0))); //Indirection of 0 for character
|
||||||
|
} else if (name == "AmbiguityPackOuter" || name == "AmbiguityPackInner") {
|
||||||
|
std::cout << "Ambigious program when parsed by this grammer! This is a bug, please report it." << std::endl;
|
||||||
|
throw "Ambigious parse!";
|
||||||
} else {
|
} else {
|
||||||
|
// Should get rid of this eventually. Right now it handles cases like sign, alpha, a comma, etc
|
||||||
|
std::cout << "Unhandled syntax node: " << name << std::endl;
|
||||||
return new NodeTree<ASTData>();
|
return new NodeTree<ASTData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Do all children but the ones we skip
|
//Do all children but the ones we skip
|
||||||
newNode->addChildren(transformChildren(children, skipChildren, scope, types, templateTypeReplacements, instantiateTemplates));
|
newNode->addChildren(transformChildren(children, skipChildren, scope, types, templateTypeReplacements));
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
//We use this functionality a lot at different places
|
//We use this functionality a lot at different places
|
||||||
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, bool instantiateTemplates) {
|
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) {
|
||||||
std::vector<NodeTree<ASTData>*> transformedChildren;
|
std::vector<NodeTree<ASTData>*> transformedChildren;
|
||||||
// In general, iterate through children and do them. Might not do this for all children.
|
// In general, iterate through children and do them. Might not do this for all children.
|
||||||
for (int i = 0; i < children.size(); i++) {
|
for (int i = 0; i < children.size(); i++) {
|
||||||
if (skipChildren.find(i) == skipChildren.end()) {
|
if (skipChildren.find(i) == skipChildren.end()) {
|
||||||
NodeTree<ASTData>* transChild = transform(children[i], scope, types, templateTypeReplacements, instantiateTemplates);
|
NodeTree<ASTData>* transChild = transform(children[i], scope, types, templateTypeReplacements);
|
||||||
if (transChild->getDataRef()->type) //Only add the children that have a real ASTData::ASTType, that is, legit ASTData.
|
if (transChild->getDataRef()->type) //Only add the children that have a real ASTData::ASTType, that is, legit ASTData.
|
||||||
transformedChildren.push_back(transChild);
|
transformedChildren.push_back(transChild);
|
||||||
else
|
else
|
||||||
@@ -837,17 +847,24 @@ NodeTree<ASTData>* ASTTransformation::templateClassLookup(NodeTree<ASTData>* sco
|
|||||||
int typeIndex = 0;
|
int typeIndex = 0;
|
||||||
int currentTraitsSatisfied = 0;
|
int currentTraitsSatisfied = 0;
|
||||||
for (auto j : nameTraitsPairs) {
|
for (auto j : nameTraitsPairs) {
|
||||||
if (j.second != templateInstantiationTypes[typeIndex]->traits) {
|
if (!subset(j.second, templateInstantiationTypes[typeIndex]->traits)) {
|
||||||
traitsEqual = false;
|
traitsEqual = false;
|
||||||
std::cout << "Traits unequal for " << j.first << " and " << templateInstantiationTypes[typeIndex]->toString() << ": ";
|
std::cout << "Traits not subset for " << j.first << " and " << templateInstantiationTypes[typeIndex]->toString() << ": ";
|
||||||
//std::cout << baseType << " " << indirection << " " << typeDefinition << " " << templateDefinition << " " << traits << ;
|
//std::cout << baseType << " " << indirection << " " << typeDefinition << " " << templateDefinition << " " << traits << ;
|
||||||
std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||||
std::cout << " vs ";
|
std::cout << " vs ";
|
||||||
std::copy(templateInstantiationTypes[typeIndex]->traits.begin(), templateInstantiationTypes[typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
std::copy(templateInstantiationTypes[typeIndex]->traits.begin(), templateInstantiationTypes[typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
std::cout << "Traits ARE subset for " << j.first << " and " << templateInstantiationTypes[typeIndex]->toString() << ": ";
|
||||||
|
//std::cout << baseType << " " << indirection << " " << typeDefinition << " " << templateDefinition << " " << traits << ;
|
||||||
|
std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||||
|
std::cout << " vs ";
|
||||||
|
std::copy(templateInstantiationTypes[typeIndex]->traits.begin(), templateInstantiationTypes[typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
currentTraitsSatisfied += templateInstantiationTypes[typeIndex]->traits.size();
|
currentTraitsSatisfied += j.second.size();
|
||||||
typeIndex++;
|
typeIndex++;
|
||||||
}
|
}
|
||||||
if (!traitsEqual)
|
if (!traitsEqual)
|
||||||
@@ -898,18 +915,24 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
|
|||||||
int typeIndex = 0;
|
int typeIndex = 0;
|
||||||
int currentTraitsSatisfied = 0;
|
int currentTraitsSatisfied = 0;
|
||||||
for (auto j : nameTraitsPairs) {
|
for (auto j : nameTraitsPairs) {
|
||||||
if (j.second != templateInstantiationTypes[typeIndex]->traits) {
|
if (!subset(j.second, templateInstantiationTypes[typeIndex]->traits)) {
|
||||||
traitsEqual = false;
|
traitsEqual = false;
|
||||||
std::cout << "Traits unequal for " << j.first << " and " << templateInstantiationTypes[typeIndex]->toString() << ": ";
|
std::cout << "Traits not a subset for " << j.first << " and " << templateInstantiationTypes[typeIndex]->toString() << ": ";
|
||||||
std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||||
std::cout << " vs ";
|
std::cout << " vs ";
|
||||||
std::copy(templateInstantiationTypes[typeIndex]->traits.begin(), templateInstantiationTypes[typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
std::copy(templateInstantiationTypes[typeIndex]->traits.begin(), templateInstantiationTypes[typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
std::cout << "Traits ARE a subset for " << j.first << " and " << templateInstantiationTypes[typeIndex]->toString() << ": ";
|
||||||
|
std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||||
|
std::cout << " vs ";
|
||||||
|
std::copy(templateInstantiationTypes[typeIndex]->traits.begin(), templateInstantiationTypes[typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
//As we go, build up the typeMap for when we transform the parameters for parameter checking
|
//As we go, build up the typeMap for when we transform the parameters for parameter checking
|
||||||
typeMap[j.first] = templateInstantiationTypes[typeIndex];
|
typeMap[j.first] = templateInstantiationTypes[typeIndex];
|
||||||
currentTraitsSatisfied += templateInstantiationTypes[typeIndex]->traits.size();
|
currentTraitsSatisfied += j.second.size();
|
||||||
typeIndex++;
|
typeIndex++;
|
||||||
}
|
}
|
||||||
if (!traitsEqual)
|
if (!traitsEqual)
|
||||||
@@ -922,7 +945,7 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
|
|||||||
|
|
||||||
bool parameterTypesMatch = true;
|
bool parameterTypesMatch = true;
|
||||||
for (int j = 0; j < functionParameters.size(); j++) {
|
for (int j = 0; j < functionParameters.size(); j++) {
|
||||||
auto paramType = typeFromTypeNode(functionParameters[j]->getChildren()[0], scope, typeMap, false);
|
auto paramType = typeFromTypeNode(functionParameters[j]->getChildren()[0], scope, typeMap);
|
||||||
std::cout << "Template param type: " << paramType->toString() << " : Needed Type: " << types[j].toString() << std::endl;
|
std::cout << "Template param type: " << paramType->toString() << " : Needed Type: " << types[j].toString() << std::endl;
|
||||||
if (*paramType != types[j]) {
|
if (*paramType != types[j]) {
|
||||||
parameterTypesMatch = false;
|
parameterTypesMatch = false;
|
||||||
@@ -978,7 +1001,7 @@ std::map<std::string, Type*> ASTTransformation::makeTemplateFunctionTypeMap(Node
|
|||||||
return typeMap;
|
return typeMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup) {
|
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules) {
|
||||||
//We first check to see if it's one of the special reserved identifiers (only this, for now) and return early if it is.
|
//We first check to see if it's one of the special reserved identifiers (only this, for now) and return early if it is.
|
||||||
auto LLElementIterator = languageLevelReservedWords.find(lookup);
|
auto LLElementIterator = languageLevelReservedWords.find(lookup);
|
||||||
if (LLElementIterator != languageLevelReservedWords.end()) {
|
if (LLElementIterator != languageLevelReservedWords.end()) {
|
||||||
@@ -988,9 +1011,12 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
|
|||||||
std::vector<NodeTree<ASTData>*> matches;
|
std::vector<NodeTree<ASTData>*> matches;
|
||||||
std::map<std::string, std::vector<NodeTree<ASTData>*>> scopeMap = scope->getDataRef()->scope;
|
std::map<std::string, std::vector<NodeTree<ASTData>*>> scopeMap = scope->getDataRef()->scope;
|
||||||
auto possibleMatches = scopeMap.find(lookup);
|
auto possibleMatches = scopeMap.find(lookup);
|
||||||
if (possibleMatches != scopeMap.end())
|
if (possibleMatches != scopeMap.end()) {
|
||||||
matches.insert(matches.end(), possibleMatches->second.begin(), possibleMatches->second.end());
|
for (auto i : possibleMatches->second)
|
||||||
|
if (includeModules || i->getName() != "translation_unit")
|
||||||
|
matches.push_back(i);
|
||||||
|
std::cout << "Found " << possibleMatches->second.size() << " match(s) at " << scope->getDataRef()->toString() << std::endl;
|
||||||
|
}
|
||||||
// Add results from our enclosing scope, if it exists
|
// Add results from our enclosing scope, if it exists
|
||||||
auto enclosingIterator = scopeMap.find("~enclosing_scope");
|
auto enclosingIterator = scopeMap.find("~enclosing_scope");
|
||||||
if (enclosingIterator != scopeMap.end()) {
|
if (enclosingIterator != scopeMap.end()) {
|
||||||
@@ -1001,7 +1027,7 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Create a type from a syntax tree. This can get complicated with templates
|
//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, bool instantiateTemplates) {
|
Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<ASTData>* scope, std::map<std::string, Type*> templateTypeReplacements) {
|
||||||
std::string typeIn = concatSymbolTree(typeNode);
|
std::string typeIn = concatSymbolTree(typeNode);
|
||||||
|
|
||||||
int indirection = 0;
|
int indirection = 0;
|
||||||
@@ -1044,6 +1070,14 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
|
|||||||
std::cout << i.first << " ";
|
std::cout << i.first << " ";
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
// getChildren()[1] is \* because of pointer instead of template_inst
|
||||||
|
// To counter this, for every indirection we step down a level
|
||||||
|
for (int i = 0; i < indirection; i++)
|
||||||
|
typeNode = typeNode->getChildren()[0];
|
||||||
|
|
||||||
|
std::cout << possibleMatches.size() << " " << typeNode->getChildren().size() << std::endl;
|
||||||
|
if (typeNode->getChildren().size() > 1)
|
||||||
|
std::cout << typeNode->getChildren()[1]->getDataRef()->getName() << std::endl;
|
||||||
//If not, we better instantiate it and then add it to the highest (not current) scope
|
//If not, we better instantiate it and then add it to the highest (not current) scope
|
||||||
if (possibleMatches.size() == 0 && typeNode->getChildren().size() > 1 && typeNode->getChildren()[1]->getData().getName() == "template_inst") {
|
if (possibleMatches.size() == 0 && typeNode->getChildren().size() > 1 && typeNode->getChildren()[1]->getData().getName() == "template_inst") {
|
||||||
std::cout << "Template type: " << edited << " not yet instantiated" << std::endl;
|
std::cout << "Template type: " << edited << " not yet instantiated" << std::endl;
|
||||||
@@ -1053,10 +1087,23 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
|
|||||||
std::vector<Type*> templateParamInstantiationTypes;
|
std::vector<Type*> templateParamInstantiationTypes;
|
||||||
std::string instTypeString = "";
|
std::string instTypeString = "";
|
||||||
for (int i = 0; i < templateParamInstantiationNodes.size(); i++) {
|
for (int i = 0; i < templateParamInstantiationNodes.size(); i++) {
|
||||||
Type* instType = typeFromTypeNode(templateParamInstantiationNodes[i], scope, templateTypeReplacements, instantiateTemplates);
|
Type* instType = typeFromTypeNode(templateParamInstantiationNodes[i], scope, templateTypeReplacements);
|
||||||
templateParamInstantiationTypes.push_back(instType);
|
templateParamInstantiationTypes.push_back(instType);
|
||||||
instTypeString += (instTypeString == "") ? instType->toString(false) : "," + instType->toString(false);
|
instTypeString += (instTypeString == "") ? instType->toString(false) : "," + instType->toString(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Finish creating the new name for this instantiation
|
||||||
|
std::string classNameWithoutTemplate = concatSymbolTree(typeNode->getChildren()[0]);
|
||||||
|
std::string fullyInstantiatedName = classNameWithoutTemplate + "<" + instTypeString + ">";
|
||||||
|
|
||||||
|
// Recheck for prior definition here, now that we have the true name.
|
||||||
|
possibleMatches = scopeLookup(scope, fullyInstantiatedName);
|
||||||
|
if (possibleMatches.size()) {
|
||||||
|
typeDefinition = possibleMatches[0];
|
||||||
|
traits = typeDefinition->getDataRef()->valueType->traits;
|
||||||
|
std::cout << "Found already instantiated template of " << fullyInstantiatedName << " at second check" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "Did not find already instantiated template of " << fullyInstantiatedName << " at second check" << std::endl;
|
||||||
//Look up this template's plain definition. It's type has the syntax tree that we need to parse
|
//Look up this template's plain definition. It's type has the syntax tree that we need to parse
|
||||||
NodeTree<ASTData>* templateDefinition = templateClassLookup(scope, concatSymbolTree(typeNode->getChildren()[0]), templateParamInstantiationTypes);
|
NodeTree<ASTData>* templateDefinition = templateClassLookup(scope, concatSymbolTree(typeNode->getChildren()[0]), templateParamInstantiationTypes);
|
||||||
if (templateDefinition == NULL)
|
if (templateDefinition == NULL)
|
||||||
@@ -1071,10 +1118,6 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
|
|||||||
for (int i = 0; i < templateParamInstantiationTypes.size(); i++)
|
for (int i = 0; i < templateParamInstantiationTypes.size(); i++)
|
||||||
newTemplateTypeReplacement[concatSymbolTree(templateParamPlaceholderNodes[i])] = templateParamInstantiationTypes[i];
|
newTemplateTypeReplacement[concatSymbolTree(templateParamPlaceholderNodes[i])] = templateParamInstantiationTypes[i];
|
||||||
|
|
||||||
//Finish creating the new name for this instantiation
|
|
||||||
std::string classNameWithoutTemplate = concatSymbolTree(typeNode->getChildren()[0]);
|
|
||||||
std::string fullyInstantiatedName = classNameWithoutTemplate + "<" + instTypeString + ">";
|
|
||||||
|
|
||||||
typeDefinition = new NodeTree<ASTData>("type_def", ASTData(type_def, Symbol(fullyInstantiatedName, true, fullyInstantiatedName)));
|
typeDefinition = new NodeTree<ASTData>("type_def", ASTData(type_def, Symbol(fullyInstantiatedName, true, fullyInstantiatedName)));
|
||||||
traits = templateDefinition->getDataRef()->valueType->traits; // We have the same traits as the template definition
|
traits = templateDefinition->getDataRef()->valueType->traits; // We have the same traits as the template definition
|
||||||
Type* selfType = new Type(typeDefinition, traits); // Type is self-referential since this is the definition.
|
Type* selfType = new Type(typeDefinition, traits); // Type is self-referential since this is the definition.
|
||||||
@@ -1082,25 +1125,24 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
|
|||||||
|
|
||||||
//Note that we're adding to the current top scope. This makes it more efficient by preventing multiple instantiation and should not cause any problems
|
//Note that we're adding to the current top scope. This makes it more efficient by preventing multiple instantiation and should not cause any problems
|
||||||
//It also makes sure it gets generated in the right place
|
//It also makes sure it gets generated in the right place
|
||||||
std::cout << "Adding to top scope with fullyInstantiatedName " << fullyInstantiatedName << std::endl;
|
std::cout << "Adding to top scope and template's origional scope with fullyInstantiatedName " << fullyInstantiatedName << std::endl;
|
||||||
topScope->getDataRef()->scope[fullyInstantiatedName].push_back(typeDefinition);
|
topScope->getDataRef()->scope[fullyInstantiatedName].push_back(typeDefinition);
|
||||||
topScope->addChild(typeDefinition); //Add this object the the highest scope's
|
topScope->addChild(typeDefinition); //Add this object the the highest scope's
|
||||||
|
NodeTree<ASTData>* templateHighScope = templateDefinition->getDataRef()->scope["~enclosing_scope"][0];
|
||||||
|
if (topScope != templateHighScope)
|
||||||
|
templateHighScope->getDataRef()->scope[fullyInstantiatedName].push_back(typeDefinition);
|
||||||
|
|
||||||
//Note that the instantiated template's scope is the template's definition.
|
//Note that the instantiated template's scope is the template's definition.
|
||||||
typeDefinition->getDataRef()->scope["~enclosing_scope"].push_back(templateDefinition);
|
typeDefinition->getDataRef()->scope["~enclosing_scope"].push_back(templateDefinition);
|
||||||
|
|
||||||
if (!instantiateTemplates) {
|
// We only partially instantiate templates no matter what now
|
||||||
std::cout << "!instantiateTemplates, so only partially instantiating " << fullyInstantiatedName << std::endl;
|
// They are all fully instantiated in the loop at the end of the 4th pass
|
||||||
|
// This is done for code simplicity and so that that loop can do template class methods
|
||||||
|
// that instantiate other templates that instantiate other templates while still retaining the
|
||||||
|
// deferred method allowing us to correctly instantiate multiple levels of mututally recursive definitions.
|
||||||
selfType->templateDefinition = templateSyntaxTree; //We're going to still need this when we finish instantiating
|
selfType->templateDefinition = templateSyntaxTree; //We're going to still need this when we finish instantiating
|
||||||
selfType->templateTypeReplacement = newTemplateTypeReplacement; //Save the types for use when this is fully instantiated in pass 4
|
selfType->templateTypeReplacement = newTemplateTypeReplacement; //Save the types for use when this is fully instantiated in pass 4
|
||||||
secondPassDoClassInsides(typeDefinition, templateSyntaxTree->getChildren(), newTemplateTypeReplacement); //Use these types when instantiating data members
|
secondPassDoClassInsides(typeDefinition, templateSyntaxTree->getChildren(), newTemplateTypeReplacement); //Use these types when instantiating data members
|
||||||
} else {
|
|
||||||
//We're fully instantiating types. (we must be in pass 4)
|
|
||||||
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, instantiateTemplates));
|
|
||||||
}
|
}
|
||||||
} else if (possibleMatches.size() == 0) {
|
} else if (possibleMatches.size() == 0) {
|
||||||
std::cout << "Could not find type " << edited << ", returning NULL" << std::endl;
|
std::cout << "Could not find type " << edited << ", returning NULL" << std::endl;
|
||||||
@@ -1124,7 +1166,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec
|
|||||||
std::string instTypeString = "";
|
std::string instTypeString = "";
|
||||||
std::vector<Type*> templateActualTypes;
|
std::vector<Type*> templateActualTypes;
|
||||||
for (int i = 0; i < templateParamInstantiationNodes.size(); i++) {
|
for (int i = 0; i < templateParamInstantiationNodes.size(); i++) {
|
||||||
Type* instType = typeFromTypeNode(templateParamInstantiationNodes[i],scope, templateTypeReplacements, true);
|
Type* instType = typeFromTypeNode(templateParamInstantiationNodes[i],scope, templateTypeReplacements);
|
||||||
instTypeString += (instTypeString == "" ? instType->toString() : "," + instType->toString());
|
instTypeString += (instTypeString == "" ? instType->toString() : "," + instType->toString());
|
||||||
templateActualTypes.push_back(instType);
|
templateActualTypes.push_back(instType);
|
||||||
}
|
}
|
||||||
@@ -1163,7 +1205,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec
|
|||||||
std::cout << ", " << i << " : " << templateChildren[i]->getDataRef()->getName();
|
std::cout << ", " << i << " : " << templateChildren[i]->getDataRef()->getName();
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
instantiatedFunction = new NodeTree<ASTData>("function", ASTData(function, Symbol(fullyInstantiatedName, true), typeFromTypeNode(templateChildren[1], scope, newTemplateTypeReplacement, true)));
|
instantiatedFunction = new NodeTree<ASTData>("function", ASTData(function, Symbol(fullyInstantiatedName, true), typeFromTypeNode(templateChildren[1], scope, newTemplateTypeReplacement)));
|
||||||
std::set<int> skipChildren;
|
std::set<int> skipChildren;
|
||||||
skipChildren.insert(0);
|
skipChildren.insert(0);
|
||||||
skipChildren.insert(1);
|
skipChildren.insert(1);
|
||||||
@@ -1171,7 +1213,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec
|
|||||||
scope->getDataRef()->scope[fullyInstantiatedName].push_back(instantiatedFunction);
|
scope->getDataRef()->scope[fullyInstantiatedName].push_back(instantiatedFunction);
|
||||||
instantiatedFunction->getDataRef()->scope["~enclosing_scope"].push_back(templateDefinition->getDataRef()->scope["~enclosing_scope"][0]); //Instantiated Template Function's scope is it's template's definition's scope
|
instantiatedFunction->getDataRef()->scope["~enclosing_scope"].push_back(templateDefinition->getDataRef()->scope["~enclosing_scope"][0]); //Instantiated Template Function's scope is it's template's definition's scope
|
||||||
std::cout << "About to do children of " << functionName << " to " << fullyInstantiatedName << std::endl;
|
std::cout << "About to do children of " << functionName << " to " << fullyInstantiatedName << std::endl;
|
||||||
instantiatedFunction->addChildren(transformChildren(templateSyntaxTree->getChildren(), skipChildren, instantiatedFunction, std::vector<Type>(), newTemplateTypeReplacement, true));
|
instantiatedFunction->addChildren(transformChildren(templateSyntaxTree->getChildren(), skipChildren, instantiatedFunction, std::vector<Type>(), newTemplateTypeReplacement));
|
||||||
|
|
||||||
topScope->getDataRef()->scope[fullyInstantiatedName].push_back(instantiatedFunction);
|
topScope->getDataRef()->scope[fullyInstantiatedName].push_back(instantiatedFunction);
|
||||||
topScope->addChild(instantiatedFunction); //Add this object the the highest scope's
|
topScope->addChild(instantiatedFunction); //Add this object the the highest scope's
|
||||||
|
|||||||
+1
-2
@@ -56,7 +56,7 @@ template <T> void delete(T* toDelete, int itemCount) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <T(Destructable)> void delete(T* toDelete, int itemCount) {
|
template <T(Destructable)> void delete(T* toDelete, int itemCount) {
|
||||||
for (int i = 0; i < itemDestructCount; i++;)
|
for (int i = 0; i < itemCount; i++;)
|
||||||
toDelete[i].destruct();
|
toDelete[i].destruct();
|
||||||
delete<T>(toDelete);
|
delete<T>(toDelete);
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,6 @@ template <T> void delete(T* toDelete) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <T(Destructable)> void delete(T* toDelete) {
|
template <T(Destructable)> void delete(T* toDelete) {
|
||||||
if (destruct)
|
|
||||||
toDelete->destruct();
|
toDelete->destruct();
|
||||||
free(toDelete);
|
free(toDelete);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,13 +1,13 @@
|
|||||||
import mem;
|
import mem;
|
||||||
import util;
|
import util;
|
||||||
|
|
||||||
typedef template<T> vector {
|
typedef template<T> vector (Destructable) {
|
||||||
T *data;
|
T *data;
|
||||||
int size;
|
int size;
|
||||||
int available;
|
int available;
|
||||||
bool destroyItems;
|
bool destroyItems;
|
||||||
|
|
||||||
vector<T> *construct(bool destroyItemsIn) {
|
vector<T>* construct(bool destroyItemsIn) {
|
||||||
destroyItems = destroyItemsIn;
|
destroyItems = destroyItemsIn;
|
||||||
return construct();
|
return construct();
|
||||||
size = 0;
|
size = 0;
|
||||||
|
|||||||
+10
-9
@@ -1,7 +1,8 @@
|
|||||||
import io;
|
import io;
|
||||||
|
import mem;
|
||||||
import vector;
|
import vector;
|
||||||
|
|
||||||
typedef Destructable {
|
typedef AbleToBeDestroyed (Destructable) {
|
||||||
void destruct() {
|
void destruct() {
|
||||||
println("Destroyed!");
|
println("Destroyed!");
|
||||||
}
|
}
|
||||||
@@ -9,19 +10,19 @@ typedef Destructable {
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
vector<int> intVec.construct(false);
|
vector<int> intVec.construct(false);
|
||||||
intVec.addBack(1);
|
intVec.addEnd(1);
|
||||||
intVec.addBack(3);
|
intVec.addEnd(3);
|
||||||
intVec.addBack(3);
|
intVec.addEnd(3);
|
||||||
intVec.addBack(7);
|
intVec.addEnd(7);
|
||||||
for (int i = 0; i < intVec.size(); i++;)
|
for (int i = 0; i < intVec.size(); i++;)
|
||||||
print(intVec.at(i));
|
print(intVec.at(i));
|
||||||
|
|
||||||
println();
|
println();
|
||||||
|
|
||||||
vector<Destructable>* desVec = new<vector<Destructable>>()->construct(true);
|
vector<AbleToBeDestroyed>* desVec = new<vector<AbleToBeDestroyed>>()->construct(true);
|
||||||
Destructable testDestruct;
|
AbleToBeDestroyed testDestruct;
|
||||||
desVec->addBack(testDestruct);
|
desVec->addEnd(testDestruct);
|
||||||
delete<vector<Destructable>>(desVec);
|
delete<vector<AbleToBeDestroyed>>(desVec);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user