diff --git a/include/CGenerator.h b/include/CGenerator.h index d7e4e03..41e55f4 100644 --- a/include/CGenerator.h +++ b/include/CGenerator.h @@ -10,6 +10,7 @@ #include "Type.h" #include "util.h" +#include "Poset.h" class CGenerator { diff --git a/include/Poset.h b/include/Poset.h index 29fea05..f29d350 100644 --- a/include/Poset.h +++ b/include/Poset.h @@ -17,6 +17,7 @@ class Poset { Poset(); ~Poset(); void addRelationship(T first, T second); + void addVertex(T vertex); bool zeroDependencies(T vertex); std::set getDependsOn(T dependency); std::vector getTopoSort(); @@ -45,6 +46,11 @@ void Poset::addRelationship(T first, T second) { adjMatrix[first][second] = true; } +template +void Poset::addVertex(T vertex) { + verticies.insert(vertex); +} + template bool Poset::zeroDependencies(T vertex) { auto depMapItr = adjMatrix.find(vertex); @@ -87,19 +93,21 @@ std::vector Poset::getTopoSort() { } -//int specilization just for testing -template<> -void Poset::test() { +//would make it just an int specilization, but then we get multiple definition complaints.... +template +void Poset::test() { std::string result; { Poset poset; + poset.addVertex(1000); for (int i = 0; i < 20; i++) poset.addRelationship(i,i+1); result = ""; for (int i : poset.getTopoSort()) result += intToString(i) + " "; //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 poset; diff --git a/main.cpp b/main.cpp index c5639ab..3654f6f 100644 --- a/main.cpp +++ b/main.cpp @@ -28,7 +28,7 @@ int main(int argc, char* argv[]) { RegEx::test(); Lexer::test(); //std::cout << strSlice("123", 0, -1) << std::endl; - Poset::test(); //int specilization just for testing. test() is actually only in the int specilization + Poset::test(); if (argc >= 3) { std::string testResults, line; diff --git a/src/CGenerator.cpp b/src/CGenerator.cpp index b2d09bd..f47ac6a 100644 --- a/src/CGenerator.cpp +++ b/src/CGenerator.cpp @@ -45,9 +45,31 @@ std::string CGenerator::generate(NodeTree* from, NodeTree* enc //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. //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) - output += generate(children[i], enclosingObject) + "\n"; + { + Poset*> typedefPoset; + 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*> 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* i : typedefPoset.getTopoSort()) + output += generate(i, enclosingObject) + "\n"; + //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 overloadedMembers : i->second) { @@ -92,6 +114,7 @@ std::string CGenerator::generate(NodeTree* from, NodeTree* enc if (children[i]->getDataRef()->type != type_def) output += generate(children[i], enclosingObject) + "\n"; return output; + } break; case interpreter_directive: //Do nothing