From b71bb8407052fe6c3316fcabc5a7b79dfab793e9 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Wed, 27 May 2015 12:27:50 -0400 Subject: [PATCH] Now allow one-line functions without codeblocks\! (espically nice for lambdas) fun a():void println(4), or fun():void println(7) --- krakenGrammer.kgm | 4 ++-- src/ASTTransformation.cpp | 4 ++-- src/CGenerator.cpp | 8 ++++--- ...test_oneStatementFunction.expected_results | 6 +++++ tests/test_oneStatementFunction.krak | 24 +++++++++++++++++++ 5 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 tests/test_oneStatementFunction.expected_results create mode 100644 tests/test_oneStatementFunction.krak diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 0406d24..926de15 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -63,8 +63,8 @@ scoped_identifier = scoped_identifier WS scope_op WS identifier | identifier ; right_shift = ">" ">" ; overloadable_operator = "\+" | "-" | "\*" | "/" | "%" | "^" | "&" | "\|" | "~" | "!" | "," | "=" | "\+\+" | "--" | "<<" | right_shift | "==" | "!=" | "&&" | "\|\|" | "\+=" | "-=" | "/=" | "%=" | "^=" | "&=" | "\|=" | "\*=" | "<<=" | ">>=" | "->" | "\(" "\)" ; func_identifier = identifier | identifier overloadable_operator ; -function = "fun" WS func_identifier WS template_dec WS "\(" WS opt_typed_parameter_list WS "\)" WS dec_type WS code_block | "fun" WS func_identifier WS "\(" WS opt_typed_parameter_list WS "\)" WS dec_type WS code_block ; -lambda = "fun" WS "\(" WS opt_typed_parameter_list WS "\)" WS dec_type WS code_block ; +function = "fun" WS func_identifier WS template_dec WS "\(" WS opt_typed_parameter_list WS "\)" WS dec_type WS statement | "fun" WS func_identifier WS "\(" WS opt_typed_parameter_list WS "\)" WS dec_type WS statement ; +lambda = "fun" WS "\(" WS opt_typed_parameter_list WS "\)" WS dec_type WS statement ; opt_typed_parameter_list = typed_parameter_list | ; typed_parameter_list = typed_parameter_list WS "," WS typed_parameter | typed_parameter ; diff --git a/src/ASTTransformation.cpp b/src/ASTTransformation.cpp index f1f5b04..8cd53e0 100644 --- a/src/ASTTransformation.cpp +++ b/src/ASTTransformation.cpp @@ -474,7 +474,7 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree newNode->addChildren(parameters); // update type with actual type newNode->getDataRef()->valueType = new Type(mapNodesToTypePointers(parameters), newNode->getDataRef()->valueType); - newNode->addChild(transform(getNode("code_block", children), scope, types, templateTypeReplacements)); + newNode->addChild(transform(getNode("statement", children), scope, types, templateTypeReplacements)); std::cout << "finished function" << functionName << std::endl; return newNode; @@ -1545,7 +1545,7 @@ NodeTree* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec instantiatedFunction->addChildren(parameters); // update type with actual type instantiatedFunction->getDataRef()->valueType = new Type(mapNodesToTypePointers(parameters), instantiatedFunction->getDataRef()->valueType); - instantiatedFunction->addChild(transform(getNode("code_block", templateSyntaxTree->getChildren()), instantiatedFunction, std::vector(), newTemplateTypeReplacement)); + instantiatedFunction->addChild(transform(getNode("statement", templateSyntaxTree->getChildren()), instantiatedFunction, std::vector(), newTemplateTypeReplacement)); std::cout << "Fully Instantiated function " << functionName << " to " << fullyInstantiatedName << std::endl; return instantiatedFunction; diff --git a/src/CGenerator.cpp b/src/CGenerator.cpp index 1aa4630..141eb83 100644 --- a/src/CGenerator.cpp +++ b/src/CGenerator.cpp @@ -301,8 +301,9 @@ std::string CGenerator::generate(NodeTree* from, NodeTree* enc // this is for using functions as values if (justFuncName) return ((data.symbol.getName() == "main") ? "" : scopePrefix(from)) + CifyName(data.symbol.getName() + nameDecoration); + // Note that we always wrap out child in {}, as we now allow one statement functions without a codeblock output += "\n" + ValueTypeToCType(data.valueType->returnType, ((data.symbol.getName() == "main") ? "" : scopePrefix(from)) + - CifyName(data.symbol.getName() + nameDecoration)) + "(" + parameters + ")\n" + generate(children[children.size()-1], enclosingObject, justFuncName); + CifyName(data.symbol.getName() + nameDecoration)) + "(" + parameters + ") {\n" + generate(children[children.size()-1], enclosingObject, justFuncName) + "}\n"; return output; } case code_block: @@ -441,7 +442,7 @@ std::string CGenerator::generate(NodeTree* from, NodeTree* enc std::string name = children[0]->getDataRef()->symbol.getName(); ASTType funcType = children[0]->getDataRef()->type; std::cout << "Doing function: " << name << std::endl; - //Test for specail functions only if what we're testing is, indeed, the definition, not a function call that returns a callable function pointer + //Test for special functions only if what we're testing is, indeed, the definition, not a function call that returns a callable function pointer if (funcType == function) { if (name == "++" || name == "--") return generate(children[1], enclosingObject, true) + name; @@ -553,7 +554,8 @@ std::string CGenerator::generateObjectMethod(NodeTree* enclosingObject, std::string functionSignature = "\n" + ValueTypeToCType(data.valueType->returnType, scopePrefix(from) + CifyName(enclosingObject->getDataRef()->symbol.getName()) +"__" + CifyName(data.symbol.getName()) + nameDecoration) + "(" + ValueTypeToCType(&enclosingObjectType, "this") + parameters + ")"; *functionPrototype += functionSignature + ";\n"; - return functionSignature + "\n" + generate(children[children.size()-1], enclosingObject); //Pass in the object so we can properly handle access to member stuff + // Note that we always wrap out child in {}, as we now allow one statement functions without a codeblock + return functionSignature + " {\n" + generate(children[children.size()-1], enclosingObject) + "}\n"; //Pass in the object so we can properly handle access to member stuff } diff --git a/tests/test_oneStatementFunction.expected_results b/tests/test_oneStatementFunction.expected_results new file mode 100644 index 0000000..195d188 --- /dev/null +++ b/tests/test_oneStatementFunction.expected_results @@ -0,0 +1,6 @@ +7 +8 +oh yeah +better? +method +templated method diff --git a/tests/test_oneStatementFunction.krak b/tests/test_oneStatementFunction.krak new file mode 100644 index 0000000..d04eb6d --- /dev/null +++ b/tests/test_oneStatementFunction.krak @@ -0,0 +1,24 @@ +import io:* + +fun oneLine1():void println(7) +fun oneLine2():int return 8 +fun oneLineID(a:T):T return a + +obj methods { + fun m1():void println("method") + fun m2(a:T):T return a +} + +fun main():int { + oneLine1() + println(oneLine2()) + println(oneLineID("oh yeah")) + var lambda = fun():void println("better?"); + lambda() + + var o: methods + o.m1() + println(o.m2("templated method")) + return 0 +} +