From 0ee44e829f5790e3f884cebc9b83ffebee2191e3 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Tue, 14 Jul 2015 22:42:25 -0400 Subject: [PATCH] pass by reference should work for templates and objects now --- src/ASTTransformation.cpp | 1 + src/CGenerator.cpp | 24 +++++---------- tests/test_references.expected_results | 5 +++ tests/test_references.krak | 42 ++++++++++++++++++++++---- 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/ASTTransformation.cpp b/src/ASTTransformation.cpp index 6cd1bd4..a5d2a5f 100644 --- a/src/ASTTransformation.cpp +++ b/src/ASTTransformation.cpp @@ -1521,6 +1521,7 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree* typeNode, NodeTreeclone(); templateTypeReplacement->modifyIndirection(indirection); + templateTypeReplacement->is_reference = is_reference; return templateTypeReplacement; } std::cout << edited << " was not found in templateTypeReplacements" << std::endl; diff --git a/src/CGenerator.cpp b/src/CGenerator.cpp index c2d4bfa..f830fd5 100644 --- a/src/CGenerator.cpp +++ b/src/CGenerator.cpp @@ -743,28 +743,19 @@ CCodeTriple CGenerator::generate(NodeTree* from, NodeTree* enc 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; - if (methodExists(children[i]->getDataRef()->valueType, "copy_construct", std::vector{children[i]->getDataRef()->valueType->withIncreasedIndirection()})) { + // 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()})) { std::string tmpParamName = "param" + getID(); CCodeTriple paramValue = generate(children[i], enclosingObject, true, enclosingFunction); parameters.preValue += paramValue.preValue; parameters.preValue += ValueTypeToCType(param_type, tmpParamName) + ";\n"; parameters.preValue += generateMethodIfExists(param_type, "copy_construct", "&"+tmpParamName + ", &" + paramValue.value, std::vector{children[i]->getDataRef()->valueType->withIncreasedIndirection()}); - if (func_param_type->is_reference) - parameters.value += "&" + tmpParamName; - else - parameters.value += tmpParamName; + parameters.value += tmpParamName; parameters.postValue += paramValue.postValue; } else { - if (func_param_type->is_reference) { - //std::string tmpParamName = "param" + getID(); - //CCodeTriple paramValue = generate(children[i], enclosingObject, true, enclosingFunction); - //parameters.preValue += paramValue.preValue; - //parameters.preValue += ValueTypeToCType(param_type, tmpParamName) + " = " + paramValue.value + ";\n"; - //parameters.value += "&" + tmpParamName; - parameters += "&" + generate(children[i], enclosingObject, true, enclosingFunction); - } else { - parameters += generate(children[i], enclosingObject, true, enclosingFunction); - } + parameters += generate(children[i], enclosingObject, true, enclosingFunction); } if (i < children.size()-1) parameters += ", "; @@ -909,7 +900,8 @@ std::string CGenerator::generateMethodIfExists(Type* type, std::string method, s std::string CGenerator::emitDestructors(std::vector*> identifiers, NodeTree* enclosingObject) { std::string destructorString = ""; for (auto identifier : identifiers) - destructorString += tabs() + generateMethodIfExists(identifier->getDataRef()->valueType, "destruct", "&" + generate(identifier, enclosingObject).oneString(), std::vector()); + if (!identifier->getDataRef()->valueType->is_reference) + destructorString += tabs() + generateMethodIfExists(identifier->getDataRef()->valueType, "destruct", "&" + generate(identifier, enclosingObject).oneString(), std::vector()); return destructorString; } diff --git a/tests/test_references.expected_results b/tests/test_references.expected_results index 7f8f011..387e106 100644 --- a/tests/test_references.expected_results +++ b/tests/test_references.expected_results @@ -1 +1,6 @@ 7 +8 +7.700000 +construct +do +destruct diff --git a/tests/test_references.krak b/tests/test_references.krak index d6cf5fc..6578c81 100644 --- a/tests/test_references.krak +++ b/tests/test_references.krak @@ -1,12 +1,34 @@ import io:* -/*fun byRef(it: ref T) {*/ - /*it = it + 1*/ -/*}*/ +obj test_cons(Object) { + fun construct(): *test_cons { + println("construct") + } + fun copy_construct(other: *test_cons) { + println("copy_construct") + } + fun destruct() { + println("destruct") + } + fun operator=(other: test_cons) { + println("=") + } + fun do() { + println("do") + } +} -/*fun byRef(it: * int) {*/ - /**it = *it + 1*/ -/*}*/ +fun call(it: ref T) { + it.do() +} + +fun byRef(it: ref T) { + it = it + 1 +} + +fun byRef(it: * int) { + *it = *it + 1 +} fun byRef(it: ref int) { it = it + 1 @@ -18,6 +40,14 @@ fun main():int { var a = 6 byRef(a) println(a) + byRef(&a) + println(a) + var b = 6.7 + byRef(b) + println(b) + + var t.construct() : test_cons + call(t) return 0 }