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:
@@ -45,7 +45,8 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
|
|||||||
std::string concatSymbolTree(NodeTree<Symbol>* root);
|
std::string concatSymbolTree(NodeTree<Symbol>* root);
|
||||||
NodeTree<ASTData>* doFunction(NodeTree<ASTData>* scope, std::string lookup, std::vector<NodeTree<ASTData>*> nodes, std::map<std::string, Type*> templateTypeReplacements);
|
NodeTree<ASTData>* doFunction(NodeTree<ASTData>* scope, std::string lookup, std::vector<NodeTree<ASTData>*> nodes, std::map<std::string, Type*> templateTypeReplacements);
|
||||||
|
|
||||||
std::set<NodeTree<ASTData>*> findVariablesToClose(NodeTree<ASTData>* func, NodeTree<ASTData>* stat);
|
NodeTree<ASTData>* generateThis(NodeTree<ASTData>* scope);
|
||||||
|
std::set<NodeTree<ASTData>*> findVariablesToClose(NodeTree<ASTData>* func, NodeTree<ASTData>* stat, NodeTree<ASTData>* scope);
|
||||||
bool inScopeChain(NodeTree<ASTData>* node, NodeTree<ASTData>* scope);
|
bool inScopeChain(NodeTree<ASTData>* node, NodeTree<ASTData>* scope);
|
||||||
NodeTree<ASTData>* functionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types);
|
NodeTree<ASTData>* functionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types);
|
||||||
NodeTree<ASTData>* templateFunctionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type*>* templateInstantiationTypes, std::vector<Type> types, std::map<std::string, Type*> scopeTypeMap);
|
NodeTree<ASTData>* templateFunctionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type*>* templateInstantiationTypes, std::vector<Type> types, std::map<std::string, Type*> scopeTypeMap);
|
||||||
|
|||||||
@@ -487,7 +487,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
newNode->getDataRef()->valueType = new Type(mapNodesToTypePointers(parameters), newNode->getDataRef()->valueType);
|
newNode->getDataRef()->valueType = new Type(mapNodesToTypePointers(parameters), newNode->getDataRef()->valueType);
|
||||||
auto statement = transform(getNode("statement", children), scope, types, limitToFunction, templateTypeReplacements);
|
auto statement = transform(getNode("statement", children), scope, types, limitToFunction, templateTypeReplacements);
|
||||||
if (name == "lambda")
|
if (name == "lambda")
|
||||||
newNode->getDataRef()->closedVariables = findVariablesToClose(newNode, statement);
|
newNode->getDataRef()->closedVariables = findVariablesToClose(newNode, statement, scope);
|
||||||
for (auto i : newNode->getDataRef()->closedVariables)
|
for (auto i : newNode->getDataRef()->closedVariables)
|
||||||
std::cout << "OK, CLOSED: " << i->getDataRef()->toString() << std::endl;
|
std::cout << "OK, CLOSED: " << i->getDataRef()->toString() << std::endl;
|
||||||
newNode->addChild(statement);
|
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;
|
std::cerr << "scope lookup error! Could not find " << functionCallString << " in boolean stuff " << std::endl;
|
||||||
throw "LOOKUP ERROR: " + functionCallString;
|
throw "LOOKUP ERROR: " + functionCallString;
|
||||||
}
|
}
|
||||||
newNode = function;
|
return function;
|
||||||
} else {
|
} else {
|
||||||
// XXX What the heck is this
|
// XXX What the heck is this
|
||||||
if (children.size() == 0)
|
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
|
// 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
|
// 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;
|
std::set<NodeTree<ASTData>*> closed;
|
||||||
//enum ASTType {undef, translation_unit, interpreter_directive, import, identifier, type_def,
|
//enum ASTType {undef, translation_unit, interpreter_directive, import, identifier, type_def,
|
||||||
//function, code_block, typed_parameter, expression, boolean_expression, statement,
|
//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};
|
//in_passthrough_params, out_passthrough_params, opt_string, param_assign, function_call, value};
|
||||||
if (stat->getDataRef()->type == function || stat->getDataRef()->type == translation_unit
|
if (stat->getDataRef()->type == function || stat->getDataRef()->type == translation_unit
|
||||||
|| stat->getDataRef()->type == type_def || stat->getDataRef()->type == value
|
|| 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;
|
return closed;
|
||||||
|
}
|
||||||
if (stat->getDataRef()->type == function_call && (stat->getDataRef()->symbol.getName() == "." || stat->getDataRef()->symbol.getName() == "->")) {
|
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 ->
|
// 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());
|
closed.insert(recClosed.begin(), recClosed.end());
|
||||||
return closed;
|
return closed;
|
||||||
}
|
}
|
||||||
if (stat->getDataRef()->type == identifier && !inScopeChain(stat, func))
|
if (stat->getDataRef()->type == identifier && !inScopeChain(stat, func))
|
||||||
closed.insert(stat);
|
closed.insert(stat);
|
||||||
for (auto child: stat->getChildren()) {
|
for (auto child: stat->getChildren()) {
|
||||||
auto recClosed = findVariablesToClose(func, child);
|
auto recClosed = findVariablesToClose(func, child, scope);
|
||||||
closed.insert(recClosed.begin(), recClosed.end());
|
closed.insert(recClosed.begin(), recClosed.end());
|
||||||
}
|
}
|
||||||
return closed;
|
return closed;
|
||||||
@@ -1140,7 +1148,18 @@ void ASTTransformation::unifyType(NodeTree<Symbol> *syntaxType, Type type, std::
|
|||||||
// to get the type it was instantiated with.
|
// to get the type it was instantiated with.
|
||||||
auto origionalType = type.typeDefinition->getDataRef()->valueType;
|
auto origionalType = type.typeDefinition->getDataRef()->valueType;
|
||||||
auto typeTemplateDefinition = origionalType->templateDefinition;
|
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>*> uninTypeInstTypes = getNodes("type", getNode("template_inst", children));
|
||||||
std::vector<NodeTree<Symbol>*> typeInstTypes = getNodes("template_param", getNode("template_dec", typeTemplateDefinition->getChildren()));
|
std::vector<NodeTree<Symbol>*> typeInstTypes = getNodes("template_param", getNode("template_dec", typeTemplateDefinition->getChildren()));
|
||||||
for (int i = 0; i < uninTypeInstTypes.size(); i++) {
|
for (int i = 0; i < uninTypeInstTypes.size(); i++) {
|
||||||
@@ -1152,6 +1171,7 @@ void ASTTransformation::unifyType(NodeTree<Symbol> *syntaxType, Type type, std::
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
throw "the inference just isn't good enough";
|
||||||
}
|
}
|
||||||
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>*>());
|
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::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 << "Scp]|[e looking up " << lookup << std::endl;
|
||||||
std::cout << "current: " << scope->getDataRef()->toString() << 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;
|
std::cout << "found it at language level as reserved word." << std::endl;
|
||||||
NodeTree<ASTData>* identifier = LLElementIterator->second[0];
|
NodeTree<ASTData>* identifier = LLElementIterator->second[0];
|
||||||
if (lookup == "this") {
|
if (lookup == "this") {
|
||||||
identifier = new NodeTree<ASTData>("identifier", identifier->getData());
|
identifier = generateThis(scope);
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
std::vector<NodeTree<ASTData>*> thingy; thingy.push_back(identifier);
|
std::vector<NodeTree<ASTData>*> thingy; thingy.push_back(identifier);
|
||||||
return thingy;
|
return thingy;
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
if (enclosingFunction->getDataRef()->closedVariables.size()) {
|
if (enclosingFunction->getDataRef()->closedVariables.size()) {
|
||||||
std::cout << "WHOH IS A CLOSER" << std::endl;
|
std::cout << "WHOH IS A CLOSER" << std::endl;
|
||||||
if (enclosingFunction->getDataRef()->closedVariables.find(from) != enclosingFunction->getDataRef()->closedVariables.end()) {
|
if (enclosingFunction->getDataRef()->closedVariables.find(from) != enclosingFunction->getDataRef()->closedVariables.end()) {
|
||||||
preName += "(*closed_varibles->";
|
preName += "(*closed_variables->";
|
||||||
postName += ")";
|
postName += ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -322,7 +322,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
|
|
||||||
std::string nameDecoration, parameters;
|
std::string nameDecoration, parameters;
|
||||||
if (data.closedVariables.size())
|
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++) {
|
for (int j = 0; j < children.size()-1; j++) {
|
||||||
if (j > 0 || data.closedVariables.size())
|
if (j > 0 || data.closedVariables.size())
|
||||||
parameters += ", ";
|
parameters += ", ";
|
||||||
@@ -345,7 +345,12 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
if (notFirst)
|
if (notFirst)
|
||||||
output.preValue += ", ";
|
output.preValue += ", ";
|
||||||
notFirst = true;
|
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.preValue += "};\n";
|
||||||
output += "("+ ValueTypeToCType(data.valueType, "") +"){(void*)" + funcName + ", &" + tmpStruct + "}";
|
output += "("+ ValueTypeToCType(data.valueType, "") +"){(void*)" + funcName + ", &" + tmpStruct + "}";
|
||||||
@@ -636,12 +641,23 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
std::string nameDecoration;
|
std::string nameDecoration;
|
||||||
for (int i = 0; i < (functionDefChildren.size() > 0 ? functionDefChildren.size()-1 : 0); i++)
|
for (int i = 0; i < (functionDefChildren.size() > 0 ? functionDefChildren.size()-1 : 0); i++)
|
||||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(functionDefChildren[i]->getData().valueType);
|
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
|
//Check to see if we're inside of an object and this is a method call
|
||||||
bool isSelfObjectMethod = enclosingObject && contains(enclosingObject->getChildren(), children[0]);
|
bool isSelfObjectMethod = enclosingObject && contains(enclosingObject->getChildren(), children[0]);
|
||||||
if (isSelfObjectMethod) {
|
if (isSelfObjectMethod) {
|
||||||
output += function_header + scopePrefix(children[0]) + CifyName(enclosingObject->getDataRef()->symbol.getName()) +"__";
|
output += function_header + scopePrefix(children[0]) + CifyName(enclosingObject->getDataRef()->symbol.getName()) +"__";
|
||||||
output += CifyName(name + nameDecoration) + "(";
|
output += CifyName(name + nameDecoration) + "(";
|
||||||
output += children.size() > 1 ? "this," : "this";
|
output += std::string(addClosedOver ? "(*closed_variables->this)" : "this") + (children.size() > 1 ? "," : "");
|
||||||
} else {
|
} else {
|
||||||
output += function_header + scopePrefix(children[0]) + CifyName(name + nameDecoration) + "(";
|
output += function_header + scopePrefix(children[0]) + CifyName(name + nameDecoration) + "(";
|
||||||
}
|
}
|
||||||
@@ -745,7 +761,8 @@ std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject,
|
|||||||
enclosingObjectType.increaseIndirection();
|
enclosingObjectType.increaseIndirection();
|
||||||
std::vector<NodeTree<ASTData>*> children = from->getChildren();
|
std::vector<NodeTree<ASTData>*> children = from->getChildren();
|
||||||
std::string nameDecoration, parameters;
|
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());
|
parameters += ", " + ValueTypeToCType(children[i]->getData().valueType, generate(children[i]).oneString());
|
||||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(children[i]->getData().valueType);
|
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
|
// note the increased indirection b/c we're using references to what we closed over
|
||||||
for (auto var : closedVariables) {
|
for (auto var : closedVariables) {
|
||||||
auto tmp = var->getDataRef()->valueType->withIncreasedIndirection();
|
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();
|
std::string structName = "closureStructType" + getID();
|
||||||
typedefString += " } " + structName + ";\n";
|
typedefString += " } " + structName + ";\n";
|
||||||
|
|||||||
@@ -38,6 +38,14 @@ fun print(toPrint: string) : void {
|
|||||||
print(charArr);
|
print(charArr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun print(toPrint: bool): void {
|
||||||
|
if (toPrint)
|
||||||
|
print("true")
|
||||||
|
else
|
||||||
|
print("false")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fun print(toPrint: int): void {
|
fun print(toPrint: int): void {
|
||||||
__if_comp__ __C__ {
|
__if_comp__ __C__ {
|
||||||
simple_passthrough(toPrint = toPrint::) """
|
simple_passthrough(toPrint = toPrint::) """
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import vector
|
import vector
|
||||||
|
import io
|
||||||
|
|
||||||
fun map<T,U>(): map<T,U> {
|
fun map<T,U>(): map<T,U> {
|
||||||
var toRet.construct(): map<T,U>
|
var toRet.construct(): map<T,U>
|
||||||
@@ -22,18 +23,19 @@ obj map<T,U> {
|
|||||||
keys.copy_construct(&old->keys)
|
keys.copy_construct(&old->keys)
|
||||||
values.copy_construct(&old->values)
|
values.copy_construct(&old->values)
|
||||||
}
|
}
|
||||||
|
fun operator=(rhs: map<T,U>) {
|
||||||
|
destruct()
|
||||||
|
copy_construct(&rhs)
|
||||||
|
}
|
||||||
fun destruct() {
|
fun destruct() {
|
||||||
keys.destruct()
|
keys.destruct()
|
||||||
values.destruct()
|
values.destruct()
|
||||||
}
|
}
|
||||||
fun find_index(key: T): int {
|
|
||||||
return keys.find_index(key)
|
|
||||||
}
|
|
||||||
fun operator[]=(key: T, value: U) {
|
fun operator[]=(key: T, value: U) {
|
||||||
set(key,value)
|
set(key,value)
|
||||||
}
|
}
|
||||||
fun set(key: T, value: U) {
|
fun set(key: T, value: U) {
|
||||||
var keyIdx = find_index(key)
|
var keyIdx = keys.find(key)
|
||||||
if (keyIdx >= 0) {
|
if (keyIdx >= 0) {
|
||||||
values.set(keyIdx, value)
|
values.set(keyIdx, value)
|
||||||
return;
|
return;
|
||||||
@@ -42,7 +44,16 @@ obj map<T,U> {
|
|||||||
values.add(value)
|
values.add(value)
|
||||||
}
|
}
|
||||||
fun get(key: T): U {
|
fun get(key: T): U {
|
||||||
return values.get(keys.find_index(key))
|
return values.get(keys.find(key))
|
||||||
|
}
|
||||||
|
fun remove(key: T) {
|
||||||
|
var idx = keys.find(key)
|
||||||
|
if (idx < 0) {
|
||||||
|
io::println("trying to remove nonexistant key-value!")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
keys.remove(idx)
|
||||||
|
values.remove(idx)
|
||||||
}
|
}
|
||||||
fun operator[](key: T): U {
|
fun operator[](key: T): U {
|
||||||
return get(key)
|
return get(key)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import io:*
|
import set
|
||||||
|
|
||||||
__if_comp__ __C__ simple_passthrough """
|
__if_comp__ __C__ simple_passthrough """
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -93,4 +93,15 @@ fun maybe_destruct<T(Object)>(it:T*):void {
|
|||||||
it->destruct()
|
it->destruct()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a function that allows the safe deletion of recursive and complicated data structures
|
||||||
|
fun safe_recursive_delete<T>(first: T*, addingFunc: fun(T*): set::set<T*>) {
|
||||||
|
var toDelete = set::set<T*>()
|
||||||
|
var next = set::set(first)
|
||||||
|
while (toDelete != next) {
|
||||||
|
toDelete = next
|
||||||
|
toDelete.for_each( fun(it: T*) next.add(addingFunc(it)); )
|
||||||
|
}
|
||||||
|
toDelete.for_each( fun(it: T*) delete(it); )
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import io
|
|||||||
import vector
|
import vector
|
||||||
import string
|
import string
|
||||||
import mem
|
import mem
|
||||||
|
import set
|
||||||
import util
|
import util
|
||||||
import conversions
|
import conversions
|
||||||
|
|
||||||
@@ -55,12 +56,14 @@ obj regex(Object) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun copy_construct(old:regex*):void {
|
fun copy_construct(old:regex*):void {
|
||||||
begin = old->begin
|
//begin = old->begin
|
||||||
regexString.copy_construct(&old->regexString)
|
//regexString.copy_construct(&old->regexString)
|
||||||
|
construct(old->regexString)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun destruct():void {
|
fun destruct():void {
|
||||||
regexString.destruct()
|
regexString.destruct()
|
||||||
|
//mem::safe_recursive_delete(begin, fun(it: regexState*): set::set<regexState*> { return set::set(it); } )
|
||||||
}
|
}
|
||||||
|
|
||||||
fun operator=(other: regex):void {
|
fun operator=(other: regex):void {
|
||||||
|
|||||||
60
stdlib/set.krak
Normal file
60
stdlib/set.krak
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import vector
|
||||||
|
import io
|
||||||
|
|
||||||
|
fun set<T>(): set<T> {
|
||||||
|
var toRet.construct() : set<T>
|
||||||
|
return toRet
|
||||||
|
}
|
||||||
|
|
||||||
|
fun set<T>(item: T): set<T> {
|
||||||
|
var toRet.construct() : set<T>
|
||||||
|
toRet.add(item)
|
||||||
|
return toRet
|
||||||
|
}
|
||||||
|
|
||||||
|
obj set<T> {
|
||||||
|
var data: vector::vector<T>
|
||||||
|
fun construct() {
|
||||||
|
data.construct()
|
||||||
|
}
|
||||||
|
fun copy_construct(old: set<T>*) {
|
||||||
|
data.copy_construct(&old->data)
|
||||||
|
}
|
||||||
|
fun operator=(rhs: set<T>) {
|
||||||
|
destruct()
|
||||||
|
copy_construct(&rhs)
|
||||||
|
}
|
||||||
|
fun operator==(rhs: set<T>): bool {
|
||||||
|
if (size() != rhs.size())
|
||||||
|
return false
|
||||||
|
return !data.any_true( fun(item: T): bool return !rhs.contains(item); )
|
||||||
|
}
|
||||||
|
fun destruct() {
|
||||||
|
data.destruct()
|
||||||
|
}
|
||||||
|
fun size():int {
|
||||||
|
return data.size
|
||||||
|
}
|
||||||
|
fun contains(item: T): bool {
|
||||||
|
return data.find(item) != -1
|
||||||
|
}
|
||||||
|
fun add(item: T) {
|
||||||
|
if (!contains(item))
|
||||||
|
data.add(item)
|
||||||
|
}
|
||||||
|
fun add(items: set<T>) {
|
||||||
|
items.for_each( fun(item: T) add(item); )
|
||||||
|
}
|
||||||
|
fun remove(item: T) {
|
||||||
|
var idx = data.find(item)
|
||||||
|
if (idx == -1) {
|
||||||
|
io::println("CANNOT FIND ITEM TO REMOVE")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data.remove(idx)
|
||||||
|
}
|
||||||
|
fun for_each(func: fun(T):void) {
|
||||||
|
data.do(func)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -34,6 +34,16 @@ obj string (Object) {
|
|||||||
construct(*old)
|
construct(*old)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun operator=(str: char*): void {
|
||||||
|
destruct();
|
||||||
|
construct(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun operator=(str: string): void {
|
||||||
|
destruct();
|
||||||
|
data.copy_construct(&str.data)
|
||||||
|
}
|
||||||
|
|
||||||
fun destruct():void {
|
fun destruct():void {
|
||||||
data.destruct()
|
data.destruct()
|
||||||
}
|
}
|
||||||
@@ -51,11 +61,6 @@ obj string (Object) {
|
|||||||
}
|
}
|
||||||
fun length():int { return data.size; }
|
fun length():int { return data.size; }
|
||||||
|
|
||||||
fun operator=(str: char*): void {
|
|
||||||
destruct();
|
|
||||||
construct(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun operator+(str: char*): string {
|
fun operator+(str: char*): string {
|
||||||
var newStr.construct(str):string
|
var newStr.construct(str):string
|
||||||
var ret.construct(data + newStr.data):string
|
var ret.construct(data + newStr.data):string
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ obj vector<T> (Object) {
|
|||||||
// on an object that we want to put in a vector. In this way we avoid the problem
|
// on an object that we want to put in a vector. In this way we avoid the problem
|
||||||
// by not generating this function unless it's called - we also get the ability to
|
// by not generating this function unless it's called - we also get the ability to
|
||||||
// do a find index using a different type, which could be fun.
|
// do a find index using a different type, which could be fun.
|
||||||
fun find_index<U>(value: U): int {
|
fun find<U>(value: U): int {
|
||||||
for (var i = 0; i < size; i++;)
|
for (var i = 0; i < size; i++;)
|
||||||
if (data[i] == value)
|
if (data[i] == value)
|
||||||
return i;
|
return i;
|
||||||
@@ -159,6 +159,16 @@ obj vector<T> (Object) {
|
|||||||
resize(size*2);
|
resize(size*2);
|
||||||
maybe_copy_construct(&data[size-1], &dataIn);
|
maybe_copy_construct(&data[size-1], &dataIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun remove(index: int) {
|
||||||
|
maybe_destruct(&data[index])
|
||||||
|
for (var i = index+1; i < size; i++;) {
|
||||||
|
maybe_copy_construct(&data[i-1], &data[i])
|
||||||
|
maybe_destruct(&data[i])
|
||||||
|
}
|
||||||
|
size--
|
||||||
|
}
|
||||||
|
|
||||||
fun do(func: fun(T):void):void {
|
fun do(func: fun(T):void):void {
|
||||||
for (var i = 0; i < size; i++;)
|
for (var i = 0; i < size; i++;)
|
||||||
func(data[i])
|
func(data[i])
|
||||||
|
|||||||
2
tests/test_close_over_members.expected_results
Normal file
2
tests/test_close_over_members.expected_results
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
4
|
||||||
|
7
|
||||||
27
tests/test_close_over_members.krak
Normal file
27
tests/test_close_over_members.krak
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import io:*
|
||||||
|
|
||||||
|
fun runFunc(func: fun():void) {
|
||||||
|
func()
|
||||||
|
}
|
||||||
|
|
||||||
|
obj ToClose {
|
||||||
|
var data: int
|
||||||
|
fun print4() {
|
||||||
|
println(4)
|
||||||
|
}
|
||||||
|
fun testMethod() {
|
||||||
|
runFunc(fun() { print4(); } )
|
||||||
|
}
|
||||||
|
fun testVariable() {
|
||||||
|
data = 7
|
||||||
|
runFunc(fun() { println(data); } )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main():int {
|
||||||
|
var it: ToClose
|
||||||
|
it.testMethod()
|
||||||
|
it.testVariable()
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
1
tests/test_comparison_overload.expected_results
Normal file
1
tests/test_comparison_overload.expected_results
Normal file
@@ -0,0 +1 @@
|
|||||||
|
false
|
||||||
25
tests/test_comparison_overload.krak
Normal file
25
tests/test_comparison_overload.krak
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import io:*
|
||||||
|
|
||||||
|
fun Comparable<T>(): Comparable<T> {
|
||||||
|
var toRet : Comparable<T>
|
||||||
|
return toRet
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Comparable<T>(item: T): Comparable<T> {
|
||||||
|
var toRet : Comparable<T>
|
||||||
|
return toRet
|
||||||
|
}
|
||||||
|
|
||||||
|
obj Comparable<T> {
|
||||||
|
fun operator==(other: Comparable<T>):bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main():int {
|
||||||
|
var first: Comparable<int>
|
||||||
|
var second: Comparable<int>
|
||||||
|
println(first == second)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
@@ -9,5 +9,4 @@
|
|||||||
Lookie, a map!
|
Lookie, a map!
|
||||||
What I get for not testing different types
|
What I get for not testing different types
|
||||||
key: 7, value: Lookie, a map!
|
key: 7, value: Lookie, a map!
|
||||||
key: 20, value: What I get for not testing different types
|
|
||||||
key: 30, value: we'll look for for_each too
|
key: 30, value: we'll look for for_each too
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ fun main():int {
|
|||||||
mapEx[30] = "we'll look for for_each too"
|
mapEx[30] = "we'll look for for_each too"
|
||||||
println(mapEx[7])
|
println(mapEx[7])
|
||||||
println(mapEx[20])
|
println(mapEx[20])
|
||||||
|
mapEx.remove(20)
|
||||||
mapEx.for_each(fun(key:int, value:char*) { print("key: "); print(key); print(", value: "); println(value); })
|
mapEx.for_each(fun(key:int, value:char*) { print("key: "); print(key); print(", value: "); println(value); })
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
13
tests/test_set.expected_results
Normal file
13
tests/test_set.expected_results
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
true
|
||||||
|
false
|
||||||
|
false
|
||||||
|
true
|
||||||
|
true
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
false
|
||||||
|
true
|
||||||
|
true
|
||||||
|
4
|
||||||
|
5
|
||||||
24
tests/test_set.krak
Normal file
24
tests/test_set.krak
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import io:*
|
||||||
|
import set:*
|
||||||
|
|
||||||
|
fun main():int {
|
||||||
|
var s = set(3)
|
||||||
|
println(s.contains(3))
|
||||||
|
println(s.contains(1))
|
||||||
|
s.remove(3)
|
||||||
|
s.add(4)
|
||||||
|
println(s.contains(3))
|
||||||
|
println(s.contains(4))
|
||||||
|
|
||||||
|
println(s == set(4))
|
||||||
|
println(s == set(5))
|
||||||
|
s.add(set(5))
|
||||||
|
println(s == set(4))
|
||||||
|
println(s == set(5))
|
||||||
|
println(s.contains(3))
|
||||||
|
println(s.contains(4))
|
||||||
|
println(s.contains(5))
|
||||||
|
|
||||||
|
s.for_each( fun(it: int) println(it); )
|
||||||
|
return 0
|
||||||
|
}
|
||||||
@@ -25,10 +25,83 @@ find test
|
|||||||
0
|
0
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
set and []= test
|
set, []=, and delete test
|
||||||
4
|
4
|
||||||
8
|
8
|
||||||
9
|
9
|
||||||
7
|
7
|
||||||
|
delete
|
||||||
|
4
|
||||||
|
8
|
||||||
|
7
|
||||||
|
delete v2
|
||||||
|
Constructed: 100
|
||||||
|
Constructed: 200
|
||||||
|
Constructed: 300
|
||||||
|
Copied: 100 to 101
|
||||||
|
Copied: 200 to 201
|
||||||
|
Copied: 300 to 301
|
||||||
|
Copied: 101 to 102
|
||||||
|
Copied: 102 to 103
|
||||||
|
Copied: 103 to 104
|
||||||
|
Destroyed: 103
|
||||||
|
Destroyed: 102
|
||||||
|
Copied: 201 to 202
|
||||||
|
Copied: 202 to 203
|
||||||
|
Copied: 203 to 204
|
||||||
|
Destroyed: 203
|
||||||
|
Destroyed: 202
|
||||||
|
Copied: 301 to 302
|
||||||
|
Copied: 302 to 303
|
||||||
|
Copied: 303 to 304
|
||||||
|
Destroyed: 303
|
||||||
|
Destroyed: 302
|
||||||
|
Copied: 104 to 105
|
||||||
|
Copied: 105 to 106
|
||||||
|
Copied: 106 to 107
|
||||||
|
Destroyed: 106
|
||||||
|
Destroyed: 105
|
||||||
|
Copied: 204 to 205
|
||||||
|
Copied: 205 to 206
|
||||||
|
Copied: 206 to 207
|
||||||
|
Destroyed: 206
|
||||||
|
Destroyed: 205
|
||||||
|
Copied: 304 to 305
|
||||||
|
Copied: 305 to 306
|
||||||
|
Copied: 306 to 307
|
||||||
|
Destroyed: 306
|
||||||
|
Destroyed: 305
|
||||||
|
Destroyed: 204
|
||||||
|
Destroyed: 304
|
||||||
|
Destroyed: 104
|
||||||
|
Destroyed: 301
|
||||||
|
Destroyed: 201
|
||||||
|
Destroyed: 101
|
||||||
|
Copied: 107 to 108
|
||||||
|
Copied: 108 to 109
|
||||||
|
Copied: 109 to 110
|
||||||
|
Destroyed: 109
|
||||||
|
Destroyed: 108
|
||||||
|
Copied: 207 to 208
|
||||||
|
Copied: 208 to 209
|
||||||
|
Copied: 209 to 210
|
||||||
|
Destroyed: 209
|
||||||
|
Destroyed: 208
|
||||||
|
Copied: 307 to 308
|
||||||
|
Copied: 308 to 309
|
||||||
|
Copied: 309 to 310
|
||||||
|
Destroyed: 309
|
||||||
|
Destroyed: 308
|
||||||
|
Destroyed: 207
|
||||||
|
Destroyed: 307
|
||||||
|
Destroyed: 107
|
||||||
|
Destroyed: 210
|
||||||
|
Copied: 310 to 311
|
||||||
|
Destroyed: 310
|
||||||
done
|
done
|
||||||
|
Destroyed: 311
|
||||||
|
Destroyed: 110
|
||||||
|
Destroyed: 300
|
||||||
|
Destroyed: 200
|
||||||
|
Destroyed: 100
|
||||||
Destroyed: 0
|
Destroyed: 0
|
||||||
|
|||||||
@@ -107,16 +107,26 @@ fun main(): int {
|
|||||||
|
|
||||||
println("find test")
|
println("find test")
|
||||||
var multipleFindTest = vector(1,2,3)
|
var multipleFindTest = vector(1,2,3)
|
||||||
println(multipleFindTest.find_index(1))
|
println(multipleFindTest.find(1))
|
||||||
println(multipleFindTest.find_index(2))
|
println(multipleFindTest.find(2))
|
||||||
println(multipleFindTest.find_index(3))
|
println(multipleFindTest.find(3))
|
||||||
|
|
||||||
println("set and []= test")
|
println("set, []=, and delete test")
|
||||||
var setTest = vector(4,5,6)
|
var setTest = vector(4,5,6)
|
||||||
setTest.add(7)
|
setTest.add(7)
|
||||||
setTest.set(1,8)
|
setTest.set(1,8)
|
||||||
setTest[2] = 9
|
setTest[2] = 9
|
||||||
setTest.do(fun(it: int) println(it);)
|
setTest.do(fun(it: int) println(it);)
|
||||||
|
println("delete")
|
||||||
|
setTest.remove(2)
|
||||||
|
setTest.do(fun(it: int) println(it);)
|
||||||
|
|
||||||
|
println("delete v2")
|
||||||
|
var firstRem.construct(100): AbleToBeDestroyed;
|
||||||
|
var secondRem.construct(200): AbleToBeDestroyed;
|
||||||
|
var thirdRem.construct(300): AbleToBeDestroyed;
|
||||||
|
var remTest = vector(firstRem, secondRem, thirdRem);
|
||||||
|
remTest.remove(1)
|
||||||
|
|
||||||
println("done")
|
println("done")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user