Commit 4edc8801 authored by Thomas Michael Timmermanns's avatar Thomas Michael Timmermanns
Browse files

Added Cocos and changed IO-variable assignment.

Removed old tests.
parent b1306f96
......@@ -11,8 +11,8 @@ grammar CNNArch extends de.monticore.lang.math.Math {
interface ArchDeclaration;
interface ArchitectureElement;
interface Nameable;
interface Variable extends Nameable;
interface Variable;
ast Variable = method String getName(){};
IODeclaration implements ArchDeclaration = "def"
(in:"input" | out:"output")
......@@ -26,14 +26,14 @@ grammar CNNArch extends de.monticore.lang.math.Math {
Dimension = IOVariable | intLiteral:UnitNumberResolution;
IOVariable implements Variable = Name&;
IOVariable implements Variable = Name& ("=" intRhs:UnitNumberResolution)?;
VariableAssignment implements Variable,ArchDeclaration = Name& "=" rhs:ArchSimpleExpression;
MethodDeclaration implements ArchDeclaration,Nameable = "def"
Name& "("
parameters:(Parameter || ",")* ")" "{"
body:ArchBody "}";
MethodDeclaration implements ArchDeclaration = "def"
Name& "("
parameters:(Parameter || ",")* ")" "{"
body:ArchBody "}";
Parameter implements Variable = Name& ("=" default:ArchSimpleExpression)?;
......
......@@ -20,7 +20,7 @@
*/
package de.monticore.lang.monticar.cnnarch._ast;
import de.monticore.lang.monticar.cnnarch.PredefinedVariables;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedVariables;
public class ASTPredefinedArgument extends ASTPredefinedArgumentTOP {
......
......@@ -25,6 +25,10 @@ public class CNNArchPreResolveCocos {
public static CNNArchCoCoChecker createChecker() {
return new CNNArchCoCoChecker()
.addCoCo(new CheckNames());
.addCoCo(new CheckMethodLayer())
.addCoCo(new CheckVariable())
.addCoCo(new CheckIOLayer())
.addCoCo(new CheckArgument())
.addCoCo(new CheckMethodDeclaration());
}
}
\ 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.ASTArgument;
import de.monticore.lang.monticar.cnnarch._symboltable.ArgumentSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.logging.Log;
public class CheckArgument implements CNNArchASTArgumentCoCo {
@Override
public void check(ASTArgument node) {
ArgumentSymbol argument = (ArgumentSymbol) node.getSymbol().get();
if (argument.getParameter() == null){
Log.error("0"+ ErrorCodes.UNKNOWN_ARGUMENT_CODE + " Unknown Argument. " +
"Parameter with name '" + node.getName() + "' does not exist."
, node.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.ASTIOLayer;
import de.monticore.lang.monticar.cnnarch._symboltable.CompositeLayerSymbol;
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.monticore.symboltable.Symbol;
import de.se_rwth.commons.logging.Log;
public class CheckIOLayer implements CNNArchASTIOLayerCoCo {
@Override
public void check(ASTIOLayer node) {
Symbol symbol = node.getSymbol().get();
IODeclarationSymbol ioDeclaration = null;
if (symbol instanceof IOLayerSymbol){
ioDeclaration = ((IOLayerSymbol) symbol).getDefinition();
}
else if (symbol instanceof CompositeLayerSymbol){
IOLayerSymbol layer = (IOLayerSymbol) ((CompositeLayerSymbol) symbol).getLayers().get(0);
ioDeclaration = layer.getDefinition();
}
if (ioDeclaration == null){
Log.error("0" + ErrorCodes.UNKNOWN_IO_CODE + " Unknown input or output name. " +
"The input or output '" + node.getName() + "' does not exist"
, node.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 CheckMethodDeclaration implements CNNArchASTMethodDeclarationCoCo {
//for duplication check
Set<String> methodNames = new HashSet<>();
//for recursion check
Set<MethodDeclarationSymbol> seenMethods = new HashSet<>();
boolean done = false;
@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);
}
MethodDeclarationSymbol method = (MethodDeclarationSymbol) node.getSymbol().get();
checkForRecursion(method, method.getBody());
}
private void checkForRecursion(MethodDeclarationSymbol startingMethod, LayerSymbol current){
if (!done) {
if (current instanceof CompositeLayerSymbol) {
for (LayerSymbol layer : ((CompositeLayerSymbol) current).getLayers()) {
checkForRecursion(startingMethod, layer);
}
}
else if (current instanceof MethodLayerSymbol) {
MethodDeclarationSymbol method = ((MethodLayerSymbol) current).getMethod();
if (method != null && !method.isPredefined() && !seenMethods.contains(method)) {
seenMethods.add(method);
if (startingMethod == method) {
Log.error("0" + ErrorCodes.RECURSION_ERROR_CODE + " Recursion is not allowed. " +
"The method '" + startingMethod.getName() + "' creates a recursive cycle."
, startingMethod.getSourcePosition());
done = true;
}
else {
checkForRecursion(startingMethod, 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.monticar.cnnarch._ast.ASTArgument;
import de.monticore.lang.monticar.cnnarch._ast.ASTMethodLayer;
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.se_rwth.commons.logging.Log;
import java.util.HashSet;
import java.util.Set;
public class CheckMethodLayer implements CNNArchASTMethodLayerCoCo{
@Override
public void check(ASTMethodLayer node) {
Set<String> nameSet = new HashSet<>();
for (ASTArgument argument : node.getArguments()){
String name = argument.getName();
if (nameSet.contains(name)){
Log.error("0" + ErrorCodes.DUPLICATED_NAME_CODE + " Duplicated name: " + name +
". Multiple values assigned to the same argument."
, argument.get_SourcePositionStart());
}
else {
nameSet.add(name);
}
}
MethodDeclarationSymbol method = ((MethodLayerSymbol) node.getSymbol().get()).getMethod();
if (method == null){
Log.error("0" + ErrorCodes.UNKNOWN_METHOD_CODE + " Unknown method error. " +
"Method with name '" + node.getName() + "' does not exist"
, node.get_SourcePositionStart());
}
else {
Set<String> requiredArguments = new HashSet<>();
for (VariableSymbol param : method.getParameters()){
if (!param.getDefaultExpression().isPresent()){
requiredArguments.add(param.getName());
}
}
for (ASTArgument argument : node.getArguments()){
requiredArguments.remove(argument.getName());
if (argument.getName().equals(PredefinedMethods.GLOBAL_NAME)){
requiredArguments.remove(PredefinedMethods.KERNEL_NAME);
}
}
for (String missingArgumentName : requiredArguments){
Log.error("0"+ErrorCodes.MISSING_ARGUMENT_CODE + " Missing argument. " +
"The argument '" + missingArgumentName + "' is required."
, node.get_SourcePositionStart());
}
}
}
}
......@@ -20,43 +20,57 @@
*/
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch.ErrorMessages;
import de.monticore.lang.monticar.cnnarch.PredefinedVariables;
import de.monticore.lang.monticar.cnnarch._ast.ASTMethodDeclaration;
import de.monticore.lang.monticar.cnnarch._ast.ASTNameable;
import de.monticore.lang.monticar.cnnarch._ast.ASTParameter;
import de.monticore.lang.monticar.cnnarch._ast.ASTVariable;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedVariables;
import de.monticore.symboltable.Symbol;
import de.se_rwth.commons.logging.Log;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class CheckNames implements CNNArchASTNameableCoCo {
public class CheckVariable implements CNNArchASTVariableCoCo {
Set<String> variableNames = new HashSet<>();
Set<String> methodNames = new HashSet<>();
@Override
public void check(ASTNameable node) {
public void check(ASTVariable node) {
String name = node.getName();
if (name.isEmpty() || !Character.isLowerCase(name.codePointAt(0))){
Log.error("0" + ErrorMessages.ILLEGAL_NAME_CODE + " Illegal name: " + name +
". All new variable and method names have to start with a lowercase letter. "
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 (name.equals(PredefinedVariables.TRUE_NAME) || name.equals(PredefinedVariables.FALSE_NAME)){
Log.error("0" + ErrorMessages.ILLEGAL_NAME_CODE + " Illegal name: " + name +
". No method or variable can be named 'true' or 'false'"
Log.error("0" + ErrorCodes.ILLEGAL_NAME_CODE + " Illegal name: " + name +
". No variable can be named 'true' or 'false'"
, node.get_SourcePositionStart());
}
if (node instanceof ASTMethodDeclaration){
if (methodNames.contains(name)){
Log.error("0" + ErrorMessages.ILLEGAL_NAME_CODE + " Duplicated name: " + name +
". This name was defined multiple times."
, node.get_SourcePositionStart());
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;
}
}
else {
methodNames.add(name);
duplicated = true;
}
}
else{
variableNames.add(name);
}
if (duplicated){
Log.error("0" + ErrorCodes.DUPLICATED_NAME_CODE + " Duplicated name: " + name +
". This name is already defined."
, node.get_SourcePositionStart());
}
}
}
......@@ -18,10 +18,8 @@
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* *******************************************************************************
*/
package de.monticore.lang.monticar.cnnarch._ast;
public interface ASTNameable extends ASTNameableTOP {
String getName();
package de.monticore.lang.monticar.cnnarch._symboltable;
public class ArchResolveException extends Exception {
//
}
......@@ -68,9 +68,6 @@ public class ArchitectureSymbol extends ArchitectureSymbolTOP {
public void resolve(){
getBody().checkIfResolvable();
Set<VariableSymbol> set = getBody().resolve();
/*if (getBody().isResolved()){
getBody().getOutputShapes();
}*/
}
public boolean isResolved(){
......
......@@ -20,8 +20,8 @@
*/
package de.monticore.lang.monticar.cnnarch._symboltable;
import de.monticore.lang.monticar.cnnarch.Constraint;
import de.monticore.lang.monticar.cnnarch.PredefinedVariables;
import de.monticore.lang.monticar.cnnarch.helper.Constraint;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedVariables;
import de.monticore.symboltable.CommonSymbol;
import de.monticore.symboltable.MutableScope;
import de.monticore.symboltable.Symbol;
......@@ -43,6 +43,10 @@ public class ArgumentSymbol extends CommonSymbol {
}
public VariableSymbol getParameter() {
if (parameter == null){
Optional<VariableSymbol> optParam = getMethodLayer().getMethod().getParameter(getName());
optParam.ifPresent(this::setParameter);
}
return parameter;
}
......@@ -50,6 +54,11 @@ public class ArgumentSymbol extends CommonSymbol {
this.parameter = parameter;
}
public MethodLayerSymbol getMethodLayer() {
return (MethodLayerSymbol) getEnclosingScope().getSpanningSymbol().get();
}
public ArchExpressionSymbol getRhs() {
return rhs;
}
......
......@@ -24,13 +24,13 @@ package de.monticore.lang.monticar.cnnarch._symboltable;
import de.monticore.lang.math.math._ast.ASTMathExpression;
import de.monticore.lang.math.math._symboltable.MathSymbolTableCreator;
import de.monticore.lang.math.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.monticar.cnnarch.Constraint;
import de.monticore.lang.monticar.cnnarch.PredefinedMethods;
import de.monticore.lang.monticar.cnnarch.PredefinedVariables;
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.Constraint;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedMethods;
import de.monticore.lang.monticar.cnnarch.helper.PredefinedVariables;
import de.monticore.lang.monticar.types2._ast.ASTType;
import de.monticore.symboltable.*;
import de.se_rwth.commons.logging.Log;
......@@ -212,21 +212,18 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
@Override
public void endVisit(ASTIOVariable node) {
Optional<VariableSymbol> optVariable = currentScope().get().resolve(node.getName(), VariableSymbol.KIND);
if (optVariable.isPresent()){
node.setSymbol(optVariable.get());
node.setEnclosingScope(currentScope().get());
optVariable.get().addConstraint(Constraint.INTEGER, Constraint.POSITIVE);
}
else {
VariableSymbol variable = new VariableSymbol.Builder()
.name(node.getName())
.type(VariableType.GLOBAL)
.constraints(Constraint.INTEGER, Constraint.POSITIVE)
.build();
//addToScope(ArchSimpleExpressionSymbol.of(variable));
addToScopeAndLinkWithNode(variable, node);
ArchSimpleExpressionSymbol defaultValue = null;
if (node.getIntRhs().isPresent()){
defaultValue = ArchSimpleExpressionSymbol.of(node.getIntRhs().get().getNumber().get().getDividend().intValue());
}
VariableSymbol variable = new VariableSymbol.Builder()
.name(node.getName())
.type(VariableType.IOVARIABLE)
.defaultValue(defaultValue)
.constraints(Constraint.INTEGER, Constraint.POSITIVE)
.build();
//addToScope(ArchSimpleExpressionSymbol.of(variable));
addToScopeAndLinkWithNode(variable, node);
}
@Override
......@@ -267,21 +264,10 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
@Override
public void endVisit(ASTVariableAssignment node) {
Optional<VariableSymbol> optVariable = currentScope().get().resolve(node.getName(), VariableSymbol.KIND);
if (optVariable.isPresent()){
VariableSymbol variable = optVariable.get();
ArchSimpleExpressionSymbol rhs = (ArchSimpleExpressionSymbol) node.getRhs().getSymbol().get();
rhs.resolveOrError();
variable.setDefaultExpression(rhs);
node.setEnclosingScope(currentScope().get());
node.setSymbol(variable);
}
else {
VariableSymbol variable = new VariableSymbol(node.getName());
variable.setType(VariableType.GLOBAL);
variable.setDefaultExpression((ArchSimpleExpressionSymbol) node.getRhs().getSymbol().get());
addToScopeAndLinkWithNode(variable, node);
}
VariableSymbol variable = new VariableSymbol(node.getName());
variable.setType(VariableType.CONSTANT);
variable.setDefaultExpression((ArchSimpleExpressionSymbol) node.getRhs().getSymbol().get());
addToScopeAndLinkWithNode(variable, node);
}
@Override
......@@ -404,7 +390,8 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
List<ArgumentSymbol> arguments = new ArrayList<>(6);
for (ASTArgument astArgument : ast.getArguments()){
arguments.add((ArgumentSymbol) astArgument.getSymbol().get());
Optional<ArgumentSymbol> optArgument = astArgument.getSymbol().map(e -> (ArgumentSymbol)e);
optArgument.ifPresent(arguments::add);
}
methodLayer.setArguments(arguments);
......@@ -416,19 +403,18 @@ public class CNNArchSymbolTableCreator extends de.monticore.symboltable.CommonSy
ArchExpressionSymbol value;
value = (ArchExpressionSymbol) node.getRhs().getSymbol().get();
MethodLayerSymbol methodLayer = (MethodLayerSymbol) currentScope().get().getSpanningSymbol().get();
ArgumentSymbol argument = new ArgumentSymbol.Builder()
.parameter(methodLayer.getMethod().getParameter(node.getName()).get())
.value(value)
.build();
ArgumentSymbol argument = new ArgumentSymbol(node.getName());
argument.setRhs(value);
addToScopeAndLinkWithNode(argument, node);
}
@Override
public void visit(ASTIOLayer node) {
IODeclarationSymbol IODef = (IODeclarationSymbol) currentScope().get().resolve(node.getName(), IODeclarationSymbol.KIND).get();
int arrayLength = IODef.getArrayLength();
Optional<IODeclarationSymbol> optIODef = currentScope().get().resolve(node.getName(), IODeclarationSymbol.KIND);
int arrayLength = 1;
if (optIODef.isPresent()){
arrayLength = optIODef.get().getArrayLength();