forked from allegro/opel
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request allegro#19 from allegro/functions
Functions
- Loading branch information
Showing
10 changed files
with
533 additions
and
23 deletions.
There are no files selected for viewing
25 changes: 25 additions & 0 deletions
25
src/main/java/pl/allegro/tech/opel/AnonymousFunctionExpressionNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package pl.allegro.tech.opel; | ||
|
||
import java.util.concurrent.CompletableFuture; | ||
import java.util.stream.Collectors; | ||
|
||
public class AnonymousFunctionExpressionNode implements OpelNode { | ||
|
||
private final OpelNode expression; | ||
private final ArgumentsListExpressionNode arguments; | ||
|
||
public AnonymousFunctionExpressionNode(OpelNode expression, ArgumentsListExpressionNode arguments) { | ||
this.expression = expression; | ||
this.arguments = arguments; | ||
} | ||
|
||
@Override | ||
public CompletableFuture<?> getValue(EvalContext context) { | ||
return expression.getValue(context).thenCompose(function -> { | ||
if (function instanceof OpelAsyncFunction) { | ||
return ((OpelAsyncFunction<?>) function).apply(arguments.getArgs().stream().map(it -> it.getValue(context)).collect(Collectors.toList())); | ||
} | ||
throw new OpelException("Can't use expression of type " + expression.getClass().getSimpleName() + " as a function"); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package pl.allegro.tech.opel; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
public class ArgsGroupNode implements OpelNode { | ||
private final List<ArgumentsListExpressionNode> argsGroup; | ||
|
||
public ArgsGroupNode(List<ArgumentsListExpressionNode> argsGroup) { | ||
this.argsGroup = argsGroup; | ||
} | ||
|
||
@Override | ||
public CompletableFuture<?> getValue(EvalContext context) { | ||
throw new UnsupportedOperationException("Can't get value on ArgsGroupNode"); | ||
} | ||
|
||
public static OpelNode empty() { | ||
return new ArgsGroupNode(Collections.emptyList()); | ||
} | ||
|
||
public List<ArgumentsListExpressionNode> getGroups() { | ||
return argsGroup; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
src/main/java/pl/allegro/tech/opel/FunctionChainExpressionNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package pl.allegro.tech.opel; | ||
|
||
import java.util.concurrent.CompletableFuture; | ||
|
||
public class FunctionChainExpressionNode implements OpelNode { | ||
private final OpelNode expression; | ||
private final ArgsGroupNode argsGroups; | ||
|
||
public FunctionChainExpressionNode(OpelNode expression, ArgsGroupNode argsGroups) { | ||
this.expression = expression; | ||
this.argsGroups = argsGroups; | ||
} | ||
|
||
@Override | ||
public CompletableFuture<?> getValue(EvalContext context) { | ||
CompletableFuture<?> result = expression.getValue(context); | ||
for (ArgumentsListExpressionNode argsGroup : argsGroups.getGroups()) { | ||
result = callFunction(result, argsGroup, context); | ||
} | ||
return result; | ||
} | ||
|
||
private CompletableFuture<Object> callFunction(CompletableFuture<?> function, ArgumentsListExpressionNode argsGroup, EvalContext context) { | ||
return function.thenCompose(fun -> { | ||
if (fun instanceof OpelAsyncFunction) { | ||
return ((OpelAsyncFunction) fun).apply(argsGroup.getListOfValues(context)); | ||
} | ||
throw new OpelException("Can't use '" + fun.getClass().getSimpleName() + "' as a function"); | ||
}); | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
src/main/java/pl/allegro/tech/opel/FunctionInstantiationExpressionNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package pl.allegro.tech.opel; | ||
|
||
import java.util.List; | ||
import java.util.concurrent.CompletableFuture; | ||
import java.util.function.Function; | ||
import java.util.stream.Collectors; | ||
|
||
public class FunctionInstantiationExpressionNode implements OpelNode { | ||
private final IdentifiersListNode arguments; | ||
private final OpelNode body; | ||
|
||
public FunctionInstantiationExpressionNode(IdentifiersListNode arguments, OpelNode body) { | ||
this.arguments = arguments; | ||
this.body = body; | ||
} | ||
|
||
@Override | ||
public CompletableFuture<?> getValue(EvalContext context) { | ||
return CompletableFuture.completedFuture(new OpelAsyncFunction<Object>() { | ||
@Override | ||
public CompletableFuture<Object> apply(List<CompletableFuture<?>> args) { | ||
|
||
List<CompletableFuture<Object>> collect = arguments.getIdentifiers().stream() | ||
.map(it -> it.getValue(context)) | ||
.map(it -> javaGenericWorkaround(it)) | ||
.collect(Collectors.toList()); | ||
CompletableFuture<List<Object>> argsNames = FutureUtil.sequence(collect); | ||
|
||
return argsNames.thenCompose(names -> { | ||
EvalContextBuilder contextBuilder = EvalContextBuilder.create().withExternalEvalContext(context); | ||
for (int i = 0; i < names.size(); i++) { | ||
String name = (String) names.get(i); | ||
if (args.size() == i) { | ||
throw new OpelException("Missing argument '" + name + "' in function call"); | ||
} | ||
CompletableFuture<Object> value = args.get(i).thenApply(Function.identity()); | ||
contextBuilder.withValue(name, value); | ||
} | ||
EvalContext localContext = contextBuilder.build(); | ||
return body.getValue(localContext).thenApply(Function.identity()); | ||
}); | ||
|
||
} | ||
}); | ||
} | ||
|
||
private CompletableFuture<Object> javaGenericWorkaround(CompletableFuture<?> future) { | ||
return future.thenApply(Function.identity()); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/pl/allegro/tech/opel/IdentifiersListNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package pl.allegro.tech.opel; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
public class IdentifiersListNode implements OpelNode { | ||
private final List<OpelNode> identifiers; | ||
|
||
public IdentifiersListNode(List<OpelNode> identifiers) { | ||
this.identifiers = identifiers; | ||
} | ||
|
||
@Override | ||
public CompletableFuture<?> getValue(EvalContext context) { | ||
throw new UnsupportedOperationException("Can't get value on ArgumentsListExpressionNode"); | ||
} | ||
|
||
public static OpelNode empty() { | ||
return new IdentifiersListNode(Collections.emptyList()); | ||
} | ||
|
||
public List<OpelNode> getIdentifiers() { | ||
return identifiers; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.