Unverified Commit 228b6e55 authored by Thomas Michael Timmermanns's avatar Thomas Michael Timmermanns Committed by GitHub

Merge pull request #14 from EmbeddedMontiArc/timmermanns

Timmermanns
parents 12c7fe16 6b579a61
This diff is collapsed.
......@@ -20,7 +20,7 @@
*/
package de.monticore.lang.monticar.cnnarch._ast;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedVariables;
import de.monticore.lang.monticar.cnnarch.predefined.AllPredefinedVariables;
public class ASTPredefinedArgument extends ASTPredefinedArgumentTOP {
......@@ -41,7 +41,7 @@ public class ASTPredefinedArgument extends ASTPredefinedArgumentTOP {
public void setParallel(String parallel) {
super.setParallel(parallel);
if (parallel != null && !parallel.isEmpty()){
setName(PredefinedVariables.CARDINALITY_NAME);
setName(AllPredefinedVariables.CARDINALITY_NAME);
}
}
......@@ -49,7 +49,7 @@ public class ASTPredefinedArgument extends ASTPredefinedArgumentTOP {
public void setSerial(String serial) {
super.setSerial(serial);
if (serial != null && !serial.isEmpty()) {
setName(PredefinedVariables.FOR_NAME);
setName(AllPredefinedVariables.FOR_NAME);
}
}
}
......@@ -27,6 +27,7 @@ public class CNNArchPreResolveCocos {
return new CNNArchCoCoChecker()
.addCoCo(new CheckMethodLayer())
.addCoCo(new CheckVariable())
.addCoCo(new CheckIODeclaration())
.addCoCo(new CheckIOLayer())
.addCoCo(new CheckArgument())
.addCoCo(new CheckMethodDeclaration());
......
/**
*
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* All rights reserved.
*
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* *******************************************************************************
*/
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTIODeclaration;
public class CheckIODeclaration implements CNNArchASTIODeclarationCoCo {
@Override
public void check(ASTIODeclaration node) {
//todo: check io shape; only 1 and 3 is allowed
}
}
......@@ -21,10 +21,12 @@
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTArchitecture;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureSymbol;
public class CheckLayerInputs implements CNNArchASTArchitectureCoCo {
@Override
public void check(ASTArchitecture node) {
//todo:
ArchitectureSymbol architecture = (ArchitectureSymbol) node.getSymbol().get();
architecture.getBody().checkInputAndOutput();
}
}
......@@ -26,7 +26,7 @@ import de.monticore.lang.monticar.cnnarch._symboltable.MethodDeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.MethodLayerSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.VariableSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedMethods;
import de.monticore.lang.monticar.cnnarch.predefined.AllPredefinedMethods;
import de.se_rwth.commons.logging.Log;
import java.util.HashSet;
......@@ -64,8 +64,8 @@ public class CheckMethodLayer implements CNNArchASTMethodLayerCoCo{
}
for (ASTArgument argument : node.getArguments()){
requiredArguments.remove(argument.getName());
if (argument.getName().equals(PredefinedMethods.GLOBAL_NAME)){
requiredArguments.remove(PredefinedMethods.KERNEL_NAME);
if (argument.getName().equals(AllPredefinedMethods.GLOBAL_NAME)){
requiredArguments.remove(AllPredefinedMethods.KERNEL_NAME);
}
}
......
......@@ -23,9 +23,9 @@ package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTParameter;
import de.monticore.lang.monticar.cnnarch._ast.ASTVariable;
import de.monticore.lang.monticar.cnnarch._symboltable.VariableSymbol;
import de.monticore.lang.monticar.cnnarch.helper.Constraints;
import de.monticore.lang.monticar.cnnarch._symboltable.Constraints;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedVariables;
import de.monticore.lang.monticar.cnnarch.predefined.AllPredefinedVariables;
import de.monticore.symboltable.Symbol;
import de.se_rwth.commons.logging.Log;
......@@ -54,11 +54,16 @@ public class CheckVariable implements CNNArchASTVariableCoCo {
". All new variable and method names have to start with a lowercase letter. "
, node.get_SourcePositionStart());
}
if (name.equals(PredefinedVariables.TRUE_NAME) || name.equals(PredefinedVariables.FALSE_NAME)){
else if (name.equals(AllPredefinedVariables.TRUE_NAME) || name.equals(AllPredefinedVariables.FALSE_NAME)){
Log.error("0" + ErrorCodes.ILLEGAL_NAME_CODE + " Illegal name: " + name +
". No variable can be named 'true' or 'false'"
, node.get_SourcePositionStart());
}
else if (name.equals(AllPredefinedVariables.IF_NAME.toLowerCase())){
Log.error("0" + ErrorCodes.ILLEGAL_NAME_CODE + " Illegal name: " + name +
". No variable can be named 'if'"
, node.get_SourcePositionStart());
}
}
private void checkForDuplicates(ASTVariable node){
......
......@@ -75,6 +75,13 @@ public class ArchitectureSymbol extends ArchitectureSymbolTOP {
}
}
public List<LayerSymbol> getFirstLayers(){
if (!getBody().isResolved()){
resolve();
}
return getBody().getFirstAtomicLayers();
}
public boolean isResolved(){
return getBody().isResolved();
}
......
......@@ -20,8 +20,7 @@
*/
package de.monticore.lang.monticar.cnnarch._symboltable;
import de.monticore.lang.monticar.cnnarch.helper.Constraints;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedVariables;
import de.monticore.lang.monticar.cnnarch.predefined.AllPredefinedVariables;
import de.monticore.symboltable.CommonSymbol;
import de.monticore.symboltable.MutableScope;
import de.monticore.symboltable.Symbol;
......@@ -67,7 +66,7 @@ public class ArgumentSymbol extends CommonSymbol {
}
protected void setRhs(ArchExpressionSymbol rhs) {
if (getName().equals(PredefinedVariables.FOR_NAME)
if (getName().equals(AllPredefinedVariables.FOR_NAME)
&& rhs instanceof ArchSimpleExpressionSymbol
&& (!rhs.getValue().isPresent() || !rhs.getValue().get().equals(1))){
this.rhs = ArchRangeExpressionSymbol.of(
......@@ -75,7 +74,7 @@ public class ArgumentSymbol extends CommonSymbol {
(ArchSimpleExpressionSymbol) rhs,
false);
}
else if (getName().equals(PredefinedVariables.CARDINALITY_NAME)
else if (getName().equals(AllPredefinedVariables.CARDINALITY_NAME)
&& rhs instanceof ArchSimpleExpressionSymbol
&& (!rhs.getValue().isPresent() || !rhs.getValue().get().equals(1))) {
this.rhs = ArchRangeExpressionSymbol.of(
......@@ -121,7 +120,7 @@ public class ArgumentSymbol extends CommonSymbol {
List<ArgumentSymbol> serialArgumentList = new ArrayList<>(serialElementList.size());
for (ArchSimpleExpressionSymbol element : serialElementList){
ArchSimpleExpressionSymbol value = element;
if (getName().equals(PredefinedVariables.FOR_NAME) || getName().equals(PredefinedVariables.CARDINALITY_NAME)){
if (getName().equals(AllPredefinedVariables.FOR_NAME) || getName().equals(AllPredefinedVariables.CARDINALITY_NAME)){
value = ArchSimpleExpressionSymbol.of(1);
}
......
......@@ -22,19 +22,14 @@ package de.monticore.lang.monticar.cnnarch._symboltable;
import de.monticore.lang.math.math._ast.ASTMathExpression;
import de.monticore.lang.math.math._ast.ASTMathFalseExpression;
import de.monticore.lang.math.math._ast.ASTMathTrueExpression;
import de.monticore.lang.math.math._symboltable.MathSymbolTableCreator;
import de.monticore.lang.math.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.math.math._symboltable.expression.MathNameExpressionSymbol;
import de.monticore.lang.math.math._visitor.MathVisitor;
import de.monticore.lang.monticar.cnnarch._ast.*;
import de.monticore.lang.monticar.cnnarch._visitor.CNNArchInheritanceVisitor;
import de.monticore.lang.monticar.cnnarch._visitor.CNNArchVisitor;
import de.monticore.lang.monticar.cnnarch._visitor.CommonCNNArchDelegatorVisitor;
import de.monticore.lang.monticar.cnnarch.helper.Constraints;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedMethods;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedVariables;
import de.monticore.lang.monticar.cnnarch.predefined.AllPredefinedMethods;
import de.monticore.lang.monticar.cnnarch.predefined.AllPredefinedVariables;
import de.monticore.lang.monticar.types2._ast.ASTType;
import de.monticore.symboltable.*;
import de.se_rwth.commons.logging.Log;
......@@ -140,12 +135,12 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
}
private void createPredefinedConstants(){
addToScope(PredefinedVariables.createTrueConstant());
addToScope(PredefinedVariables.createFalseConstant());
addToScope(AllPredefinedVariables.createTrueConstant());
addToScope(AllPredefinedVariables.createFalseConstant());
}
private void createPredefinedMethods(){
for (MethodDeclarationSymbol sym : PredefinedMethods.createList()){
for (MethodDeclarationSymbol sym : AllPredefinedMethods.createList()){
addToScope(sym);
}
}
......@@ -413,11 +408,13 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
public void visit(ASTIOLayer node) {
Optional<IODeclarationSymbol> optIODef = currentScope().get().resolve(node.getName(), IODeclarationSymbol.KIND);
int arrayLength = 1;
boolean isInput = false;
if (optIODef.isPresent()){
arrayLength = optIODef.get().getArrayLength();
isInput = optIODef.get().isInput();
}
if (!node.getIndex().isPresent() && arrayLength > 1){
if (!node.getIndex().isPresent() && arrayLength > 1 && isInput){
List<LayerSymbol> ioLayers = new ArrayList<>(arrayLength);
IOLayerSymbol ioLayer;
for (int i = 0; i < arrayLength; i++){
......@@ -455,7 +452,7 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
@Override
public void visit(ASTArrayAccessLayer node) {
MethodLayerSymbol methodLayer = new MethodLayerSymbol(PredefinedMethods.GET_NAME);
MethodLayerSymbol methodLayer = new MethodLayerSymbol(AllPredefinedMethods.GET_NAME);
addToScopeAndLinkWithNode(methodLayer, node);
}
......
......@@ -20,8 +20,10 @@
*/
package de.monticore.lang.monticar.cnnarch._symboltable;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.symboltable.MutableScope;
import de.monticore.symboltable.Symbol;
import de.se_rwth.commons.logging.Log;
import java.util.*;
......@@ -51,17 +53,26 @@ public class CompositeLayerSymbol extends LayerSymbol {
for (LayerSymbol current : layers){
if (previous != null && !isParallel()){
current.setInputLayer(previous);
previous.setOutputLayer(current);
}
else {
if (getInputLayer().isPresent()){
current.setInputLayer(getInputLayer().get());
}
if (getOutputLayer().isPresent()){
current.setOutputLayer(getOutputLayer().get());
}
}
previous = current;
}
this.layers = layers;
}
@Override
public boolean isAtomic() {
return getLayers().isEmpty();
}
@Override
public void setInputLayer(LayerSymbol inputLayer) {
super.setInputLayer(inputLayer);
......@@ -78,17 +89,53 @@ public class CompositeLayerSymbol extends LayerSymbol {
}
@Override
public boolean isCompositeLayer(){
return true;
public void setOutputLayer(LayerSymbol outputLayer) {
super.setOutputLayer(outputLayer);
if (isParallel()){
for (LayerSymbol current : getLayers()){
current.setOutputLayer(outputLayer);
}
}
else {
if (!getLayers().isEmpty()){
getLayers().get(getLayers().size()-1).setOutputLayer(outputLayer);
}
}
}
/*@Override
public void reset() {
for (LayerSymbol layer : getLayers()){
layer.reset();
@Override
public List<LayerSymbol> getFirstAtomicLayers() {
if (getLayers().isEmpty()){
return Collections.singletonList(this);
}
else if (isParallel()){
List<LayerSymbol> firstLayers = new ArrayList<>();
for (LayerSymbol layer : getLayers()){
firstLayers.addAll(layer.getFirstAtomicLayers());
}
return firstLayers;
}
else {
return getLayers().get(0).getFirstAtomicLayers();
}
}
@Override
public List<LayerSymbol> getLastAtomicLayers() {
if (getLayers().isEmpty()){
return Collections.singletonList(this);
}
else if (isParallel()){
List<LayerSymbol> lastLayers = new ArrayList<>();
for (LayerSymbol layer : getLayers()){
lastLayers.addAll(layer.getLastAtomicLayers());
}
return lastLayers;
}
setUnresolvableVariables(null);
}*/
else {
return getLayers().get(getLayers().size()-1).getLastAtomicLayers();
}
}
@Override
public Set<VariableSymbol> resolve() throws ArchResolveException {
......@@ -130,15 +177,14 @@ public class CompositeLayerSymbol extends LayerSymbol {
}
@Override
protected List<ShapeSymbol> computeOutputShapes() {
if (layers.size() == 0){
public List<ShapeSymbol> computeOutputShapes() {
if (getLayers().isEmpty()){
return getInputLayer().get().getOutputShapes();
}
else {
if (isParallel()){
List<ShapeSymbol> outputShapes = new ArrayList<>(getLayers().size());
for (LayerSymbol layer : getLayers()){
//todo: assure with coco that last layer in each parallel group has only one outputShape
if (layer.getOutputShapes().size() != 0){
outputShapes.add(layer.getOutputShapes().get(0));
}
......@@ -154,6 +200,24 @@ public class CompositeLayerSymbol extends LayerSymbol {
}
}
@Override
public void checkInputAndOutput() {
if (!getLayers().isEmpty()){
if (isParallel()){
for (LayerSymbol layer : getLayers()){
if (layer.getOutputShapes().size() > 1){
Log.error("0" + ErrorCodes.MISSING_MERGE + " Missing merge layer (Add(), Concatenate, [i]). " +
"Each stream at the end of a parallel layer can only have one output stream. "
, getSourcePosition());
}
}
}
for (LayerSymbol layer : getLayers()){
layer.checkInputAndOutput();
}
}
}
@Override
public Optional<Integer> getParallelLength() {
if (isParallel()){
......@@ -193,6 +257,9 @@ public class CompositeLayerSymbol extends LayerSymbol {
for (LayerSymbol layer : getLayers()){
layers.add(layer.copy());
}
if (getAstNode().isPresent()){
copy.setAstNode(getAstNode().get());
}
copy.setLayers(layers);
return copy;
}
......
......@@ -18,9 +18,9 @@
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* *******************************************************************************
*/
package de.monticore.lang.monticar.cnnarch.helper;
package de.monticore.lang.monticar.cnnarch._symboltable;
import de.monticore.lang.monticar.cnnarch._symboltable.*;
import de.monticore.lang.monticar.cnnarch.predefined.AllPredefinedMethods;
import de.se_rwth.commons.SourcePosition;
import de.se_rwth.commons.logging.Log;
......@@ -151,7 +151,9 @@ public enum Constraints {
public boolean isValid(ArchSimpleExpressionSymbol exp) {
Optional<String> optString= exp.getStringValue();
if (optString.isPresent()){
if (optString.get().equals(PredefinedMethods.PADDING_VALID) || optString.get().equals(PredefinedMethods.PADDING_SAME)){
if (optString.get().equals(AllPredefinedMethods.PADDING_VALID)
|| optString.get().equals(AllPredefinedMethods.PADDING_SAME)
|| optString.get().equals(AllPredefinedMethods.PADDING_NO_LOSS)){
return true;
}
}
......@@ -160,7 +162,7 @@ public enum Constraints {
@Override
protected String msgString() {
return PredefinedMethods.PADDING_VALID + " or " + PredefinedMethods.PADDING_SAME;
return AllPredefinedMethods.PADDING_VALID + " or " + AllPredefinedMethods.PADDING_SAME;
}
};
......
......@@ -20,9 +20,10 @@
*/
package de.monticore.lang.monticar.cnnarch._symboltable;
import de.monticore.lang.monticar.cnnarch.helper.Constraints;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.symboltable.MutableScope;
import de.monticore.symboltable.Symbol;
import de.se_rwth.commons.logging.Log;
import java.util.*;
......@@ -74,13 +75,20 @@ public class IOLayerSymbol extends LayerSymbol {
return getDefinition().isOutput();
}
/*@Override
public void reset() {
setUnresolvableVariables(null);
if (getArrayAccess().isPresent()){
getArrayAccess().get().reset();
}
}*/
@Override
public boolean isAtomic(){
return true;
}
@Override
public List<LayerSymbol> getFirstAtomicLayers() {
return Collections.singletonList(this);
}
@Override
public List<LayerSymbol> getLastAtomicLayers() {
return Collections.singletonList(this);
}
@Override
public Set<VariableSymbol> resolve() throws ArchResolveException {
......@@ -118,13 +126,10 @@ public class IOLayerSymbol extends LayerSymbol {
}
@Override
protected List<ShapeSymbol> computeOutputShapes() {
public List<ShapeSymbol> computeOutputShapes() {
List<ShapeSymbol> outputShapes;
if (isInput()){
outputShapes = new ArrayList<>(getDefinition().getArrayLength());
for (int i = 0; i < getDefinition().getArrayLength(); i++){
outputShapes.add(getDefinition().getShape());
}
outputShapes = Collections.singletonList(getDefinition().getShape());
}
else {
outputShapes = Collections.emptyList();
......@@ -132,6 +137,32 @@ public class IOLayerSymbol extends LayerSymbol {
return outputShapes;
}
@Override
public void checkInputAndOutput() {
if (isOutput()){
List<ShapeSymbol> inputShapes = getInputShapes();
if (inputShapes.isEmpty()){
Log.error("0" + ErrorCodes.INVALID_LAYER_INPUT + " Invalid number of input streams. " +
"The number of input streams to the output " + getName() + " is 0."
, getSourcePosition());
}
else{
int size = getDefinition().getArrayLength();
if (getArrayAccess().isPresent()){
size = 1;
}
if (inputShapes.size() != size){
Log.error("0" + ErrorCodes.INVALID_LAYER_INPUT + " Invalid number of input streams. " +
"The output " + getName() + " is an array of size " + size +
" but the number of input streams is " + inputShapes.size() + "."
, getSourcePosition());
}
}
//todo check type
}
}
@Override
public Optional<Integer> getParallelLength() {
return Optional.of(getDefinition().getArrayLength());
......
......@@ -24,16 +24,14 @@ import de.monticore.symboltable.CommonScopeSpanningSymbol;
import de.monticore.symboltable.MutableScope;
import de.se_rwth.commons.Joiners;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.*;
public abstract class LayerSymbol extends CommonScopeSpanningSymbol {
public static final LayerKind KIND = new LayerKind();
private LayerSymbol inputLayer;
private LayerSymbol outputLayer;
private List<ShapeSymbol> outputShapes = null;
private Set<VariableSymbol> unresolvableVariables = null;
......@@ -59,6 +57,15 @@ public abstract class LayerSymbol extends CommonScopeSpanningSymbol {
this.inputLayer = inputLayer;
}
public Optional<LayerSymbol> getOutputLayer() {
return Optional.ofNullable(outputLayer);
}
public void setOutputLayer(LayerSymbol outputLayer) {
this.outputLayer = outputLayer;
}
//only call after resolve
public List<ShapeSymbol> getOutputShapes() {
if (outputShapes == null){
outputShapes = computeOutputShapes();
......@@ -70,20 +77,46 @@ public abstract class LayerSymbol extends CommonScopeSpanningSymbol {
this.outputShapes = outputShapes;
}
public List<ShapeSymbol> getInputShapes() {
if (getInputLayer().isPresent()){
return getInputLayer().get().getOutputShapes();
}
else {
return new ArrayList<>();
}
}
/**
* only call after resolve():
* @return returns the atomic layers which get the output of this layer as input.
*/
public List<LayerSymbol> getNext(){
if (getOutputLayer().isPresent()){
return getOutputLayer().get().getFirstAtomicLayers();
}
else {
return new ArrayList<>();