Some bugfixes and added templated member functions\! (even for templated objs\!) In this vein, added in_place and map functions to vector\!
This commit is contained in:
@@ -27,6 +27,7 @@ class ASTData {
|
|||||||
~ASTData();
|
~ASTData();
|
||||||
std::string toString();
|
std::string toString();
|
||||||
static std::string ASTTypeToString(ASTType type);
|
static std::string ASTTypeToString(ASTType type);
|
||||||
|
|
||||||
ASTType type;
|
ASTType type;
|
||||||
Type* valueType;
|
Type* valueType;
|
||||||
Symbol symbol;
|
Symbol symbol;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
|
|||||||
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::map<std::string, Type*> scopeTypeMap);
|
||||||
std::vector<NodeTree<ASTData>*> scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules = false);
|
std::vector<NodeTree<ASTData>*> scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules = false);
|
||||||
std::vector<NodeTree<ASTData>*> scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules, std::vector<NodeTree<ASTData>*> visited);
|
std::vector<NodeTree<ASTData>*> scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules, std::vector<NodeTree<ASTData>*> visited);
|
||||||
|
|
||||||
@@ -56,10 +56,10 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
|
|||||||
NodeTree<ASTData>* addToScope(std::string name, NodeTree<ASTData>* toAdd, NodeTree<ASTData>* addTo);
|
NodeTree<ASTData>* addToScope(std::string name, NodeTree<ASTData>* toAdd, NodeTree<ASTData>* addTo);
|
||||||
Type* typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<ASTData>* scope, std::map<std::string, Type*> templateTypeReplacements);
|
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);
|
||||||
void unifyType(NodeTree<Symbol> *syntaxType, Type type, std::map<std::string, Type>* templateTypeMap);
|
void unifyType(NodeTree<Symbol> *syntaxType, Type type, std::map<std::string, Type>* templateTypeMap, std::map<std::string, Type*> typeMap);
|
||||||
void unifyTemplateFunction(NodeTree<ASTData>* templateFunction, std::vector<Type> types, std::vector<Type*>* templateInstantiationTypes);
|
void unifyTemplateFunction(NodeTree<ASTData>* templateFunction, std::vector<Type> types, std::vector<Type*>* templateInstantiationTypes, std::map<std::string, Type*> typeMap);
|
||||||
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, std::map<std::string, Type*> scopeTypeMap);
|
||||||
std::vector<std::pair<std::string, std::set<std::string>>> makeTemplateNameTraitPairs(NodeTree<Symbol>* templateNode);
|
std::vector<std::pair<std::string, std::set<std::string>>> makeTemplateNameTraitPairs(NodeTree<Symbol>* templateNode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -241,14 +241,6 @@ 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
|
||||||
}
|
}
|
||||||
// Just to see, I don't think templated functions actually need parameters at this point, and we might not have enough info anyway...
|
|
||||||
auto transChildren = transformChildren(slice(children,2,-3), std::set<int>(), functionDef, std::vector<Type>(), yetToBeInstantiatedTemplateTypes);
|
|
||||||
std::cout << "Template function " << functionName << " has these parameters: ";
|
|
||||||
for (auto i : transChildren)
|
|
||||||
std::cout << "||" << i->getDataRef()->toString() << "|| ";
|
|
||||||
std::cout << "DoneList" << std::endl;
|
|
||||||
functionDef->addChildren(transChildren);
|
|
||||||
|
|
||||||
std::cout << "Finished Non-Instantiated Template function " << functionName << std::endl;
|
std::cout << "Finished Non-Instantiated Template function " << functionName << std::endl;
|
||||||
return functionDef;
|
return functionDef;
|
||||||
}
|
}
|
||||||
@@ -286,7 +278,8 @@ void ASTTransformation::thirdPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* pars
|
|||||||
|
|
||||||
//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") {
|
// skip templated member functions
|
||||||
|
if (j->getDataRef()->getName() == "function" && j->getChildren()[1]->getDataRef()->getName() != "template_dec") {
|
||||||
thirdPassFunction(j, searchScopeForFunctionDef(typeDef, j, std::map<std::string, Type*>()), std::map<std::string, Type*>()); //do member method
|
thirdPassFunction(j, searchScopeForFunctionDef(typeDef, j, std::map<std::string, Type*>()), std::map<std::string, Type*>()); //do member method
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -316,7 +309,7 @@ void ASTTransformation::thirdPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* pars
|
|||||||
Type* classTemplateType = i->getDataRef()->valueType;
|
Type* classTemplateType = i->getDataRef()->valueType;
|
||||||
std::cout << "Instantiating template " << i->getDataRef()->toString() << std::endl;
|
std::cout << "Instantiating template " << i->getDataRef()->toString() << std::endl;
|
||||||
for (NodeTree<Symbol>* j : classTemplateType->templateDefinition->getChildren())
|
for (NodeTree<Symbol>* j : classTemplateType->templateDefinition->getChildren())
|
||||||
if (j->getDataRef()->getName() == "function")
|
if (j->getDataRef()->getName() == "function" && j->getChildren()[1]->getDataRef()->getName() != "template_dec")
|
||||||
thirdPassFunction(j, searchScopeForFunctionDef(i, j, classTemplateType->templateTypeReplacement), classTemplateType->templateTypeReplacement); //do member method
|
thirdPassFunction(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
|
classTemplateType->templateTypeReplacement.clear(); // This template has been fully instantiated, clear it's map so it won't be instantiated again
|
||||||
}
|
}
|
||||||
@@ -527,6 +520,9 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
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); //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
|
||||||
|
// this might be a template member function, so do like below would do, but make it our rhs
|
||||||
|
if (rhs == nullptr)
|
||||||
|
rhs = findOrInstantiateFunctionTemplate(slice(children,2,-1), lhs->getDataRef()->valueType->typeDefinition, types, templateTypeReplacements);
|
||||||
} else
|
} else
|
||||||
rhs = transform(children[2], scope, types, templateTypeReplacements);
|
rhs = transform(children[2], scope, types, templateTypeReplacements);
|
||||||
|
|
||||||
@@ -1013,11 +1009,14 @@ NodeTree<ASTData>* ASTTransformation::templateClassLookup(NodeTree<ASTData>* sco
|
|||||||
return *mostFittingTemplates.begin();
|
return *mostFittingTemplates.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASTTransformation::unifyType(NodeTree<Symbol> *syntaxType, Type type, std::map<std::string, Type>* templateTypeMap) {
|
void ASTTransformation::unifyType(NodeTree<Symbol> *syntaxType, Type type, std::map<std::string, Type>* templateTypeMap, std::map<std::string, Type*> typeMap) {
|
||||||
// Ok, 3 options for syntaxType here.
|
// Ok, 3 options for syntaxType here.
|
||||||
// 1) This a basic type. (int, or object, etc)
|
// 1) This a basic type. (int, or object, etc)
|
||||||
// THIS ONE will fall through and get put in the map, but it
|
// THIS ONE will fall through and get put in the map, but it
|
||||||
// doesn't matter b/c it'll get filterd out in unifyTemplateFunction
|
// doesn't matter b/c it'll get filterd out in unifyTemplateFunction
|
||||||
|
// I also kina feel like maybe I need to worry about typeMap, which is why
|
||||||
|
// I passed it in... It would contain the typemap from our scope if we are
|
||||||
|
// doing a template member function of a templated object
|
||||||
// 2) This is a template type type (i.e. T)
|
// 2) This is a template type type (i.e. T)
|
||||||
// match! set up templateTypeMap[T] -> type
|
// match! set up templateTypeMap[T] -> type
|
||||||
// 3) This some sort of instantiated template
|
// 3) This some sort of instantiated template
|
||||||
@@ -1037,20 +1036,23 @@ void ASTTransformation::unifyType(NodeTree<Symbol> *syntaxType, Type type, std::
|
|||||||
auto childrenTypes = getNodes("type", children.back()->getChildren());
|
auto childrenTypes = getNodes("type", children.back()->getChildren());
|
||||||
// unify params
|
// unify params
|
||||||
for (int i = 0; i < childrenTypes.size()-1; i++)
|
for (int i = 0; i < childrenTypes.size()-1; i++)
|
||||||
unifyType(childrenTypes[i], *type.parameterTypes[i], templateTypeMap);
|
unifyType(childrenTypes[i], *type.parameterTypes[i], templateTypeMap, typeMap);
|
||||||
unifyType(childrenTypes.back(), *type.returnType, templateTypeMap);
|
unifyType(childrenTypes.back(), *type.returnType, templateTypeMap, typeMap);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (children.size() == 1) {
|
if (children.size() == 1) {
|
||||||
(*templateTypeMap)[concatSymbolTree(children.back())] = type;
|
(*templateTypeMap)[concatSymbolTree(children.back())] = type;
|
||||||
|
// I also kina feel like maybe I need to worry about typeMap, which is why
|
||||||
|
// I passed it in... It would contain the typemap from our scope if we are
|
||||||
|
// doing a template member function of a templated object
|
||||||
} else {
|
} else {
|
||||||
// go down one in our pointer
|
// go down one in our pointer
|
||||||
if (children.back()->getDataRef()->getValue() == "*") {
|
if (children.back()->getDataRef()->getValue() == "*") {
|
||||||
// gotta be a better way to do this
|
// gotta be a better way to do this
|
||||||
Type* clonedType = type.clone();
|
Type* clonedType = type.clone();
|
||||||
clonedType->decreaseIndirection();
|
clonedType->decreaseIndirection();
|
||||||
unifyType(children.front(), *clonedType, templateTypeMap);
|
unifyType(children.front(), *clonedType, templateTypeMap, typeMap);
|
||||||
delete clonedType;
|
delete clonedType;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1068,7 +1070,7 @@ void ASTTransformation::unifyType(NodeTree<Symbol> *syntaxType, Type type, std::
|
|||||||
std::vector<NodeTree<Symbol>*> uninTypeInstTypes = getNodes("type", getNode("template_inst", children));
|
std::vector<NodeTree<Symbol>*> uninTypeInstTypes = getNodes("type", getNode("template_inst", children));
|
||||||
std::vector<NodeTree<Symbol>*> typeInstTypes = getNodes("template_param", getNode("template_dec", typeTemplateDefinition->getChildren()));
|
std::vector<NodeTree<Symbol>*> typeInstTypes = getNodes("template_param", getNode("template_dec", typeTemplateDefinition->getChildren()));
|
||||||
for (int i = 0; i < uninTypeInstTypes.size(); i++)
|
for (int i = 0; i < uninTypeInstTypes.size(); i++)
|
||||||
unifyType(uninTypeInstTypes[i], *origionalType->templateTypeReplacement[concatSymbolTree(typeInstTypes[i])], templateTypeMap);
|
unifyType(uninTypeInstTypes[i], *origionalType->templateTypeReplacement[concatSymbolTree(typeInstTypes[i])], templateTypeMap, typeMap);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1077,20 +1079,20 @@ void ASTTransformation::unifyType(NodeTree<Symbol> *syntaxType, Type type, std::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASTTransformation::unifyTemplateFunction(NodeTree<ASTData>* templateFunction, std::vector<Type> types, std::vector<Type*>* templateInstantiationTypes) {
|
void ASTTransformation::unifyTemplateFunction(NodeTree<ASTData>* templateFunction, std::vector<Type> types, std::vector<Type*>* templateInstantiationTypes, std::map<std::string, Type*> typeMap) {
|
||||||
NodeTree<Symbol>* templateSyntaxTree = templateFunction->getDataRef()->valueType->templateDefinition;
|
NodeTree<Symbol>* templateSyntaxTree = templateFunction->getDataRef()->valueType->templateDefinition;
|
||||||
std::vector<NodeTree<Symbol>*> templateParameters = getNodes("typed_parameter", templateSyntaxTree);
|
std::vector<NodeTree<Symbol>*> templateParameters = getNodes("typed_parameter", templateSyntaxTree);
|
||||||
if (templateParameters.size() != types.size())
|
if (templateParameters.size() != types.size())
|
||||||
return;
|
return;
|
||||||
std::map<std::string, Type> templateTypeMap;
|
std::map<std::string, Type> templateTypeMap;
|
||||||
for (int i = 0; i < types.size(); i++)
|
for (int i = 0; i < types.size(); i++)
|
||||||
unifyType(getNode("type", templateParameters[i]), types[i], &templateTypeMap);
|
unifyType(getNode("type", templateParameters[i]), types[i], &templateTypeMap, typeMap);
|
||||||
for (auto instantiationParam : getNodes("template_param", getNode("template_dec", templateSyntaxTree)))
|
for (auto instantiationParam : getNodes("template_param", getNode("template_dec", templateSyntaxTree)))
|
||||||
templateInstantiationTypes->push_back(templateTypeMap[concatSymbolTree(instantiationParam)].clone());
|
templateInstantiationTypes->push_back(templateTypeMap[concatSymbolTree(instantiationParam)].clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
//Lookup function for template functions. It has some extra concerns compared to function lookup, namely traits
|
//Lookup function for template functions. It has some extra concerns compared to function lookup, namely traits
|
||||||
NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type*>* templateInstantiationTypes, std::vector<Type> types) {
|
NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type*>* templateInstantiationTypes, std::vector<Type> types, std::map<std::string, Type*> scopeTypeMap) {
|
||||||
std::map<NodeTree<ASTData>*, std::vector<Type*>> templateInstantiationTypesPerFunction;
|
std::map<NodeTree<ASTData>*, std::vector<Type*>> templateInstantiationTypesPerFunction;
|
||||||
std::set<NodeTree<ASTData>*> mostFittingTemplates;
|
std::set<NodeTree<ASTData>*> mostFittingTemplates;
|
||||||
int bestNumTraitsSatisfied = -1;
|
int bestNumTraitsSatisfied = -1;
|
||||||
@@ -1104,17 +1106,19 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
|
|||||||
std::cout << "Not a template, skipping" << std::endl;
|
std::cout << "Not a template, skipping" << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// We have the type map here because we might want to augment it with the typeMap from
|
||||||
|
// the current scope, which would happen if we're trying to instantiate a template member function
|
||||||
|
std::map<std::string, Type*> typeMap = scopeTypeMap;
|
||||||
// If template instantiation was explicit, use those types. Otherwise, unify to find them
|
// If template instantiation was explicit, use those types. Otherwise, unify to find them
|
||||||
if (templateInstantiationTypes->size())
|
if (templateInstantiationTypes->size())
|
||||||
templateInstantiationTypesPerFunction[i] = *templateInstantiationTypes;
|
templateInstantiationTypesPerFunction[i] = *templateInstantiationTypes;
|
||||||
else
|
else
|
||||||
unifyTemplateFunction(i, types, &templateInstantiationTypesPerFunction[i]);
|
unifyTemplateFunction(i, types, &templateInstantiationTypesPerFunction[i], typeMap);
|
||||||
auto nameTraitsPairs = makeTemplateNameTraitPairs(templateSyntaxTree->getChildren()[1]);
|
auto nameTraitsPairs = makeTemplateNameTraitPairs(templateSyntaxTree->getChildren()[1]);
|
||||||
//Check if sizes match between the placeholder and actual template types
|
//Check if sizes match between the placeholder and actual template types
|
||||||
if (nameTraitsPairs.size() != templateInstantiationTypesPerFunction[i].size())
|
if (nameTraitsPairs.size() != templateInstantiationTypesPerFunction[i].size())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::map<std::string, Type*> typeMap;
|
|
||||||
bool traitsEqual = true;
|
bool traitsEqual = true;
|
||||||
int typeIndex = 0;
|
int typeIndex = 0;
|
||||||
int currentTraitsSatisfied = 0;
|
int currentTraitsSatisfied = 0;
|
||||||
@@ -1197,9 +1201,11 @@ std::vector<std::pair<std::string, std::set<std::string>>> ASTTransformation::ma
|
|||||||
return typePairs;
|
return typePairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, Type*> ASTTransformation::makeTemplateFunctionTypeMap(NodeTree<Symbol>* templateNode, std::vector<Type*> types) {
|
std::map<std::string, Type*> ASTTransformation::makeTemplateFunctionTypeMap(NodeTree<Symbol>* templateNode, std::vector<Type*> types, std::map<std::string, Type*> scopeTypeMap) {
|
||||||
auto typePairs = makeTemplateNameTraitPairs(templateNode);
|
auto typePairs = makeTemplateNameTraitPairs(templateNode);
|
||||||
std::map<std::string, Type*> typeMap;
|
// we start with the scopeTypeMap because we want to combine
|
||||||
|
// them (this is for templated member functions of templated objects)
|
||||||
|
std::map<std::string, Type*> typeMap = scopeTypeMap;
|
||||||
int typeIndex = 0;
|
int typeIndex = 0;
|
||||||
std::cout << typePairs.size() << " " << types.size() << std::endl;
|
std::cout << typePairs.size() << " " << types.size() << std::endl;
|
||||||
for (auto i : typePairs) {
|
for (auto i : typePairs) {
|
||||||
@@ -1450,6 +1456,17 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec
|
|||||||
std::vector<Type*> templateActualTypes;
|
std::vector<Type*> templateActualTypes;
|
||||||
NodeTree<ASTData>* templateDefinition = NULL;
|
NodeTree<ASTData>* templateDefinition = NULL;
|
||||||
|
|
||||||
|
// If this is a templated member function, we should also add this function to the object
|
||||||
|
NodeTree<ASTData>* objectForTemplateMethod = NULL;
|
||||||
|
// Ok, our scope might have a typeMap if we are inside a templated object and are looking
|
||||||
|
// for a templated member function
|
||||||
|
std::map<std::string, Type*> scopeTypeMap;
|
||||||
|
if (scope->getDataRef()->valueType && scope->getDataRef()->valueType->typeDefinition
|
||||||
|
&& scope->getDataRef()->valueType->typeDefinition->getDataRef()->valueType) {
|
||||||
|
objectForTemplateMethod = scope->getDataRef()->valueType->typeDefinition;
|
||||||
|
scopeTypeMap = objectForTemplateMethod->getDataRef()->valueType->templateTypeReplacement;
|
||||||
|
}
|
||||||
|
|
||||||
// Are we supposed to infer our instantiation, or not? If we have only one child we're inferring as we don't
|
// Are we supposed to infer our instantiation, or not? If we have only one child we're inferring as we don't
|
||||||
// have the actual instantiation part. If do have the instantiation part, then we'll use that.
|
// have the actual instantiation part. If do have the instantiation part, then we'll use that.
|
||||||
// Note that as a part o finferring the instantiation we already find the template, so we make that
|
// Note that as a part o finferring the instantiation we already find the template, so we make that
|
||||||
@@ -1457,7 +1474,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec
|
|||||||
std::string instTypeString = "";
|
std::string instTypeString = "";
|
||||||
if (children.size() == 1) {
|
if (children.size() == 1) {
|
||||||
// templateFunctionLookup adds the actual types to templateActualTypes if it's currently empty
|
// templateFunctionLookup adds the actual types to templateActualTypes if it's currently empty
|
||||||
templateDefinition = templateFunctionLookup(scope, functionName, &templateActualTypes, types);
|
templateDefinition = templateFunctionLookup(scope, functionName, &templateActualTypes, types, scopeTypeMap);
|
||||||
for (auto instType : templateActualTypes)
|
for (auto instType : templateActualTypes)
|
||||||
instTypeString += (instTypeString == "" ? instType->toString() : "," + instType->toString());
|
instTypeString += (instTypeString == "" ? instType->toString() : "," + instType->toString());
|
||||||
} else {
|
} else {
|
||||||
@@ -1497,7 +1514,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec
|
|||||||
// by here, it's not as either we had the instantiation already or we figured out out before
|
// by here, it's not as either we had the instantiation already or we figured out out before
|
||||||
// and are not actually doing this call
|
// and are not actually doing this call
|
||||||
if (!templateDefinition)
|
if (!templateDefinition)
|
||||||
templateDefinition = templateFunctionLookup(scope, functionName, &templateActualTypes, types);
|
templateDefinition = templateFunctionLookup(scope, functionName, &templateActualTypes, types, scopeTypeMap);
|
||||||
if (templateDefinition == NULL) {
|
if (templateDefinition == NULL) {
|
||||||
std::cout << functionName << " search turned up null, returing null" << std::endl;
|
std::cout << functionName << " search turned up null, returing null" << std::endl;
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1505,7 +1522,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec
|
|||||||
|
|
||||||
NodeTree<Symbol>* templateSyntaxTree = templateDefinition->getDataRef()->valueType->templateDefinition;
|
NodeTree<Symbol>* templateSyntaxTree = templateDefinition->getDataRef()->valueType->templateDefinition;
|
||||||
// Makes a map between the names of the template placeholder parameters and the provided types
|
// Makes a map between the names of the template placeholder parameters and the provided types
|
||||||
std::map<std::string, Type*> newTemplateTypeReplacement = makeTemplateFunctionTypeMap(templateSyntaxTree->getChildren()[1], templateActualTypes);
|
std::map<std::string, Type*> newTemplateTypeReplacement = makeTemplateFunctionTypeMap(templateSyntaxTree->getChildren()[1], templateActualTypes, scopeTypeMap);
|
||||||
|
|
||||||
std::vector<NodeTree<Symbol>*> templateChildren = templateSyntaxTree->getChildren();
|
std::vector<NodeTree<Symbol>*> templateChildren = templateSyntaxTree->getChildren();
|
||||||
for (int i = 0; i < templateChildren.size(); i++)
|
for (int i = 0; i < templateChildren.size(); i++)
|
||||||
@@ -1516,7 +1533,8 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec
|
|||||||
addToScope("~enclosing_scope", templateDefinition->getDataRef()->scope["~enclosing_scope"][0], instantiatedFunction);
|
addToScope("~enclosing_scope", templateDefinition->getDataRef()->scope["~enclosing_scope"][0], instantiatedFunction);
|
||||||
// Arrrrrgh this has a hard time working because the functions will need to see their parameter once they are emitted as C.
|
// Arrrrrgh this has a hard time working because the functions will need to see their parameter once they are emitted as C.
|
||||||
// HAHAHAHAHA DOESN'T MATTER ALL ONE C FILE NOW, swap back to old way
|
// HAHAHAHAHA DOESN'T MATTER ALL ONE C FILE NOW, swap back to old way
|
||||||
auto templateTopScope = getUpperTranslationUnit(templateDefinition);
|
// OR, THIS IS A TEMPLATE METHOD AND ADD TO THE OBJECT
|
||||||
|
auto templateTopScope = objectForTemplateMethod ? objectForTemplateMethod : getUpperTranslationUnit(templateDefinition);
|
||||||
addToScope(fullyInstantiatedName, instantiatedFunction, templateTopScope);
|
addToScope(fullyInstantiatedName, instantiatedFunction, templateTopScope);
|
||||||
templateTopScope->addChild(instantiatedFunction); // Add this object the the highest scope's
|
templateTopScope->addChild(instantiatedFunction); // Add this object the the highest scope's
|
||||||
|
|
||||||
|
|||||||
@@ -227,7 +227,8 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
|||||||
std::string objectFunctionDefinitions = "/* Method Definitions for " + declarationData.symbol.getName() + " */\n";
|
std::string objectFunctionDefinitions = "/* Method Definitions for " + declarationData.symbol.getName() + " */\n";
|
||||||
for (int j = 0; j < decChildren.size(); j++) {
|
for (int j = 0; j < decChildren.size(); j++) {
|
||||||
std::cout << decChildren[j]->getName() << std::endl;
|
std::cout << decChildren[j]->getName() << std::endl;
|
||||||
if (decChildren[j]->getName() == "function") //If object method
|
if (decChildren[j]->getName() == "function"
|
||||||
|
&& decChildren[j]->getDataRef()->valueType->baseType != template_type) //If object method and not template
|
||||||
objectFunctionDefinitions += generateObjectMethod(declaration, decChildren[j], &functionPrototypes) + "\n";
|
objectFunctionDefinitions += generateObjectMethod(declaration, decChildren[j], &functionPrototypes) + "\n";
|
||||||
}
|
}
|
||||||
// Add all aliases to the plain typedefs. This will add any alias that aliases to this object, and any alias that aliases to that, and so on
|
// Add all aliases to the plain typedefs. This will add any alias that aliases to this object, and any alias that aliases to that, and so on
|
||||||
@@ -397,7 +398,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
&& children[1]->getChildren()[0]->getChildren()[1] == children[0]) {
|
&& children[1]->getChildren()[0]->getChildren()[1] == children[0]) {
|
||||||
//That is, if we're a declaration with an init position call (Object a.construct())
|
//That is, if we're a declaration with an init position call (Object a.construct())
|
||||||
//We can tell if our function call (children[1])'s access operation([0])'s lhs ([1]) is the thing we just declared (children[0])
|
//We can tell if our function call (children[1])'s access operation([0])'s lhs ([1]) is the thing we just declared (children[0])
|
||||||
return ValueTypeToCType(children[0]->getData().valueType, generate(children[0], enclosingObject, justFuncName)) + "; " + generate(children[1]) + "/*Init Position Call*/";
|
return ValueTypeToCType(children[0]->getData().valueType, generate(children[0], enclosingObject, justFuncName)) + "; " + generate(children[1], enclosingObject, true) + "/*Init Position Call*/";
|
||||||
} else
|
} else
|
||||||
return ValueTypeToCType(children[0]->getData().valueType, generate(children[0], enclosingObject, justFuncName)) + " = " + generate(children[1], enclosingObject, true) + ";";
|
return ValueTypeToCType(children[0]->getData().valueType, generate(children[0], enclosingObject, justFuncName)) + " = " + generate(children[1], enclosingObject, true) + ";";
|
||||||
case if_comp:
|
case if_comp:
|
||||||
|
|||||||
@@ -26,6 +26,13 @@ obj vector<T> (Destructable) {
|
|||||||
delete<T>(data);
|
delete<T>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone(): vector<T> {
|
||||||
|
var newVec.construct(size): vector<T>
|
||||||
|
for (var i = 0; i < size; i++;)
|
||||||
|
newVec.set(i, data[i])
|
||||||
|
return newVec
|
||||||
|
}
|
||||||
|
|
||||||
fun resize(newSize: int): bool {
|
fun resize(newSize: int): bool {
|
||||||
var newData: T* = new<T>(newSize);
|
var newData: T* = new<T>(newSize);
|
||||||
if (!newData)
|
if (!newData)
|
||||||
@@ -67,5 +74,15 @@ obj vector<T> (Destructable) {
|
|||||||
resize(size*2);
|
resize(size*2);
|
||||||
data[size-1] = dataIn;
|
data[size-1] = dataIn;
|
||||||
}
|
}
|
||||||
|
fun in_place(func: fun(T):T):void {
|
||||||
|
for (var i = 0; i < size; i++;)
|
||||||
|
data[i] = func(data[i])
|
||||||
|
}
|
||||||
|
fun map<U>(func: fun(T):U):vector<U> {
|
||||||
|
var newVec.construct(size): vector<U>
|
||||||
|
for (var i = 0; i < size; i++;)
|
||||||
|
newVec.set(i, func(data[i]))
|
||||||
|
return newVec
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
3
tests/test_templateMemberFunction.expected_results
Normal file
3
tests/test_templateMemberFunction.expected_results
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
3.141592
|
||||||
|
7
|
||||||
|
hi
|
||||||
30
tests/test_templateMemberFunction.krak
Normal file
30
tests/test_templateMemberFunction.krak
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import io:*
|
||||||
|
|
||||||
|
obj templd<T> {
|
||||||
|
var data: T
|
||||||
|
fun construct(dataIn:T):void {
|
||||||
|
data = dataIn
|
||||||
|
}
|
||||||
|
fun conv<U>(func: fun(T):U): U {
|
||||||
|
return func(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
obj onlyMember {
|
||||||
|
var data: int
|
||||||
|
fun printAThing<T>(otherDat: T):void {
|
||||||
|
println(data)
|
||||||
|
println(otherDat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main():int {
|
||||||
|
var hmm.construct(3): templd<int>
|
||||||
|
println(hmm.conv(fun(it:int):double { return it + 0.141592; }))
|
||||||
|
|
||||||
|
var onlyM: onlyMember
|
||||||
|
onlyM.data = 7
|
||||||
|
onlyM.printAThing("hi")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
4
|
4
|
||||||
1337
|
1337
|
||||||
|
26614
|
||||||
|
15513
|
||||||
|
3.7000007.7000007.70000015.700000
|
||||||
Destroyed!
|
Destroyed!
|
||||||
|
|||||||
@@ -17,7 +17,22 @@ fun main(): int {
|
|||||||
println(intVec.size);
|
println(intVec.size);
|
||||||
for (var i: int = 0; i < intVec.size; i++;)
|
for (var i: int = 0; i < intVec.size; i++;)
|
||||||
print(intVec.at(i));
|
print(intVec.at(i));
|
||||||
|
println();
|
||||||
|
|
||||||
|
// in place lambda map
|
||||||
|
intVec.in_place(fun(it:int):int { return it*2; })
|
||||||
|
for (var i: int = 0; i < intVec.size; i++;)
|
||||||
|
print(intVec.at(i));
|
||||||
|
println();
|
||||||
|
|
||||||
|
var subd = intVec.map(fun(it:int):int { return it-1; })
|
||||||
|
for (var i: int = 0; i < subd.size; i++;)
|
||||||
|
print(subd.at(i));
|
||||||
|
println();
|
||||||
|
|
||||||
|
var newType = intVec.map(fun(it:int):double { return it+1.7; })
|
||||||
|
for (var i: int = 0; i < newType.size; i++;)
|
||||||
|
print(newType.at(i));
|
||||||
println();
|
println();
|
||||||
|
|
||||||
var desVec: vector<AbleToBeDestroyed>* = new<vector<AbleToBeDestroyed>>()->construct();
|
var desVec: vector<AbleToBeDestroyed>* = new<vector<AbleToBeDestroyed>>()->construct();
|
||||||
|
|||||||
Reference in New Issue
Block a user