Fixed operator overloading so that both method and non-method operator overloads work.

This commit is contained in:
Nathan Braswell
2014-04-27 02:48:57 -04:00
parent 3728a849de
commit 1997ba49d2
2 changed files with 47 additions and 41 deletions

View File

@@ -20,7 +20,7 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
std::vector<NodeTree<ASTData>*> transformChildren(std::vector<NodeTree<Symbol>*> children, std::set<int> skipChildren, NodeTree<ASTData>* scope, std::vector<Type> types); std::vector<NodeTree<ASTData>*> transformChildren(std::vector<NodeTree<Symbol>*> children, std::set<int> skipChildren, NodeTree<ASTData>* scope, std::vector<Type> types);
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>* scopeLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<NodeTree<ASTData>*> nodes); NodeTree<ASTData>* doFunction(NodeTree<ASTData>* scope, std::string lookup, std::vector<NodeTree<ASTData>*> nodes);
NodeTree<ASTData>* scopeLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types = std::vector<Type>()); NodeTree<ASTData>* scopeLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types = std::vector<Type>());
Type* typeFromString(std::string type, NodeTree<ASTData>* scope); Type* typeFromString(std::string type, NodeTree<ASTData>* scope);
private: private:

View File

@@ -122,14 +122,15 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
skipChildren.insert(1); skipChildren.insert(1);
std::vector<NodeTree<ASTData>*> transformedChildren = transformChildren(children, skipChildren, scope, types); std::vector<NodeTree<ASTData>*> transformedChildren = transformChildren(children, skipChildren, scope, types);
std::string functionCallString = concatSymbolTree(children[1]); std::string functionCallString = concatSymbolTree(children[1]);
NodeTree<ASTData>* function = scopeLookup(scope, functionCallString, transformedChildren); NodeTree<ASTData>* function = doFunction(scope, functionCallString, transformedChildren);
if (function == NULL) { if (function == NULL) {
std::cout << "scope lookup error! Could not find " << functionCallString << " in boolean stuff " << std::endl; std::cout << "scope lookup error! Could not find " << functionCallString << " in boolean stuff " << std::endl;
throw "LOOKUP ERROR: " + functionCallString; throw "LOOKUP ERROR: " + functionCallString;
} }
newNode = new NodeTree<ASTData>(functionCallString, ASTData(function_call, function->getDataRef()->valueType)); newNode = function;
newNode->addChild(function); // First child of function call is a link to the function // newNode = new NodeTree<ASTData>(functionCallString, ASTData(function_call, function->getDataRef()->valueType));
newNode->addChildren(transformedChildren); // newNode->addChild(function); // First child of function call is a link to the function
// newNode->addChildren(transformedChildren);
} else { } else {
//std::cout << children.size() << std::endl; //std::cout << children.size() << std::endl;
if (children.size() == 0) if (children.size() == 0)
@@ -150,20 +151,21 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
std::string functionCallName = concatSymbolTree(children[1]); std::string functionCallName = concatSymbolTree(children[1]);
//std::cout << "scope lookup from expression or similar" << std::endl; //std::cout << "scope lookup from expression or similar" << std::endl;
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);
NodeTree<ASTData>* function = scopeLookup(scope, functionCallName, transformedChildren); NodeTree<ASTData>* function = doFunction(scope, functionCallName, transformedChildren);
if (function == NULL) { if (function == NULL) {
std::cout << "scope lookup error! Could not find " << functionCallName << " in expression " << std::endl; std::cout << "scope lookup error! Could not find " << functionCallName << " in expression " << std::endl;
throw "LOOKUP ERROR: " + functionCallName; throw "LOOKUP ERROR: " + functionCallName;
} }
newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true))); newNode = function;
newNode->addChild(function); // First child of function call is a link to the function definition // newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
newNode->addChild(lhs); // newNode->addChild(function); // First child of function call is a link to the function definition
newNode->addChild(rhs); // newNode->addChild(lhs);
// newNode->addChild(rhs);
if (name == "access_operation") // if (name == "access_operation")
std::cout << "Access Operation: " << lhs->getDataRef()->symbol.getName() << " : " << rhs->getDataRef()->symbol.getName() << std::endl; // std::cout << "Access Operation: " << lhs->getDataRef()->symbol.getName() << " : " << rhs->getDataRef()->symbol.getName() << std::endl;
std::cout << functionCallName << " - " << function->getName() << " has value type " << function->getDataRef()->valueType << " and rhs " << rhs->getDataRef()->valueType << std::endl; // std::cout << functionCallName << " - " << function->getName() << " has value type " << function->getDataRef()->valueType << " and rhs " << rhs->getDataRef()->valueType << std::endl;
//Set the value of this function call // //Set the value of this function call
if (function->getDataRef()->valueType) if (function->getDataRef()->valueType)
newNode->getDataRef()->valueType = function->getDataRef()->valueType; newNode->getDataRef()->valueType = function->getDataRef()->valueType;
else if (rhs->getDataRef()->valueType) else if (rhs->getDataRef()->valueType)
@@ -189,18 +191,19 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
//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);
NodeTree<ASTData>* function = scopeLookup(scope, funcName, transformedChildren); NodeTree<ASTData>* function = doFunction(scope, funcName, transformedChildren);
if (function == NULL) { if (function == NULL) {
std::cout << "scope lookup error! Could not find " << funcName << " in factor " << std::endl; std::cout << "scope lookup error! Could not find " << funcName << " in factor " << std::endl;
throw "LOOKUP ERROR: " + funcName; throw "LOOKUP ERROR: " + funcName;
} }
newNode = new NodeTree<ASTData>(funcName, ASTData(function_call, Symbol(funcName, true))); newNode = function;
newNode->addChild(function); // newNode = new NodeTree<ASTData>(funcName, ASTData(function_call, Symbol(funcName, true)));
newNode->addChild(param); // newNode->addChild(function);
if (function->getDataRef()->valueType) // newNode->addChild(param);
newNode->getDataRef()->valueType = function->getDataRef()->valueType; // if (function->getDataRef()->valueType)
else // newNode->getDataRef()->valueType = function->getDataRef()->valueType;
newNode->getDataRef()->valueType = param->getDataRef()->valueType; // else
// newNode->getDataRef()->valueType = param->getDataRef()->valueType;
return newNode; return newNode;
} else { } else {
@@ -228,17 +231,13 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
NodeTree<ASTData>* rhs = transform(children[2], scope, types); NodeTree<ASTData>* rhs = transform(children[2], scope, types);
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>* childCall = new NodeTree<ASTData>(functionName, ASTData(function_call, Symbol(functionName, true))); NodeTree<ASTData>* operatorCall = doFunction(scope, functionName, transformedChildren);
NodeTree<ASTData>* functionDef = scopeLookup(scope, functionName, transformedChildren); if (operatorCall == NULL) {
if (functionDef == NULL) {
std::cout << "scope lookup error! Could not find " << functionName << " in assignment_statement " << std::endl; std::cout << "scope lookup error! Could not find " << functionName << " in assignment_statement " << std::endl;
throw "LOOKUP ERROR: " + functionName; throw "LOOKUP ERROR: " + functionName;
} }
childCall->addChild(functionDef); //First child of function call is definition of the function
childCall->addChild(lhs);
childCall->addChild(rhs);
newNode->addChild(lhs); newNode->addChild(lhs);
newNode->addChild(childCall); newNode->addChild(operatorCall);
} }
return newNode; return newNode;
} else if (name == "declaration_statement") { } else if (name == "declaration_statement") {
@@ -363,9 +362,10 @@ std::string ASTTransformation::concatSymbolTree(NodeTree<Symbol>* root) {
} }
//Overloaded with the actual children to allow us to handle operator methods //Overloaded with the actual children to allow us to handle operator methods
NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<NodeTree<ASTData>*> nodes) { NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::string lookup, std::vector<NodeTree<ASTData>*> nodes) {
// //
auto LLElementIterator = languageLevelScope.find(lookup); auto LLElementIterator = languageLevelScope.find(lookup);
NodeTree<ASTData>* newNode;
if (LLElementIterator != languageLevelScope.end()) { if (LLElementIterator != languageLevelScope.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; std::string lookupOp = "operator" + lookup;
@@ -379,23 +379,29 @@ NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std:
//Ok, so we construct //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; //return operatorMethod;
newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true))); NodeTree<ASTData>* newNode = new NodeTree<ASTData>(lookupOp, ASTData(function_call, Symbol(lookupOp, true)));
newNode->addChild(function); // First child of function call is a link to the function definition NodeTree<ASTData>* dotFunctionCall = new NodeTree<ASTData>(".", ASTData(function_call, Symbol(".", true)));
newNode->addChild(lhs); dotFunctionCall->addChild(languageLevelScope["."][0]); //function definition
newNode->addChild(rhs); dotFunctionCall->addChild(nodes[0]); // The object whose method we're calling
dotFunctionCall->addChild(operatorMethod); //The method we're calling
newNode->addChild(dotFunctionCall); // First child of function call is a link to the function definition
newNode->addChildren(slice(nodes, 1, -1)); //The rest of the parameters to the operator
//Set the value of this function call //Set the value of this function call
if (function->getDataRef()->valueType) newNode->getDataRef()->valueType = operatorMethod->getDataRef()->valueType;
newNode->getDataRef()->valueType = function->getDataRef()->valueType; return newNode;
else if (rhs->getDataRef()->valueType)
newNode->getDataRef()->valueType = rhs->getDataRef()->valueType;
else
newNode->getDataRef()->valueType = NULL;
} }
std::cout << "Early method level operator was NOT found" << std::endl; std::cout << "Early method level operator was NOT found" << std::endl;
} }
return scopeLookup(scope, lookup, mapNodesToTypes(nodes));
newNode = new NodeTree<ASTData>(lookup, ASTData(function_call, Symbol(lookup, true)));
NodeTree<ASTData>* function = scopeLookup(scope, lookup, mapNodesToTypes(nodes));
newNode->addChild(function);
newNode->addChildren(nodes);
newNode->getDataRef()->valueType = function->getDataRef()->valueType;
return newNode;
} }
NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types) { NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types) {