Closures work\!
This commit is contained in:
@@ -42,8 +42,6 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
|
|||||||
virtual NodeTree<ASTData>* transform(NodeTree<Symbol>* from);
|
virtual NodeTree<ASTData>* transform(NodeTree<Symbol>* from);
|
||||||
NodeTree<ASTData>* transform(NodeTree<Symbol>* from, NodeTree<ASTData>* scope, std::vector<Type> types, bool limitToFunction, std::map<std::string, Type*> templateTypeReplacements);
|
NodeTree<ASTData>* transform(NodeTree<Symbol>* from, NodeTree<ASTData>* scope, std::vector<Type> types, bool limitToFunction, std::map<std::string, Type*> templateTypeReplacements);
|
||||||
std::vector<NodeTree<ASTData>*> transformChildren(std::vector<NodeTree<Symbol>*> children, std::set<int> skipChildren, NodeTree<ASTData>* scope, std::vector<Type> types, bool limitToFunction, std::map<std::string, Type*> templateTypeReplacements);
|
std::vector<NodeTree<ASTData>*> transformChildren(std::vector<NodeTree<Symbol>*> children, std::set<int> skipChildren, NodeTree<ASTData>* scope, std::vector<Type> types, bool limitToFunction, std::map<std::string, Type*> templateTypeReplacements);
|
||||||
std::vector<Type> mapNodesToTypes(std::vector<NodeTree<ASTData>*> nodes);
|
|
||||||
std::vector<Type*> mapNodesToTypePointers(std::vector<NodeTree<ASTData>*> nodes);
|
|
||||||
std::string concatSymbolTree(NodeTree<Symbol>* root);
|
std::string concatSymbolTree(NodeTree<Symbol>* root);
|
||||||
NodeTree<ASTData>* doFunction(NodeTree<ASTData>* scope, std::string lookup, std::vector<NodeTree<ASTData>*> nodes, std::map<std::string, Type*> templateTypeReplacements);
|
NodeTree<ASTData>* doFunction(NodeTree<ASTData>* scope, std::string lookup, std::vector<NodeTree<ASTData>*> nodes, std::map<std::string, Type*> templateTypeReplacements);
|
||||||
|
|
||||||
@@ -73,4 +71,7 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
|
|||||||
int lambdaID = 0;
|
int lambdaID = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::vector<Type> mapNodesToTypes(std::vector<NodeTree<ASTData>*> nodes);
|
||||||
|
std::vector<Type*> mapNodesToTypePointers(std::vector<NodeTree<ASTData>*> nodes);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
#include "NodeTree.h"
|
#include "NodeTree.h"
|
||||||
#include "ASTData.h"
|
#include "ASTData.h"
|
||||||
#include "Type.h"
|
#include "Type.h"
|
||||||
|
// for mapNodesToTypes
|
||||||
|
#include "ASTTransformation.h"
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "Poset.h"
|
#include "Poset.h"
|
||||||
@@ -31,6 +33,8 @@ class CGenerator {
|
|||||||
std::pair<std::string, std::string> generateTranslationUnit(std::string name, std::map<std::string, NodeTree<ASTData>*> ASTs);
|
std::pair<std::string, std::string> generateTranslationUnit(std::string name, std::map<std::string, NodeTree<ASTData>*> ASTs);
|
||||||
CCodeTriple generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enclosingObject = NULL, bool justFuncName = false, NodeTree<ASTData>* enclosingFunction = NULL);
|
CCodeTriple generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enclosingObject = NULL, bool justFuncName = false, NodeTree<ASTData>* enclosingFunction = NULL);
|
||||||
std::string generateAliasChains(std::map<std::string, NodeTree<ASTData>*> ASTs, NodeTree<ASTData>* definition);
|
std::string generateAliasChains(std::map<std::string, NodeTree<ASTData>*> ASTs, NodeTree<ASTData>* definition);
|
||||||
|
|
||||||
|
std::string closureStructType(std::set<NodeTree<ASTData>*> closedVariables);
|
||||||
std::string ValueTypeToCType(Type *type, std::string, ClosureTypeSpecialType closureSpecial = ClosureTypeRegularNone);
|
std::string ValueTypeToCType(Type *type, std::string, ClosureTypeSpecialType closureSpecial = ClosureTypeRegularNone);
|
||||||
std::string ValueTypeToCTypeDecoration(Type *type, ClosureTypeSpecialType closureSpecial = ClosureTypeRegularNone);
|
std::string ValueTypeToCTypeDecoration(Type *type, ClosureTypeSpecialType closureSpecial = ClosureTypeRegularNone);
|
||||||
std::string ValueTypeToCTypeThingHelper(Type *type, std::string ptrStr, ClosureTypeSpecialType closureSpecial);
|
std::string ValueTypeToCTypeThingHelper(Type *type, std::string ptrStr, ClosureTypeSpecialType closureSpecial);
|
||||||
@@ -52,6 +56,7 @@ class CGenerator {
|
|||||||
std::string linkerString;
|
std::string linkerString;
|
||||||
std::string functionTypedefString;
|
std::string functionTypedefString;
|
||||||
std::map<Type, std::pair<std::string, std::string>> functionTypedefMap;
|
std::map<Type, std::pair<std::string, std::string>> functionTypedefMap;
|
||||||
|
std::map<std::set<NodeTree<ASTData>*>, std::string> closureStructMap;
|
||||||
std::vector<std::vector<NodeTree<ASTData>*>> distructDoubleStack;
|
std::vector<std::vector<NodeTree<ASTData>*>> distructDoubleStack;
|
||||||
std::stack<int> loopDistructStackDepth;
|
std::stack<int> loopDistructStackDepth;
|
||||||
std::vector<std::vector<NodeTree<ASTData>*>> deferDoubleStack;
|
std::vector<std::vector<NodeTree<ASTData>*>> deferDoubleStack;
|
||||||
|
|||||||
@@ -794,26 +794,6 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::transformChildren(std::vector
|
|||||||
return transformedChildren;
|
return transformedChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Extract types from already transformed nodes
|
|
||||||
std::vector<Type*> ASTTransformation::mapNodesToTypePointers(std::vector<NodeTree<ASTData>*> nodes) {
|
|
||||||
std::vector<Type*> types;
|
|
||||||
for (auto i : nodes) {
|
|
||||||
std::cout << i->getDataRef()->toString() << std::endl;
|
|
||||||
types.push_back((i->getDataRef()->valueType));
|
|
||||||
}
|
|
||||||
return types;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Extract types from already transformed nodes
|
|
||||||
std::vector<Type> ASTTransformation::mapNodesToTypes(std::vector<NodeTree<ASTData>*> nodes) {
|
|
||||||
std::vector<Type> types;
|
|
||||||
for (auto i : nodes) {
|
|
||||||
std::cout << i->getDataRef()->toString() << std::endl;
|
|
||||||
types.push_back(*(i->getDataRef()->valueType));
|
|
||||||
}
|
|
||||||
return types;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Simple way to extract strings from syntax trees. Used often for identifiers, strings, types
|
//Simple way to extract strings from syntax trees. Used often for identifiers, strings, types
|
||||||
std::string ASTTransformation::concatSymbolTree(NodeTree<Symbol>* root) {
|
std::string ASTTransformation::concatSymbolTree(NodeTree<Symbol>* root) {
|
||||||
std::string concatString;
|
std::string concatString;
|
||||||
@@ -929,24 +909,24 @@ bool ASTTransformation::inScopeChain(NodeTree<ASTData>* node, NodeTree<ASTData>*
|
|||||||
// used to calculate the closedvariables for closures
|
// used to calculate the closedvariables for closures
|
||||||
std::set<NodeTree<ASTData>*> ASTTransformation::findVariablesToClose(NodeTree<ASTData>* func, NodeTree<ASTData>* stat) {
|
std::set<NodeTree<ASTData>*> ASTTransformation::findVariablesToClose(NodeTree<ASTData>* func, NodeTree<ASTData>* stat) {
|
||||||
std::set<NodeTree<ASTData>*> closed;
|
std::set<NodeTree<ASTData>*> closed;
|
||||||
for (auto child: stat->getChildren()) {
|
|
||||||
//enum ASTType {undef, translation_unit, interpreter_directive, import, identifier, type_def,
|
//enum ASTType {undef, translation_unit, interpreter_directive, import, identifier, type_def,
|
||||||
//function, code_block, typed_parameter, expression, boolean_expression, statement,
|
//function, code_block, typed_parameter, expression, boolean_expression, statement,
|
||||||
//if_statement, while_loop, for_loop, return_statement, break_statement, continue_statement, defer_statement,
|
//if_statement, while_loop, for_loop, return_statement, break_statement, continue_statement, defer_statement,
|
||||||
//assignment_statement, declaration_statement, if_comp, simple_passthrough, passthrough_params,
|
//assignment_statement, declaration_statement, if_comp, simple_passthrough, passthrough_params,
|
||||||
//in_passthrough_params, out_passthrough_params, opt_string, param_assign, function_call, value};
|
//in_passthrough_params, out_passthrough_params, opt_string, param_assign, function_call, value};
|
||||||
if (child->getDataRef()->type == function || child->getDataRef()->type == translation_unit
|
if (stat->getDataRef()->type == function || stat->getDataRef()->type == translation_unit
|
||||||
|| child->getDataRef()->type == type_def || child->getDataRef()->type == value
|
|| stat->getDataRef()->type == type_def || stat->getDataRef()->type == value
|
||||||
)
|
)
|
||||||
continue;
|
return closed;
|
||||||
if (child->getDataRef()->type == function_call && (child->getDataRef()->symbol.getName() == "." || child->getDataRef()->symbol.getName() == "->")) {
|
if (stat->getDataRef()->type == function_call && (stat->getDataRef()->symbol.getName() == "." || stat->getDataRef()->symbol.getName() == "->")) {
|
||||||
// only search on the left side of access operators like . and ->
|
// only search on the left side of access operators like . and ->
|
||||||
auto recClosed = findVariablesToClose(func, child->getChildren().front());
|
auto recClosed = findVariablesToClose(func, stat->getChildren()[1]);
|
||||||
closed.insert(recClosed.begin(), recClosed.end());
|
closed.insert(recClosed.begin(), recClosed.end());
|
||||||
continue;
|
return closed;
|
||||||
}
|
}
|
||||||
if (child->getDataRef()->type == identifier && !inScopeChain(child, func))
|
if (stat->getDataRef()->type == identifier && !inScopeChain(stat, func))
|
||||||
closed.insert(child);
|
closed.insert(stat);
|
||||||
|
for (auto child: stat->getChildren()) {
|
||||||
auto recClosed = findVariablesToClose(func, child);
|
auto recClosed = findVariablesToClose(func, child);
|
||||||
closed.insert(recClosed.begin(), recClosed.end());
|
closed.insert(recClosed.begin(), recClosed.end());
|
||||||
}
|
}
|
||||||
@@ -1671,3 +1651,22 @@ NodeTree<ASTData>* ASTTransformation::addToScope(std::string name, NodeTree<ASTD
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Extract types from already transformed nodes
|
||||||
|
std::vector<Type*> mapNodesToTypePointers(std::vector<NodeTree<ASTData>*> nodes) {
|
||||||
|
std::vector<Type*> types;
|
||||||
|
for (auto i : nodes) {
|
||||||
|
std::cout << i->getDataRef()->toString() << std::endl;
|
||||||
|
types.push_back((i->getDataRef()->valueType));
|
||||||
|
}
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Extract types from already transformed nodes
|
||||||
|
std::vector<Type> mapNodesToTypes(std::vector<NodeTree<ASTData>*> nodes) {
|
||||||
|
std::vector<Type> types;
|
||||||
|
for (auto i : nodes) {
|
||||||
|
std::cout << i->getDataRef()->toString() << std::endl;
|
||||||
|
types.push_back(*(i->getDataRef()->valueType));
|
||||||
|
}
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
|||||||
else {
|
else {
|
||||||
std::string nameDecoration, parameters;
|
std::string nameDecoration, parameters;
|
||||||
if (declarationData.closedVariables.size())
|
if (declarationData.closedVariables.size())
|
||||||
parameters += "struct closed *closed_varibles";
|
parameters += closureStructType(declarationData.closedVariables) + "*";
|
||||||
for (int j = 0; j < decChildren.size()-1; j++) {
|
for (int j = 0; j < decChildren.size()-1; j++) {
|
||||||
if (j > 0 || declarationData.closedVariables.size() )
|
if (j > 0 || declarationData.closedVariables.size() )
|
||||||
parameters += ", ";
|
parameters += ", ";
|
||||||
@@ -319,7 +319,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
|
|
||||||
std::string nameDecoration, parameters;
|
std::string nameDecoration, parameters;
|
||||||
if (data.closedVariables.size())
|
if (data.closedVariables.size())
|
||||||
parameters += "struct closed *closed_varibles";
|
parameters += closureStructType(data.closedVariables) + " *closed_varibles";
|
||||||
for (int j = 0; j < children.size()-1; j++) {
|
for (int j = 0; j < children.size()-1; j++) {
|
||||||
if (j > 0 || data.closedVariables.size())
|
if (j > 0 || data.closedVariables.size())
|
||||||
parameters += ", ";
|
parameters += ", ";
|
||||||
@@ -336,8 +336,16 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
funcName += CifyName(data.symbol.getName() + nameDecoration);
|
funcName += CifyName(data.symbol.getName() + nameDecoration);
|
||||||
if (from->getDataRef()->closedVariables.size()) {
|
if (from->getDataRef()->closedVariables.size()) {
|
||||||
std::string tmpStruct = "closureStruct" + getID();
|
std::string tmpStruct = "closureStruct" + getID();
|
||||||
output.preValue += "struct specialClosure " + tmpStruct + ";\n";
|
output.preValue += closureStructType(data.closedVariables) + " " + tmpStruct + " = {";
|
||||||
output += "("+ ValueTypeToCType(data.valueType, "") +"){" + funcName + ", &" + tmpStruct + "}";
|
bool notFirst = false;
|
||||||
|
for (auto var : data.closedVariables) {
|
||||||
|
if (notFirst)
|
||||||
|
output.preValue += ", ";
|
||||||
|
notFirst = true;
|
||||||
|
output.preValue += "." + scopePrefix(var) + var->getDataRef()->symbol.getName() + " = &" + scopePrefix(var) + var->getDataRef()->symbol.getName();
|
||||||
|
}
|
||||||
|
output.preValue += "};\n";
|
||||||
|
output += "("+ ValueTypeToCType(data.valueType, "") +"){(void*)" + funcName + ", &" + tmpStruct + "}";
|
||||||
} else {
|
} else {
|
||||||
output += "("+ ValueTypeToCType(data.valueType, "") +"){" + funcName + ", NULL}";
|
output += "("+ ValueTypeToCType(data.valueType, "") +"){" + funcName + ", NULL}";
|
||||||
}
|
}
|
||||||
@@ -802,6 +810,22 @@ std::string CGenerator::emitDestructors(std::vector<NodeTree<ASTData>*> identifi
|
|||||||
return destructorString;
|
return destructorString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CGenerator::closureStructType(std::set<NodeTree<ASTData>*> closedVariables) {
|
||||||
|
auto it = closureStructMap.find(closedVariables);
|
||||||
|
if (it != closureStructMap.end())
|
||||||
|
return it->second;
|
||||||
|
std::string typedefString = "typedef struct { ";
|
||||||
|
// note the increased indirection b/c we're using references to what we closed over
|
||||||
|
for (auto var : closedVariables) {
|
||||||
|
auto tmp = var->getDataRef()->valueType->withIncreasedIndirection();
|
||||||
|
typedefString += ValueTypeToCType(&tmp, scopePrefix(var) + var->getDataRef()->symbol.getName()) + ";";
|
||||||
|
}
|
||||||
|
std::string structName = "closureStructType" + getID();
|
||||||
|
typedefString += " } " + structName + ";\n";
|
||||||
|
functionTypedefString += typedefString;
|
||||||
|
closureStructMap[closedVariables] = structName;
|
||||||
|
return structName;
|
||||||
|
}
|
||||||
|
|
||||||
std::string CGenerator::ValueTypeToCType(Type *type, std::string declaration, ClosureTypeSpecialType closureSpecial) { return ValueTypeToCTypeThingHelper(type, " " + declaration, closureSpecial); }
|
std::string CGenerator::ValueTypeToCType(Type *type, std::string declaration, ClosureTypeSpecialType closureSpecial) { return ValueTypeToCTypeThingHelper(type, " " + declaration, closureSpecial); }
|
||||||
std::string CGenerator::ValueTypeToCTypeDecoration(Type *type, ClosureTypeSpecialType closureSpecial) { return CifyName(ValueTypeToCTypeThingHelper(type, "", closureSpecial)); }
|
std::string CGenerator::ValueTypeToCTypeDecoration(Type *type, ClosureTypeSpecialType closureSpecial) { return CifyName(ValueTypeToCTypeThingHelper(type, "", closureSpecial)); }
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ std::string replaceExEscape(std::string first, std::string search, std::string r
|
|||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
int numBackslashes = 0;
|
int numBackslashes = 0;
|
||||||
int countBack = 1;
|
int countBack = 1;
|
||||||
while (pos-countBack >= 0 && first[pos-countBack] == '\\') {
|
while ((int)pos-countBack >= 0 && first[pos-countBack] == '\\') {
|
||||||
numBackslashes++;
|
numBackslashes++;
|
||||||
countBack++;
|
countBack++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,18 +32,7 @@ obj regexState(Object) {
|
|||||||
next_states.destruct()
|
next_states.destruct()
|
||||||
}
|
}
|
||||||
fun match(input: char): vector::vector<regexState*> {
|
fun match(input: char): vector::vector<regexState*> {
|
||||||
return next_states.filter(fun(it:regexState*, input:char):bool { return it->character == input; }, input)
|
return next_states.filter(fun(it:regexState*):bool { return it->character == input; })
|
||||||
|
|
||||||
io::print("in match for: "); io::println(character)
|
|
||||||
io::println("pre")
|
|
||||||
for (var i = 0; i < next_states.size; i++;)
|
|
||||||
io::println(next_states[i]->character)
|
|
||||||
var nx = next_states.filter(fun(it:regexState*, input:char):bool { return it->character == input; }, input)
|
|
||||||
io::println("next")
|
|
||||||
for (var i = 0; i < nx.size; i++;)
|
|
||||||
io::println(nx[i]->character)
|
|
||||||
//return next_states.filter(fun(it:regexState*, input:char):bool { return it->character == input; }, input)
|
|
||||||
return nx
|
|
||||||
}
|
}
|
||||||
fun is_end():bool {
|
fun is_end():bool {
|
||||||
return next_states.any_true(fun(state: regexState*):bool { return state->character == 1; })
|
return next_states.any_true(fun(state: regexState*):bool { return state->character == 1; })
|
||||||
@@ -60,7 +49,8 @@ obj regex(Object) {
|
|||||||
var beginningAndEnd = compile(regexStringIn)
|
var beginningAndEnd = compile(regexStringIn)
|
||||||
// init our begin, and the end state as the next state of each end
|
// init our begin, and the end state as the next state of each end
|
||||||
begin = beginningAndEnd.first
|
begin = beginningAndEnd.first
|
||||||
beginningAndEnd.second.do(fun(it: regexState*, end: regexState*): void { it->next_states.add(end); }, mem::new<regexState>()->construct(conversions::to_char(1)))
|
var end = mem::new<regexState>()->construct(conversions::to_char(1))
|
||||||
|
beginningAndEnd.second.do(fun(it: regexState*): void { it->next_states.add(end); })
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,11 +108,11 @@ obj regex(Object) {
|
|||||||
i = perenEnd-1
|
i = perenEnd-1
|
||||||
|
|
||||||
if (alternating) {
|
if (alternating) {
|
||||||
previous_end.do(fun(it: regexState*, innerBegin: vector::vector<regexState*>):void { it->next_states.add_all(innerBegin); }, innerBeginEnd.first->next_states)
|
previous_end.do(fun(it: regexState*):void { it->next_states.add_all(innerBeginEnd.first->next_states); } )
|
||||||
current_begin.add_all(innerBeginEnd.first->next_states)
|
current_begin.add_all(innerBeginEnd.first->next_states)
|
||||||
current_end.add_all(innerBeginEnd.second)
|
current_end.add_all(innerBeginEnd.second)
|
||||||
} else {
|
} else {
|
||||||
current_end.do(fun(it: regexState*, innerBegin: vector::vector<regexState*>):void { it->next_states.add_all(innerBegin); }, innerBeginEnd.first->next_states)
|
current_end.do(fun(it: regexState*):void { it->next_states.add_all(innerBeginEnd.first->next_states); } )
|
||||||
previous_begin = current_begin
|
previous_begin = current_begin
|
||||||
previous_end = current_end
|
previous_end = current_end
|
||||||
current_begin = innerBeginEnd.first->next_states
|
current_begin = innerBeginEnd.first->next_states
|
||||||
@@ -136,11 +126,11 @@ obj regex(Object) {
|
|||||||
} else {
|
} else {
|
||||||
var next = mem::new<regexState>()->construct(regex_string[i])
|
var next = mem::new<regexState>()->construct(regex_string[i])
|
||||||
if (alternating) {
|
if (alternating) {
|
||||||
previous_end.do(fun(it: regexState*, next: regexState*):void { it->next_states.add(next); }, next)
|
previous_end.do(fun(it: regexState*):void { it->next_states.add(next); })
|
||||||
current_begin.add(next)
|
current_begin.add(next)
|
||||||
current_end.add(next)
|
current_end.add(next)
|
||||||
} else {
|
} else {
|
||||||
current_end.do(fun(it: regexState*, next: regexState*):void { it->next_states.add(next); }, next)
|
current_end.do(fun(it: regexState*):void { it->next_states.add(next); })
|
||||||
previous_begin = current_begin
|
previous_begin = current_begin
|
||||||
previous_end = current_end
|
previous_end = current_end
|
||||||
current_begin = vector::vector(next)
|
current_begin = vector::vector(next)
|
||||||
@@ -154,7 +144,6 @@ obj regex(Object) {
|
|||||||
return beginAndEnd
|
return beginAndEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun long_match(to_match: char*): int { return long_match(string::string(to_match)); }
|
fun long_match(to_match: char*): int { return long_match(string::string(to_match)); }
|
||||||
fun long_match(to_match: string::string): int {
|
fun long_match(to_match: string::string): int {
|
||||||
var next = vector::vector(begin)
|
var next = vector::vector(begin)
|
||||||
@@ -165,7 +154,7 @@ obj regex(Object) {
|
|||||||
if (next.any_true(fun(state: regexState*):bool { return state->is_end(); }))
|
if (next.any_true(fun(state: regexState*):bool { return state->is_end(); }))
|
||||||
longest = i
|
longest = i
|
||||||
//next = next.flatten_map<regexState*>(fun(state: regexState*): vector::vector<regexState*> { return state->match(to_match[i]); })
|
//next = next.flatten_map<regexState*>(fun(state: regexState*): vector::vector<regexState*> { return state->match(to_match[i]); })
|
||||||
next = next.flatten_map(fun(state: regexState*, c:char): vector::vector<regexState*> { return state->match(c); }, to_match[i])
|
next = next.flatten_map(fun(state: regexState*): vector::vector<regexState*> { return state->match(to_match[i]); })
|
||||||
}
|
}
|
||||||
if (next.any_true(fun(state: regexState*):bool { return state->is_end(); }))
|
if (next.any_true(fun(state: regexState*):bool { return state->is_end(); }))
|
||||||
return to_match.length()
|
return to_match.length()
|
||||||
@@ -173,4 +162,3 @@ obj regex(Object) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,3 +11,8 @@
|
|||||||
7
|
7
|
||||||
8
|
8
|
||||||
9
|
9
|
||||||
|
4
|
||||||
|
closures now
|
||||||
|
1337
|
||||||
|
13371010
|
||||||
|
80
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import io:*
|
import io:*
|
||||||
|
import vector:*
|
||||||
|
|
||||||
fun runLambda(func: fun():int):void {
|
fun runLambda(func: fun():int):void {
|
||||||
println(func())
|
println(func())
|
||||||
@@ -6,27 +7,33 @@ fun runLambda(func: fun():int):void {
|
|||||||
|
|
||||||
fun somethingElse():int { return 4; }
|
fun somethingElse():int { return 4; }
|
||||||
|
|
||||||
//fun callLambda(func: fun(int):void):void {
|
fun callLambda(func: fun(int):void):void {
|
||||||
//func(10)
|
func(10)
|
||||||
//}
|
}
|
||||||
|
|
||||||
//fun itr<T>(it: T, func: fun(T):T):T {
|
fun itr<T>(it: T, func: fun(T):T):T {
|
||||||
//println(it)
|
println(it)
|
||||||
//return func(it);
|
return func(it);
|
||||||
//}
|
}
|
||||||
|
|
||||||
fun main():int {
|
fun main():int {
|
||||||
//var func = fun():void { println("8"); }
|
var func = fun():void { println("8"); }
|
||||||
//func()
|
func()
|
||||||
//runLambda(fun():int { return 9;})
|
runLambda(fun():int { return 9;})
|
||||||
//callLambda(fun(a:int):void { println(a);})
|
callLambda(fun(a:int):void { println(a);})
|
||||||
//var j = 0
|
var j = 0
|
||||||
//while (j < 10) j = itr(j, fun(a:int):int { return a+1; })
|
while (j < 10) j = itr(j, fun(a:int):int { return a+1; })
|
||||||
|
|
||||||
runLambda(somethingElse)
|
runLambda(somethingElse)
|
||||||
println("closures now")
|
println("closures now")
|
||||||
var a = 1337
|
var a = 1337
|
||||||
runLambda(fun():int { return a;})
|
runLambda(fun():int { return a;})
|
||||||
|
runLambda(fun():int { print(a); print(j); return j;})
|
||||||
|
|
||||||
|
var v = vector(80)
|
||||||
|
var idx = 0
|
||||||
|
runLambda(fun():int { return v.get(idx);})
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user