Return by reference and pass by reference working with objects. Closures might present problems, however

This commit is contained in:
Nathan Braswell
2015-07-15 00:53:53 -04:00
parent 0ee44e829f
commit 06f36f2a87
12 changed files with 79 additions and 67 deletions

View File

@@ -43,6 +43,8 @@ class Type {
Type withIncreasedIndirection(); Type withIncreasedIndirection();
Type withDecreasedIndirection(); Type withDecreasedIndirection();
Type* withoutReference();
ValueType baseType; ValueType baseType;
NodeTree<ASTData>* typeDefinition; NodeTree<ASTData>* typeDefinition;
NodeTree<Symbol>* templateDefinition; NodeTree<Symbol>* templateDefinition;

View File

@@ -506,8 +506,11 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
CCodeTriple expr = generate(children[0], enclosingObject, true, enclosingFunction); CCodeTriple expr = generate(children[0], enclosingObject, true, enclosingFunction);
output.preValue += expr.preValue; output.preValue += expr.preValue;
std::string retTemp = "ret_temp" + getID(); std::string retTemp = "ret_temp" + getID();
output.preValue += ValueTypeToCType(children[0]->getDataRef()->valueType, retTemp) + ";\n"; // use the function's return value so we do the right thing with references
if (methodExists(children[0]->getDataRef()->valueType, "copy_construct", std::vector<Type>{children[0]->getDataRef()->valueType->withIncreasedIndirection()})) output.preValue += ValueTypeToCType(enclosingFunction->getDataRef()->valueType->returnType, retTemp) + ";\n";
if (enclosingFunction->getDataRef()->valueType->returnType->is_reference)
output.preValue += retTemp + " = &" + expr.value + ";\n";
else if (methodExists(children[0]->getDataRef()->valueType, "copy_construct", std::vector<Type>{children[0]->getDataRef()->valueType->withIncreasedIndirection()}))
output.preValue += generateMethodIfExists(children[0]->getDataRef()->valueType, "copy_construct", "&"+retTemp + ", &" + expr.value, std::vector<Type>{children[0]->getDataRef()->valueType->withIncreasedIndirection()}); output.preValue += generateMethodIfExists(children[0]->getDataRef()->valueType, "copy_construct", "&"+retTemp + ", &" + expr.value, std::vector<Type>{children[0]->getDataRef()->valueType->withIncreasedIndirection()});
else else
output.preValue += retTemp + " = " + expr.value + ";\n"; output.preValue += retTemp + " = " + expr.value + ";\n";
@@ -742,11 +745,12 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
// see if we should copy_construct / referencize all the parameters // see if we should copy_construct / referencize all the parameters
for (int i = 1; i < children.size(); i++) { //children[0] is the declaration for (int i = 1; i < children.size(); i++) { //children[0] is the declaration
Type* func_param_type = children[0]->getDataRef()->valueType->parameterTypes[i-1]; Type* func_param_type = children[0]->getDataRef()->valueType->parameterTypes[i-1];
Type *param_type = children[i]->getDataRef()->valueType; // ok, if our param is a reference returned by another function, we don't actually want this type to be a reference if it is now.
Type *param_type = children[i]->getDataRef()->valueType->withoutReference();
// don't copy_construct references // don't copy_construct references
if (func_param_type->is_reference) { if (func_param_type->is_reference) {
parameters += "&" + generate(children[i], enclosingObject, true, enclosingFunction); parameters += "&" + generate(children[i], enclosingObject, true, enclosingFunction);
} else if (methodExists(children[i]->getDataRef()->valueType, "copy_construct", std::vector<Type>{children[i]->getDataRef()->valueType->withIncreasedIndirection()})) { } else if (methodExists(children[i]->getDataRef()->valueType, "copy_construct", std::vector<Type>{param_type->withIncreasedIndirection()})) {
std::string tmpParamName = "param" + getID(); std::string tmpParamName = "param" + getID();
CCodeTriple paramValue = generate(children[i], enclosingObject, true, enclosingFunction); CCodeTriple paramValue = generate(children[i], enclosingObject, true, enclosingFunction);
parameters.preValue += paramValue.preValue; parameters.preValue += paramValue.preValue;
@@ -782,7 +786,9 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
std::string retTempName = "return_temp" + getID(); std::string retTempName = "return_temp" + getID();
output.preValue += ValueTypeToCType(retType, retTempName) + " = " + output.value + ";\n"; output.preValue += ValueTypeToCType(retType, retTempName) + " = " + output.value + ";\n";
output.value = retTempName; output.value = retTempName;
if (methodExists(retType, "destruct", std::vector<Type>())) { if (retType->is_reference)
output.value = "(*" + output.value + ")";
else if (methodExists(retType, "destruct", std::vector<Type>())) {
output.postValue = generateMethodIfExists(retType, "destruct", "&"+retTempName, std::vector<Type>()) + ";\n" + output.postValue; output.postValue = generateMethodIfExists(retType, "destruct", "&"+retTempName, std::vector<Type>()) + ";\n" + output.postValue;
} }
} }
@@ -848,7 +854,7 @@ std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject,
// Note that we always wrap out child in {}, as we now allow one statement functions without a codeblock // Note that we always wrap out child in {}, as we now allow one statement functions without a codeblock
// //
std::string output; std::string output;
output += functionSignature + " {\n" + generate(children.back(), enclosingObject).oneString(); output += functionSignature + " {\n" + generate(children.back(), enclosingObject, false, from).oneString();
output += emitDestructors(reverse(distructDoubleStack.back()), enclosingObject); output += emitDestructors(reverse(distructDoubleStack.back()), enclosingObject);
output += "}\n"; //Pass in the object so we can properly handle access to member stuff output += "}\n"; //Pass in the object so we can properly handle access to member stuff
distructDoubleStack.pop_back(); distructDoubleStack.pop_back();
@@ -868,7 +874,8 @@ NodeTree<ASTData>* CGenerator::getMethod(Type* type, std::string method, std::ve
if (types.size() != methodTypes.size()) if (types.size() != methodTypes.size())
continue; continue;
for (int i = 0; i < types.size(); i++) { for (int i = 0; i < types.size(); i++) {
if (types[i] != methodTypes[i]) { // don't care about references
if (!types[i].test_equality(methodTypes[i], false)) {
methodFits = false; methodFits = false;
break; break;
} }

View File

@@ -245,4 +245,9 @@ Type Type::withDecreasedIndirection() {
newOne->decreaseIndirection(); newOne->decreaseIndirection();
return *newOne; return *newOne;
} }
Type* Type::withoutReference() {
Type *newOne = clone();
newOne->is_reference = false;
return newOne;
}

View File

@@ -65,7 +65,7 @@ obj future<T> {
status = pthread_create(&thread,wrapper) status = pthread_create(&thread,wrapper)
} }
fun get_status() { fun get_status():int {
return status return status
} }

View File

@@ -70,7 +70,7 @@ fun load_grammer(gram_str: string::string): grammer {
doLeftSide = true doLeftSide = true
} else { } else {
if (doLeftSide) { if (doLeftSide) {
leftSide = symbol::symbol(word, true) leftSide = symbol::symbol(word, false)
gram.non_terminals.add(leftSide) gram.non_terminals.add(leftSide)
} else { } else {
if (word[0] == '"') { if (word[0] == '"') {

View File

@@ -46,7 +46,7 @@ obj map<T,U> (Object) {
fun contains_key(key: T): bool { fun contains_key(key: T): bool {
return keys.contains(key) return keys.contains(key)
} }
fun get(key: T): U { fun get(key: T): ref U {
return values.get(keys.find(key)) return values.get(keys.find(key))
} }
fun remove(key: T) { fun remove(key: T) {
@@ -58,7 +58,7 @@ obj map<T,U> (Object) {
keys.remove(idx) keys.remove(idx)
values.remove(idx) values.remove(idx)
} }
fun operator[](key: T): U { fun operator[](key: T): ref U {
return get(key) return get(key)
} }
fun for_each(func: fun(T, U):void) { fun for_each(func: fun(T, U):void) {

View File

@@ -52,14 +52,11 @@ obj string (Object) {
data.destruct() data.destruct()
} }
fun operator[](index: int): char { return data[index]; } fun operator[](index: int): ref char { return data[index]; }
fun slice(first: int, second: int): string { fun slice(first: int, second: int): string {
var new.construct(data.slice(first,second)): string var new.construct(data.slice(first,second)): string
return new return new
} }
fun operator[]=(index: int, toSet: char) {
data[index] = toSet
}
fun set(index: int, toSet: char) { fun set(index: int, toSet: char) {
data.set(index, toSet) data.set(index, toSet)
} }

View File

@@ -92,9 +92,9 @@ obj vector<T> (Object) {
return new return new
} }
fun at(index: int): T { return get(index); } fun at(index: int): ref T { return get(index); }
fun operator[](index: int): T { return get(index); } fun operator[](index: int): ref T { return get(index); }
fun get(index: int): T { fun get(index: int): ref T {
if (index < 0 || index >= size) { if (index < 0 || index >= size) {
println("Vector access out of bounds! Retuning 0th element as sanest option"); println("Vector access out of bounds! Retuning 0th element as sanest option");
print("Vector tried to access element: "); print("Vector tried to access element: ");
@@ -124,9 +124,6 @@ obj vector<T> (Object) {
return find(item) != -1 return find(item) != -1
} }
fun operator[]=(index: int, dataIn: T) {
set(index, dataIn)
}
fun set(index: int, dataIn: T): void { fun set(index: int, dataIn: T): void {
if (index < 0 || index >= size) if (index < 0 || index >= size)
return; return;

View File

@@ -10,32 +10,35 @@ fun main():int {
/*var a = load_grammer(read_file(string("../krakenGrammer.kgm")))*/ /*var a = load_grammer(read_file(string("../krakenGrammer.kgm")))*/
var a = load_grammer(read_file(string("grammer.kgm"))) var a = load_grammer(read_file(string("grammer.kgm")))
println(a.to_string()) println(a.to_string())
/*a.calculate_first_set()*/ var doFirstSet = fun() {
println("///////////////////START FIRST SET/////////////") a.calculate_first_set()
println("//TERMINALS//") println("///////////////////START FIRST SET/////////////")
a.terminals.for_each( fun(terminal: util::pair<symbol::symbol, regex::regex>) { println("//TERMINALS//")
var set_str = string::string("{ ") a.terminals.for_each( fun(terminal: util::pair<symbol::symbol, regex::regex>) {
a.first_set_map[terminal.first].for_each( fun(sym: symbol::symbol) { var set_str = string::string("{ ")
set_str += sym.to_string() + " " a.first_set_map[terminal.first].for_each( fun(sym: symbol::symbol) {
set_str += sym.to_string() + ", "
})
set_str += "}"
print(terminal.first.to_string() + " first: " + set_str + "\n")
}) })
set_str += "}" println("//NON TERMINALS//")
print(terminal.first.to_string() + " first: " + set_str + "\n") a.non_terminals.for_each( fun(non_terminal: symbol::symbol) {
}) var set_str = string::string("{ ")
println("//NON TERMINALS//") a.first_set_map[non_terminal].for_each( fun(sym: symbol::symbol) {
a.non_terminals.for_each( fun(non_terminal: symbol::symbol) { set_str += sym.to_string() + ", "
var set_str = string::string("{ ") })
a.first_set_map[non_terminal].for_each( fun(sym: symbol::symbol) { set_str += "}"
set_str += sym.to_string() + " " print(non_terminal.to_string() + " first: " + set_str + "\n")
println()
}) })
set_str += "}" println("///////////////////END FIRST SET/////////////")
print(non_terminal.to_string() + " first: " + set_str + "\n") }
println() doFirstSet()
})
println("///////////////////END FIRST SET/////////////")
var lex = lexer(a.terminals) var lex = lexer(a.terminals)
/*lex.set_input(read_file(string("test_grammer.krak")))*/ /*lex.set_input(read_file(string("test_grammer.krak")))*/
lex.set_input(string("ccdahas spacedhas lex.set_input(string("ccdahas spacedhas
returndaaaaaaaaaaaaaa")) returndaaaaaaaaaaaaaa"))
println("woo lexing:") println("woo lexing:")

View File

@@ -1,6 +1,8 @@
7 7
8 8
14
7.700000 7.700000
construct construct
do do
do
destruct destruct

View File

@@ -34,6 +34,14 @@ fun byRef(it: ref int) {
it = it + 1 it = it + 1
} }
fun id(it: ref int): ref int {
return it
}
fun id<T>(it: ref T): ref T {
return it
}
// what about cosures closing over references? // what about cosures closing over references?
fun main():int { fun main():int {
@@ -42,12 +50,15 @@ fun main():int {
println(a) println(a)
byRef(&a) byRef(&a)
println(a) println(a)
id(a) = 14
println(a)
var b = 6.7 var b = 6.7
byRef(b) byRef(b)
println(b) println(b)
var t.construct() : test_cons var t.construct() : test_cons
call(t) call(t)
id(t).do()
return 0 return 0
} }

View File

@@ -67,18 +67,12 @@ Destroyed: 303
Destroyed: 302 Destroyed: 302
Copied: 104 to 105 Copied: 104 to 105
Copied: 105 to 106 Copied: 105 to 106
Copied: 106 to 107
Destroyed: 106
Destroyed: 105 Destroyed: 105
Copied: 204 to 205 Copied: 204 to 205
Copied: 205 to 206 Copied: 205 to 206
Copied: 206 to 207
Destroyed: 206
Destroyed: 205 Destroyed: 205
Copied: 304 to 305 Copied: 304 to 305
Copied: 305 to 306 Copied: 305 to 306
Copied: 306 to 307
Destroyed: 306
Destroyed: 305 Destroyed: 305
Destroyed: 104 Destroyed: 104
Destroyed: 204 Destroyed: 204
@@ -86,30 +80,24 @@ Destroyed: 304
Destroyed: 301 Destroyed: 301
Destroyed: 201 Destroyed: 201
Destroyed: 101 Destroyed: 101
Copied: 106 to 107
Copied: 107 to 108 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: 107 Destroyed: 107
Copied: 206 to 207
Copied: 207 to 208
Destroyed: 207 Destroyed: 207
Copied: 306 to 307
Copied: 307 to 308
Destroyed: 307 Destroyed: 307
Destroyed: 210 Destroyed: 106
Copied: 310 to 311 Destroyed: 206
Destroyed: 310 Destroyed: 306
Destroyed: 208
Copied: 308 to 309
Destroyed: 308
done done
Destroyed: 110 Destroyed: 108
Destroyed: 311 Destroyed: 309
Destroyed: 300 Destroyed: 300
Destroyed: 200 Destroyed: 200
Destroyed: 100 Destroyed: 100