From 88bab7f0d73e91a11972a0f38746c4aa954e7340 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Mon, 25 May 2015 22:03:24 -0400 Subject: [PATCH] Woo! Very basic lambdas! --- include/ASTTransformation.h | 1 + krakenGrammer.kgm | 3 ++- src/ASTTransformation.cpp | 12 ++++++++---- tests/test_lambda.expected_results | 13 +++++++++++++ tests/test_lambda.krak | 25 +++++++++++++++++++++++++ 5 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 tests/test_lambda.expected_results create mode 100644 tests/test_lambda.krak diff --git a/include/ASTTransformation.h b/include/ASTTransformation.h index bbf367b..f6c4c01 100644 --- a/include/ASTTransformation.h +++ b/include/ASTTransformation.h @@ -68,6 +68,7 @@ class ASTTransformation: public NodeTransformation { std::map*>> languageLevelReservedWords; std::map*>> languageLevelOperators; NodeTree* topScope; //maintained for templates that need to add themselves to the top scope no matter where they are instantiated + int lambdaID = 0; }; #endif diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 10eeafc..0406d24 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -64,6 +64,7 @@ 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 ; opt_typed_parameter_list = typed_parameter_list | ; typed_parameter_list = typed_parameter_list WS "," WS typed_parameter | typed_parameter ; @@ -107,7 +108,7 @@ expression = expression WS "<<" WS term | expression WS right_shift WS shiftand shiftand = shiftand WS "-" WS term | shiftand WS "\+" WS term | term ; term = term WS "/" WS factor | term WS "\*" WS factor | term WS "%" WS factor | factor ; factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" | "\+" WS unarad | "-" WS unarad | "!" WS unarad | "~" WS unarad | "\(" WS type WS "\)" WS unarad | "\*" WS unarad | "&" WS unarad | unarad ; -unarad = number | scoped_identifier | scoped_identifier WS template_inst | function_call | bool | string | character | "\(" WS boolean_expression WS "\)" | access_operation | unarad WS "[" WS expression WS "]" ; +unarad = number | scoped_identifier | scoped_identifier WS template_inst | function_call | bool | string | character | "\(" WS boolean_expression WS "\)" | access_operation | unarad WS "[" WS expression WS "]" | lambda ; number = integer | floating_literal ; access_operation = unarad "." identifier | unarad "->" identifier ; diff --git a/src/ASTTransformation.cpp b/src/ASTTransformation.cpp index 8f24658..939665a 100644 --- a/src/ASTTransformation.cpp +++ b/src/ASTTransformation.cpp @@ -442,7 +442,7 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree if (children[1]->getData().getName() == "template_dec") return newNode; scope = newNode; - } else if (name == "function") { + } else if (name == "function" || name == "lambda") { std::string functionName; //If this is a function template if (children[1]->getData().getName() == "template_dec") { @@ -465,13 +465,17 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree std::cout << "Finished Non-Instantiated Template function " << functionName << std::endl; return newNode; } - functionName = concatSymbolTree(children[0]); - for (auto child: children) - std::cout << "Function child: " << child->getDataRef()->toString() << std::endl; + if (name == "lambda") + functionName = "lambda" + intToString(lambdaID++); + else + functionName = concatSymbolTree(children[0]); newNode = new NodeTree(name, ASTData(function, Symbol(functionName, true), typeFromTypeNode(children[children.size()-2], scope, templateTypeReplacements))); addToScope(functionName, newNode, scope); addToScope("~enclosing_scope", scope, newNode); scope = newNode; + // If lambda, add to top scope so it gets emitted + if (name == "lambda") + addToScope(functionName, newNode, topScope); auto parameters = transformChildren(getNodes("typed_parameter", children), skipChildren, scope, types, templateTypeReplacements); newNode->addChildren(parameters); diff --git a/tests/test_lambda.expected_results b/tests/test_lambda.expected_results new file mode 100644 index 0000000..d8d6539 --- /dev/null +++ b/tests/test_lambda.expected_results @@ -0,0 +1,13 @@ +8 +9 +10 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 diff --git a/tests/test_lambda.krak b/tests/test_lambda.krak new file mode 100644 index 0000000..4e68b10 --- /dev/null +++ b/tests/test_lambda.krak @@ -0,0 +1,25 @@ +import io:* + +fun runLambda(func: fun():int):void { + println(func()) +} + +fun callLambda(func: fun(int):void):void { + func(10) +} + +fun itr(it: T, func: fun(T):T):T { + println(it) + return func(it); +} + +fun main():int { + var func = fun():void { println("8"); } + func() + runLambda(fun():int { return 9;}) + callLambda(fun(a:int):void { println(a);}) + var j = 0 + while (j < 10) j = itr(j, fun(a:int):int { return a+1; }) + return 0 +} +