org.protelis.lang.interpreter.impl.AlignedMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of protelis-interpreter Show documentation
Show all versions of protelis-interpreter Show documentation
The Protelis language interpreter
/*
* Copyright (C) 2021, Danilo Pianini and contributors listed in the project's build.gradle.kts or pom.xml file.
*
* This file is part of Protelis, and is distributed under the terms of the GNU General Public License,
* with a linking exception, as described in the file LICENSE.txt in this project's top directory.
*/
package org.protelis.lang.interpreter.impl;
import org.protelis.lang.datatype.DatatypeFactory;
import org.protelis.lang.datatype.DeviceUID;
import org.protelis.lang.datatype.Either;
import org.protelis.lang.datatype.Field;
import org.protelis.lang.datatype.FunctionDefinition;
import org.protelis.lang.datatype.Tuple;
import org.protelis.lang.interpreter.ProtelisAST;
import org.protelis.lang.interpreter.util.Bytecode;
import org.protelis.lang.interpreter.util.HashingFunnel;
import org.protelis.lang.loading.Metadata;
import org.protelis.vm.ExecutionContext;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import static org.protelis.lang.interpreter.util.Bytecode.ALIGNED_MAP;
import static org.protelis.lang.interpreter.util.Bytecode.ALIGNED_MAP_DEFAULT;
import static org.protelis.lang.interpreter.util.Bytecode.ALIGNED_MAP_EXECUTE;
import static org.protelis.lang.interpreter.util.Bytecode.ALIGNED_MAP_FILTER;
import static org.protelis.lang.interpreter.util.Bytecode.ALIGNED_MAP_GENERATOR;
/**
* Operation evaluating a collection of expressions associated with keys, such
* as a set of publish-subscribe streams. This allows devices with different
* sets of keys to align the expressions that share keys together.
*/
public final class AlignedMap extends AbstractProtelisAST {
private static final long serialVersionUID = 2L;
private final HashingFunnel hasher;
private final ProtelisAST> defaultValue;
private final ProtelisAST> fieldGenerator;
private final ProtelisAST filter;
private final ProtelisAST execute;
/**
* @param hasher a function producing a valid, reproducible, and unambiguous hash for arbitrary objects
* @param metadata
* A {@link Metadata} object containing information about the code that generated this AST node.
* @param argument
* the field on which {@link AlignedMap} should be applied
* @param filter
* filtering function
* @param operation
* function to run
* @param defaultValue
* default value
*/
public AlignedMap(
final HashingFunnel hasher,
final Metadata metadata,
final ProtelisAST> argument,
final ProtelisAST filter,
final ProtelisAST operation,
final ProtelisAST> defaultValue
) {
super(metadata, argument, filter, operation, defaultValue);
this.hasher = hasher;
fieldGenerator = argument;
this.filter = filter;
execute = operation;
this.defaultValue = defaultValue;
}
@Override
public Tuple evaluate(final ExecutionContext context) {
final Field> origin = context.runInNewStackFrame(ALIGNED_MAP_GENERATOR.getCode(), fieldGenerator::eval);
/*
* Extract one field for each key.
*
* This operation translates a field of tuples of tuples of the form:
*
* {ID0 : [[key1, val1], [key2, val2]], ID2 : [[key3, val3], [key2, val4]]}
*
* into a collection such as:
*
* key1 : {ID0 : val1}
* key2 : {ID0 : val2, ID2 : val4}
* key3 : {ID2: val3}
*/
final Map