Skip to content

Commit

Permalink
Merge pull request #354 from DimitriPlotnikov/new_cli_api
Browse files Browse the repository at this point in the history
Add a command line interface to NESTML.
  • Loading branch information
Plotnikov committed May 29, 2017
2 parents 4925a45 + e7be07f commit bfbf9e2
Show file tree
Hide file tree
Showing 93 changed files with 1,846 additions and 976 deletions.
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

0 comments on commit bfbf9e2

Please sign in to comment.