Woo! Very basic lambdas!

This commit is contained in:
Nathan Braswell
2015-05-25 22:03:24 -04:00
parent 920a9ab81f
commit 88bab7f0d7
5 changed files with 49 additions and 5 deletions

View File

@@ -68,6 +68,7 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
std::map<std::string, std::vector<NodeTree<ASTData>*>> languageLevelReservedWords;
std::map<std::string, std::vector<NodeTree<ASTData>*>> languageLevelOperators;
NodeTree<ASTData>* topScope; //maintained for templates that need to add themselves to the top scope no matter where they are instantiated
int lambdaID = 0;
};
#endif

View File

@@ -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 ;

View File

@@ -442,7 +442,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* 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<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* 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<ASTData>(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);

View File

@@ -0,0 +1,13 @@
8
9
10
0
1
2
3
4
5
6
7
8
9

25
tests/test_lambda.krak Normal file
View File

@@ -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<T>(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
}