Posets now integrated into the CGenerator, so the CGenerator now chooses a valid order for the object definitions based on their dependence on each other. Another test now passing

This commit is contained in:
Nathan Braswell
2014-05-21 13:14:16 -04:00
parent d37a07201a
commit 0f6b6c0c67
4 changed files with 40 additions and 8 deletions

View File

@@ -10,6 +10,7 @@
#include "Type.h" #include "Type.h"
#include "util.h" #include "util.h"
#include "Poset.h"
class CGenerator { class CGenerator {

View File

@@ -17,6 +17,7 @@ class Poset {
Poset(); Poset();
~Poset(); ~Poset();
void addRelationship(T first, T second); void addRelationship(T first, T second);
void addVertex(T vertex);
bool zeroDependencies(T vertex); bool zeroDependencies(T vertex);
std::set<T> getDependsOn(T dependency); std::set<T> getDependsOn(T dependency);
std::vector<T> getTopoSort(); std::vector<T> getTopoSort();
@@ -45,6 +46,11 @@ void Poset<T>::addRelationship(T first, T second) {
adjMatrix[first][second] = true; adjMatrix[first][second] = true;
} }
template <class T>
void Poset<T>::addVertex(T vertex) {
verticies.insert(vertex);
}
template <class T> template <class T>
bool Poset<T>::zeroDependencies(T vertex) { bool Poset<T>::zeroDependencies(T vertex) {
auto depMapItr = adjMatrix.find(vertex); auto depMapItr = adjMatrix.find(vertex);
@@ -87,19 +93,21 @@ std::vector<T> Poset<T>::getTopoSort() {
} }
//int specilization just for testing //would make it just an int specilization, but then we get multiple definition complaints....
template<> template<class T>
void Poset<int>::test() { void Poset<T>::test() {
std::string result; std::string result;
{ {
Poset<int> poset; Poset<int> poset;
poset.addVertex(1000);
for (int i = 0; i < 20; i++) for (int i = 0; i < 20; i++)
poset.addRelationship(i,i+1); poset.addRelationship(i,i+1);
result = ""; result = "";
for (int i : poset.getTopoSort()) for (int i : poset.getTopoSort())
result += intToString(i) + " "; result += intToString(i) + " ";
//std::cout << result << std::endl; //std::cout << result << std::endl;
assert(result == "20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 "); assert(result == "20 1000 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 "); //Note that sets do not have a set order, so this could change
//This is why the 1000 is in an odd, yet valid, position
} }
{ {
Poset<int> poset; Poset<int> poset;

View File

@@ -28,7 +28,7 @@ int main(int argc, char* argv[]) {
RegEx::test(); RegEx::test();
Lexer::test(); Lexer::test();
//std::cout << strSlice("123", 0, -1) << std::endl; //std::cout << strSlice("123", 0, -1) << std::endl;
Poset<int>::test(); //int specilization just for testing. test() is actually only in the int specilization Poset<int>::test();
if (argc >= 3) { if (argc >= 3) {
std::string testResults, line; std::string testResults, line;

View File

@@ -45,9 +45,31 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
//Do here because we may need the typedefs before the declarations of variables //Do here because we may need the typedefs before the declarations of variables
//Note that we need to be careful of the order, though, as some declarations depend on others. //Note that we need to be careful of the order, though, as some declarations depend on others.
//What is this then? It's a poset! Wooo posets! //What is this then? It's a poset! Wooo posets!
for (int i = 0; i < children.size(); i++) {
if (children[i]->getDataRef()->type == type_def) Poset<NodeTree<ASTData>*> typedefPoset;
output += generate(children[i], enclosingObject) + "\n"; for (int i = 0; i < children.size(); i++) {
if (children[i]->getDataRef()->type == type_def) {
typedefPoset.addVertex(children[i]); //We add this definition by itself just in case there are no dependencies.
//If it has dependencies, there's no harm in adding it here
//Go through every child in the class looking for declaration statements. For each of these that is not a primitive type
//we will add a dependency from this definition to that definition in the poset.
std::vector<NodeTree<ASTData>*> classChildren = children[i]->getChildren();
for (auto j : classChildren) {
if (j->getDataRef()->type == declaration_statement) {
Type* decType = j->getChildren()[0]->getDataRef()->valueType; //Type of the declaration
if (decType->typeDefinition && decType->getIndirection() == 0) //If this is a custom type and not a pointer
typedefPoset.addRelationship(children[i], decType->typeDefinition); //Add a dependency
}
}
//In case there are pointer dependencies. If the typedef has no children, then it is a simple renaming and we don't need to predeclare the class (maybe?)
if (classChildren.size())
output += "struct " + CifyName(children[i]->getDataRef()->symbol.getName()) + ";\n";
}
}
//Now generate the typedef's in the correct, topological order
for (NodeTree<ASTData>* i : typedefPoset.getTopoSort())
output += generate(i, enclosingObject) + "\n";
//Declare everything in translation unit scope here. (allows stuff from other files, automatic forward declarations) //Declare everything in translation unit scope here. (allows stuff from other files, automatic forward declarations)
for (auto i = data.scope.begin(); i != data.scope.end(); i++) { for (auto i = data.scope.begin(); i != data.scope.end(); i++) {
for (auto overloadedMembers : i->second) { for (auto overloadedMembers : i->second) {
@@ -92,6 +114,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
if (children[i]->getDataRef()->type != type_def) if (children[i]->getDataRef()->type != type_def)
output += generate(children[i], enclosingObject) + "\n"; output += generate(children[i], enclosingObject) + "\n";
return output; return output;
}
break; break;
case interpreter_directive: case interpreter_directive:
//Do nothing //Do nothing