Fix the CGenerator so that function values can be stored in member variables
This commit is contained in:
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
// Note the use of std::pair to hold two strings - the running string for the header file and the running string for the c file.
|
// Note the use of std::pair to hold two strings - the running string for the header file and the running string for the c file.
|
||||||
|
|
||||||
enum ClosureTypeSpecialType { ClosureTypeRegularNone, ClosureFunctionPointerTypeWithClosedParam };
|
enum ClosureTypeSpecialType { ClosureTypeRegularNone, ClosureFunctionPointerTypeWithoutClosedParam, ClosureFunctionPointerTypeWithClosedParam };
|
||||||
|
|
||||||
class CGenerator {
|
class CGenerator {
|
||||||
public:
|
public:
|
||||||
@@ -55,7 +55,8 @@ class CGenerator {
|
|||||||
std::string generatorString;
|
std::string generatorString;
|
||||||
std::string linkerString;
|
std::string linkerString;
|
||||||
std::string functionTypedefString;
|
std::string functionTypedefString;
|
||||||
std::map<Type, std::pair<std::string, std::string>> functionTypedefMap;
|
std::string functionTypedefStringPre;
|
||||||
|
std::map<Type, triple<std::string, std::string, std::string>> functionTypedefMap;
|
||||||
std::map<std::set<NodeTree<ASTData>*>, std::string> closureStructMap;
|
std::map<std::set<NodeTree<ASTData>*>, std::string> closureStructMap;
|
||||||
std::vector<std::vector<NodeTree<ASTData>*>> distructDoubleStack;
|
std::vector<std::vector<NodeTree<ASTData>*>> distructDoubleStack;
|
||||||
std::stack<int> loopDistructStackDepth;
|
std::stack<int> loopDistructStackDepth;
|
||||||
|
|||||||
@@ -22,6 +22,21 @@ std::string join(const std::vector<std::string> &strVec, std::string joinStr);
|
|||||||
std::string readFile(std::istream &file);
|
std::string readFile(std::istream &file);
|
||||||
std::string padWithSpaces(std::string str, int padTo);
|
std::string padWithSpaces(std::string str, int padTo);
|
||||||
|
|
||||||
|
template <typename T, typename U, typename V>
|
||||||
|
class triple {
|
||||||
|
public:
|
||||||
|
T first;
|
||||||
|
U second;
|
||||||
|
V third;
|
||||||
|
};
|
||||||
|
template <typename T, typename U, typename V>
|
||||||
|
triple<T,U,V> make_triple(T f, U s, V t) {
|
||||||
|
triple<T,U,V> out;
|
||||||
|
out.first = f;
|
||||||
|
out.second = s;
|
||||||
|
out.third = t;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool contains(std::vector<T> vec, T item) {
|
bool contains(std::vector<T> vec, T item) {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ CGenerator::CGenerator() : generatorString("__C__") {
|
|||||||
tabLevel = 0;
|
tabLevel = 0;
|
||||||
id = 0;
|
id = 0;
|
||||||
function_header = "fun_";
|
function_header = "fun_";
|
||||||
|
functionTypedefString = "";
|
||||||
|
functionTypedefStringPre = "";
|
||||||
}
|
}
|
||||||
CGenerator::~CGenerator() {
|
CGenerator::~CGenerator() {
|
||||||
}
|
}
|
||||||
@@ -259,7 +261,7 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hOutput += plainTypedefs + importIncludes + topLevelCPassthrough + variableExternDeclarations + classStructs + functionTypedefString + functionPrototypes;
|
hOutput += plainTypedefs + importIncludes + topLevelCPassthrough + functionTypedefStringPre + variableExternDeclarations + classStructs + functionTypedefString + functionPrototypes;
|
||||||
cOutput += variableDeclarations + functionDefinitions;
|
cOutput += variableDeclarations + functionDefinitions;
|
||||||
return std::make_pair(hOutput, cOutput);
|
return std::make_pair(hOutput, cOutput);
|
||||||
}
|
}
|
||||||
@@ -730,8 +732,8 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
std::string retTmpName = "closureRetTemp" + getID();
|
std::string retTmpName = "closureRetTemp" + getID();
|
||||||
output += CCodeTriple(parameters.preValue + functionCallSource.preValue + ValueTypeToCType(funcType, tmpName) + " = " + functionCallSource.value + ";\n"
|
output += CCodeTriple(parameters.preValue + functionCallSource.preValue + ValueTypeToCType(funcType, tmpName) + " = " + functionCallSource.value + ";\n"
|
||||||
+ (doRet ? ValueTypeToCType(retType, retTmpName) + ";\n" : "")
|
+ (doRet ? ValueTypeToCType(retType, retTmpName) + ";\n" : "")
|
||||||
+ "if (" + tmpName + ".val) { " + (doRet ? (retTmpName + " =") : "") + " (("+ ValueTypeToCTypeDecoration(funcType,ClosureFunctionPointerTypeWithClosedParam) +") (" + tmpName + ".func))(" + tmpName + ".val" + (children.size() > 1 ? ", " : "") + parameters.value + "); }\n"
|
+ "if (" + tmpName + ".data) { " + (doRet ? (retTmpName + " =") : "") + " (("+ ValueTypeToCTypeDecoration(funcType,ClosureFunctionPointerTypeWithClosedParam) +") (" + tmpName + ".func))(" + tmpName + ".data" + (children.size() > 1 ? ", " : "") + parameters.value + "); }\n"
|
||||||
+ "else { " + (doRet ? (retTmpName + " = ") : "") + tmpName + ".func(" + parameters.value + "); }\n",
|
+ "else { " + (doRet ? (retTmpName + " = ") : "") + " (("+ ValueTypeToCTypeDecoration(funcType,ClosureFunctionPointerTypeWithoutClosedParam) +") (" + tmpName + ".func))(" + parameters.value + "); }\n",
|
||||||
(doRet ? retTmpName : ""),
|
(doRet ? retTmpName : ""),
|
||||||
parameters.postValue + functionCallSource.postValue);
|
parameters.postValue + functionCallSource.postValue);
|
||||||
} else {
|
} else {
|
||||||
@@ -909,6 +911,8 @@ std::string CGenerator::ValueTypeToCTypeThingHelper(Type *type, std::string decl
|
|||||||
if (it != functionTypedefMap.end()) {
|
if (it != functionTypedefMap.end()) {
|
||||||
if (closureSpecial == ClosureFunctionPointerTypeWithClosedParam)
|
if (closureSpecial == ClosureFunctionPointerTypeWithClosedParam)
|
||||||
return_type = it->second.second + declaration;
|
return_type = it->second.second + declaration;
|
||||||
|
else if (closureSpecial == ClosureFunctionPointerTypeWithoutClosedParam)
|
||||||
|
return_type = it->second.third + declaration;
|
||||||
else
|
else
|
||||||
return_type = it->second.first + declaration;
|
return_type = it->second.first + declaration;
|
||||||
} else {
|
} else {
|
||||||
@@ -918,7 +922,11 @@ std::string CGenerator::ValueTypeToCTypeThingHelper(Type *type, std::string decl
|
|||||||
std::string typedefWithVoidID = "ID_withvoid_" + CifyName(type->toString(false));
|
std::string typedefWithVoidID = "ID_withvoid_" + CifyName(type->toString(false));
|
||||||
std::string typedefStructID = "ID_struct_" + CifyName(type->toString(false));
|
std::string typedefStructID = "ID_struct_" + CifyName(type->toString(false));
|
||||||
|
|
||||||
std::string typedefStructStr = "typedef struct {" + typedefWithoutVoidID + " func; void* val; } " + typedefStructID + ";\n";
|
// How I wish the world were this kind. Because of C name resolution not looking ahead, this definition needs to be BEFORE
|
||||||
|
// the object definitions. So to prevent circular dependencies, I'm making this take in a void pointer and we'll simply
|
||||||
|
// cast in both cases, whether or not there's a data pointer. Sigh.
|
||||||
|
//std::string typedefStructStr = "typedef struct {" + typedefWithoutVoidID + " func; void* val; } " + typedefStructID + ";\n";
|
||||||
|
std::string typedefStructStr = "typedef struct { void* func; void* data; } " + typedefStructID + ";\n";
|
||||||
|
|
||||||
typedefWithoutVoidStr += ValueTypeToCTypeThingHelper(type->returnType, "", closureSpecial);
|
typedefWithoutVoidStr += ValueTypeToCTypeThingHelper(type->returnType, "", closureSpecial);
|
||||||
typedefWithVoidStr += ValueTypeToCTypeThingHelper(type->returnType, "", closureSpecial);
|
typedefWithVoidStr += ValueTypeToCTypeThingHelper(type->returnType, "", closureSpecial);
|
||||||
@@ -935,15 +943,17 @@ std::string CGenerator::ValueTypeToCTypeThingHelper(Type *type, std::string decl
|
|||||||
}
|
}
|
||||||
typedefWithoutVoidStr += ");\n";
|
typedefWithoutVoidStr += ");\n";
|
||||||
typedefWithVoidStr += ");\n";
|
typedefWithVoidStr += ");\n";
|
||||||
|
// again, sigh
|
||||||
functionTypedefString += typedefWithoutVoidStr;
|
functionTypedefString += typedefWithoutVoidStr;
|
||||||
functionTypedefString += typedefWithVoidStr;
|
functionTypedefString += typedefWithVoidStr;
|
||||||
functionTypedefString += typedefStructStr;
|
functionTypedefStringPre += typedefStructStr;
|
||||||
|
//functionTypedefString += typedefStructStr;
|
||||||
if (closureSpecial == ClosureFunctionPointerTypeWithClosedParam)
|
if (closureSpecial == ClosureFunctionPointerTypeWithClosedParam)
|
||||||
return_type = typedefWithVoidID + indr_str + declaration;
|
return_type = typedefWithVoidID + indr_str + declaration;
|
||||||
else
|
else
|
||||||
return_type = typedefStructID + indr_str + declaration;
|
return_type = typedefStructID + indr_str + declaration;
|
||||||
|
|
||||||
functionTypedefMap[*type] = std::make_pair(typedefStructID, typedefWithVoidID);
|
functionTypedefMap[*type] = make_triple(typedefStructID, typedefWithVoidID, typedefWithoutVoidID);
|
||||||
}
|
}
|
||||||
do_ending = false;
|
do_ending = false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user