Unverified Commit 12c7fe16 authored by Thomas Michael Timmermanns's avatar Thomas Michael Timmermanns Committed by GitHub
Browse files

Merge pull request #13 from EmbeddedMontiArc/timmermanns

Added CoCos and tests.
parents 683cbacd 3450d47d
......@@ -69,8 +69,9 @@ grammar CNNArch extends de.monticore.lang.math.Math {
ArchSimpleExpression = (arithmeticExpression:MathArithmeticExpression
| booleanExpression:MathBooleanExpression
| tupleExpression:TupleExpression);
| tupleExpression:TupleExpression
| string:StringLiteral);
TupleExpression implements MathExpression = "(" expressions:MathArithmeticExpression "," expressions:(MathArithmeticExpression || ",")* ")";
TupleExpression implements MathExpression = "(" expressions:MathExpression "," expressions:(MathExpression || ",")* ")";
}
\ No newline at end of file
......@@ -24,7 +24,8 @@ public class CNNArchPostResolveCocos {
public static CNNArchCoCoChecker createChecker() {
return new CNNArchCoCoChecker()
.addCoCo(new CheckVariableConstraints());
.addCoCo(new CheckLayerInputs())
.addCoCo(new CheckIOType());
}
}
......@@ -35,6 +35,14 @@ public class CheckArgument implements CNNArchASTArgumentCoCo {
"Parameter with name '" + node.getName() + "' does not exist."
, node.get_SourcePositionStart());
}
else {
//check argument constraints before resolve.
if (argument.getRhs().isResolvable()) {
argument.getRhs().resolveOrError();
argument.checkConstraints();
argument.getRhs().reset();
}
}
}
}
......@@ -20,31 +20,13 @@
*/
package de.monticore.lang.monticar.cnnarch._cocos;
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._ast.ASTArchitecture;
import java.util.HashSet;
import java.util.Set;
public class CheckVariableConstraints implements CNNArchASTVariableCoCo {
/*@Override
public void check(ASTArchitecture node) {
ArchitectureSymbol architecture = (ArchitectureSymbol) node.getSymbol().get();
}*/
Set<VariableSymbol> variableSet = new HashSet<>();
public class CheckIOType implements CNNArchASTArchitectureCoCo {
@Override
public void check(ASTVariable node) {
VariableSymbol variable = (VariableSymbol) node.getSymbol().get();
if (!variableSet.contains(variable)) {
if (variable.hasExpression() && variable.getExpression().isResolvable()) {
variable.getExpression().resolveOrError();
Constraints.check(variable);
}
}
variableSet.add(variable);
public void check(ASTArchitecture node) {
//todo:
}
}
\ No newline at end of file
}
/**
*
* ******************************************************************************
* 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.ASTArchitecture;
public class CheckLayerInputs implements CNNArchASTArchitectureCoCo {
@Override
public void check(ASTArchitecture node) {
//todo:
}
}
......@@ -37,7 +37,7 @@ public class CheckMethodDeclaration implements CNNArchASTMethodDeclarationCoCo {
Set<String> methodNames = new HashSet<>();
//for recursion check
Set<MethodDeclarationSymbol> seenMethods = new HashSet<>();
boolean done = false;
boolean done;
@Override
......@@ -58,6 +58,7 @@ public class CheckMethodDeclaration implements CNNArchASTMethodDeclarationCoCo {
methodNames.add(name);
}
done = false;
MethodDeclarationSymbol method = (MethodDeclarationSymbol) node.getSymbol().get();
checkForRecursion(method, method.getBody());
}
......
......@@ -40,7 +40,7 @@ public class CheckMethodLayer implements CNNArchASTMethodLayerCoCo{
for (ASTArgument argument : node.getArguments()){
String name = argument.getName();
if (nameSet.contains(name)){
Log.error("0" + ErrorCodes.DUPLICATED_NAME_CODE + " Duplicated name: " + name +
Log.error("0" + ErrorCodes.DUPLICATED_ARG_CODE + " Duplicated name: " + name +
". Multiple values assigned to the same argument."
, argument.get_SourcePositionStart());
}
......
......@@ -22,6 +22,8 @@ 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.helper.ErrorCodes;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedVariables;
import de.monticore.symboltable.Symbol;
......@@ -38,6 +40,14 @@ public class CheckVariable implements CNNArchASTVariableCoCo {
@Override
public void check(ASTVariable node) {
checkForIllegalNames(node);
checkForDuplicates(node);
checkConstraints(node);
}
private void checkForIllegalNames(ASTVariable node){
String name = node.getName();
if (name.isEmpty() || !Character.isLowerCase(name.codePointAt(0))){
Log.error("0" + ErrorCodes.ILLEGAL_NAME_CODE + " Illegal name: " + name +
......@@ -49,7 +59,10 @@ public class CheckVariable implements CNNArchASTVariableCoCo {
". No variable can be named 'true' or 'false'"
, node.get_SourcePositionStart());
}
}
private void checkForDuplicates(ASTVariable node){
String name = node.getName();
boolean duplicated = false;
if (variableNames.contains(name)){
if (node instanceof ASTParameter){
......@@ -73,4 +86,12 @@ public class CheckVariable implements CNNArchASTVariableCoCo {
}
}
private void checkConstraints(ASTVariable node){
VariableSymbol variable = (VariableSymbol) node.getSymbol().get();
if (variable.hasExpression() && variable.getExpression().isResolvable()) {
variable.getExpression().resolveOrError();
Constraints.check(variable);
}
}
}
......@@ -84,6 +84,13 @@ abstract public class ArchExpressionSymbol extends CommonSymbol {
*/
abstract public boolean isTuple();
public boolean isString(){
if (getValue().isPresent()){
return getStringValue().isPresent();
}
return false;
}
/**
* Checks whether the value is an integer. This can only be checked if the expression is resolved.
* If true getRhs() will return an Integer.
......@@ -195,6 +202,14 @@ abstract public class ArchExpressionSymbol extends CommonSymbol {
return Optional.empty();
}
public Optional<String> getStringValue(){
Optional<Object> optValue = getValue();
if (optValue.isPresent() && (optValue.get() instanceof String)){
return Optional.of((String) optValue.get());
}
return Optional.empty();
}
public Optional<List<Integer>> getIntTupleValues(){
Optional<List<Object>> optValue = getTupleValues();
if (optValue.isPresent()){
......
......@@ -20,10 +20,7 @@
*/
package de.monticore.lang.monticar.cnnarch._symboltable;
import de.monticore.lang.math.math._symboltable.expression.MathArithmeticExpressionSymbol;
import de.monticore.lang.math.math._symboltable.expression.MathCompareExpressionSymbol;
import de.monticore.lang.math.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.math.math._symboltable.expression.MathNameExpressionSymbol;
import de.monticore.lang.math.math._symboltable.expression.*;
import de.monticore.lang.monticar.cnnarch.helper.Calculator;
import de.monticore.lang.monticar.cnnarch.helper.ExpressionHelper;
......@@ -58,8 +55,10 @@ public class ArchSimpleExpressionSymbol extends ArchExpressionSymbol {
@Override
public void reset(){
if (getMathExpression().isPresent()){
setValue(null);
setUnresolvableVariables(null);
if (getMathExpression().isPresent()){
setValue(null);
setUnresolvableVariables(null);
}
}
}
......@@ -71,31 +70,32 @@ public class ArchSimpleExpressionSymbol extends ArchExpressionSymbol {
@Override
public boolean isBoolean() {
if (getMathExpression().isPresent() && !(getMathExpression().get() instanceof MathNameExpressionSymbol)){
return getMathExpression().get().getRealMathExpressionSymbol() instanceof MathCompareExpressionSymbol;
}
else {
return getBooleanValue().isPresent();
if (getMathExpression().get().getRealMathExpressionSymbol() instanceof MathCompareExpressionSymbol){
return true;
}
}
return getBooleanValue().isPresent();
}
@Override
public boolean isNumber() {
if (getMathExpression().isPresent() && !(getMathExpression().get() instanceof MathNameExpressionSymbol)){
return getMathExpression().get().getRealMathExpressionSymbol() instanceof MathArithmeticExpressionSymbol;
}
else {
return getDoubleValue().isPresent();
if (getMathExpression().isPresent()){
MathExpressionSymbol mathExp = getMathExpression().get().getRealMathExpressionSymbol();
if (mathExp instanceof MathArithmeticExpressionSymbol || mathExp instanceof MathNumberExpressionSymbol){
return true;
}
}
return getDoubleValue().isPresent();
}
@Override
public boolean isTuple() {
if (getMathExpression().isPresent() && !(getMathExpression().get() instanceof MathNameExpressionSymbol)){
return getMathExpression().get().getRealMathExpressionSymbol() instanceof TupleExpressionSymbol;
}
else {
return getTupleValues().isPresent();
if (getMathExpression().get().getRealMathExpressionSymbol() instanceof TupleExpressionSymbol){
return true;
}
}
return getTupleValues().isPresent();
}
protected void computeUnresolvableVariables(Set<VariableSymbol> unresolvableVariables, Set<VariableSymbol> allVariables) {
......@@ -233,6 +233,12 @@ public class ArchSimpleExpressionSymbol extends ArchExpressionSymbol {
return res;
}
public static ArchSimpleExpressionSymbol of(String value){
ArchSimpleExpressionSymbol res = new ArchSimpleExpressionSymbol();
res.setValue(value);
return res;
}
public static ArchSimpleExpressionSymbol of(MathExpressionSymbol expressions){
ArchSimpleExpressionSymbol res = new ArchSimpleExpressionSymbol();
res.setMathExpression(expressions);
......
......@@ -67,7 +67,12 @@ public class ArchitectureSymbol extends ArchitectureSymbolTOP {
public void resolve(){
getBody().checkIfResolvable();
Set<VariableSymbol> set = getBody().resolve();
try{
getBody().resolve();
}
catch (ArchResolveException e){
//do nothing; error is already logged
}
}
public boolean isResolved(){
......
......@@ -90,16 +90,26 @@ public class ArgumentSymbol extends CommonSymbol {
//do not call if value is a sequence
public void set(){
if (getRhs().isSimpleValue()){
getRhs().resolveOrError();
Constraints.check(this);
if (getRhs().isResolved() && getRhs().isSimpleValue()){
getParameter().setExpression((ArchSimpleExpressionSymbol) getRhs());
}
else {
throw new IllegalStateException("The value of the parameter is set to a sequence. This should never happen.");
throw new IllegalStateException("The value of the parameter is set to a sequence or the expression is not resolved. This should never happen.");
}
}
public void resolveExpression() throws ArchResolveException {
getRhs().resolveOrError();
boolean valid = Constraints.check(this);
if (!valid){
throw new ArchResolveException();
}
}
public void checkConstraints(){
Constraints.check(this);
}
public List<List<ArgumentSymbol>> split(){
if (getRhs().isRange()){
getRhs().resolveOrError();
......@@ -116,6 +126,9 @@ public class ArgumentSymbol extends CommonSymbol {
}
ArgumentSymbol argument = new Builder().parameter(getParameter()).value(value).build();
if (getAstNode().isPresent()){
argument.setAstNode(getAstNode().get());
}
serialArgumentList.add(argument);
}
arguments.add(serialArgumentList);
......
......@@ -274,31 +274,22 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
addToScopeAndLinkWithNode(variable, node);
}
@Override
public void endVisit(ASTMathExpression node) {
boolean t = true;
boolean b = t;
}
@Override
public void visit(ASTArchSimpleExpression ast) {
ArchSimpleExpressionSymbol sym = new ArchSimpleExpressionSymbol();
addToScopeAndLinkWithNode(sym, ast);
}
@Override
public void endVisit(ASTArchSimpleExpression ast) {
MathExpressionSymbol mathExp;
ArchSimpleExpressionSymbol sym = new ArchSimpleExpressionSymbol();
MathExpressionSymbol mathExp = null;
if (ast.getArithmeticExpression().isPresent()) {
mathExp = (MathExpressionSymbol) ast.getArithmeticExpression().get().getSymbol().get();
}
else if (ast.getBooleanExpression().isPresent()) {
mathExp = (MathExpressionSymbol) ast.getBooleanExpression().get().getSymbol().get();
}
else {
else if (ast.getTupleExpression().isPresent()){
mathExp = (MathExpressionSymbol) ast.getTupleExpression().get().getSymbol().get();
}
ArchSimpleExpressionSymbol sym = new ArchSimpleExpressionSymbol();
else {
sym.setValue(ast.getString().get().getValue());
}
sym.setMathExpression(mathExp);
addToScopeAndLinkWithNode(sym, ast);
}
......@@ -475,6 +466,7 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
.parameter(methodLayer.getMethod().getParameter("index").get())
.value((ArchSimpleExpressionSymbol) node.getIndex().getSymbol().get())
.build();
indexArgument.setAstNode(node.getIndex());
addToScope(indexArgument);
methodLayer.setArguments(Collections.singletonList(indexArgument));
......
......@@ -91,7 +91,7 @@ public class CompositeLayerSymbol extends LayerSymbol {
}*/
@Override
public Set<VariableSymbol> resolve() {
public Set<VariableSymbol> resolve() throws ArchResolveException {
if (!isResolved()) {
if (isResolvable()) {
List<LayerSymbol> resolvedLayers = new ArrayList<>();
......@@ -104,7 +104,7 @@ public class CompositeLayerSymbol extends LayerSymbol {
}
@Override
protected void resolveExpressions() {
protected void resolveExpressions() throws ArchResolveException {
for (LayerSymbol layer : getLayers()){
layer.resolveExpressions();
}
......
......@@ -20,6 +20,7 @@
*/
package de.monticore.lang.monticar.cnnarch._symboltable;
import de.monticore.lang.monticar.cnnarch.helper.Constraints;
import de.monticore.symboltable.MutableScope;
import de.monticore.symboltable.Symbol;
......@@ -82,7 +83,7 @@ public class IOLayerSymbol extends LayerSymbol {
}*/
@Override
public Set<VariableSymbol> resolve() {
public Set<VariableSymbol> resolve() throws ArchResolveException {
if (!isResolved()) {
if (isResolvable()) {
resolveExpressions();
......@@ -100,7 +101,6 @@ public class IOLayerSymbol extends LayerSymbol {
isResolved = false;
}
}
//todo getShape().isResolved
if (!getDefinition().getShape().isResolved()){
isResolved = false;
}
......@@ -142,8 +142,6 @@ public class IOLayerSymbol extends LayerSymbol {
return Optional.of(Collections.nCopies(getParallelLength().get(), 1));
}
@Override
protected void putInScope(MutableScope scope) {
Collection<Symbol> symbolsInScope = scope.getLocalSymbols().get(getName());
......@@ -165,13 +163,22 @@ public class IOLayerSymbol extends LayerSymbol {
.definition(getDefinition())
.arrayAccess(arrayAccessCopy)
.build();
if (getAstNode().isPresent()){
copy.setAstNode(getAstNode().get());
}
return copy;
}
@Override
protected void resolveExpressions() {
protected void resolveExpressions() throws ArchResolveException {
if (getArrayAccess().isPresent()){
getArrayAccess().get().resolveOrError();
boolean valid = true;
valid = valid && Constraints.INTEGER.check(getArrayAccess().get(), getSourcePosition(), getName());
valid = valid && Constraints.NON_NEGATIVE.check(getArrayAccess().get(), getSourcePosition(), getName());
if (!valid){
throw new ArchResolveException();
}
}
}
......
......@@ -111,14 +111,14 @@ public abstract class LayerSymbol extends CommonScopeSpanningSymbol {
setUnresolvableVariables(unresolvableVariables);
}
public void resolveOrError(){
public void resolveOrError() throws ArchResolveException{
Set<VariableSymbol> names = resolve();
if (!isResolved()){
throw new IllegalStateException("The following names could not be resolved: " + Joiners.COMMA.join(getUnresolvableVariables()));
}
}
abstract public Set<VariableSymbol> resolve();
abstract public Set<VariableSymbol> resolve() throws ArchResolveException;
abstract protected List<ShapeSymbol> computeOutputShapes();
......@@ -151,7 +151,7 @@ public abstract class LayerSymbol extends CommonScopeSpanningSymbol {
abstract protected void putInScope(MutableScope scope);
abstract protected void resolveExpressions();
abstract protected void resolveExpressions() throws ArchResolveException;
/*abstract public void reset();*/
}
......@@ -108,13 +108,14 @@ public class MethodDeclarationSymbol extends CommonScopeSpanningSymbol {
}
public LayerSymbol call(MethodLayerSymbol layer) {
public LayerSymbol call(MethodLayerSymbol layer) throws ArchResolveException{
checkForSequence(layer.getArguments());
if (isPredefined()){
return layer;
}
else {
reset();
set(layer.getArguments());
CompositeLayerSymbol copy = getBody().copy();
......@@ -132,7 +133,6 @@ public class MethodDeclarationSymbol extends CommonScopeSpanningSymbol {
for (VariableSymbol param : getParameters()){
param.reset();
}
//getBody().reset();
}
private void set(List<ArgumentSymbol> arguments){
......
......@@ -131,11 +131,16 @@ public class MethodLayerSymbol extends LayerSymbol {
}
public boolean isResolved(){
return getResolvedThis().isPresent();
if (getResolvedThis().isPresent() && getResolvedThis().get() != this){
return getResolvedThis().get().isResolved();
}
else {
return getResolvedThis().isPresent();
}
}
@Override
public Set<VariableSymbol> resolve() {
public Set<VariableSymbol> resolve() throws ArchResolveException {
if (!isResolved()) {
if (isResolvable()) {
getMethod();
......@@ -172,9 +177,9 @@ public class MethodLayerSymbol extends LayerSymbol {
}
}
protected void resolveExpressions(){
protected void resolveExpressions() throws ArchResolveException{
for (ArgumentSymbol argument : getArguments()){
argument.getRhs().resolveOrError();
argument.resolveExpression();
}
}
......@@ -234,20 +239,24 @@ public class MethodLayerSymbol extends LayerSymbol {
@Override
protected List<ShapeSymbol> computeOutputShapes() {
if (getMethod().isPredefined()){
BiFunction<List<ShapeSymbol>, MethodLayerSymbol, List<ShapeSymbol>> shapeFunction = getMethod().getShapeFunction();
return shapeFunction.apply(getInputLayer().get().getOutputShapes(), this);
}
else {
Set<VariableSymbol> unresolvableVariables = resolve();