Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a command line interface to NESTML. #354

Merged
merged 17 commits into from
May 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<!-- .. Libraries ..................................................... -->
<guava.version>18.0</guava.version>
<commons.cli.version>1.3.1</commons.cli.version>
<jackson.version>2.8.8</jackson.version>
<junit.version>4.12</junit.version>

<!-- Monticore versions and dependencies -->
Expand Down Expand Up @@ -139,7 +140,7 @@
</build>

<dependencies>

<!-- General dependencies -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
Expand All @@ -158,6 +159,11 @@
<version>${commons.cli.version}</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>

<!-- MontiCore Dependencies -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static Optional<Path> generateSympyODEAnalyzer(
else {
final String msg = String.format("The neuron %s doesn't contain an ODE. The script generation "
+ "is skipped.", neuron.getName());
Log.warn(msg);
Log.trace(msg, LOG_NAME);

return empty();
}
Expand Down Expand Up @@ -120,7 +120,7 @@ static Optional<Path> generateODEAnalyserForDeltaShape(
else {
final String msg = String.format("The neuron %s doesn't contain an ODE. The script generation "
+ "is skipped.", neuron.getName());
Log.warn(msg);
Log.trace(msg, LOG_NAME);

return empty();
}
Expand All @@ -137,7 +137,7 @@ private static Path generateSympyScript(
final Scope scope = astOdeDeclaration.getEnclosingScope().get();

if (astOdeDeclaration.getODEs().size() >= 1) {
Log.warn("It works only for a single ODE. Only the first equation will be used.");
Log.trace("It works only for a single ODE. Only the first equation will be used.", LOG_NAME);
}

glex.setGlobalValue("ode", astOdeDeclaration.getODEs().get(0));
Expand Down
10 changes: 6 additions & 4 deletions src/main/java/org/nest/codegeneration/sympy/OdeProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import static com.google.common.base.Preconditions.checkState;
import static de.se_rwth.commons.logging.Log.info;
import static de.se_rwth.commons.logging.Log.trace;
import static de.se_rwth.commons.logging.Log.warn;
import static org.nest.codegeneration.sympy.ODESolverGenerator.generateODEAnalyserForDeltaShape;
import static org.nest.codegeneration.sympy.ODESolverGenerator.generateSympyODEAnalyzer;
Expand Down Expand Up @@ -66,7 +67,7 @@ public ASTNeuron solveODE(
else {
final String msg = "The neuron: " + astNeuron.getName() + " doesn't contain ODE. "
+ "The analysis is skipped.";
Log.warn(msg);
Log.trace(msg, LOG_NAME);
return astNeuron;
}

Expand Down Expand Up @@ -111,8 +112,9 @@ private ASTNeuron handleDeltaShape(
Paths.get(outputBase.toString(), astNeuron.getName() + "." + DeltaSolutionTransformer.PROPAGATOR_STEP));
}
else {
Log.warn(astNeuron.getName() + " has a delta shape function with a non-linear ODE.");
Log.trace(astNeuron.getName() + " has a delta shape function with a non-linear ODE.", LOG_NAME);
}

}

return astNeuron;
Expand Down Expand Up @@ -160,12 +162,12 @@ else if (solutionType.equals(SolverType.NUMERIC)) {
Paths.get(outputBase.toString(),astNeuron.getName() + "." + ImplicitFormTransformer.EQUATIONS_FILE));
}
else {
warn(astNeuron.getName() + ": ODEs could not be solved. The model remains unchanged.");
trace(astNeuron.getName() + ": ODEs could not be solved. The model remains unchanged.", LOG_NAME);
return astNeuron;
}
}
else {
warn(astNeuron.getName() + ": ODEs could not be solved. The model remains unchanged.");
trace(astNeuron.getName() + ": ODEs could not be solved. The model remains unchanged.", LOG_NAME);
return astNeuron;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import static org.nest.utils.AstUtils.getVectorizedVariable;

/**
* Provides common methods for solver transformations.
* Provides common methods for AST transformations which are performed after SymPy analysis.
*
* @author plotnikov
*/
Expand Down Expand Up @@ -114,14 +114,12 @@ ASTNeuron replaceODEPropagationStep(final ASTNeuron astNeuron, List<ASTStmt> pro
break;
}
}

