diff --git a/include/ASTData.h b/include/ASTData.h index 4136645..2d80ffe 100644 --- a/include/ASTData.h +++ b/include/ASTData.h @@ -3,6 +3,7 @@ #include #include +#include #include "Symbol.h" //Circular dependency @@ -32,6 +33,7 @@ class ASTData { Type* valueType; Symbol symbol; std::map*>> scope; + std::set*> closedVariables; private: }; diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 0c4377d..ee946f7 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -63,8 +63,10 @@ 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 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 ; +# allow omitting of return type (automatic void) +typed_return = dec_type | ; +function = "fun" WS func_identifier WS template_dec WS "\(" WS opt_typed_parameter_list WS "\)" WS typed_return WS statement | "fun" WS func_identifier WS "\(" WS opt_typed_parameter_list WS "\)" WS typed_return WS statement ; +lambda = "fun" WS "\(" WS opt_typed_parameter_list WS "\)" WS typed_return 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 08b33a5..cfbbad1 100644 --- a/src/ASTTransformation.cpp +++ b/src/ASTTransformation.cpp @@ -246,11 +246,14 @@ NodeTree* ASTTransformation::secondPassFunction(NodeTree* from, return functionDef; } functionName = concatSymbolTree(children[0]); - functionDef = new NodeTree("function", ASTData(function, Symbol(functionName, true), typeFromTypeNode(children[children.size()-2], scope, templateTypeReplacements))); + auto returnTypeNode = getNode("type", getNode("typed_return", children)); // if null, the typed_return had no children and we're supposed to automatically do a void type + auto returnType = returnTypeNode ? typeFromTypeNode(returnTypeNode, scope, templateTypeReplacements): new Type(void_type); + functionDef = new NodeTree("function", ASTData(function, Symbol(functionName, true), returnType)); addToScope("~enclosing_scope", scope, functionDef); addToScope(functionName, functionDef, scope); //We only do the parameter nodes. We don't do the body yet, as this is the secondPass - auto transChildren = transformChildren(slice(children,1,-3, 2), std::set(), functionDef, std::vector(), false, templateTypeReplacements); + //auto transChildren = transformChildren(slice(children,1,-3, 2), std::set(), functionDef, std::vector(), false, templateTypeReplacements); + auto transChildren = transformChildren(getNodes("typed_parameter", children), std::set(), functionDef, std::vector(), false, templateTypeReplacements); functionDef->addChildren(transChildren); // Swap the function type over to be the correct type (a function with parameter and return types, etc) @@ -327,10 +330,9 @@ NodeTree* ASTTransformation::searchScopeForFunctionDef(NodeTree*> children = parseTree->getChildren(); //Skipping the initial return type and identifier as well as the final code block std::cout << "\n Searching scope for function def, function is: " << concatSymbolTree(children[0]) << ", children size is " << children.size() << std::endl; - for (int i = 1; i < children.size()-3; i+=2) { //Skip over commas - std::cout << "Making type for lookup ||" << concatSymbolTree(children[i]) << "||" << std::endl; - Type type = *typeFromTypeNode(children[i]->getChildren().back(), scope, templateTypeReplacements); - //Type type = *typeFromTypeNode(children[i]->getChildren()[0], scope, templateTypeReplacements); + for (auto param: getNodes("typed_parameter", children)) { //Skip over commas + std::cout << "Making type for lookup ||" << concatSymbolTree(param) << "||" << std::endl; + Type type = *typeFromTypeNode(param->getChildren().back(), scope, templateTypeReplacements); std::cout << "Type made: " << type.toString() << std::endl; types.push_back(type); } @@ -478,7 +480,9 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree 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))); + auto returnTypeNode = getNode("type", getNode("typed_return", children)); // if null, the typed_return had no children and we're supposed to automatically do a void type + auto returnType = returnTypeNode ? typeFromTypeNode(returnTypeNode, scope, templateTypeReplacements): new Type(void_type); + newNode = new NodeTree(name, ASTData(function, Symbol(functionName, true), returnType)); addToScope(functionName, newNode, scope); addToScope("~enclosing_scope", scope, newNode); scope = newNode; @@ -1186,7 +1190,8 @@ NodeTree* ASTTransformation::templateFunctionLookup(NodeTree* if (!traitsEqual) continue; - std::vector*> functionParameters = slice(templateSyntaxTree->getChildren(), 2, -4, 2); //skip name, intervening commas, return type, and the code block + //std::vector*> functionParameters = slice(templateSyntaxTree->getChildren(), 2, -4, 2); //skip name, intervening commas, return type, and the code block + std::vector*> functionParameters = getNodes("typed_parameter", templateSyntaxTree->getChildren()); std::cout << functionParameters.size() << " " << types.size() << std::endl; if (functionParameters.size() != types.size()) continue; @@ -1596,7 +1601,9 @@ NodeTree* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec std::cout << std::endl; // return type should be looked up in template's scope - instantiatedFunction = new NodeTree("function", ASTData(function, Symbol(scopelessFullyInstantiatedName, true), typeFromTypeNode(templateChildren[templateChildren.size()-2], templateDefinition, newTemplateTypeReplacement))); + auto returnTypeNode = getNode("type", getNode("typed_return", templateChildren)); // if null, the typed_return had no children and we're supposed to automatically do a void type + auto returnType = returnTypeNode ? typeFromTypeNode(returnTypeNode, templateDefinition, newTemplateTypeReplacement): new Type(void_type); + instantiatedFunction = new NodeTree("function", ASTData(function, Symbol(scopelessFullyInstantiatedName, true), returnType)); addToScope("~enclosing_scope", templateDefinition->getDataRef()->scope["~enclosing_scope"][0], instantiatedFunction); addToScope(scopelessFullyInstantiatedName, instantiatedFunction, templateDefinition->getDataRef()->scope["~enclosing_scope"][0]); templateDefinition->getDataRef()->scope["~enclosing_scope"][0]->addChild(instantiatedFunction); // Add this object the the highest scope's diff --git a/tests/test_auto_void.expected_results b/tests/test_auto_void.expected_results new file mode 100644 index 0000000..ad12014 --- /dev/null +++ b/tests/test_auto_void.expected_results @@ -0,0 +1,3 @@ +Woooo +7 +uh huh diff --git a/tests/test_auto_void.krak b/tests/test_auto_void.krak new file mode 100644 index 0000000..3c75e23 --- /dev/null +++ b/tests/test_auto_void.krak @@ -0,0 +1,16 @@ +import io:* + +fun retVoid() { + println("Woooo") +} + +fun withParams(a:int, b:char*) { + println(a) + println(b) +} + +fun main():int { + retVoid() + withParams(7, "uh huh") + return 0 +} diff --git a/tests/test_lambda.krak b/tests/test_lambda.krak index 4e68b10..2d94634 100644 --- a/tests/test_lambda.krak +++ b/tests/test_lambda.krak @@ -20,6 +20,10 @@ fun main():int { callLambda(fun(a:int):void { println(a);}) var j = 0 while (j < 10) j = itr(j, fun(a:int):int { return a+1; }) + + //println("closures now") + //var a = 1337 + //runLambda(fun():int { return a;}) return 0 }