Unverified Commit 94b95cfe authored by Thomas Michael Timmermanns's avatar Thomas Michael Timmermanns Committed by GitHub

Timmermanns (#15)

Added Cocos and tests
parent 65852675
......@@ -105,7 +105,11 @@ architecture ExampleNetwork{
```
## Methods
It is possible to avoid redundancy in the architecture through the declaration of new methods. The method declaration is similar to python. Each parameter can have a default value that makes it an optional argument. The method call is also similar to python but, in contrast to python, it is necessary to specify the name of each argument. The body of a new method is constructed from other layers including other user-defined methods. However, recursion is not allowed. The compiler will throw an error if recursion occurs. The following is a example of multiple method declarations.
It is possible to declare of new methods. The method declaration is similar to python.
Each parameter can have a default value that makes it an optional argument.
The method call is also similar to python but, in contrast to python, it is necessary to specify the name of each argument.
The body of a new method is constructed from other layers including other user-defined methods. However, recursion is not allowed.
The compiler will throw an error if recursion occurs. The following is a example of multiple method declarations.
```
def conv(filter, channels, stride=1, act=true){
Convolution(kernel=(filter,filter), channels=channels, stride=(stride,stride)) ->
......@@ -130,7 +134,10 @@ It is possible to avoid redundancy in the architecture through the declaration o
The method `resLayer` in this example corresponds to a building block of a Residual Network. The `If` argument is a special argument which is explained in the next section.
## Special Arguments
There exists special structural arguments which can be used in each method. These are `->`, `|` and `If`. `->` and `|` can only be positive integers and `If` can only be a boolean. The argument `If` does not nothing if it is true and removes the layer completely if it is false. The other two arguments create a repetition of the method. We will show their effect with examples. Assuming `a` is a method without required arguments, then `a(-> = 3)->` is equal to `a()->a()->a()->`, `a(| = 3)->` is equal to `(a() | a() | a())->` and `a(-> = 3, | = 2->` is equal to `(a()->a()->a() | a()->a()->a())->`.
There exists special structural arguments which can be used in each method. These are `->`, `|` and `If`. `->` and `|` can only be positive integers and `If` can only be a boolean.
The argument `If` does not nothing if it is true and removes the layer completely if it is false. The other two arguments create a repetition of the method.
We will show their effect with examples. Assuming `a` is a method without required arguments,
then `a(-> = 3)->` is equal to `a()->a()->a()->`, `a(| = 3)->` is equal to `(a() | a() | a())->` and `a(-> = 3, | = 2->)` is equal to `(a()->a()->a() | a()->a()->a())->`.
## Argument Sequences
It is also possible to create a repetition of a method in another way through the use of argument sequences. The following are valid sequences: `[2->5->3]`, `[true|false|false]`, `[2->1|4->4->6]`, `[ |2->3]`, `1->..->5` and `3|..|-2`. All values in these examples could also be replaced by variable names or expressions. The first three are standard sequences and the last two are intervals. An interval can be translated to a standard sequence. The interval `3|..|-2` is equal to `[3|2|1|0|-1|-2]` and `1->..->5` is equal to `[1->2->3->4->5]`.
......@@ -153,7 +160,7 @@ However, the line `m(a=[5->3], b=[2|4->6], c=2)->` would throw an error because
## Expressions
Currently, the working expression operators are the basic arithmetic operators "+", "-", "\*", "/", the logical operators "&&", "||" and for most cases the comparison operators "==", "!=", "<", ">", "<=", ">=". The comparison operators do not work reliably for the comparison of tuple (they only compare the last element in the tuples).
## Another Example
## Advanced Example
This version of Alexnet, which uses method construction, argument sequences and special arguments, is identical to the one in the section Basic Structure.
```
architecture Alexnet{
......@@ -297,6 +304,5 @@ All methods with the exception of *Concatenate*, *Add*, *Get* and *Split* can on
Opposite of *Concatenate*. Handles a single input stream and splits it into *n* output streams. The output streams have the same height and width as the input stream and a number channels which is in general `input_channels / n`. The last output stream will have a higher number of channels than the other if `input_channels` is not divisible by `n`.
* **n** (integer > 0, required): The number of output streams. Cannot be higher than the number of input channels.
<br><br>
......@@ -25,6 +25,7 @@ public class CNNArchPostResolveCocos {
public static CNNArchCoCoChecker createChecker() {
return new CNNArchCoCoChecker()
.addCoCo(new CheckLayerInputs())
.addCoCo(new CheckIOAccessAndIOMissing())
.addCoCo(new CheckIOType());
}
......
......@@ -25,11 +25,14 @@ public class CNNArchPreResolveCocos {
public static CNNArchCoCoChecker createChecker() {
return new CNNArchCoCoChecker()
.addCoCo(new CheckIOName())
.addCoCo(new CheckNameExpression())
.addCoCo(new CheckMethodLayer())
.addCoCo(new CheckVariable())
.addCoCo(new CheckIODeclaration())
.addCoCo(new CheckIOLayer())
.addCoCo(new CheckVariableName())
.addCoCo(new CheckIOShape())
.addCoCo(new CheckUnknownIO())
.addCoCo(new CheckArgument())
.addCoCo(new CheckMethodDeclaration());
.addCoCo(new CheckMethodName())
.addCoCo(new CheckMethodRecursion());
}
}
\ No newline at end of file
......@@ -36,12 +36,14 @@ public class CheckArgument implements CNNArchASTArgumentCoCo {
, node.get_SourcePositionStart());
}
else {
//check argument constraints before resolve.
if (argument.getRhs().isResolvable()) {
/*if (argument.getRhs().getValue().isPresent()){
argument.checkConstraints();
}*/
/*if (argument.getRhs().isResolvable()) {
argument.getRhs().resolveOrError();
argument.checkConstraints();
argument.getRhs().reset();
}
}*/
}
}
......
/**
*
* ******************************************************************************
* 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;
import de.monticore.lang.monticar.cnnarch._symboltable.IODeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.IOLayerSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.Joiners;
import de.se_rwth.commons.logging.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class CheckIOAccessAndIOMissing implements CNNArchASTIODeclarationCoCo {
@Override
public void check(ASTIODeclaration node) {
IODeclarationSymbol ioDeclaration = (IODeclarationSymbol) node.getSymbol().get();
if (ioDeclaration.getArrayLength() == 1){
checkSingleIO(ioDeclaration);
}
else {
checkIOArray(ioDeclaration);
}
}
private void checkSingleIO(IODeclarationSymbol ioDeclaration){
if (ioDeclaration.getConnectedLayers().isEmpty()){
Log.error("0" + ErrorCodes.MISSING_IO + " Input or output '" + ioDeclaration.getName() + "' was declared but never used."
, ioDeclaration.getSourcePosition());
}
else {
for (IOLayerSymbol layer : ioDeclaration.getConnectedLayers()){
if (layer.getArrayAccess().isPresent()){
Log.error("0" + ErrorCodes.INVALID_ARRAY_ACCESS + " Invalid IO array access. " +
"This input or output is not an array."
, layer.getSourcePosition());
}
}
}
}
private void checkIOArray(IODeclarationSymbol ioDeclaration){
List<Integer> unusedIndices = IntStream.range(0, ioDeclaration.getArrayLength()).boxed().collect(Collectors.toList());
for (IOLayerSymbol layer : ioDeclaration.getConnectedLayers()){
if (layer.getArrayAccess().isPresent()){
Optional<Integer> arrayAccess = layer.getArrayAccess().get().getIntValue();
if (arrayAccess.isPresent() && arrayAccess.get() >= 0 && arrayAccess.get() < ioDeclaration.getArrayLength()){
unusedIndices.remove(arrayAccess.get());
}
else {
Log.error("0" + ErrorCodes.INVALID_ARRAY_ACCESS + " The IO array access value must be an integer between 0 and " + (ioDeclaration.getArrayLength()-1) + ". " +
"The current value is: " + layer.getArrayAccess().get().getValue().get().toString()
, layer.getSourcePosition());
}
}
else{
unusedIndices = new ArrayList<>();
}
}
if (!unusedIndices.isEmpty()){
Log.error("0" + ErrorCodes.MISSING_IO + " Input or output array with name '" + ioDeclaration.getName() + "' was declared but not used. " +
"The following indices are unused: " + Joiners.COMMA.join(unusedIndices) + "."
, ioDeclaration.getSourcePosition());
}
}
}
......@@ -21,12 +21,26 @@
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTIODeclaration;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.logging.Log;
public class CheckIODeclaration implements CNNArchASTIODeclarationCoCo {
import java.util.HashSet;
import java.util.Set;
public class CheckIOName implements CNNArchASTIODeclarationCoCo {
Set<String> ioNames = new HashSet<>();
@Override
public void check(ASTIODeclaration node) {
//todo: check io shape; only 1 and 3 is allowed
if (ioNames.contains(node.getName())){
Log.error("0" + ErrorCodes.DUPLICATED_NAME_CODE + " Duplicated IO name. " +
"The name '" + node.getName() + "' is already used."
, node.get_SourcePositionStart());
}
else {
ioNames.add(node.getName());
}
}
}
/**
*
* ******************************************************************************
* 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.ASTDimension;
import de.monticore.lang.monticar.cnnarch._ast.ASTIODeclaration;
import de.monticore.lang.monticar.cnnarch._symboltable.ShapeSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.lang.monticar.types2._ast.ASTUnitNumberResolution;
import de.se_rwth.commons.logging.Log;
import org.jscience.mathematics.number.Rational;
import java.util.Optional;
public class CheckIOShape implements CNNArchASTIODeclarationCoCo {
@Override
public void check(ASTIODeclaration node) {
int shapeSize = node.getType().getShape().getDimensions().size();
if (shapeSize != 1 && shapeSize != 3){
Log.error("0" + ErrorCodes.INVALID_IO_SHAPE + " Invalid shape. " +
"IO Shape has to be either {height, width, channels} or {channels}."
, node.getType().getShape().get_SourcePositionStart());
}
else {
for (ASTDimension dimension : node.getType().getShape().getDimensions()){
Rational rational;
if (dimension.getIntLiteral().isPresent()){
rational = dimension.getIntLiteral().get().getNumber().get();
}
else {
rational = dimension.getIOVariable().get().getIntRhs().get().getNumber().get();
}
if (rational.getDivisor().intValue() != 1 || !rational.isPositive()){
Log.error("0" + ErrorCodes.INVALID_IO_SHAPE + " Invalid shape. " +
"The dimension can only be defined by a positive integer."
, dimension.get_SourcePositionStart());
}
}
}
}
}
/**
*
* ******************************************************************************
* 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.ASTMethodDeclaration;
import de.monticore.lang.monticar.cnnarch._symboltable.CompositeLayerSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.LayerSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.MethodDeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.MethodLayerSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.logging.Log;
import java.util.HashSet;
import java.util.Set;
public class CheckMethodName implements CNNArchASTMethodDeclarationCoCo {
Set<String> methodNames = new HashSet<>();
@Override
public void check(ASTMethodDeclaration node) {
String name = node.getName();
if (name.isEmpty() || !Character.isLowerCase(name.codePointAt(0))){
Log.error("0" + ErrorCodes.ILLEGAL_NAME_CODE + " Illegal name: " + name +
". All new variable and method names have to start with a lowercase letter. "
, node.get_SourcePositionStart());
}
if (methodNames.contains(name)){
Log.error("0" + ErrorCodes.DUPLICATED_NAME_CODE + " Duplicated method name. " +
"The name '" + name + "' is already used."
, node.get_SourcePositionStart());
}
else {
methodNames.add(name);
}
}
}
......@@ -31,33 +31,13 @@ import de.se_rwth.commons.logging.Log;
import java.util.HashSet;
import java.util.Set;
public class CheckMethodDeclaration implements CNNArchASTMethodDeclarationCoCo {
public class CheckMethodRecursion implements CNNArchASTMethodDeclarationCoCo {
//for duplication check
Set<String> methodNames = new HashSet<>();
//for recursion check
Set<MethodDeclarationSymbol> seenMethods = new HashSet<>();
boolean done;
@Override
public void check(ASTMethodDeclaration node) {
String name = node.getName();
if (name.isEmpty() || !Character.isLowerCase(name.codePointAt(0))){
Log.error("0" + ErrorCodes.ILLEGAL_NAME_CODE + " Illegal name: " + name +
". All new variable and method names have to start with a lowercase letter. "
, node.get_SourcePositionStart());
}
if (methodNames.contains(name)){
Log.error("0" + ErrorCodes.DUPLICATED_NAME_CODE + " Duplicated name. " +
"The name '" + name + "' is already defined."
, node.get_SourcePositionStart());
}
else {
methodNames.add(name);
}
done = false;
MethodDeclarationSymbol method = (MethodDeclarationSymbol) node.getSymbol().get();
checkForRecursion(method, method.getBody());
......
/**
*
* ******************************************************************************
* 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.math.math._ast.ASTMathNameExpression;
import de.monticore.lang.math.math._cocos.MathASTMathNameExpressionCoCo;
import de.monticore.lang.math.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.math.math._symboltable.expression.MathNameExpressionSymbol;
import de.monticore.lang.monticar.cnnarch._ast.ASTArchSimpleExpression;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchSimpleExpressionSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.VariableSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.lang.monticar.cnnarch.helper.ExpressionHelper;
import de.se_rwth.commons.logging.Log;
import java.util.Optional;
public class CheckNameExpression implements CNNArchASTArchSimpleExpressionCoCo {
@Override
public void check(ASTArchSimpleExpression node) {
ArchSimpleExpressionSymbol expression = (ArchSimpleExpressionSymbol) node.getSymbol().get();
if (expression.getMathExpression().isPresent()){
MathExpressionSymbol mathExpression = expression.getMathExpression().get();
for (MathExpressionSymbol subMathExp : ExpressionHelper.createSubExpressionList(mathExpression)){
if (subMathExp instanceof MathNameExpressionSymbol){
String name = ((MathNameExpressionSymbol) subMathExp).getNameToAccess();
Optional<VariableSymbol> variable = node.getEnclosingScope().get().resolve(name, VariableSymbol.KIND);
if (!variable.isPresent()){
Log.error("0" + ErrorCodes.UNKNOWN_VARIABLE_NAME + " Unknown variable name. " +
"The variable '" + name + "' does not exist. "
, subMathExp.getSourcePosition());
}
}
}
}
}
}
......@@ -28,7 +28,7 @@ import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.symboltable.Symbol;
import de.se_rwth.commons.logging.Log;
public class CheckIOLayer implements CNNArchASTIOLayerCoCo {
public class CheckUnknownIO implements CNNArchASTIOLayerCoCo {
@Override
public void check(ASTIOLayer node) {
......
......@@ -22,8 +22,6 @@ 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._symboltable.Constraints;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.lang.monticar.cnnarch.predefined.AllPredefinedVariables;
import de.monticore.symboltable.Symbol;
......@@ -33,18 +31,15 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class CheckVariable implements CNNArchASTVariableCoCo {
public class CheckVariableName implements CNNArchASTVariableCoCo {
Set<String> variableNames = new HashSet<>();
@Override
public void check(ASTVariable node) {
checkForIllegalNames(node);
checkForDuplicates(node);
checkConstraints(node);
}
private void checkForIllegalNames(ASTVariable node){
......@@ -68,35 +63,26 @@ public class CheckVariable implements CNNArchASTVariableCoCo {
private void checkForDuplicates(ASTVariable node){
String name = node.getName();
boolean duplicated = false;
if (variableNames.contains(name)){
if (node instanceof ASTParameter){
Collection<Symbol> collection = ((ASTParameter) node).getEnclosingScope().get().getLocalSymbols().get(name);
if (collection.size() > 1){
duplicated = true;
Collection<Symbol> allParametersWithSameName = node.getEnclosingScope().get().getLocalSymbols().get(name);
if (allParametersWithSameName.size() > 1){
duplicationError(node);
}
}
else {
duplicated = true;
duplicationError(node);
}
}
else{
variableNames.add(name);
}
if (duplicated){
Log.error("0" + ErrorCodes.DUPLICATED_NAME_CODE + " Duplicated name: " + name +
". This name is already defined."
, node.get_SourcePositionStart());
}
}
private void checkConstraints(ASTVariable node){
VariableSymbol variable = (VariableSymbol) node.getSymbol().get();
if (variable.hasExpression() && variable.getExpression().isResolvable()) {
variable.getExpression().resolveOrError();
Constraints.check(variable);
}
private void duplicationError(ASTVariable node){
Log.error("0" + ErrorCodes.DUPLICATED_NAME_CODE + " Duplicated variable name. " +
"The name '" + node.getName() + "' is already used."
, node.get_SourcePositionStart());
}
}
}
\ No newline at end of file
......@@ -104,17 +104,23 @@ public class ArchSimpleExpressionSymbol extends ArchExpressionSymbol {
if (exp instanceof MathNameExpressionSymbol) {
String name = ((MathNameExpressionSymbol) exp).getNameToAccess();
Optional<VariableSymbol> variable = getEnclosingScope().resolve(name, VariableSymbol.KIND);
//todo: implement coco to check isPresent()
if (!allVariables.contains(variable.get())) {
allVariables.add(variable.get());
if (variable.get().hasExpression()) {
if (!variable.get().getExpression().isResolved()) {
variable.get().getExpression().computeUnresolvableVariables(unresolvableVariables, allVariables);
if (variable.isPresent()) {
if (!allVariables.contains(variable.get())) {
allVariables.add(variable.get());
if (variable.get().hasExpression()) {
if (!variable.get().getExpression().isResolved()) {
variable.get().getExpression().computeUnresolvableVariables(unresolvableVariables, allVariables);
}
} else {
unresolvableVariables.add(variable.get());
}
}
else {
unresolvableVariables.add(variable.get());
}
}
else {
unresolvableVariables.add(new VariableSymbol.Builder()
.name(name)
.type(VariableType.UNKNOWN)
.build());
}
}
}
......
......@@ -183,16 +183,19 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
public void endVisit(ASTShape node) {
ShapeSymbol sym = (ShapeSymbol) node.getSymbol().get();
if (node.getDimensions().size() == 1){
sym.setChannels((ArchSimpleExpressionSymbol) node.getDimensions().get(0).getSymbol().get());
ArchSimpleExpressionSymbol channels = (ArchSimpleExpressionSymbol) node.getDimensions().get(0).getSymbol().get();
sym.setChannels(channels);
}
else if (node.getDimensions().size() == 3){
sym.setHeight((ArchSimpleExpressionSymbol) node.getDimensions().get(ShapeSymbol.HEIGHT_INDEX - 1).getSymbol().get());
sym.setWidth((ArchSimpleExpressionSymbol) node.getDimensions().get(ShapeSymbol.WIDTH_INDEX - 1).getSymbol().get());
sym.setChannels((ArchSimpleExpressionSymbol) node.getDimensions().get(ShapeSymbol.CHANNEL_INDEX - 1).getSymbol().get());
ArchSimpleExpressionSymbol height = (ArchSimpleExpressionSymbol) node.getDimensions().get(ShapeSymbol.HEIGHT_INDEX - 1).getSymbol().get();
ArchSimpleExpressionSymbol width = (ArchSimpleExpressionSymbol) node.getDimensions().get(ShapeSymbol.WIDTH_INDEX - 1).getSymbol().get();
ArchSimpleExpressionSymbol channels = (ArchSimpleExpressionSymbol) node.getDimensions().get(ShapeSymbol.CHANNEL_INDEX - 1).getSymbol().get();
sym.setHeight(height);
sym.setWidth(width);
sym.setChannels(channels);
}
else {
//todo
throw new IllegalStateException("todo: incorrect shape");
//do nothing; will be checked in coco
}
addToScopeAndLinkWithNode(sym, node);
}
......@@ -219,7 +222,6 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
.name(node.getName())
.type(VariableType.IOVARIABLE)
.defaultValue(defaultValue)
.constraints(Constraints.INTEGER, Constraints.POSITIVE)
.build();
//addToScope(ArchSimpleExpressionSymbol.of(variable));
addToScopeAndLinkWithNode(variable, node);
......@@ -282,7 +284,7 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
else if (ast.getTupleExpression().isPresent()){
mathExp = (MathExpressionSymbol) ast.getTupleExpression().get().getSymbol().get();
}
else {
else{
sym.setValue(ast.getString().get().getValue());
}
sym.setMathExpression(mathExp);
......@@ -406,12 +408,13 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
@Override
public void visit(ASTIOLayer node) {
Optional<IODeclarationSymbol> optIODef = currentScope().get().resolve(node.getName(), IODeclarationSymbol.KIND);
Collection<IODeclarationSymbol> ioDefCollection = currentScope().get().<IODeclarationSymbol>resolveMany(node.getName(), IODeclarationSymbol.KIND);
int arrayLength = 1;
boolean isInput = false;
if (optIODef.isPresent()){
arrayLength = optIODef.get().getArrayLength();
isInput = optIODef.get().isInput();
if (!ioDefCollection.isEmpty()){
IODeclarationSymbol ioDeclaration = ioDefCollection.iterator().next();
arrayLength = ioDeclaration.getArrayLength();
isInput = ioDeclaration.isInput();