Fixed the close over methods and member vars bug, but there's something remaining causing the safe_recursive_delete not to work. Gotta save progress and do other stuff

This commit is contained in:
Nathan Braswell
2015-06-27 18:06:02 -04:00
parent 8feb9819b8
commit c50c977a9e
20 changed files with 370 additions and 40 deletions

View File

@@ -487,7 +487,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
newNode->getDataRef()->valueType = new Type(mapNodesToTypePointers(parameters), newNode->getDataRef()->valueType);
auto statement = transform(getNode("statement", children), scope, types, limitToFunction, templateTypeReplacements);
if (name == "lambda")
newNode->getDataRef()->closedVariables = findVariablesToClose(newNode, statement);
newNode->getDataRef()->closedVariables = findVariablesToClose(newNode, statement, scope);
for (auto i : newNode->getDataRef()->closedVariables)
std::cout << "OK, CLOSED: " << i->getDataRef()->toString() << std::endl;
newNode->addChild(statement);
@@ -520,7 +520,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
std::cerr << "scope lookup error! Could not find " << functionCallString << " in boolean stuff " << std::endl;
throw "LOOKUP ERROR: " + functionCallString;
}
newNode = function;
return function;
} else {
// XXX What the heck is this
if (children.size() == 0)
@@ -928,7 +928,7 @@ bool ASTTransformation::inScopeChain(NodeTree<ASTData>* node, NodeTree<ASTData>*
}
// We return a set of all identifers used in the children of stat that are not declared somewhere below stat
// used to calculate the closedvariables for closures
std::set<NodeTree<ASTData>*> ASTTransformation::findVariablesToClose(NodeTree<ASTData>* func, NodeTree<ASTData>* stat) {
std::set<NodeTree<ASTData>*> ASTTransformation::findVariablesToClose(NodeTree<ASTData>* func, NodeTree<ASTData>* stat, NodeTree<ASTData>* scope) {
std::set<NodeTree<ASTData>*> closed;
//enum ASTType {undef, translation_unit, interpreter_directive, import, identifier, type_def,
//function, code_block, typed_parameter, expression, boolean_expression, statement,
@@ -937,18 +937,26 @@ std::set<NodeTree<ASTData>*> ASTTransformation::findVariablesToClose(NodeTree<AS
//in_passthrough_params, out_passthrough_params, opt_string, param_assign, function_call, value};
if (stat->getDataRef()->type == function || stat->getDataRef()->type == translation_unit
|| stat->getDataRef()->type == type_def || stat->getDataRef()->type == value
)
) {
// if this is a method we know that it is a method of our current enclosing object (as we already know that we're not on the right side of . or ->, see below)
// we should add our enclosing object, this, to our closed over variables
if (stat->getDataRef()->type == function) {
auto statEnclosingScope = stat->getDataRef()->scope["~enclosing_scope"][0];
if (statEnclosingScope && statEnclosingScope->getDataRef()->valueType && statEnclosingScope->getDataRef()->valueType->typeDefinition)
closed.insert(generateThis(scope));
}
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]);
auto recClosed = findVariablesToClose(func, stat->getChildren()[1], scope);
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);
auto recClosed = findVariablesToClose(func, child, scope);
closed.insert(recClosed.begin(), recClosed.end());
}
return closed;
@@ -1140,7 +1148,18 @@ void ASTTransformation::unifyType(NodeTree<Symbol> *syntaxType, Type type, std::
// to get the type it was instantiated with.
auto origionalType = type.typeDefinition->getDataRef()->valueType;
auto typeTemplateDefinition = origionalType->templateDefinition;
if (typeTemplateDefinition && concatSymbolTree(getNode("scoped_identifier", children)) == concatSymbolTree(getNode("identifier", typeTemplateDefinition->getChildren()))) {
// we have to get rid of the scope partion of the scoped_identifier so we can compare properly with the typeTemplateDefinition's identifier
auto scoped = getNode("scoped_identifier", children);
NodeTree<Symbol>* ident = nullptr;
while(scoped && !ident) {
ident = getNode("identifier", scoped);
scoped = getNode("scoped_identifier", scoped);
}
//if (typeTemplateDefinition) {
//std::cout << concatSymbolTree(ident) << std::endl;
//std::cout << concatSymbolTree(getNode("identifier", typeTemplateDefinition->getChildren())) << std::endl;
//}
if (typeTemplateDefinition && concatSymbolTree(ident) == concatSymbolTree(getNode("identifier", typeTemplateDefinition->getChildren()))) {
std::vector<NodeTree<Symbol>*> uninTypeInstTypes = getNodes("type", getNode("template_inst", children));
std::vector<NodeTree<Symbol>*> typeInstTypes = getNodes("template_param", getNode("template_dec", typeTemplateDefinition->getChildren()));
for (int i = 0; i < uninTypeInstTypes.size(); i++) {
@@ -1152,6 +1171,7 @@ void ASTTransformation::unifyType(NodeTree<Symbol> *syntaxType, Type type, std::
return;
}
throw "the inference just isn't good enough";
}
throw "the inference just isn't good enough";
}
@@ -1314,6 +1334,18 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
return scopeLookup(scope, lookup, includeModules, std::set<NodeTree<ASTData>*>());
}
NodeTree<ASTData>* ASTTransformation::generateThis(NodeTree<ASTData>* scope) {
NodeTree<ASTData>* identifier = languageLevelReservedWords["this"][0];
identifier = new NodeTree<ASTData>("identifier", identifier->getData());
// if we're looking for this, traverse up until we find the declaration of this object and assign it's type to this
NodeTree<ASTData>* trans;
for (trans = scope; trans->getDataRef()->type != type_def; trans = trans->getDataRef()->scope["~enclosing_scope"][0]);
identifier->getDataRef()->valueType = trans->getDataRef()->valueType->clone();
identifier->getDataRef()->valueType->increaseIndirection();
identifier->getDataRef()->scope = trans->getDataRef()->scope;
return identifier;
}
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules, std::set<NodeTree<ASTData>*> visited) {
std::cout << "Scp]|[e looking up " << lookup << std::endl;
std::cout << "current: " << scope->getDataRef()->toString() << std::endl;
@@ -1330,12 +1362,7 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
std::cout << "found it at language level as reserved word." << std::endl;
NodeTree<ASTData>* identifier = LLElementIterator->second[0];
if (lookup == "this") {
identifier = new NodeTree<ASTData>("identifier", identifier->getData());
// if we're looking for this, traverse up until we find the declaration of this object and assign it's type to this
NodeTree<ASTData>* trans;
for (trans = scope; trans->getDataRef()->type != type_def; trans = trans->getDataRef()->scope["~enclosing_scope"][0]);
identifier->getDataRef()->valueType = trans->getDataRef()->valueType->clone();
identifier->getDataRef()->valueType->increaseIndirection();
identifier = generateThis(scope);
}
std::vector<NodeTree<ASTData>*> thingy; thingy.push_back(identifier);
return thingy;

View File

@@ -302,7 +302,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
if (enclosingFunction->getDataRef()->closedVariables.size()) {
std::cout << "WHOH IS A CLOSER" << std::endl;
if (enclosingFunction->getDataRef()->closedVariables.find(from) != enclosingFunction->getDataRef()->closedVariables.end()) {
preName += "(*closed_varibles->";
preName += "(*closed_variables->";
postName += ")";
}
}
@@ -322,7 +322,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
std::string nameDecoration, parameters;
if (data.closedVariables.size())
parameters += closureStructType(data.closedVariables) + " *closed_varibles";
parameters += closureStructType(data.closedVariables) + " *closed_variables";
for (int j = 0; j < children.size()-1; j++) {
if (j > 0 || data.closedVariables.size())
parameters += ", ";
@@ -345,7 +345,12 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
if (notFirst)
output.preValue += ", ";
notFirst = true;
output.preValue += "." + scopePrefix(var) + var->getDataRef()->symbol.getName() + " = &" + scopePrefix(var) + var->getDataRef()->symbol.getName();
std::string varName = var->getDataRef()->symbol.getName();
std::string preName;
if (enclosingObject && enclosingObject->getDataRef()->scope.find(varName) != enclosingObject->getDataRef()->scope.end())
preName += "this->";
varName = (varName == "this") ? varName : scopePrefix(var) + varName;
output.preValue += "." + varName + " = &" + preName + varName;
}
output.preValue += "};\n";
output += "("+ ValueTypeToCType(data.valueType, "") +"){(void*)" + funcName + ", &" + tmpStruct + "}";
@@ -636,12 +641,23 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
std::string nameDecoration;
for (int i = 0; i < (functionDefChildren.size() > 0 ? functionDefChildren.size()-1 : 0); i++)
nameDecoration += "_" + ValueTypeToCTypeDecoration(functionDefChildren[i]->getData().valueType);
// it is possible that this is an object method from inside a closure
// in which case, recover the enclosing object from this
bool addClosedOver = false;
if (enclosingFunction && enclosingFunction->getDataRef()->closedVariables.size()) {
for (auto closedVar : enclosingFunction->getDataRef()->closedVariables) {
if (closedVar->getDataRef()->symbol.getName() == "this") {
enclosingObject = closedVar->getDataRef()->valueType->typeDefinition;
addClosedOver = true;
}
}
}
//Check to see if we're inside of an object and this is a method call
bool isSelfObjectMethod = enclosingObject && contains(enclosingObject->getChildren(), children[0]);
if (isSelfObjectMethod) {
output += function_header + scopePrefix(children[0]) + CifyName(enclosingObject->getDataRef()->symbol.getName()) +"__";
output += CifyName(name + nameDecoration) + "(";
output += children.size() > 1 ? "this," : "this";
output += std::string(addClosedOver ? "(*closed_variables->this)" : "this") + (children.size() > 1 ? "," : "");
} else {
output += function_header + scopePrefix(children[0]) + CifyName(name + nameDecoration) + "(";
}
@@ -745,7 +761,8 @@ std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject,
enclosingObjectType.increaseIndirection();
std::vector<NodeTree<ASTData>*> children = from->getChildren();
std::string nameDecoration, parameters;
for (int i = 0; i < children.size()-1; i++) {
// note how we get around children.size() being an unsigned type
for (int i = 0; i+1 < children.size(); i++) {
parameters += ", " + ValueTypeToCType(children[i]->getData().valueType, generate(children[i]).oneString());
nameDecoration += "_" + ValueTypeToCTypeDecoration(children[i]->getData().valueType);
@@ -821,7 +838,9 @@ std::string CGenerator::closureStructType(std::set<NodeTree<ASTData>*> closedVar
// 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 varName = var->getDataRef()->symbol.getName();
varName = (varName == "this") ? varName : scopePrefix(var) + varName;
typedefString += ValueTypeToCType(&tmp, varName) + ";";
}
std::string structName = "closureStructType" + getID();
typedefString += " } " + structName + ";\n";