diff --git a/include/Type.h b/include/Type.h index 04b289a..f783fdb 100644 --- a/include/Type.h +++ b/include/Type.h @@ -43,6 +43,8 @@ class Type { Type withIncreasedIndirection(); Type withDecreasedIndirection(); + Type* withoutReference(); + ValueType baseType; NodeTree* typeDefinition; NodeTree* templateDefinition; diff --git a/src/CGenerator.cpp b/src/CGenerator.cpp index f830fd5..d1f2a23 100644 --- a/src/CGenerator.cpp +++ b/src/CGenerator.cpp @@ -506,8 +506,11 @@ CCodeTriple CGenerator::generate(NodeTree* from, NodeTree* enc CCodeTriple expr = generate(children[0], enclosingObject, true, enclosingFunction); output.preValue += expr.preValue; std::string retTemp = "ret_temp" + getID(); - output.preValue += ValueTypeToCType(children[0]->getDataRef()->valueType, retTemp) + ";\n"; - if (methodExists(children[0]->getDataRef()->valueType, "copy_construct", std::vector{children[0]->getDataRef()->valueType->withIncreasedIndirection()})) + // use the function's return value so we do the right thing with references + 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{children[0]->getDataRef()->valueType->withIncreasedIndirection()})) output.preValue += generateMethodIfExists(children[0]->getDataRef()->valueType, "copy_construct", "&"+retTemp + ", &" + expr.value, std::vector{children[0]->getDataRef()->valueType->withIncreasedIndirection()}); else output.preValue += retTemp + " = " + expr.value + ";\n"; @@ -742,11 +745,12 @@ CCodeTriple CGenerator::generate(NodeTree* from, NodeTree* enc // see if we should copy_construct / referencize all the parameters 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 *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 if (func_param_type->is_reference) { parameters += "&" + generate(children[i], enclosingObject, true, enclosingFunction); - } else if (methodExists(children[i]->getDataRef()->valueType, "copy_construct", std::vector{children[i]->getDataRef()->valueType->withIncreasedIndirection()})) { + } else if (methodExists(children[i]->getDataRef()->valueType, "copy_construct", std::vector{param_type->withIncreasedIndirection()})) { std::string tmpParamName = "param" + getID(); CCodeTriple paramValue = generate(children[i], enclosingObject, true, enclosingFunction); parameters.preValue += paramValue.preValue; @@ -782,7 +786,9 @@ CCodeTriple CGenerator::generate(NodeTree* from, NodeTree* enc std::string retTempName = "return_temp" + getID(); output.preValue += ValueTypeToCType(retType, retTempName) + " = " + output.value + ";\n"; output.value = retTempName; - if (methodExists(retType, "destruct", std::vector())) { + if (retType->is_reference) + output.value = "(*" + output.value + ")"; + else if (methodExists(retType, "destruct", std::vector())) { output.postValue = generateMethodIfExists(retType, "destruct", "&"+retTempName, std::vector()) + ";\n" + output.postValue; } } @@ -848,7 +854,7 @@ std::string CGenerator::generateObjectMethod(NodeTree* enclosingObject, // Note that we always wrap out child in {}, as we now allow one statement functions without a codeblock // 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 += "}\n"; //Pass in the object so we can properly handle access to member stuff distructDoubleStack.pop_back(); @@ -868,7 +874,8 @@ NodeTree* CGenerator::getMethod(Type* type, std::string method, std::ve if (types.size() != methodTypes.size()) continue; 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; break; } diff --git a/src/Type.cpp b/src/Type.cpp index 512706a..e33cee2 100644 --- a/src/Type.cpp +++ b/src/Type.cpp @@ -245,4 +245,9 @@ Type Type::withDecreasedIndirection() { newOne->decreaseIndirection(); return *newOne; } +Type* Type::withoutReference() { + Type *newOne = clone(); + newOne->is_reference = false; + return newOne; +} diff --git a/stdlib/future.krak b/stdlib/future.krak index 8e3323e..55a9922 100644 --- a/stdlib/future.krak +++ b/stdlib/future.krak @@ -65,7 +65,7 @@ obj future { status = pthread_create(&thread,wrapper) } - fun get_status() { + fun get_status():int { return status } diff --git a/stdlib/grammer.krak b/stdlib/grammer.krak index b84b352..6584e65 100644 --- a/stdlib/grammer.krak +++ b/stdlib/grammer.krak @@ -70,7 +70,7 @@ fun load_grammer(gram_str: string::string): grammer { doLeftSide = true } else { if (doLeftSide) { - leftSide = symbol::symbol(word, true) + leftSide = symbol::symbol(word, false) gram.non_terminals.add(leftSide) } else { if (word[0] == '"') { diff --git a/stdlib/map.krak b/stdlib/map.krak index bc84c48..68e83a6 100644 --- a/stdlib/map.krak +++ b/stdlib/map.krak @@ -46,7 +46,7 @@ obj map (Object) { fun contains_key(key: T): bool { return keys.contains(key) } - fun get(key: T): U { + fun get(key: T): ref U { return values.get(keys.find(key)) } fun remove(key: T) { @@ -58,7 +58,7 @@ obj map (Object) { keys.remove(idx) values.remove(idx) } - fun operator[](key: T): U { + fun operator[](key: T): ref U { return get(key) } fun for_each(func: fun(T, U):void) { diff --git a/stdlib/string.krak b/stdlib/string.krak index a2a0cdb..8fab7fa 100644 --- a/stdlib/string.krak +++ b/stdlib/string.krak @@ -52,14 +52,11 @@ obj string (Object) { 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 { var new.construct(data.slice(first,second)): string return new } - fun operator[]=(index: int, toSet: char) { - data[index] = toSet - } fun set(index: int, toSet: char) { data.set(index, toSet) } diff --git a/stdlib/vector.krak b/stdlib/vector.krak index f399f55..0f6ff14 100644 --- a/stdlib/vector.krak +++ b/stdlib/vector.krak @@ -92,9 +92,9 @@ obj vector (Object) { return new } - fun at(index: int): T { return get(index); } - fun operator[](index: int): T { return get(index); } - fun get(index: int): T { + fun at(index: int): ref T { return get(index); } + fun operator[](index: int): ref T { return get(index); } + fun get(index: int): ref T { if (index < 0 || index >= size) { println("Vector access out of bounds! Retuning 0th element as sanest option"); print("Vector tried to access element: "); @@ -124,9 +124,6 @@ obj vector (Object) { return find(item) != -1 } - fun operator[]=(index: int, dataIn: T) { - set(index, dataIn) - } fun set(index: int, dataIn: T): void { if (index < 0 || index >= size) return; diff --git a/tests/test_grammer.krak b/tests/test_grammer.krak index 3ffa009..099cb3b 100644 --- a/tests/test_grammer.krak +++ b/tests/test_grammer.krak @@ -10,32 +10,35 @@ fun main():int { /*var a = load_grammer(read_file(string("../krakenGrammer.kgm")))*/ var a = load_grammer(read_file(string("grammer.kgm"))) println(a.to_string()) - /*a.calculate_first_set()*/ - println("///////////////////START FIRST SET/////////////") - println("//TERMINALS//") - a.terminals.for_each( fun(terminal: util::pair) { - var set_str = string::string("{ ") - a.first_set_map[terminal.first].for_each( fun(sym: symbol::symbol) { - set_str += sym.to_string() + " " + var doFirstSet = fun() { + a.calculate_first_set() + println("///////////////////START FIRST SET/////////////") + println("//TERMINALS//") + a.terminals.for_each( fun(terminal: util::pair) { + var set_str = string::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 += "}" - print(terminal.first.to_string() + " first: " + set_str + "\n") - }) - println("//NON TERMINALS//") - a.non_terminals.for_each( fun(non_terminal: symbol::symbol) { - var set_str = string::string("{ ") - a.first_set_map[non_terminal].for_each( fun(sym: symbol::symbol) { - set_str += sym.to_string() + " " + println("//NON TERMINALS//") + a.non_terminals.for_each( fun(non_terminal: symbol::symbol) { + var set_str = string::string("{ ") + a.first_set_map[non_terminal].for_each( fun(sym: symbol::symbol) { + set_str += sym.to_string() + ", " + }) + set_str += "}" + print(non_terminal.to_string() + " first: " + set_str + "\n") + println() }) - set_str += "}" - print(non_terminal.to_string() + " first: " + set_str + "\n") - println() - }) - println("///////////////////END FIRST SET/////////////") + println("///////////////////END FIRST SET/////////////") + } + doFirstSet() 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 returndaaaaaaaaaaaaaa")) println("woo lexing:") diff --git a/tests/test_references.expected_results b/tests/test_references.expected_results index 387e106..af7ccef 100644 --- a/tests/test_references.expected_results +++ b/tests/test_references.expected_results @@ -1,6 +1,8 @@ 7 8 +14 7.700000 construct do +do destruct diff --git a/tests/test_references.krak b/tests/test_references.krak index 6578c81..fb6f1ce 100644 --- a/tests/test_references.krak +++ b/tests/test_references.krak @@ -34,6 +34,14 @@ fun byRef(it: ref int) { it = it + 1 } +fun id(it: ref int): ref int { + return it +} + +fun id(it: ref T): ref T { + return it +} + // what about cosures closing over references? fun main():int { @@ -42,12 +50,15 @@ fun main():int { println(a) byRef(&a) println(a) + id(a) = 14 + println(a) var b = 6.7 byRef(b) println(b) var t.construct() : test_cons call(t) + id(t).do() return 0 } diff --git a/tests/test_vectorTest.expected_results b/tests/test_vectorTest.expected_results index d531c56..4ad4ecf 100644 --- a/tests/test_vectorTest.expected_results +++ b/tests/test_vectorTest.expected_results @@ -67,18 +67,12 @@ 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: 104 Destroyed: 204 @@ -86,30 +80,24 @@ Destroyed: 304 Destroyed: 301 Destroyed: 201 Destroyed: 101 +Copied: 106 to 107 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 +Copied: 206 to 207 +Copied: 207 to 208 Destroyed: 207 +Copied: 306 to 307 +Copied: 307 to 308 Destroyed: 307 -Destroyed: 210 -Copied: 310 to 311 -Destroyed: 310 +Destroyed: 106 +Destroyed: 206 +Destroyed: 306 +Destroyed: 208 +Copied: 308 to 309 +Destroyed: 308 done -Destroyed: 110 -Destroyed: 311 +Destroyed: 108 +Destroyed: 309 Destroyed: 300 Destroyed: 200 Destroyed: 100