blob: 74d845d517eb8f29a0818bd374183c332f85e5a1 [file] [log] [blame]
/**
* Copyright (c) 2015, 2020 fortiss GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Martin Jobst
* - initial API and implementation and/or initial documentation
* Kirill Dorofeev - extended support for adapters used in BFB
*/
package org.eclipse.fordiac.ide.export.forte_lua.filter;
import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.fordiac.ide.export.forte_lua.filter.LuaConstants;
import org.eclipse.fordiac.ide.export.forte_lua.filter.STAlgorithmFilter;
import org.eclipse.fordiac.ide.model.libraryElement.AdapterDeclaration;
import org.eclipse.fordiac.ide.model.libraryElement.AdapterEvent;
import org.eclipse.fordiac.ide.model.libraryElement.Algorithm;
import org.eclipse.fordiac.ide.model.libraryElement.BasicFBType;
import org.eclipse.fordiac.ide.model.libraryElement.ECAction;
import org.eclipse.fordiac.ide.model.libraryElement.ECC;
import org.eclipse.fordiac.ide.model.libraryElement.ECState;
import org.eclipse.fordiac.ide.model.libraryElement.ECTransition;
import org.eclipse.fordiac.ide.model.libraryElement.Event;
import org.eclipse.fordiac.ide.model.libraryElement.STAlgorithm;
import org.eclipse.fordiac.ide.model.libraryElement.VarDeclaration;
import org.eclipse.xtend.lib.annotations.AccessorType;
import org.eclipse.xtend.lib.annotations.Accessors;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xbase.lib.StringExtensions;
@SuppressWarnings("all")
public class BasicFBFilter {
@Accessors(AccessorType.PUBLIC_GETTER)
private List<String> errors = new ArrayList<String>();
private STAlgorithmFilter stAlgorithmFilter = new STAlgorithmFilter();
public CharSequence lua(final BasicFBType type) {
StringConcatenation _builder = new StringConcatenation();
CharSequence _luaConstants = LuaConstants.luaConstants(type);
_builder.append(_luaConstants);
_builder.newLineIfNotEmpty();
_builder.newLine();
CharSequence _luaAlgorithms = this.luaAlgorithms(type);
_builder.append(_luaAlgorithms);
_builder.newLineIfNotEmpty();
_builder.newLine();
CharSequence _luaStates = this.luaStates(type.getECC());
_builder.append(_luaStates);
_builder.newLineIfNotEmpty();
_builder.newLine();
CharSequence _luaECC = this.luaECC(type.getECC(), this.getVariables(type), this.getAdapterSocketsVariables(type), this.getAdapterPlugsVariables(type));
_builder.append(_luaECC);
_builder.newLineIfNotEmpty();
_builder.newLine();
CharSequence _luaInterfaceSpec = LuaConstants.luaInterfaceSpec(type.getInterfaceList());
_builder.append(_luaInterfaceSpec);
_builder.newLineIfNotEmpty();
_builder.newLine();
CharSequence _luaInternalVarsInformation = LuaConstants.luaInternalVarsInformation(type);
_builder.append(_luaInternalVarsInformation);
_builder.newLineIfNotEmpty();
_builder.newLine();
_builder.append("return {ECC = executeEvent, interfaceSpec = interfaceSpec, internalVarsInformation = internalVarsInformation}");
_builder.newLine();
return _builder;
}
private CharSequence luaECC(final ECC ecc, final Iterable<VarDeclaration> variables, final Map<AdapterDeclaration, String> adapterSocketsVariables, final Map<AdapterDeclaration, String> adapterPlugsVariables) {
StringConcatenation _builder = new StringConcatenation();
_builder.append("local function transition(fb, id)");
_builder.newLine();
_builder.append(" ");
_builder.append("local ");
CharSequence _luaStateVariable = LuaConstants.luaStateVariable();
_builder.append(_luaStateVariable, " ");
_builder.append(" = ");
CharSequence _luaFBStateVariable = LuaConstants.luaFBStateVariable();
_builder.append(_luaFBStateVariable, " ");
_builder.newLineIfNotEmpty();
_builder.append(" ");
CharSequence _luaFBVariablesPrefix = LuaConstants.luaFBVariablesPrefix(variables);
_builder.append(_luaFBVariablesPrefix, " ");
_builder.newLineIfNotEmpty();
{
Set<AdapterDeclaration> _keySet = adapterSocketsVariables.keySet();
for(final AdapterDeclaration adapter : _keySet) {
{
EList<VarDeclaration> _inputVars = adapter.getType().getAdapterFBType().getInterfaceList().getInputVars();
for(final VarDeclaration input : _inputVars) {
_builder.append(" ");
CharSequence _luaFBAdapterInECCVariablesPrefix = LuaConstants.luaFBAdapterInECCVariablesPrefix(input, adapter.getName(), false);
_builder.append(_luaFBAdapterInECCVariablesPrefix, " ");
_builder.newLineIfNotEmpty();
}
}
{
EList<VarDeclaration> _outputVars = adapter.getType().getAdapterFBType().getInterfaceList().getOutputVars();
for(final VarDeclaration output : _outputVars) {
_builder.append(" ");
CharSequence _luaFBAdapterInECCVariablesPrefix_1 = LuaConstants.luaFBAdapterInECCVariablesPrefix(output, adapter.getName(), false);
_builder.append(_luaFBAdapterInECCVariablesPrefix_1, " ");
_builder.newLineIfNotEmpty();
}
}
}
}
{
Set<AdapterDeclaration> _keySet_1 = adapterPlugsVariables.keySet();
for(final AdapterDeclaration adapter_1 : _keySet_1) {
{
EList<VarDeclaration> _inputVars_1 = adapter_1.getType().getAdapterFBType().getInterfaceList().getInputVars();
for(final VarDeclaration input_1 : _inputVars_1) {
_builder.append(" ");
CharSequence _luaFBAdapterInECCVariablesPrefix_2 = LuaConstants.luaFBAdapterInECCVariablesPrefix(input_1, adapter_1.getName(), true);
_builder.append(_luaFBAdapterInECCVariablesPrefix_2, " ");
_builder.newLineIfNotEmpty();
}
}
{
EList<VarDeclaration> _outputVars_1 = adapter_1.getType().getAdapterFBType().getInterfaceList().getOutputVars();
for(final VarDeclaration output_1 : _outputVars_1) {
_builder.append(" ");
CharSequence _luaFBAdapterInECCVariablesPrefix_3 = LuaConstants.luaFBAdapterInECCVariablesPrefix(output_1, adapter_1.getName(), true);
_builder.append(_luaFBAdapterInECCVariablesPrefix_3, " ");
_builder.newLineIfNotEmpty();
}
}
}
}
_builder.append(" ");
CharSequence _luaTransitions = this.luaTransitions(ecc);
_builder.append(_luaTransitions, " ");
_builder.newLineIfNotEmpty();
_builder.append("end");
_builder.newLine();
_builder.newLine();
_builder.append("local function executeEvent(fb, id)");
_builder.newLine();
_builder.append(" ");
_builder.append("local modified = transition(fb, id)");
_builder.newLine();
_builder.append(" ");
_builder.append("while modified do");
_builder.newLine();
_builder.append(" ");
_builder.append("modified = transition(fb, -1)");
_builder.newLine();
_builder.append(" ");
_builder.append("end");
_builder.newLine();
_builder.append("end");
_builder.newLine();
return _builder;
}
private Iterable<VarDeclaration> getVariables(final BasicFBType type) {
EList<VarDeclaration> _inputVars = type.getInterfaceList().getInputVars();
EList<VarDeclaration> _outputVars = type.getInterfaceList().getOutputVars();
Iterable<VarDeclaration> _plus = Iterables.<VarDeclaration>concat(_inputVars, _outputVars);
EList<VarDeclaration> _internalVars = type.getInternalVars();
return Iterables.<VarDeclaration>concat(_plus, _internalVars);
}
private Map<AdapterDeclaration, String> getAdapterSocketsVariables(final BasicFBType type) {
Map<AdapterDeclaration, String> ret = new HashMap<AdapterDeclaration, String>();
EList<AdapterDeclaration> _sockets = type.getInterfaceList().getSockets();
for (final AdapterDeclaration adapterDecl : _sockets) {
ret.put(adapterDecl, adapterDecl.getName());
}
return ret;
}
private Map<AdapterDeclaration, String> getAdapterPlugsVariables(final BasicFBType type) {
Map<AdapterDeclaration, String> ret = new HashMap<AdapterDeclaration, String>();
EList<AdapterDeclaration> _plugs = type.getInterfaceList().getPlugs();
for (final AdapterDeclaration adapterDecl : _plugs) {
ret.put(adapterDecl, adapterDecl.getName());
}
return ret;
}
private CharSequence luaTransitions(final ECC ecc) {
StringConcatenation _builder = new StringConcatenation();
{
EList<ECState> _eCState = ecc.getECState();
boolean _hasElements = false;
for(final ECState state : _eCState) {
if (!_hasElements) {
_hasElements = true;
_builder.append("if ");
} else {
_builder.appendImmediate("\nelseif ", "");
}
CharSequence _luaStateName = LuaConstants.luaStateName(state);
_builder.append(_luaStateName);
_builder.append(" == ");
CharSequence _luaStateVariable = LuaConstants.luaStateVariable();
_builder.append(_luaStateVariable);
_builder.append(" then");
_builder.newLineIfNotEmpty();
CharSequence _luaTransition = this.luaTransition(state);
_builder.append(_luaTransition);
}
if (_hasElements) {
_builder.append("\nelse return false\nend");
}
}
return _builder;
}
private CharSequence luaTransition(final ECState state) {
StringConcatenation _builder = new StringConcatenation();
{
EList<ECTransition> _outTransitions = state.getOutTransitions();
boolean _hasElements = false;
for(final ECTransition tran : _outTransitions) {
if (!_hasElements) {
_hasElements = true;
_builder.append("if ");
} else {
_builder.appendImmediate("\nelseif ", "");
}
CharSequence _luaTransitionCondition = this.luaTransitionCondition(tran);
_builder.append(_luaTransitionCondition);
_builder.append(" then return enter");
CharSequence _luaStateName = LuaConstants.luaStateName(tran.getDestination());
_builder.append(_luaStateName);
_builder.append("(fb)");
}
if (_hasElements) {
_builder.append("\nelse return false\nend");
}
}
return _builder;
}
private CharSequence luaTransitionCondition(final ECTransition tran) {
StringConcatenation _builder = new StringConcatenation();
{
Event _conditionEvent = tran.getConditionEvent();
boolean _notEquals = (!Objects.equal(_conditionEvent, null));
if (_notEquals) {
CharSequence _luaInputEventName = LuaConstants.luaInputEventName(tran.getConditionEvent());
_builder.append(_luaInputEventName);
_builder.append(" == id");
} else {
_builder.append("true");
}
}
_builder.append(" and ");
{
boolean _isNullOrEmpty = StringExtensions.isNullOrEmpty(tran.getConditionExpression());
boolean _not = (!_isNullOrEmpty);
if (_not) {
CharSequence _luaTransitionConditionExpression = this.luaTransitionConditionExpression(tran);
_builder.append(_luaTransitionConditionExpression);
} else {
_builder.append("true");
}
}
return _builder;
}
private CharSequence luaTransitionConditionExpression(final ECTransition tran) {
CharSequence _xblockexpression = null;
{
EObject _rootContainer = EcoreUtil.getRootContainer(tran);
final BasicFBType type = ((BasicFBType) _rootContainer);
_xblockexpression = this.stAlgorithmFilter.lua(type, tran.getConditionExpression());
}
return _xblockexpression;
}
private CharSequence luaStates(final ECC ecc) {
StringConcatenation _builder = new StringConcatenation();
{
EList<ECState> _eCState = ecc.getECState();
for(final ECState state : _eCState) {
CharSequence _luaState = this.luaState(state);
_builder.append(_luaState);
_builder.newLineIfNotEmpty();
_builder.newLine();
}
}
return _builder;
}
private CharSequence luaState(final ECState state) {
StringConcatenation _builder = new StringConcatenation();
_builder.append("local function enter");
CharSequence _luaStateName = LuaConstants.luaStateName(state);
_builder.append(_luaStateName);
_builder.append("(fb)");
_builder.newLineIfNotEmpty();
_builder.append(" ");
CharSequence _luaFBStateVariable = LuaConstants.luaFBStateVariable();
_builder.append(_luaFBStateVariable, " ");
_builder.append(" = ");
CharSequence _luaStateName_1 = LuaConstants.luaStateName(state);
_builder.append(_luaStateName_1, " ");
_builder.newLineIfNotEmpty();
{
EList<ECAction> _eCAction = state.getECAction();
for(final ECAction action : _eCAction) {
_builder.append(" ");
{
Algorithm _algorithm = action.getAlgorithm();
boolean _notEquals = (!Objects.equal(null, _algorithm));
if (_notEquals) {
CharSequence _luaAlgorithmName = LuaConstants.luaAlgorithmName(action.getAlgorithm());
_builder.append(_luaAlgorithmName, " ");
_builder.append("(fb)");
}
}
_builder.newLineIfNotEmpty();
{
Event _output = action.getOutput();
if ((_output instanceof AdapterEvent)) {
_builder.append(" ");
Event _output_1 = action.getOutput();
CharSequence _luaSendAdapterOutputEvent = null;
if (_output_1!=null) {
_luaSendAdapterOutputEvent=LuaConstants.luaSendAdapterOutputEvent(_output_1);
}
_builder.append(_luaSendAdapterOutputEvent, " ");
_builder.newLineIfNotEmpty();
} else {
_builder.append(" ");
Event _output_2 = action.getOutput();
CharSequence _luaSendOutputEvent = null;
if (_output_2!=null) {
_luaSendOutputEvent=LuaConstants.luaSendOutputEvent(_output_2);
}
_builder.append(_luaSendOutputEvent, " ");
_builder.newLineIfNotEmpty();
}
}
}
}
_builder.append(" ");
_builder.append("return true");
_builder.newLine();
_builder.append("end");
_builder.newLine();
return _builder;
}
private CharSequence luaAlgorithms(final BasicFBType type) {
StringConcatenation _builder = new StringConcatenation();
{
EList<Algorithm> _algorithm = type.getAlgorithm();
for(final Algorithm alg : _algorithm) {
String _luaAlgorithm = this.luaAlgorithm(alg);
_builder.append(_luaAlgorithm);
_builder.newLineIfNotEmpty();
_builder.newLine();
}
}
return _builder;
}
private String _luaAlgorithm(final Algorithm alg) {
Class<? extends Algorithm> _class = alg.getClass();
String _plus = ("Cannot export algorithm " + _class);
throw new UnsupportedOperationException(_plus);
}
private String _luaAlgorithm(final STAlgorithm alg) {
StringConcatenation _builder = new StringConcatenation();
_builder.append("local function ");
CharSequence _luaAlgorithmName = LuaConstants.luaAlgorithmName(alg);
_builder.append(_luaAlgorithmName);
_builder.append("(fb)");
_builder.newLineIfNotEmpty();
_builder.append(" ");
String _lua = this.stAlgorithmFilter.lua(alg);
_builder.append(_lua, " ");
_builder.newLineIfNotEmpty();
_builder.append("end");
_builder.newLine();
final String result = _builder.toString();
final Function1<String, String> _function = (String it) -> {
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("Error in algorithm ");
String _name = alg.getName();
_builder_1.append(_name);
_builder_1.append(": ");
_builder_1.append(it);
return _builder_1.toString();
};
this.errors.addAll(ListExtensions.<String, String>map(this.stAlgorithmFilter.getErrors(), _function));
this.stAlgorithmFilter.getErrors().clear();
return result;
}
private String luaAlgorithm(final Algorithm alg) {
if (alg instanceof STAlgorithm) {
return _luaAlgorithm((STAlgorithm)alg);
} else if (alg != null) {
return _luaAlgorithm(alg);
} else {
throw new IllegalArgumentException("Unhandled parameter types: " +
Arrays.<Object>asList(alg).toString());
}
}
@Pure
public List<String> getErrors() {
return this.errors;
}
}