Closures work\!
This commit is contained in:
@@ -794,26 +794,6 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::transformChildren(std::vector
|
||||
return transformedChildren;
|
||||
}
|
||||
|
||||
//Extract types from already transformed nodes
|
||||
std::vector<Type*> ASTTransformation::mapNodesToTypePointers(std::vector<NodeTree<ASTData>*> nodes) {
|
||||
std::vector<Type*> types;
|
||||
for (auto i : nodes) {
|
||||
std::cout << i->getDataRef()->toString() << std::endl;
|
||||
types.push_back((i->getDataRef()->valueType));
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
//Extract types from already transformed nodes
|
||||
std::vector<Type> ASTTransformation::mapNodesToTypes(std::vector<NodeTree<ASTData>*> nodes) {
|
||||
std::vector<Type> types;
|
||||
for (auto i : nodes) {
|
||||
std::cout << i->getDataRef()->toString() << std::endl;
|
||||
types.push_back(*(i->getDataRef()->valueType));
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
//Simple way to extract strings from syntax trees. Used often for identifiers, strings, types
|
||||
std::string ASTTransformation::concatSymbolTree(NodeTree<Symbol>* root) {
|
||||
std::string concatString;
|
||||
@@ -929,24 +909,24 @@ bool ASTTransformation::inScopeChain(NodeTree<ASTData>* node, NodeTree<ASTData>*
|
||||
// used to calculate the closedvariables for closures
|
||||
std::set<NodeTree<ASTData>*> ASTTransformation::findVariablesToClose(NodeTree<ASTData>* func, NodeTree<ASTData>* stat) {
|
||||
std::set<NodeTree<ASTData>*> closed;
|
||||
for (auto child: stat->getChildren()) {
|
||||
//enum ASTType {undef, translation_unit, interpreter_directive, import, identifier, type_def,
|
||||
//function, code_block, typed_parameter, expression, boolean_expression, statement,
|
||||
//if_statement, while_loop, for_loop, return_statement, break_statement, continue_statement, defer_statement,
|
||||
//assignment_statement, declaration_statement, if_comp, simple_passthrough, passthrough_params,
|
||||
//in_passthrough_params, out_passthrough_params, opt_string, param_assign, function_call, value};
|
||||
if (child->getDataRef()->type == function || child->getDataRef()->type == translation_unit
|
||||
|| child->getDataRef()->type == type_def || child->getDataRef()->type == value
|
||||
)
|
||||
continue;
|
||||
if (child->getDataRef()->type == function_call && (child->getDataRef()->symbol.getName() == "." || child->getDataRef()->symbol.getName() == "->")) {
|
||||
// only search on the left side of access operators like . and ->
|
||||
auto recClosed = findVariablesToClose(func, child->getChildren().front());
|
||||
closed.insert(recClosed.begin(), recClosed.end());
|
||||
continue;
|
||||
}
|
||||
if (child->getDataRef()->type == identifier && !inScopeChain(child, func))
|
||||
closed.insert(child);
|
||||
if (stat->getDataRef()->type == function || stat->getDataRef()->type == translation_unit
|
||||
|| stat->getDataRef()->type == type_def || stat->getDataRef()->type == value
|
||||
)
|
||||
return closed;
|
||||
if (stat->getDataRef()->type == function_call && (stat->getDataRef()->symbol.getName() == "." || stat->getDataRef()->symbol.getName() == "->")) {
|
||||
// only search on the left side of access operators like . and ->
|
||||
auto recClosed = findVariablesToClose(func, stat->getChildren()[1]);
|
||||
closed.insert(recClosed.begin(), recClosed.end());
|
||||
return closed;
|
||||
}
|
||||
if (stat->getDataRef()->type == identifier && !inScopeChain(stat, func))
|
||||
closed.insert(stat);
|
||||
for (auto child: stat->getChildren()) {
|
||||
auto recClosed = findVariablesToClose(func, child);
|
||||
closed.insert(recClosed.begin(), recClosed.end());
|
||||
}
|
||||
@@ -1671,3 +1651,22 @@ NodeTree<ASTData>* ASTTransformation::addToScope(std::string name, NodeTree<ASTD
|
||||
}
|
||||
|
||||
|
||||
//Extract types from already transformed nodes
|
||||
std::vector<Type*> mapNodesToTypePointers(std::vector<NodeTree<ASTData>*> nodes) {
|
||||
std::vector<Type*> types;
|
||||
for (auto i : nodes) {
|
||||
std::cout << i->getDataRef()->toString() << std::endl;
|
||||
types.push_back((i->getDataRef()->valueType));
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
//Extract types from already transformed nodes
|
||||
std::vector<Type> mapNodesToTypes(std::vector<NodeTree<ASTData>*> nodes) {
|
||||
std::vector<Type> types;
|
||||
for (auto i : nodes) {
|
||||
std::cout << i->getDataRef()->toString() << std::endl;
|
||||
types.push_back(*(i->getDataRef()->valueType));
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
||||
else {
|
||||
std::string nameDecoration, parameters;
|
||||
if (declarationData.closedVariables.size())
|
||||
parameters += "struct closed *closed_varibles";
|
||||
parameters += closureStructType(declarationData.closedVariables) + "*";
|
||||
for (int j = 0; j < decChildren.size()-1; j++) {
|
||||
if (j > 0 || declarationData.closedVariables.size() )
|
||||
parameters += ", ";
|
||||
@@ -319,7 +319,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
|
||||
std::string nameDecoration, parameters;
|
||||
if (data.closedVariables.size())
|
||||
parameters += "struct closed *closed_varibles";
|
||||
parameters += closureStructType(data.closedVariables) + " *closed_varibles";
|
||||
for (int j = 0; j < children.size()-1; j++) {
|
||||
if (j > 0 || data.closedVariables.size())
|
||||
parameters += ", ";
|
||||
@@ -336,8 +336,16 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
funcName += CifyName(data.symbol.getName() + nameDecoration);
|
||||
if (from->getDataRef()->closedVariables.size()) {
|
||||
std::string tmpStruct = "closureStruct" + getID();
|
||||
output.preValue += "struct specialClosure " + tmpStruct + ";\n";
|
||||
output += "("+ ValueTypeToCType(data.valueType, "") +"){" + funcName + ", &" + tmpStruct + "}";
|
||||
output.preValue += closureStructType(data.closedVariables) + " " + tmpStruct + " = {";
|
||||
bool notFirst = false;
|
||||
for (auto var : data.closedVariables) {
|
||||
if (notFirst)
|
||||
output.preValue += ", ";
|
||||
notFirst = true;
|
||||
output.preValue += "." + scopePrefix(var) + var->getDataRef()->symbol.getName() + " = &" + scopePrefix(var) + var->getDataRef()->symbol.getName();
|
||||
}
|
||||
output.preValue += "};\n";
|
||||
output += "("+ ValueTypeToCType(data.valueType, "") +"){(void*)" + funcName + ", &" + tmpStruct + "}";
|
||||
} else {
|
||||
output += "("+ ValueTypeToCType(data.valueType, "") +"){" + funcName + ", NULL}";
|
||||
}
|
||||
@@ -802,6 +810,22 @@ std::string CGenerator::emitDestructors(std::vector<NodeTree<ASTData>*> identifi
|
||||
return destructorString;
|
||||
}
|
||||
|
||||
std::string CGenerator::closureStructType(std::set<NodeTree<ASTData>*> closedVariables) {
|
||||
auto it = closureStructMap.find(closedVariables);
|
||||
if (it != closureStructMap.end())
|
||||
return it->second;
|
||||
std::string typedefString = "typedef struct { ";
|
||||
// note the increased indirection b/c we're using references to what we closed over
|
||||
for (auto var : closedVariables) {
|
||||
auto tmp = var->getDataRef()->valueType->withIncreasedIndirection();
|
||||
typedefString += ValueTypeToCType(&tmp, scopePrefix(var) + var->getDataRef()->symbol.getName()) + ";";
|
||||
}
|
||||
std::string structName = "closureStructType" + getID();
|
||||
typedefString += " } " + structName + ";\n";
|
||||
functionTypedefString += typedefString;
|
||||
closureStructMap[closedVariables] = structName;
|
||||
return structName;
|
||||
}
|
||||
|
||||
std::string CGenerator::ValueTypeToCType(Type *type, std::string declaration, ClosureTypeSpecialType closureSpecial) { return ValueTypeToCTypeThingHelper(type, " " + declaration, closureSpecial); }
|
||||
std::string CGenerator::ValueTypeToCTypeDecoration(Type *type, ClosureTypeSpecialType closureSpecial) { return CifyName(ValueTypeToCTypeThingHelper(type, "", closureSpecial)); }
|
||||
|
||||
@@ -17,7 +17,7 @@ std::string replaceExEscape(std::string first, std::string search, std::string r
|
||||
if (pos > 0) {
|
||||
int numBackslashes = 0;
|
||||
int countBack = 1;
|
||||
while (pos-countBack >= 0 && first[pos-countBack] == '\\') {
|
||||
while ((int)pos-countBack >= 0 && first[pos-countBack] == '\\') {
|
||||
numBackslashes++;
|
||||
countBack++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user