return astNeuron;
} else {
Log.warn("The model has defined an ODE. But its solution is not used in the update state.");
Log.trace("The model has defined an ODE. But its solution is not used in the update state.", this.getClass().getSimpleName());
return astNeuron;
}


}

/**
Expand Down
13 changes: 6 additions & 7 deletions src/main/java/org/nest/commons/_visitor/BinaryLogicVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import org.nest.commons._ast.ASTExpr;
import org.nest.spl.symboltable.typechecking.Either;
import org.nest.symboltable.symbols.TypeSymbol;
import org.nest.utils.AstUtils;

import static org.nest.spl.symboltable.typechecking.TypeChecker.isBoolean;
import static org.nest.symboltable.predefined.PredefinedTypes.getBooleanType;
Expand All @@ -13,11 +12,11 @@
/**
* @author ptraeder
*/
public class BinaryLogicVisitor implements CommonsVisitor{
final String ERROR_CODE = "SPL_BINARY_LOGIC_VISITOR";
public class BinaryLogicVisitor implements CommonsVisitor {

@Override
public void visit(ASTExpr expr) {
public void visit(final ASTExpr expr) {
// both elements are there by construction
final Either<TypeSymbol, String> lhsType = expr.getLeft().get().getType();
final Either<TypeSymbol, String> rhsType = expr.getRight().get().getType();

Expand All @@ -32,13 +31,13 @@ public void visit(ASTExpr expr) {

if (isBoolean(lhsType.getValue()) && isBoolean(rhsType.getValue())) {
expr.setType(Either.value(getBooleanType()));
return;
}
else {
final String errorMsg = ERROR_CODE+ " " + AstUtils.print(expr.get_SourcePositionStart()) + " : " +"Both operands of the logical expression must be boolean ";
final String errorMsg = CommonsErrorStrings.message(this, expr.get_SourcePositionStart());
expr.setType(Either.error(errorMsg));
Log.error(errorMsg,expr.get_SourcePositionStart());
Log.error(errorMsg, expr.get_SourcePositionStart());
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* @author ptraeder
*/
public class BooleanLiteralVisitor implements CommonsVisitor{
public class BooleanLiteralVisitor implements CommonsVisitor {

@Override
public void visit(ASTExpr expr) {
Expand Down
218 changes: 218 additions & 0 deletions src/main/java/org/nest/commons/_visitor/CommonsErrorStrings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
/*
* CommonsErrorStrings.java
*
* This file is part of NEST.
*
* Copyright (C) 2004 The NEST Initiative
*
* NEST is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* NEST 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NEST. If not, see <http://www.gnu.org/licenses/>.
*/
package org.nest.commons._visitor;

import de.se_rwth.commons.SourcePosition;
import org.nest.utils.AstUtils;

/**
* Factory for CoCo error strings. The dispatch is done by the static type of the context condition object.
* IMPORTANT: Error code must start with the SPL_-prefix
*
* @author plotnikov, traeder
*/
public class CommonsErrorStrings {
private static final String SEPARATOR = " : ";

public static String messageType(final DotOperatorVisitor coco,
final String tyoeMissmatch,
final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = tyoeMissmatch + "(" + AstUtils.print(sourcePosition) + ")";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT;
}

public static String messageModulo(final DotOperatorVisitor coco, final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "Modulo with non integer parameters.";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

@SuppressWarnings({"unused"}) // used for the routing
static String code(final DotOperatorVisitor coco) {
return "SPL_FUNCTION_CALL_VISITOR";
}

public static String message(final BinaryLogicVisitor coco, final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "Both operands of the logical expression must be boolean.";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

@SuppressWarnings({"unused"}) // used for the routing
static String code(final BinaryLogicVisitor coco) {
return "SPL_BINARY_LOGIC_VISITOR";
}

public static String messageNumeric(final ComparisonOperatorVisitor coco, final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "Both operands of the logical expression must be boolean.";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

public static String messageComparison(final ComparisonOperatorVisitor coco, final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "Both operands of the logical expression must be boolean.";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

@SuppressWarnings({"unused"}) // used for the routing
static String code(final ComparisonOperatorVisitor coco) {
return "SPL_COMPARISON_OPERATOR_VISITOR";
}

public static String messageTernary(final ConditionVisitor coco, final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "The ternary operator condition must be boolean.";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

public static String messageTrueNot(final ConditionVisitor coco,
final String ifTrue,
final String ifNot,
final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "Mismatched conditional alternatives " + ifTrue + " and " +
ifNot + "-> Assuming real.";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

public static String messageTypeMissmatch(final ConditionVisitor coco,
final String ifTrue,
final String ifNot,
final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "Mismatched conditional alternatives " + ifTrue + " and " + ifNot + ".";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

@SuppressWarnings({"unused"}) // used for the routing
static String code(final ConditionVisitor coco) {
return "SPL_CONDITION_VISITOR";
}

public static String messageNonNumericType(final UnaryVisitor coco,
final String type,
final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "Cannot perform an arithmetic operation on a non-numeric type: " + type;

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

public static String messageTypeError(final UnaryVisitor coco,
final String expression,
final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "Cannot determine the type of the expression: " + expression;

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

@SuppressWarnings({"unused"}) // used for the routing
static String code(final UnaryVisitor coco) {
return "SPL_UNARY_VISITOR";
}


public static String messageDifferentTypes(final LineOperatorVisitor coco,
final String lhsType,
final String rhsType,
final String resultingType,
final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "Addition/substraction of " + lhsType + " and " + rhsType +
". Assuming: " + resultingType + ".";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

@SuppressWarnings({"unused"}) // used for the routing
public static String messageTypeError(final LineOperatorVisitor coco,
final String lhsType,
final String rhsType,
final String operation,
final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "Cannot determine the type of " + operation + " with types: " + lhsType + " and " +
rhsType;

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

@SuppressWarnings({"unused"}) // used for the routing
static String code(final LineOperatorVisitor coco) {
return "SPL_LINE_OPERATOR_VISITOR";
}

public static String message(final LogicalNotVisitor coco, final String exprType, final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "Logical 'not' expects an boolean type and not: " + exprType;

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

@SuppressWarnings({"unused"}) // used for the routing
static String code(final LogicalNotVisitor coco) {
return "SPL_LOGICAL_NOT_VISITOR";
}

public static String message(final NoSemantics coco, final String expr, final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "This expression is not implemented: " + expr;

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

@SuppressWarnings({"unused"}) // used for the routing
static String code(final NoSemantics coco) {
return "SPL_LOGICAL_NOT_VISITOR";
}

public static String messageUnitBase(final PowVisitor coco, final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "With a Unit base, the exponent must be an integer.";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

public static String messageType(final PowVisitor coco,
final String base,
final String exponent,
final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "With a Unit base, the exponent must be an integer.";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

public static String messageFloatingPointExponent(final PowVisitor coco,
final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "No floating point values allowed in the exponent to a UNIT base";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

public static String messageNonConstantExponent(final PowVisitor coco,
final SourcePosition sourcePosition) {
final String ERROR_MSG_FORMAT = "Cannot calculate value of exponent. Must be a constant value!";

return code(coco) + SEPARATOR + ERROR_MSG_FORMAT + "(" + AstUtils.print(sourcePosition) + ")";
}

@SuppressWarnings({"unused"}) // used for the routing
static String code(final PowVisitor coco) {
return "SPL_POW_VISITOR";
}

}
Loading