Objects work now! We have methods!
This commit is contained in:
@@ -23,4 +23,5 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
|
|||||||
private:
|
private:
|
||||||
Importer * importer;
|
Importer * importer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
2
main.cpp
2
main.cpp
@@ -138,7 +138,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
/*NodeTree<ASTData>* AST =*/
|
/*NodeTree<ASTData>* AST =*/
|
||||||
importer.import(programName);
|
importer.import(programName);
|
||||||
std::map<std::string, NodeTree<ASTData>*> ASTs =importer.getASTMap();
|
std::map<std::string, NodeTree<ASTData>*> ASTs = importer.getASTMap();
|
||||||
|
|
||||||
//Do optomization, etc. here.
|
//Do optomization, etc. here.
|
||||||
//None at this time, instead going straight to C in this first (more naive) version
|
//None at this time, instead going straight to C in this first (more naive) version
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ ASTData::~ASTData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string ASTData::toString() {
|
std::string ASTData::toString() {
|
||||||
return ASTTypeToString(type) + (symbol.isTerminal() ? " " + symbol.toString() : "") + " " + (valueType ? valueType->toString() : "no_type");
|
return ASTTypeToString(type) + " " +
|
||||||
|
(symbol.isTerminal() ? " " + symbol.toString() : "") + " " +
|
||||||
|
(valueType ? valueType->toString() : "no_type");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ASTData::ASTTypeToString(ASTType type) {
|
std::string ASTData::ASTTypeToString(ASTType type) {
|
||||||
|
|||||||
@@ -24,27 +24,26 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
if (name == "translation_unit") {
|
if (name == "translation_unit") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(translation_unit));
|
newNode = new NodeTree<ASTData>(name, ASTData(translation_unit));
|
||||||
scope = newNode;
|
scope = newNode;
|
||||||
//Temporary scope fix
|
//Temporary scope fix, use placeholder type
|
||||||
Type placeholderType;
|
scope->getDataRef()->scope["+"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("+", true), NULL));
|
||||||
scope->getDataRef()->scope["+"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("+", true), &placeholderType));
|
scope->getDataRef()->scope["-"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("-", true), NULL));
|
||||||
scope->getDataRef()->scope["-"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("-", true), &placeholderType));
|
scope->getDataRef()->scope["*"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("*", true), NULL));
|
||||||
scope->getDataRef()->scope["*"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("*", true), &placeholderType));
|
scope->getDataRef()->scope["&"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("&", true), NULL));
|
||||||
scope->getDataRef()->scope["&"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("&", true), &placeholderType));
|
scope->getDataRef()->scope["--"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("--", true), NULL));
|
||||||
scope->getDataRef()->scope["--"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("--", true), &placeholderType));
|
scope->getDataRef()->scope["++"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("++", true), NULL));
|
||||||
scope->getDataRef()->scope["++"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("++", true), &placeholderType));
|
scope->getDataRef()->scope["=="] = new NodeTree<ASTData>("function", ASTData(function, Symbol("==", true), NULL));
|
||||||
scope->getDataRef()->scope["=="] = new NodeTree<ASTData>("function", ASTData(function, Symbol("==", true), &placeholderType));
|
scope->getDataRef()->scope["<="] = new NodeTree<ASTData>("function", ASTData(function, Symbol("<=", true), NULL));
|
||||||
scope->getDataRef()->scope["<="] = new NodeTree<ASTData>("function", ASTData(function, Symbol("<=", true), &placeholderType));
|
scope->getDataRef()->scope[">="] = new NodeTree<ASTData>("function", ASTData(function, Symbol(">=", true), NULL));
|
||||||
scope->getDataRef()->scope[">="] = new NodeTree<ASTData>("function", ASTData(function, Symbol(">=", true), &placeholderType));
|
scope->getDataRef()->scope["<"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("<", true), NULL));
|
||||||
scope->getDataRef()->scope["<"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("<", true), &placeholderType));
|
scope->getDataRef()->scope[">"] = new NodeTree<ASTData>("function", ASTData(function, Symbol(">", true), NULL));
|
||||||
scope->getDataRef()->scope[">"] = new NodeTree<ASTData>("function", ASTData(function, Symbol(">", true), &placeholderType));
|
scope->getDataRef()->scope["&&"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("&&", true), NULL));
|
||||||
scope->getDataRef()->scope["&&"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("&&", true), &placeholderType));
|
scope->getDataRef()->scope["||"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("||", true), NULL));
|
||||||
scope->getDataRef()->scope["||"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("||", true), &placeholderType));
|
scope->getDataRef()->scope["!"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("!", true), NULL));
|
||||||
scope->getDataRef()->scope["!"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("!", true), &placeholderType));
|
scope->getDataRef()->scope["*="] = new NodeTree<ASTData>("function", ASTData(function, Symbol("*=", true), NULL));
|
||||||
scope->getDataRef()->scope["*="] = new NodeTree<ASTData>("function", ASTData(function, Symbol("*=", true), &placeholderType));
|
scope->getDataRef()->scope["+="] = new NodeTree<ASTData>("function", ASTData(function, Symbol("+=", true), NULL));
|
||||||
scope->getDataRef()->scope["+="] = new NodeTree<ASTData>("function", ASTData(function, Symbol("+=", true), &placeholderType));
|
scope->getDataRef()->scope["-="] = new NodeTree<ASTData>("function", ASTData(function, Symbol("-=", true), NULL));
|
||||||
scope->getDataRef()->scope["-="] = new NodeTree<ASTData>("function", ASTData(function, Symbol("-=", true), &placeholderType));
|
scope->getDataRef()->scope["."] = new NodeTree<ASTData>("function", ASTData(function, Symbol(".", true), NULL));
|
||||||
scope->getDataRef()->scope["."] = new NodeTree<ASTData>("function", ASTData(function, Symbol(".", true), &placeholderType));
|
scope->getDataRef()->scope["->"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("->", true), NULL));
|
||||||
scope->getDataRef()->scope["->"] = new NodeTree<ASTData>("function", ASTData(function, Symbol("->", true), &placeholderType));
|
|
||||||
|
|
||||||
} else if (name == "interpreter_directive") {
|
} else if (name == "interpreter_directive") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(interpreter_directive));
|
newNode = new NodeTree<ASTData>(name, ASTData(interpreter_directive));
|
||||||
@@ -116,7 +115,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
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));
|
newNode = new NodeTree<ASTData>(functionCallString, ASTData(function_call, function->getDataRef()->valueType));
|
||||||
newNode->addChild(function); // First child of function call is a link to the function
|
newNode->addChild(function); // First child of function call is a link to the function
|
||||||
skipChildren.insert(1);
|
skipChildren.insert(1);
|
||||||
} else {
|
} else {
|
||||||
@@ -150,6 +149,14 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
|
|
||||||
newNode->addChild(lhs);
|
newNode->addChild(lhs);
|
||||||
newNode->addChild(rhs);
|
newNode->addChild(rhs);
|
||||||
|
std::cout << functionCallName << " - " << function->getName() << " has value type " << function->getDataRef()->valueType << " and rhs " << rhs->getDataRef()->valueType << std::endl;
|
||||||
|
if (function->getDataRef()->valueType)
|
||||||
|
newNode->getDataRef()->valueType = function->getDataRef()->valueType;
|
||||||
|
else if (rhs->getDataRef()->valueType)
|
||||||
|
newNode->getDataRef()->valueType = rhs->getDataRef()->valueType;
|
||||||
|
else
|
||||||
|
newNode->getDataRef()->valueType = NULL;
|
||||||
|
std::cout << "function call to " << functionCallName << " - " << function->getName() << " is now " << newNode->getDataRef()->valueType << std::endl;
|
||||||
return newNode;
|
return newNode;
|
||||||
//skipChildren.insert(1);
|
//skipChildren.insert(1);
|
||||||
} else {
|
} else {
|
||||||
@@ -160,11 +167,11 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
//NO SUPPORT FOR CASTING YET
|
//NO SUPPORT FOR CASTING YET
|
||||||
if (children.size() == 2) {
|
if (children.size() == 2) {
|
||||||
std::string funcName = concatSymbolTree(children[0]);
|
std::string funcName = concatSymbolTree(children[0]);
|
||||||
int funcNum;
|
NodeTree<ASTData>* param;
|
||||||
if (funcName == "*" || funcName == "&" || funcName == "++" || funcName == "--" || funcName == "-" || funcName == "!" || funcName == "~")
|
if (funcName == "*" || funcName == "&" || funcName == "++" || funcName == "--" || funcName == "-" || funcName == "!" || funcName == "~")
|
||||||
funcNum = 0;
|
param = transform(children[1], scope);
|
||||||
else
|
else
|
||||||
funcName = concatSymbolTree(children[1]), funcNum = 1;
|
funcName = concatSymbolTree(children[1]), param = transform(children[0], scope);
|
||||||
|
|
||||||
//std::cout << "scope lookup from factor" << std::endl;
|
//std::cout << "scope lookup from factor" << std::endl;
|
||||||
NodeTree<ASTData>* function = scopeLookup(scope, funcName);
|
NodeTree<ASTData>* function = scopeLookup(scope, funcName);
|
||||||
@@ -174,7 +181,13 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
}
|
}
|
||||||
newNode = new NodeTree<ASTData>(funcName, ASTData(function_call, Symbol(funcName, true)));
|
newNode = new NodeTree<ASTData>(funcName, ASTData(function_call, Symbol(funcName, true)));
|
||||||
newNode->addChild(function);
|
newNode->addChild(function);
|
||||||
skipChildren.insert(funcNum);
|
newNode->addChild(param);
|
||||||
|
if (function->getDataRef()->valueType)
|
||||||
|
newNode->getDataRef()->valueType = function->getDataRef()->valueType;
|
||||||
|
else
|
||||||
|
newNode->getDataRef()->valueType = param->getDataRef()->valueType;
|
||||||
|
|
||||||
|
return newNode;
|
||||||
} else {
|
} else {
|
||||||
return transform(children[0], scope); //Just a promoted child, so do it instead
|
return transform(children[0], scope); //Just a promoted child, so do it instead
|
||||||
}
|
}
|
||||||
@@ -258,11 +271,10 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
// throw "LOOKUP ERROR: " + functionCallName;
|
// throw "LOOKUP ERROR: " + functionCallName;
|
||||||
// }
|
// }
|
||||||
newNode->addChild(function);
|
newNode->addChild(function);
|
||||||
|
newNode->getDataRef()->valueType = function->getDataRef()->valueType;
|
||||||
skipChildren.insert(0);
|
skipChildren.insert(0);
|
||||||
} else if (name == "parameter") {
|
} else if (name == "parameter") {
|
||||||
return transform(children[0], scope); //Don't need a parameter node, just the value
|
return transform(children[0], scope); //Don't need a parameter node, just the value
|
||||||
} else if (name == "parameter") {
|
|
||||||
return transform(children[0], scope); //Don't need a parameter node, just the value
|
|
||||||
} else if (name == "type") {
|
} else if (name == "type") {
|
||||||
std::string theConcat = concatSymbolTree(from); //We have no symbol, so this will concat our children
|
std::string theConcat = concatSymbolTree(from); //We have no symbol, so this will concat our children
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(theConcat, true), typeFromString(theConcat, scope)));
|
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(theConcat, true), typeFromString(theConcat, scope)));
|
||||||
|
|||||||
@@ -194,22 +194,32 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
else if (name == "." || name == "->") {
|
else if (name == "." || name == "->") {
|
||||||
if (children.size() == 1)
|
if (children.size() == 1)
|
||||||
return "/*dot operation with one child*/" + generate(children[0], enclosingObject) + "/*end one child*/";
|
return "/*dot operation with one child*/" + generate(children[0], enclosingObject) + "/*end one child*/";
|
||||||
//If this is accessing an actual function, just output the name. No actual function definition should be in an access operation
|
//If this is accessing an actual function, find the function in scope and take the appropriate action. Probabally an object method
|
||||||
if (children[2]->getDataRef()->type == function)
|
if (children[2]->getDataRef()->type == function) {
|
||||||
return "((" + generate(children[1], enclosingObject) + ")" + name + children[2]->getDataRef()->symbol.getName() + ")";
|
std::string functionName = children[2]->getDataRef()->symbol.getName();
|
||||||
return "((" + generate(children[1], enclosingObject) + ")" + name + generate(children[2], enclosingObject) + ")";
|
NodeTree<ASTData>* possibleObjectType = children[1]->getDataRef()->valueType->typeDefinition;
|
||||||
}
|
//If is an object method, generate it like one. Needs extension/modification for inheritence
|
||||||
}
|
if (possibleObjectType && possibleObjectType->getDataRef()->scope.find(functionName) != possibleObjectType->getDataRef()->scope.end()) {
|
||||||
//output += data.symbol.getName() + "(";
|
return possibleObjectType->getDataRef()->symbol.getName() +"__" + functionName + "(" + (name == "." ? "&" : "") + generate(children[1], enclosingObject) + ",";
|
||||||
if (funcType == function) {
|
//The comma lets the upper function call know we already started the param list
|
||||||
output += name + "(";
|
//Note that we got here from a function call. We just pass up this special case and let them finish with the perentheses
|
||||||
std::cout << "Is a function, outputting name!" << std::cout;
|
std::cout << "Is in scope or not type!" << std::endl;
|
||||||
if (enclosingObject && enclosingObject->getDataRef()->scope.find(name) != enclosingObject->getDataRef()->scope.end()) {
|
} else {
|
||||||
//So, it is part of the enclosing object's namespace, so it's (for now) a member function and we need to pass in an implicit self reference
|
std::cout << "Is not in scope or not type" << std::endl;
|
||||||
output += ValueTypeToCType(enclosingObject->getDataRef()->valueType) + "* self, ";
|
return "((" + generate(children[1], enclosingObject) + ")" + name + functionName + ")";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "((" + generate(children[1], enclosingObject) + ")" + name + generate(children[2], enclosingObject) + ")";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
output += name + "(";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
output += generate(children[0], enclosingObject) + "(";
|
std::string functionCallSource = generate(children[0], enclosingObject);
|
||||||
|
if (functionCallSource[functionCallSource.size()-1] == ',') //If it's a member method, it's already started the parameter list.
|
||||||
|
output += children.size() > 1 ? functionCallSource : functionCallSource.substr(0, functionCallSource.size()-1);
|
||||||
|
else
|
||||||
|
output += functionCallSource + "(";
|
||||||
}
|
}
|
||||||
for (int i = 1; i < children.size(); i++) //children[0] is the declaration
|
for (int i = 1; i < children.size(); i++) //children[0] is the declaration
|
||||||
if (i < children.size()-1)
|
if (i < children.size()-1)
|
||||||
@@ -233,7 +243,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject, NodeTree<ASTData>* from) {
|
std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject, NodeTree<ASTData>* from) {
|
||||||
std::string output;
|
std::string output;
|
||||||
ASTData data = from->getData();
|
ASTData data = from->getData();
|
||||||
Type enclosingObjectType = *(enclosingObject->getDataRef()->valueType); //Copy a new type so we can turn it into a pointer
|
Type enclosingObjectType = *(enclosingObject->getDataRef()->valueType); //Copy a new type so we can turn it into a pointer if we need to
|
||||||
enclosingObjectType.indirection++;
|
enclosingObjectType.indirection++;
|
||||||
std::vector<NodeTree<ASTData>*> children = from->getChildren();
|
std::vector<NodeTree<ASTData>*> children = from->getChildren();
|
||||||
output += "\n" + ValueTypeToCType(data.valueType) + " " + enclosingObject->getDataRef()->symbol.getName() +"__" + data.symbol.getName() + "(" + ValueTypeToCType(&enclosingObjectType) + " self";
|
output += "\n" + ValueTypeToCType(data.valueType) + " " + enclosingObject->getDataRef()->symbol.getName() +"__" + data.symbol.getName() + "(" + ValueTypeToCType(&enclosingObjectType) + " self";
|
||||||
|
|||||||
Reference in New Issue
Block a user