ADT equality for basic types should work

This commit is contained in:
Nathan Braswell
2015-11-13 15:49:00 -05:00
parent 2ea504ffc1
commit ed4ed75449
3 changed files with 215 additions and 172 deletions

View File

@@ -104,7 +104,7 @@ NodeTree<ASTData>* ASTTransformation::firstPass(std::string fileName, NodeTree<S
translationUnit->addChild(adt_dec);
adt_dec->getDataRef()->valueType = new Type(adt_dec);
} else if (i->getDataRef()->getName() == "if_comp") {
std::cout << "IF COMP" << std::endl;
//std::cout << "IF COMP" << std::endl;
NodeTree<ASTData>* newNode = addToScope("~enclosing_scope", translationUnit, new NodeTree<ASTData>(i->getDataRef()->getName(), ASTData(if_comp)));
newNode->addChild(addToScope("~enclosing_scope", newNode, new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(concatSymbolTree(i->getChildren()[0]),true)))));
std::set<int> skipChildren;
@@ -201,11 +201,15 @@ void ASTTransformation::secondPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
// Let's make an equality function prototype
Type *thisADTType = adtDef->getDataRef()->valueType;
NodeTree<ASTData>* equalityFunc = new NodeTree<ASTData>("function", ASTData(function, Symbol("operator==", true), new Type(std::vector<Type*>{thisADTType}, new Type(boolean))));
//NodeTree<ASTData>* equalityFunc = new NodeTree<ASTData>("function", ASTData(function, Symbol("operator==", true), new Type(std::vector<Type*>{thisADTType, thisADTType}, new Type(boolean))));
adtDef->addChild(equalityFunc);
addToScope("operator==", equalityFunc, adtDef);
addToScope("~enclosing_scope", adtDef, equalityFunc);
NodeTree<ASTData>* inequalityFunc = new NodeTree<ASTData>("function", ASTData(function, Symbol("operator!=", true), new Type(std::vector<Type*>{thisADTType}, new Type(boolean))));
adtDef->addChild(inequalityFunc);
addToScope("operator!=", inequalityFunc, adtDef);
addToScope("~enclosing_scope", adtDef, inequalityFunc);
for (NodeTree<Symbol>* j : getNodes("adt_option", i)) {
std::string ident_name = concatSymbolTree(getNode("identifier", j));
std::cout << "add ing " << ident_name << " to " << name << " for ADT" << std::endl;
@@ -282,7 +286,7 @@ NodeTree<ASTData>* ASTTransformation::secondPassFunction(NodeTree<Symbol>* from,
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
}
std::cout << "Finished Non-Instantiated Template function " << functionName << std::endl;
//std::cout << "Finished Non-Instantiated Template function " << functionName << std::endl;
return functionDef;
}
functionName = concatSymbolTree(children[0]);
@@ -356,13 +360,13 @@ bool ASTTransformation::fourthPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
if (i.second[0]->getDataRef()->type == type_def && i.second[0]->getDataRef()->valueType->templateTypeReplacement.size()
&& !i.second[0]->getDataRef()->valueType->templateInstantiated) {
classTemplates.push_back(i.second[0]);
std::cout << "Saving " << i.second[0]->getDataRef()->toString() << " to instantiate." << std::endl;
//std::cout << "Saving " << i.second[0]->getDataRef()->toString() << " to instantiate." << std::endl;
changed = true;
}
}
for (auto i : classTemplates) {
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())
if (j->getDataRef()->getName() == "function" && j->getChildren()[1]->getDataRef()->getName() != "template_dec")
thirdPassFunction(j, searchScopeForFunctionDef(i, j, classTemplateType->templateTypeReplacement), classTemplateType->templateTypeReplacement); //do member method
@@ -378,16 +382,16 @@ NodeTree<ASTData>* ASTTransformation::searchScopeForFunctionDef(NodeTree<ASTData
std::vector<Type> types;
std::vector<NodeTree<Symbol>*> children = parseTree->getChildren();
//Skipping the initial return type and identifier as well as the final code block
std::cout << "\n Searching scope for function def, function is: " << concatSymbolTree(children[0]) << ", children size is " << children.size() << std::endl;
//std::cout << "\n Searching scope for function def, function is: " << concatSymbolTree(children[0]) << ", children size is " << children.size() << std::endl;
for (auto param: getNodes("typed_parameter", children)) { //Skip over commas
std::cout << "Making type for lookup ||" << concatSymbolTree(param) << "||" << std::endl;
//std::cout << "Making type for lookup ||" << concatSymbolTree(param) << "||" << std::endl;
Type type = *typeFromTypeNode(param->getChildren().back(), scope, templateTypeReplacements);
std::cout << "Type made: " << type.toString() << std::endl;
//std::cout << "Type made: " << type.toString() << std::endl;
types.push_back(type);
}
std::cout << "About to search scope about " << concatSymbolTree(children[0]) << std::endl;
//std::cout << "About to search scope about " << concatSymbolTree(children[0]) << std::endl;
NodeTree<ASTData>* result = functionLookup(scope, functionName, types);
std::cout << "Done searching scope about " << concatSymbolTree(children[0]) << std::endl;
//std::cout << "Done searching scope about " << concatSymbolTree(children[0]) << std::endl;
return result;
}
@@ -414,12 +418,12 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
if (name == "identifier" || name == "scoped_identifier") {
//Make sure we get the entire name
std::string lookupName = concatSymbolTree(from);
std::cout << "Looking up: " << lookupName << std::endl;
//std::cout << "Looking up: " << lookupName << std::endl;
if (limitToFunction) {
newNode = functionLookup(scope, lookupName, types);
if (newNode == NULL) {
std::cout << "scope lookup failed! Could not find " << lookupName << " in identifier (functionLookup)" << std::endl;
std::cout << "(maybe this is supposted to happen because the function is a template and we're infrencing), or this is a operator() call" << std::endl;
std::cout << "scope lookup failed! Could not find " << lookupName << " in identifier (functionLookup)" << std::endl;
std::cout << "(maybe this is supposted to happen because the function is a template and we're infrencing), or this is a operator() call" << std::endl;
// Ok, now we try the case where the lookupName is an object, and we'll try to look for operator()
// in its scope
for (auto possibleObj : scopeLookup(scope, lookupName)) {
@@ -468,7 +472,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
} else if (name == "type_def") {
//If it is an alisis of a type
std::string typeAlias;
std::cout << "The scope here at type_def is " << scope->getDataRef()->toString() << std::endl;
//std::cout << "The scope here at type_def is " << scope->getDataRef()->toString() << std::endl;
if (children[1]->getData().getName() == "type") {
typeAlias = concatSymbolTree(children[0]);
newNode = scope->getDataRef()->scope[typeAlias][0]; //The node for this type_def has already been made by translation_unit.
@@ -481,7 +485,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
Type* objectType = NULL;
if (children[1]->getData().getName() == "template_dec") {
typeAlias = concatSymbolTree(children[0]);
std::cout << "Template Type!"<<std::endl;
//std::cout << "Template Type!"<<std::endl;
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
// std::cout << "typeAlias is " << typeAlias << " and newNode is " << newNode << std::endl;
@@ -521,13 +525,13 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
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, limitToFunction, yetToBeInstantiatedTemplateTypes);
std::cout << "Template function " << functionName << " has these parameters: ";
for (auto i : transChildren)
std::cout << "||" << i->getDataRef()->toString() << "|| ";
std::cout << "??||" << std::endl;
//std::cout << "Template function " << functionName << " has these parameters: ";
//for (auto i : transChildren)
//std::cout << "||" << i->getDataRef()->toString() << "|| ";
//std::cout << "??||" << std::endl;
newNode->addChildren(transChildren);
std::cout << "Finished Non-Instantiated Template function " << functionName << std::endl;
//std::cout << "Finished Non-Instantiated Template function " << functionName << std::endl;
return newNode;
}
if (name == "lambda")
@@ -552,9 +556,9 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
if (name == "lambda")
newNode->getDataRef()->closedVariables = findVariablesToClose(newNode, statement, scope);
for (auto i : newNode->getDataRef()->closedVariables)
std::cout << "OK, CLOSED: " << i->getDataRef()->toString() << std::endl;
//std::cout << "OK, CLOSED: " << i->getDataRef()->toString() << std::endl;
newNode->addChild(statement);
std::cout << "finished function" << functionName << std::endl;
//std::cout << "finished function" << functionName << std::endl;
return newNode;
} else if (name == "code_block") {
@@ -564,12 +568,12 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
} else if (name == "typed_parameter") {
//newNode = transform(children[1]); //Transform to get the identifier
std::string parameterName = concatSymbolTree(children[0]);
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
newNode = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(parameterName, true), typeFromTypeNode(children[2], scope, templateTypeReplacements)));
addToScope(parameterName, newNode, scope);
addToScope("~enclosing_scope", scope, newNode);
std::cout << "Done doing typed_parameter " << parameterName << std::endl;
//std::cout << "Done doing typed_parameter " << parameterName << std::endl;
return newNode;
} else if (name == "boolean_expression" || name == "and_boolean_expression" || name == "bool_exp") {
//If this is an actual part of an expression, not just a premoted term
@@ -597,7 +601,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
NodeTree<ASTData>* lhs = transform(children[0], scope, std::vector<Type>(),false, templateTypeReplacements); //LHS does not inherit types, or limittofunction
NodeTree<ASTData>* rhs;
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, limitToFunction, 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)
@@ -640,11 +644,11 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
else
funcName = concatSymbolTree(children[1]), param = transform(children[0], scope, types, limitToFunction, templateTypeReplacements);
std::cout << "\t\t\t funcName= " << funcName << " param: " << param->getDataRef()->symbol.getName() << std::endl;
//std::cout << "\t\t\t funcName= " << funcName << " param: " << param->getDataRef()->symbol.getName() << std::endl;
//std::cout << "scope lookup from factor" << std::endl;
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(param);
NodeTree<ASTData>* function = doFunction(scope, funcName, transformedChildren, templateTypeReplacements);
std::cout << "\t\t\t AFTER dofunction= " << std::endl;
//std::cout << "\t\t\t AFTER dofunction= " << std::endl;
if (function == NULL) {
std::cerr << "scope lookup error! Could not find " << funcName << " in factor " << std::endl;
throw "LOOKUP ERROR: " + funcName;
@@ -718,10 +722,10 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
NodeTree<Symbol>* typeSyntaxNode = getNode("type", children);
Type* identifierType = typeSyntaxNode ? typeFromTypeNode(typeSyntaxNode, scope, templateTypeReplacements) : nullptr;
if (identifierType)
std::cout << "Declaring an identifier " << newIdentifierStr << " to be of type " << identifierType->toString() << std::endl;
else
std::cout << "Declaring an identifier " << newIdentifierStr << " with type to be type-inferenced " << std::endl;
//if (identifierType)
//std::cout << "Declaring an identifier " << newIdentifierStr << " to be of type " << identifierType->toString() << std::endl;
//else
//std::cout << "Declaring an identifier " << newIdentifierStr << " with type to be type-inferenced " << std::endl;
if (children.size() > 1 && concatSymbolTree(children[1]) == ".") {
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), identifierType));
@@ -801,15 +805,15 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
skipChildren.insert(0);
std::vector<NodeTree<ASTData>*> transformedChildren = transformChildren(children, skipChildren, scope, types, limitToFunction, templateTypeReplacements);
std::cout << "scope lookup from function_call: " << functionCallName << std::endl;
for (auto i : children)
std::cout << i << " : " << i->getName() << " : " << i->getDataRef()->getName() << std::endl;
//std::cout << "scope lookup from function_call: " << functionCallName << std::endl;
//for (auto i : children)
//std::cout << i << " : " << i->getName() << " : " << i->getDataRef()->getName() << std::endl;
NodeTree<ASTData>* function = transform(children[0], scope, mapNodesToTypes(transformedChildren), true, templateTypeReplacements);
std::cout << "The thing: " << function << " : " << function->getName() << std::endl;
for (auto i : function->getChildren())
std::cout << i->getName() << " ";
std::cout << std::endl;
//std::cout << "The thing: " << function << " : " << function->getName() << std::endl;
//for (auto i : function->getChildren())
//std::cout << i->getName() << " ";
//std::cout << std::endl;
newNode->addChild(function);
// note that we now get the return type from the function call's type
newNode->getDataRef()->valueType = function->getDataRef()->valueType->returnType;
@@ -895,11 +899,11 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
auto LLElementIterator = languageLevelOperators.find(lookup);
NodeTree<ASTData>* newNode;
if (LLElementIterator != languageLevelOperators.end()) {
std::cout << "Checking for early method level operator overload" << std::endl;
//std::cout << "Checking for early method level operator overload" << std::endl;
std::string lookupOp = "operator" + lookup;
for (auto i : nodes)
std::cout << i->getDataRef()->toString() << " ";
std::cout << std::endl;
//for (auto i : nodes)
//std::cout << i->getDataRef()->toString() << " ";
//std::cout << std::endl;
NodeTree<ASTData>* operatorMethod = NULL;
// make sure this isn't a pointer, also. Silly vector<string> bug
@@ -911,7 +915,7 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
}
if (operatorMethod) {
//Ok, so we construct
std::cout << "Early method level operator was found" << std::endl;
//std::cout << "Early method level operator was found" << std::endl;
//return operatorMethod;
NodeTree<ASTData>* newNode = new NodeTree<ASTData>(lookupOp, ASTData(function_call, Symbol(lookupOp, true)));
NodeTree<ASTData>* dotFunctionCall = new NodeTree<ASTData>(".", ASTData(function_call, Symbol(".", true), operatorMethod->getDataRef()->valueType));
@@ -926,32 +930,32 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
newNode->getDataRef()->valueType = operatorMethod->getDataRef()->valueType->returnType;
return newNode;
}
std::cout << "Early method level operator was NOT found" << std::endl;
//std::cout << "Early method level operator was NOT found" << std::endl;
if (lookup == "[]=") {
std::cout << "as the operator was []= we're returning nullptr now and gonna let our above handle it as seperate ones" << std::endl;
//std::cout << "as the operator was []= we're returning nullptr now and gonna let our above handle it as seperate ones" << std::endl;
return nullptr;
}
}
newNode = new NodeTree<ASTData>(lookup, ASTData(function_call, Symbol(lookup, true)));
NodeTree<ASTData>* function = functionLookup(scope, lookup, mapNodesToTypes(nodes));
std::cout << "Num of newNode children " << newNode->getChildren().size() << std::endl;
//std::cout << "Num of newNode children " << newNode->getChildren().size() << std::endl;
newNode->addChild(function);
std::cout << "Num of newNode children " << newNode->getChildren().size() << std::endl;
//std::cout << "Num of newNode children " << newNode->getChildren().size() << std::endl;
newNode->addChildren(nodes);
std::cout << "Num of newNode children " << newNode->getChildren().size() << std::endl;
std::cout << "nodes " << nodes.size() << std::endl;
//std::cout << "Num of newNode children " << newNode->getChildren().size() << std::endl;
//std::cout << "nodes " << nodes.size() << std::endl;
//Specially handle dereference and address of to assign the correct type
//We need some significant other type corrections here, maybe to the point of being their own function. (int + float, etc.)
std::cout << "the passed in nodes" << std::endl;
for (auto i : nodes)
std::cout << i->getDataRef()->toString() << " ";
std::cout<<std::endl;
//std::cout << "the passed in nodes" << std::endl;
//for (auto i : nodes)
//std::cout << i->getDataRef()->toString() << " ";
//std::cout<<std::endl;
std::vector<Type> oldTypes = mapNodesToTypes(nodes);
std::cout << "the oldtypes size" << oldTypes.size() << std::endl;
//std::cout << "the oldtypes size" << oldTypes.size() << std::endl;
if ((nodes.size() != 2 && lookup == "*") || lookup == "&" || lookup == "[]") {
Type* newType = oldTypes[0].clone();
if (lookup == "*" || lookup == "[]")
@@ -959,9 +963,9 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
else
newType->increaseIndirection();
newNode->getDataRef()->valueType = newType, std::cout << "Operator " + lookup << " is altering indirection from " << oldTypes[0].toString() << " to " << newType->toString() << std::endl;
newNode->getDataRef()->valueType = newType; //, std::cout << "Operator " + lookup << " is altering indirection from " << oldTypes[0].toString() << " to " << newType->toString() << std::endl;
} else {
std::cout << "Some other ||" << lookup << "||" << std::endl;
//std::cout << "Some other ||" << lookup << "||" << std::endl;
if (function->getDataRef()->valueType)
newNode->getDataRef()->valueType = function->getDataRef()->valueType->returnType;
}
@@ -970,7 +974,7 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
// It's important that it's the last parameter, the rhs if it has one
// because of the . operator, etc
if (newNode->getDataRef()->valueType == NULL) {
std::cout << "The value type from doFunction was null! (for " << lookup << ")" << std::endl;
//std::cout << "The value type from doFunction was null! (for " << lookup << ")" << std::endl;
Type* newType = nullptr;
if (lookup == "->")
newType = oldTypes.back().clone();
@@ -984,7 +988,7 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
//newType = oldTypes.back().clone();
newNode->getDataRef()->valueType = newType;
std::cout << "function call to " << lookup << " - " << newNode->getName() << " is now " << newNode->getDataRef()->valueType << std::endl;
//std::cout << "function call to " << lookup << " - " << newNode->getName() << " is now " << newNode->getDataRef()->valueType << std::endl;
}
return newNode;
}
@@ -1049,7 +1053,7 @@ NodeTree<ASTData>* ASTTransformation::functionLookup(NodeTree<ASTData>* scope, s
//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);
if (LLElementIterator != languageLevelReservedWords.end()) {
std::cout << "found it at language level as reserved word." << std::endl;
//std::cout << "found it at language level as reserved word." << std::endl;
return LLElementIterator->second[0];
}
//We search the languageLevelOperators to see if it's an operator. If so, we modifiy the lookup with a preceding "operator"
@@ -1071,14 +1075,14 @@ NodeTree<ASTData>* ASTTransformation::functionLookup(NodeTree<ASTData>* scope, s
int numTypes = functionType->parameterTypes.size();
if (types.size() != numTypes) {
std::cout << "Type sizes do not match between two " << lookup << "(" << types.size() << "," << numTypes << "), types are: ";
for (auto j : types)
std::cout << j.toString() << " ";
std::cout << std::endl;
std::cout << "Versus" << std::endl;
for (int j = 0; j < numTypes; j++)
std::cout << functionType->parameterTypes[j]->toString() << " ";
std::cout << std::endl;
//std::cout << "Type sizes do not match between two " << lookup << "(" << types.size() << "," << numTypes << "), types are: ";
//for (auto j : types)
//std::cout << j.toString() << " ";
//std::cout << std::endl;
//std::cout << "Versus" << std::endl;
//for (int j = 0; j < numTypes; j++)
//std::cout << functionType->parameterTypes[j]->toString() << " ";
//std::cout << std::endl;
continue;
}
bool typesMatch = true;
@@ -1092,8 +1096,8 @@ NodeTree<ASTData>* ASTTransformation::functionLookup(NodeTree<ASTData>* scope, s
// we use test_equality so that we can pass in a false to not care about references
if (!types[j].test_equality(*tmpType, false)) {
typesMatch = false;
std::cout << "Types do not match between two " << lookup << " " << types[j].toString();
std::cout << " vs " << tmpType->toString() << std::endl;
//std::cout << "Types do not match between two " << lookup << " " << types[j].toString();
//std::cout << " vs " << tmpType->toString() << std::endl;
break;
}
}
@@ -1102,11 +1106,11 @@ NodeTree<ASTData>* ASTTransformation::functionLookup(NodeTree<ASTData>* scope, s
}
}
std::cout << "could not find " << lookup << " in standard scopes, checking for operator" << std::endl;
//std::cout << "could not find " << lookup << " in standard scopes, checking for operator" << std::endl;
//Note that we don't check for types. At some point we should, as we don't know how to add objects/structs without overloaded operators, etc
//Also, we've already searched for the element because this is also how we keep track of operator overloading
if (LLElementIterator != languageLevelOperators.end()) {
std::cout << "found it at language level as operator." << std::endl;
//std::cout << "found it at language level as operator." << std::endl;
return LLElementIterator->second[0];
}
std::cout << "Did not find, returning NULL" << std::endl;
@@ -1118,7 +1122,7 @@ NodeTree<ASTData>* ASTTransformation::templateClassLookup(NodeTree<ASTData>* sco
std::set<NodeTree<ASTData>*> mostFittingTemplates;
int bestNumTraitsSatisfied = -1;
auto possibleMatches = scopeLookup(scope, lookup);
std::cout << "Template Class instantiation has " << possibleMatches.size() << " possible matches." << std::endl;
//std::cout << "Template Class instantiation has " << possibleMatches.size() << " possible matches." << std::endl;
for (auto i : possibleMatches) {
if (i->getDataRef()->type != type_def)
continue;
@@ -1136,20 +1140,20 @@ NodeTree<ASTData>* ASTTransformation::templateClassLookup(NodeTree<ASTData>* sco
// error out if not subset, or if we're a pointer but should have traits
if (!subset(j.second, templateInstantiationTypes[typeIndex]->traits) || (templateInstantiationTypes[typeIndex]->getIndirection() && j.second.size())) {
traitsEqual = false;
std::cout << "Traits not subset 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::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;
//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;
break;
} else {
std::cout << "Traits ARE subset for " << j.first << " and " << templateInstantiationTypes[typeIndex]->toString() << ": ";
//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;
//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 += j.second.size();
typeIndex++;
@@ -1160,12 +1164,12 @@ NodeTree<ASTData>* ASTTransformation::templateClassLookup(NodeTree<ASTData>* sco
//See if this is a better match than the current best
if (currentTraitsSatisfied > bestNumTraitsSatisfied) {
mostFittingTemplates.clear();
std::cout << "Class satisfying " << currentTraitsSatisfied << " beats previous " << bestNumTraitsSatisfied << std::endl;
//std::cout << "Class satisfying " << currentTraitsSatisfied << " beats previous " << bestNumTraitsSatisfied << std::endl;
bestNumTraitsSatisfied = currentTraitsSatisfied;
} else if (currentTraitsSatisfied < bestNumTraitsSatisfied)
continue;
mostFittingTemplates.insert(i);
std::cout << "Current class fits, satisfying " << currentTraitsSatisfied << " traits" << std::endl;
//std::cout << "Current class fits, satisfying " << currentTraitsSatisfied << " traits" << std::endl;
}
if (!mostFittingTemplates.size()) {
std::cout << "No template classes fit for " << lookup << "!" << std::endl;
@@ -1253,8 +1257,8 @@ void ASTTransformation::unifyType(NodeTree<Symbol> *syntaxType, Type type, std::
std::vector<NodeTree<Symbol>*> uninTypeInstTypes = getNodes("type", getNode("template_inst", children));
std::vector<NodeTree<Symbol>*> typeInstTypes = getNodes("template_param", getNode("template_dec", typeTemplateDefinition->getChildren()));
for (int i = 0; i < uninTypeInstTypes.size(); i++) {
std::cout << concatSymbolTree(uninTypeInstTypes[i]) << " : " << origionalType->toString() << " : " << concatSymbolTree(typeInstTypes[i]) << std::endl;
std::cout << "which is " << origionalType->templateTypeReplacement[concatSymbolTree(typeInstTypes[i])]->toString() << std::endl;
//std::cout << concatSymbolTree(uninTypeInstTypes[i]) << " : " << origionalType->toString() << " : " << concatSymbolTree(typeInstTypes[i]) << std::endl;
//std::cout << "which is " << origionalType->templateTypeReplacement[concatSymbolTree(typeInstTypes[i])]->toString() << std::endl;
//std::cout << "which is " << *origionalType->templateTypeReplacement[concatSymbolTree(typeInstTypes[i])] << std::endl;
unifyType(uninTypeInstTypes[i], *origionalType->templateTypeReplacement[concatSymbolTree(typeInstTypes[i])], templateTypeMap, typeMap);
}
@@ -1291,10 +1295,10 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
for (auto i : possibleMatches) {
if (i->getDataRef()->type != function)
continue;
std::cout << "Possibility " << index++ << std::endl;
//std::cout << "Possibility " << index++ << std::endl;
NodeTree<Symbol>* templateSyntaxTree = i->getDataRef()->valueType->templateDefinition;
if (!templateSyntaxTree) {
std::cout << "Not a template, skipping" << std::endl;
//std::cout << "Not a template, skipping" << std::endl;
continue;
}
// We have the type map here because we might want to augment it with the typeMap from
@@ -1303,15 +1307,15 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
// If template instantiation was explicit, use those types. Otherwise, unify to find them
if (templateInstantiationTypes->size()) {
templateInstantiationTypesPerFunction[i] = *templateInstantiationTypes;
std::cout << "passed in types" << std::endl;
//std::cout << "passed in types" << std::endl;
}else{
unifyTemplateFunction(i, types, &templateInstantiationTypesPerFunction[i], typeMap);
std::cout << "unified types" << std::endl;
//std::cout << "unified types" << std::endl;
}
std::cout << "TYPES ARE: ";
for (Type *a : templateInstantiationTypesPerFunction[i])
std::cout << a->toString() << " : ";
std::cout << std::endl;
//std::cout << "TYPES ARE: ";
//for (Type *a : templateInstantiationTypesPerFunction[i])
//std::cout << a->toString() << " : ";
//std::cout << std::endl;
auto nameTraitsPairs = makeTemplateNameTraitPairs(templateSyntaxTree->getChildren()[1]);
//Check if sizes match between the placeholder and actual template types
if (nameTraitsPairs.size() != templateInstantiationTypesPerFunction[i].size())
@@ -1324,18 +1328,18 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
// error out if not subset, or if we're a pointer but should have traits
if (!subset(j.second, templateInstantiationTypesPerFunction[i][typeIndex]->traits) || (templateInstantiationTypesPerFunction[i][typeIndex]->getIndirection() && j.second.size())) {
traitsEqual = false;
std::cout << "Traits not a subset for " << j.first << " and " << templateInstantiationTypesPerFunction[i][typeIndex]->toString() << ": |";
std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
std::cout << "| vs |";
std::copy(templateInstantiationTypesPerFunction[i][typeIndex]->traits.begin(), templateInstantiationTypesPerFunction[i][typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
std::cout << "|" << std::endl;
//std::cout << "Traits not a subset for " << j.first << " and " << templateInstantiationTypesPerFunction[i][typeIndex]->toString() << ": |";
//std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
//std::cout << "| vs |";
//std::copy(templateInstantiationTypesPerFunction[i][typeIndex]->traits.begin(), templateInstantiationTypesPerFunction[i][typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
//std::cout << "|" << std::endl;
break;
} else {
std::cout << "Traits ARE a subset for " << j.first << " and " << templateInstantiationTypesPerFunction[i][typeIndex]->toString() << ": ";
std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
std::cout << " vs ";
std::copy(templateInstantiationTypesPerFunction[i][typeIndex]->traits.begin(), templateInstantiationTypesPerFunction[i][typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
std::cout << std::endl;
//std::cout << "Traits ARE a subset for " << j.first << " and " << templateInstantiationTypesPerFunction[i][typeIndex]->toString() << ": ";
//std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
//std::cout << " vs ";
//std::copy(templateInstantiationTypesPerFunction[i][typeIndex]->traits.begin(), templateInstantiationTypesPerFunction[i][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
typeMap[j.first] = templateInstantiationTypesPerFunction[i][typeIndex];
@@ -1354,11 +1358,11 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
bool parameterTypesMatch = true;
for (int j = 0; j < functionParameters.size(); j++) {
auto paramType = typeFromTypeNode(functionParameters[j]->getChildren()[2], 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;
// use test_equality so we can pass false and not care about references
if (!paramType->test_equality(types[j], false)) {
parameterTypesMatch = false;
std::cout << "Not equal template param: " << paramType->toString() << " : Needed Type actual param: " << types[j].toString() << std::endl;
//std::cout << "Not equal template param: " << paramType->toString() << " : Needed Type actual param: " << types[j].toString() << std::endl;
break;
}
}
@@ -1367,12 +1371,12 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
//See if this is a better match than the current best
if (currentTraitsSatisfied > bestNumTraitsSatisfied) {
mostFittingTemplates.clear();
std::cout << "Function satisfying " << currentTraitsSatisfied << " beats previous " << bestNumTraitsSatisfied << std::endl;
//std::cout << "Function satisfying " << currentTraitsSatisfied << " beats previous " << bestNumTraitsSatisfied << std::endl;
bestNumTraitsSatisfied = currentTraitsSatisfied;
} else if (currentTraitsSatisfied < bestNumTraitsSatisfied)
continue;
mostFittingTemplates.insert(i);
std::cout << "Current function fits, satisfying " << currentTraitsSatisfied << " traits" << std::endl;
//std::cout << "Current function fits, satisfying " << currentTraitsSatisfied << " traits" << std::endl;
}
if (!mostFittingTemplates.size()) {
std::cout << "No template functions fit for " << lookup << "(";
@@ -1415,7 +1419,7 @@ std::map<std::string, Type*> ASTTransformation::makeTemplateFunctionTypeMap(Node
std::cout << typePairs.size() << " " << types.size() << std::endl;
for (auto i : typePairs) {
typeMap[i.first] = types[typeIndex];
std::cout << "Mapping " << i.first << " to " << types[typeIndex]->toString() << std::endl;
//std::cout << "Mapping " << i.first << " to " << types[typeIndex]->toString() << std::endl;
typeIndex++;
}
return typeMap;
@@ -1443,8 +1447,8 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
}
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules, std::set<NodeTree<ASTData>*> visited) {
std::cout << "Scp]|[e looking up " << lookup << std::endl;
std::cout << "current: " << scope->getDataRef()->toString() << std::endl;
//std::cout << "Scp]|[e looking up " << lookup << std::endl;
//std::cout << "current: " << scope->getDataRef()->toString() << std::endl;
//for (auto i : scope->getDataRef()->scope)
//std::cout << "\t" << i.first << std::endl;
//std::cout << i.first << " : " << i.second->toString() << std::endl;
@@ -1455,7 +1459,7 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
//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);
if (LLElementIterator != languageLevelReservedWords.end()) {
std::cout << "found it at language level as reserved word." << std::endl;
//std::cout << "found it at language level as reserved word." << std::endl;
NodeTree<ASTData>* identifier = LLElementIterator->second[0];
if (lookup == "this") {
identifier = generateThis(scope);
@@ -1469,9 +1473,9 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
size_t scopeOpPos = lookup.find("::");
size_t angleBrktPos = lookup.find("<");
if (scopeOpPos != std::string::npos && (angleBrktPos == std::string::npos || scopeOpPos < angleBrktPos)) {
std::cout << "Has :: operator, doing left then right" << std::endl;
//std::cout << "Has :: operator, doing left then right" << std::endl;
for (auto scopeMatch : scopeLookup(scope, strSlice(lookup, 0, scopeOpPos), true)) {
std::cout << "Trying right side with found left side " << scopeMatch->getDataRef()->toString() << std::endl;
//std::cout << "Trying right side with found left side " << scopeMatch->getDataRef()->toString() << std::endl;
auto addMatches = scopeLookup(scopeMatch, strSlice(lookup, scopeOpPos+2, -1), includeModules);
matches.insert(matches.end(), addMatches.begin(), addMatches.end());
}
@@ -1484,7 +1488,7 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
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;
//std::cout << "Found " << possibleMatches->second.size() << " match(s) at " << scope->getDataRef()->toString() << std::endl;
}
// Add results from our enclosing scope, if it exists.
// If it doesn't we should be at the top of a translation unit, and we should check the scope of import statements.
@@ -1583,24 +1587,24 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
//So either this is an uninstatiated template class type, or this is literally a template type T, and we should get it from our
//templateTypeReplacements map. We try this first
if (templateTypeReplacements.find(edited) != templateTypeReplacements.end()) {
std::cout << "Template type! (" << edited << ")" << std::endl;
//std::cout << "Template type! (" << edited << ")" << std::endl;
Type* templateTypeReplacement = templateTypeReplacements[edited]->clone();
templateTypeReplacement->modifyIndirection(indirection);
templateTypeReplacement->is_reference = is_reference;
return templateTypeReplacement;
}
std::cout << edited << " was not found in templateTypeReplacements" << std::endl;
std::cout << "templateTypeReplacements consists of : ";
for (auto i : templateTypeReplacements)
std::cout << i.first << " ";
std::cout << std::endl;
//std::cout << edited << " was not found in templateTypeReplacements" << std::endl;
//std::cout << "templateTypeReplacements consists of : ";
//for (auto i : templateTypeReplacements)
//std::cout << i.first << " ";
//std::cout << std::endl;
std::cout << possibleMatches.size() << " " << typeNode->getChildren().size() << std::endl;
if (typeNode->getChildren().size() > 1)
std::cout << typeNode->getChildren()[1]->getDataRef()->getName() << std::endl;
//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 (possibleMatches.size() == 0 && typeNode->getChildren().size() > 1 && typeNode->getChildren()[1]->getData().getName() == "template_inst") {
std::cout << "Template type: " << edited << " not yet instantiated" << std::endl;
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;
//We pull out the replacement types first so that we can choose the correct possibly overloaded template
std::vector<NodeTree<Symbol>*> templateParamInstantiationNodes = slice(typeNode->getChildren()[1]->getChildren(), 1, -2, 2); //same
@@ -1630,9 +1634,9 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
if (possibleMatches.size()) {
typeDefinition = possibleMatches[0];
traits = typeDefinition->getDataRef()->valueType->traits;
std::cout << "Found already instantiated template of " << templateLookupName << " at second check" << std::endl;
//std::cout << "Found already instantiated template of " << templateLookupName << " at second check" << std::endl;
} else {
std::cout << "Did not find already instantiated template of " << templateLookupName << " at second check" << std::endl;
//std::cout << "Did not find already instantiated template of " << templateLookupName << " at second check" << std::endl;
//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);
@@ -1658,9 +1662,9 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
// Actually, let's just put it in the scope of the origional template, which should work just fine under the new scoping rules and will ACTUALLY prevent multiple instantiation.
// At least, hopefully it will if we also check it's scope for it. Which I think it should be anyway. Yeah, I think it should work.
std::cout << "Adding to template top scope and template's origional scope with fullyInstantiatedName " << fullyInstantiatedName << std::endl;
//std::cout << "Adding to template top scope and template's origional scope with fullyInstantiatedName " << fullyInstantiatedName << std::endl;
auto templateTopScope = getUpperTranslationUnit(templateDefinition);
std::cout << "UPPER TRANS for " << fullyInstantiatedName << " " << templateTopScope->getDataRef()->toString() << std::endl;
//std::cout << "UPPER TRANS for " << fullyInstantiatedName << " " << templateTopScope->getDataRef()->toString() << std::endl;
templateTopScope->getDataRef()->scope[fullyInstantiatedName].push_back(typeDefinition);
templateTopScope->addChild(typeDefinition); // Add this object the the highest scope's
@@ -1679,22 +1683,22 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
// 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->templateTypeReplacement = newTemplateTypeReplacement; //Save the types for use when this is fully instantiated in pass 4
for (auto daPair : selfType->templateTypeReplacement) {
std::cout << " BREAK HERE " << daPair.first << " : " << daPair.second->toString() << std::endl;
if (daPair.second == NULL)
std::cout << " BREAK HERE " << std::endl;
}
//for (auto daPair : selfType->templateTypeReplacement) {
//std::cout << " BREAK HERE " << daPair.first << " : " << daPair.second->toString() << std::endl;
//if (daPair.second == NULL)
//std::cout << " BREAK HERE " << std::endl;
//}
secondPassDoClassInsides(typeDefinition, templateSyntaxTree->getChildren(), newTemplateTypeReplacement); //Use these types when instantiating data members
}
} 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;
return NULL;
} else {
std::cout << "Type: " << edited << " already instantiated with " << typeDefinition << ", will be " << Type(baseType, typeDefinition, indirection, is_reference, traits).toString() << std::endl;
//std::cout << "Type: " << edited << " already instantiated with " << typeDefinition << ", will be " << Type(baseType, typeDefinition, indirection, is_reference, traits).toString() << std::endl;
}
}
Type* toReturn = new Type(baseType, typeDefinition, indirection, is_reference, traits);
std::cout << "Returning type " << toReturn->toString() << std::endl;
//std::cout << "Returning type " << toReturn->toString() << std::endl;
return toReturn;
}
@@ -1715,7 +1719,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::str
}
NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::string functionName, std::vector<NodeTree<Symbol>*> children, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements) {
//First look to see if we can find this already instantiated
std::cout << "\n\nFinding or instantiating templated function\n\n" << std::endl;
//std::cout << "\n\nFinding or instantiating templated function\n\n" << std::endl;
if (children.size())
functionName = concatSymbolTree(children[0]);
std::string fullyInstantiatedName;
@@ -1752,27 +1756,27 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::str
instTypeString += (instTypeString == "" ? instType->toString() : "," + instType->toString());
templateActualTypes.push_back(instType);
}
std::cout << "Size: " << templateParamInstantiationNodes.size() << std::endl;
//std::cout << "Size: " << templateParamInstantiationNodes.size() << std::endl;
}
fullyInstantiatedName = functionName + "<" + instTypeString + ">";
std::cout << "Looking for " << fullyInstantiatedName << std::endl;
std::cout << "Types are : ";
for (auto i : types)
std::cout << " " << i.toString();
std::cout << std::endl;
//std::cout << "Looking for " << fullyInstantiatedName << std::endl;
//std::cout << "Types are : ";
//for (auto i : types)
//std::cout << " " << i.toString();
//std::cout << std::endl;
NodeTree<ASTData>* instantiatedFunction = functionLookup(scope, fullyInstantiatedName, types);
//If it already exists, return it
if (instantiatedFunction) {
std::cout << fullyInstantiatedName << " already exists! Returning" << std::endl;
//std::cout << fullyInstantiatedName << " already exists! Returning" << std::endl;
return instantiatedFunction;
} else {
instantiatedFunction = functionLookup(topScope, fullyInstantiatedName, types);
if (instantiatedFunction) {
std::cout << fullyInstantiatedName << "already exists! Found in TopScope" << std::endl;
//std::cout << fullyInstantiatedName << "already exists! Found in TopScope" << std::endl;
return instantiatedFunction;
}
std::cout << fullyInstantiatedName << " does NOT exist" << std::endl;
//std::cout << fullyInstantiatedName << " does NOT exist" << std::endl;
}
//Otherwise, we're going to instantiate it
@@ -1783,7 +1787,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::str
if (!templateDefinition)
templateDefinition = templateFunctionLookup(scope, functionName, &templateActualTypes, types, scopeTypeMap);
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;
}
scopelessFullyInstantiatedName = templateDefinition->getDataRef()->symbol.getName() + "<" + instTypeString + ">";
@@ -1793,9 +1797,9 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::str
std::map<std::string, Type*> newTemplateTypeReplacement = makeTemplateFunctionTypeMap(templateSyntaxTree->getChildren()[1], templateActualTypes, scopeTypeMap);
std::vector<NodeTree<Symbol>*> templateChildren = templateSyntaxTree->getChildren();
for (int i = 0; i < templateChildren.size(); i++)
std::cout << ", " << i << " : " << templateChildren[i]->getDataRef()->getName();
std::cout << std::endl;
//for (int i = 0; i < templateChildren.size(); i++)
//std::cout << ", " << i << " : " << templateChildren[i]->getDataRef()->getName();
//std::cout << std::endl;
// return type should be looked up in template's scope
auto returnTypeNode = getNode("type", getNode("typed_return", templateChildren)); // if null, the typed_return had no children and we're supposed to automatically do a void type
@@ -1805,7 +1809,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::str
addToScope(scopelessFullyInstantiatedName, instantiatedFunction, templateDefinition->getDataRef()->scope["~enclosing_scope"][0]);
templateDefinition->getDataRef()->scope["~enclosing_scope"][0]->addChild(instantiatedFunction); // Add this object the the highest scope's
std::cout << "About to do children of " << functionName << " to " << fullyInstantiatedName << std::endl;
//std::cout << "About to do children of " << functionName << " to " << fullyInstantiatedName << std::endl;
std::set<int> skipChildren;
auto parameters = transformChildren(getNodes("typed_parameter", templateSyntaxTree->getChildren()), skipChildren, instantiatedFunction, std::vector<Type>(), false, newTemplateTypeReplacement);
@@ -1814,7 +1818,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::str
instantiatedFunction->getDataRef()->valueType = new Type(mapNodesToTypePointers(parameters), instantiatedFunction->getDataRef()->valueType);
instantiatedFunction->addChild(transform(getNode("statement", templateSyntaxTree->getChildren()), instantiatedFunction, std::vector<Type>(), false, newTemplateTypeReplacement));
std::cout << "Fully Instantiated function " << functionName << " to " << fullyInstantiatedName << std::endl;
//std::cout << "Fully Instantiated function " << functionName << " to " << fullyInstantiatedName << std::endl;
return instantiatedFunction;
}
@@ -1828,7 +1832,7 @@ NodeTree<ASTData>* ASTTransformation::addToScope(std::string name, NodeTree<ASTD
std::vector<Type*> mapNodesToTypePointers(std::vector<NodeTree<ASTData>*> nodes) {
std::vector<Type*> types;
for (auto i : nodes) {
std::cout << i->getDataRef()->toString() << std::endl;
//std::cout << i->getDataRef()->toString() << std::endl;
types.push_back((i->getDataRef()->valueType));
}
return types;
@@ -1838,7 +1842,7 @@ std::vector<Type*> mapNodesToTypePointers(std::vector<NodeTree<ASTData>*> nodes)
std::vector<Type> mapNodesToTypes(std::vector<NodeTree<ASTData>*> nodes) {
std::vector<Type> types;
for (auto i : nodes) {
std::cout << i->getDataRef()->toString() << std::endl;
//std::cout << i->getDataRef()->toString() << std::endl;
types.push_back(*(i->getDataRef()->valueType));
}
return types;

View File

@@ -63,7 +63,8 @@ std::string CGenerator::generateTypeStruct(NodeTree<ASTData>* from) {
structString = "struct __struct_dummy_";
structString += prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName())+"__") + " {\n";
if (data.type == adt_def) {
structString = "typedef " + structString + "enum " + enumName + " flag;\n union { \n";
structString = "typedef " + structString + " enum " + enumName + " flag;\n union { \n";
tabLevel++;
}
tabLevel++;
@@ -81,23 +82,52 @@ std::string CGenerator::generateTypeStruct(NodeTree<ASTData>* from) {
enumString += tabs() + generate(child, nullptr).oneString() + (data.type == adt_def ? ",\n" : "\n");
} else {
if (data.type == adt_def) {
std::string fun_name = child->getDataRef()->symbol.getName();
std::string orig_fun_name = child->getDataRef()->symbol.getName();
std::string fun_name;
std::string first_param;
if (fun_name == "operator==") {
fun_name = "fun_" + data.symbol.getName() + "__" + CifyName(fun_name);
if (orig_fun_name == "operator==" || orig_fun_name == "operator!=") {
fun_name = "fun_" + data.symbol.getName() + "__" + CifyName(orig_fun_name);
first_param = ValueTypeToCType(child->getDataRef()->valueType->parameterTypes[0]->withIncreasedIndirectionPtr(), "this") + ", ";
} else {
fun_name = "fun_" + fun_name;
fun_name = "fun_" + orig_fun_name;
}
bool has_param = child->getDataRef()->valueType->parameterTypes.size();
functionString += "\n" + ValueTypeToCType(child->getDataRef()->valueType->returnType, fun_name) + "(" + first_param +
(child->getDataRef()->valueType->parameterTypes.size() ? ValueTypeToCType(child->getDataRef()->valueType->parameterTypes[0], "in") : "") + "); /*adt func*/\n";
(has_param ? ValueTypeToCType(child->getDataRef()->valueType->parameterTypes[0], "in") : "") + ") { /*adt func*/\n";
if (orig_fun_name == "operator==") {
functionString += " /* equality woop woop */\n";
functionString += " if (this->flag != in.flag) return false;\n";
for (auto child : children) {
if (child->getName() != "function" && child->getDataRef()->valueType->typeDefinition != from) {
std::string option_name = child->getDataRef()->symbol.getName();
functionString += " if (this->flag == " + option_name + ")\n";
functionString += " return this->" + option_name + " == in." + option_name + ";\n";
}
}
functionString += " return true;\n";
} else if (orig_fun_name == "operator!=") {
functionString += " /* inequality woop woop */\n";
functionString += " return !fun_" + data.symbol.getName() + "__" + CifyName("operator==") + "(this, in);\n";
} else {
// ok, is a constructor function
functionString += " /* constructor woop woop */\n";
functionString += " " + data.symbol.getName() + " toRet;\n";
functionString += " toRet.flag = " + orig_fun_name + ";\n";
if (has_param)
functionString += " toRet." + orig_fun_name + " = in;\n";
functionString += " return toRet;\n";
}
functionString += "}\n";
}
}
}
tabLevel--;
if (data.type == adt_def) {
//structString += "} data; /*end union*/ \n";
structString += "}; /*end union*/\n } " + CifyName(data.symbol.getName()) + "; /* end struct */";
tabLevel--;
structString += " }; /*end union*/\n} " + CifyName(data.symbol.getName()) + "; /* end struct */";
} else {
structString += "};";
}
@@ -268,7 +298,7 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
function_header + prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName() + nameDecoration));
functionPrototypes += "\n" + ValueTypeToCType(declarationData.valueType->returnType, funName) + "(" + parameters + "); /*func*/\n";
// generate function
std::cout << "Generating " << prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName())) << std::endl;
//std::cout << "Generating " << prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName())) << std::endl;
functionDefinitions += generate(declaration, nullptr).oneString();
}
}
@@ -294,7 +324,7 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
// We use a seperate string for this because we only include it if this is the file we're defined in
std::string objectFunctionDefinitions = "/* Method Definitions for " + declarationData.symbol.getName() + " */\n";
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"
&& decChildren[j]->getDataRef()->valueType->baseType != template_type) //If object method and not template
objectFunctionDefinitions += generateObjectMethod(declaration, decChildren[j], &functionPrototypes) + "\n";
@@ -361,7 +391,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
// first, get declaring function, if it exists
if (enclosingFunction) {
if (enclosingFunction->getDataRef()->closedVariables.size()) {
std::cout << "WHOH IS A CLOSER" << std::endl;
//std::cout << "WHOH IS A CLOSER" << std::endl;
if (enclosingFunction->getDataRef()->closedVariables.find(from) != enclosingFunction->getDataRef()->closedVariables.end()) {
preName += "(*closed_variables->";
postName += ")";

View File

@@ -1,4 +1,4 @@
/*import io:**/
import io:*
adt options {
option0,
@@ -12,12 +12,12 @@ adt maybe_int {
fun handle_possibility(it: maybe_int) {
if (it == maybe_int::no_int()) {
/*println("no int")*/
println("no int")
}
/*if (it == maybe_int::an_int) {*/
else {
/*print("an int: ")*/
/*println(it.an_int)*/
print("an int: ")
println(it.an_int)
}
}
@@ -34,16 +34,25 @@ fun can_pass(it: options): options {
fun main():int {
var it: options = can_pass(options::option0())
if (it == options::option0()) {
/*println("nope")*/
println("nope")
}
if (it == options::option1()) {
/*println("option1")*/
println("option1")
}
var possibility = give_maybe(false)
handle_possibility(possibility)
possibility = give_maybe(true)
handle_possibility(possibility)
if ( maybe_int::an_int(7) == maybe_int::an_int(7) )
println("equality true works!")
else
println("equality true fails!")
if ( maybe_int::an_int(7) != maybe_int::an_int(8) )
println("equality false works!")
else
println("equality false fails!")
return 0
}