aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/java/coffee/liz/abstractionengine/grid/system
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/coffee/liz/abstractionengine/grid/system')
-rw-r--r--core/src/main/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystem.java52
1 files changed, 27 insertions, 25 deletions
diff --git a/core/src/main/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystem.java b/core/src/main/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystem.java
index 74bc3fc..f93d60b 100644
--- a/core/src/main/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystem.java
+++ b/core/src/main/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystem.java
@@ -8,12 +8,16 @@ import coffee.liz.abstractionengine.grid.component.GridPosition;
import coffee.liz.abstractionengine.grid.component.LambdaTerm;
import coffee.liz.abstractionengine.grid.component.Substitution;
import coffee.liz.ecs.math.Vec2;
+import coffee.liz.ecs.model.Entity;
import coffee.liz.ecs.model.System;
import coffee.liz.ecs.model.World;
import coffee.liz.ecs.model.Query;
import coffee.liz.lambda.LambdaDriver;
+import coffee.liz.lambda.ast.LambdaProgram;
import coffee.liz.lambda.ast.SourceCode;
import coffee.liz.lambda.eval.Environment;
+import coffee.liz.lambda.eval.NormalOrderEvaluator;
+import coffee.liz.lambda.eval.Thunk;
import coffee.liz.lambda.eval.Value;
import coffee.liz.lambda.format.ValueEmitter;
import lombok.extern.log4j.Log4j2;
@@ -21,10 +25,7 @@ import lombok.extern.log4j.Log4j2;
import java.time.Duration;
import java.util.Collection;
import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
+import java.util.Objects;
@Log4j2
public class LambdaEvaluatorSystem implements System<GridInputState> {
@@ -45,38 +46,39 @@ public class LambdaEvaluatorSystem implements System<GridInputState> {
world.resolve(Query.allOf(Substitution.class, LambdaTerm.class, GridPosition.class)).forEach(entity -> {
final LambdaTerm term = entity.get(LambdaTerm.class);
- final Substitution substitution = entity.get(Substitution.class);
final GridPosition position = entity.get(GridPosition.class);
+ final Substitution substitution = entity.get(Substitution.class);
- final Map<String, Supplier<Value>> dependencies = substitution.getTermDependencies().entrySet().stream()
- .map(e -> {
- final String symbol = e.getKey();
- // Ideally we should only ever have one match to replace the symbol with.
- // But maybe there's a use-case where this is not the case?
- final Optional<SourceCode> sourceCode = gridIndexSystem.entitiesAt(e.getValue()).stream()
- .filter(_entity -> _entity.has(LambdaTerm.class))
- .map(_entity -> _entity.get(LambdaTerm.class)).map(LambdaTerm::getTerm).findFirst();
- // TODO: Map error
- final Optional<Supplier<Value>> val = sourceCode.map(s -> () -> LambdaDriver.interpret(s));
- return Map.entry(symbol, val);
- }).filter(e -> e.getValue().isPresent())
- .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get()));
+ final List<Entity> resolvedDependencies = substitution.getTermDependencies().stream()
+ .map(dependencyPos -> gridIndexSystem.entitiesAt(dependencyPos).stream()
+ .filter(_entity -> _entity.has(LambdaTerm.class))
+ .findFirst()
+ .orElse(null))
+ .toList();
- final boolean dependenciesSatisified = dependencies.keySet()
- .equals(substitution.getTermDependencies().keySet());
+ final boolean dependenciesSatisified = resolvedDependencies.stream().allMatch(Objects::nonNull);
if (!dependenciesSatisified) {
+ entity.add(substitution.toBuilder().isActive(true).build());
return;
}
- final Environment env = dependencies.entrySet().stream().reduce(Environment.root(),
- (_env, e) -> _env.extend(e.getKey(), e.getValue()), (a, b) -> b);
- final Value evaluationResult = LambdaDriver.interpret(term.getTerm(), List.of(), env);
- final SourceCode emittedResult = ValueEmitter.emit(evaluationResult, preferredSyntax);
+ if (!substitution.isActive()) {
+ return;
+ }
+
+ Value result = LambdaDriver.interpret(term.getTerm());
+ for (final Entity dependency : resolvedDependencies) {
+ result = new Value.Application(result, LambdaDriver.interpret(dependency.get(LambdaTerm.class).getTerm()));
+ }
+
+ final SourceCode emittedResult = ValueEmitter.emit(LambdaDriver.interpret(ValueEmitter.emit(result, preferredSyntax)), preferredSyntax);
final Vec2<Integer> spawnMomentum = substitution.getSpawnMomentum();
- EntityFactory.Abstraction.addToWorld(world, position.getPosition(), new LambdaTerm(emittedResult))
+ final Entity producedTerm = EntityFactory.Abstraction.addToWorld(world, position.getPosition(), new LambdaTerm(emittedResult))
.add(EntityType.ABSTRACTION).add(new GridPosition(position.getPosition()))
.add(new GridMomentum(spawnMomentum));
+ entity.add(substitution.toBuilder().isActive(false).build());
+ log.info("Entity {} produced {}", entity, producedTerm);
});
}
}