Beispiel #1
0
  @Override
  public void visit(ASTExpr expr) {
    final Either<TypeSymbol, String> baseType = expr.getBase().get().getType();
    final Either<TypeSymbol, String> exponentType = expr.getExponent().get().getType();

    if (baseType.isError()) {
      expr.setType(baseType);
      return;
    }
    if (exponentType.isError()) {
      expr.setType(exponentType);
      return;
    } else if (isNumeric(baseType.getValue()) && isNumeric(exponentType.getValue())) {
      if (isInteger(baseType.getValue()) && isInteger(exponentType.getValue())) {
        expr.setType(Either.value(getIntegerType()));
        return;
      } else if (isUnit(baseType.getValue())) {
        if (!isInteger(exponentType.getValue())) {
          final String errorMsg =
              ERROR_CODE
                  + " "
                  + AstUtils.print(expr.get_SourcePositionStart())
                  + " : "
                  + "With a Unit base, the exponent must be an integer.";
          expr.setType(Either.error(errorMsg));
          error(errorMsg, expr.get_SourcePositionStart());
          return;
        }
        UnitRepresentation baseRep = new UnitRepresentation(baseType.getValue().getName());
        Either<Integer, String> numericValue =
            calculateNumericValue(
                expr.getExponent()
                    .get()); // calculate exponent value if exponent composed of literals
        if (numericValue.isValue()) {
          expr.setType(
              Either.value(
                  getTypeIfExists((baseRep.pow(numericValue.getValue())).serialize()).get()));
          return;
        } else {
          final String errorMsg = numericValue.getError();
          expr.setType(Either.error(errorMsg));
          error(errorMsg, expr.get_SourcePositionStart());
          return;
        }
      } else {
        expr.setType(Either.value(getRealType()));
        return;
      }
    }
    // Catch-all if no case has matched
    final String errorMsg =
        ERROR_CODE
            + " "
            + AstUtils.print(expr.get_SourcePositionStart())
            + " : "
            + "Cannot determine the type of the expression: "
            + baseType.getValue().prettyPrint()
            + "**"
            + exponentType.getValue().prettyPrint();
    expr.setType(Either.error(errorMsg));
    error(errorMsg, expr.get_SourcePositionStart());
  }
  public void visit(ASTEquation astEquation) {
    if (astEquation.getRhs().getType().isError()) {
      warn(
          ERROR_CODE
              + ": Error in Expression type calculation: "
              + astEquation.getRhs().getType().getError());

      return;
    }
    if (!astEquation.getEnclosingScope().isPresent()) {
      warn(ERROR_CODE + "Enclosing scope not present. Run ScopeCreator");
      return;
    }

    // Resolve LHS Variable
    String varName = astEquation.getLhs().getSimpleName();
    Scope enclosingScope = astEquation.getEnclosingScope().get();
    Optional<VariableSymbol> varSymbol = NESTMLSymbols.resolve(varName, enclosingScope);

    TypeSymbol varType;
    if (!varSymbol.isPresent()) {
      warn(ERROR_CODE + " Error while resolving the variable to be derived in ODE: " + varName);
      return;
    }
    // Derive varType
    varType = varSymbol.get().getType();

    if (varType.getType() != TypeSymbol.Type.UNIT && varType != getRealType()) {
      warn(
          ERROR_CODE
              + "Type of LHS Variable in ODE is neither a Unit nor real at: "
              + astEquation.get_SourcePositionStart()
              + ". Skipping.");
      return;
    }

    UnitRepresentation varUnit = new UnitRepresentation(varType.getName());
    UnitRepresentation derivedVarUnit =
        varUnit.deriveT(astEquation.getLhs().getDifferentialOrder().size());

    // get type of RHS expression
    TypeSymbol typeFromExpression = astEquation.getRhs().getType().getValue();

    if (typeFromExpression.getType() != TypeSymbol.Type.UNIT
        && typeFromExpression != getRealType()) {
      warn(
          ERROR_CODE
              + "Type of ODE is neither a Unit nor real at: "
              + astEquation.get_SourcePositionStart());
      return;
    }
    UnitRepresentation unitFromExpression = new UnitRepresentation(typeFromExpression.getName());
    // set any of the units to ignoreMagnitude
    unitFromExpression.setIgnoreMagnitude(true);
    // do the actual test:
    if (!unitFromExpression.equals(derivedVarUnit)) {
      // remove magnitude for clearer error message
      derivedVarUnit.setMagnitude(0);
      unitFromExpression.setMagnitude(0);
      warn(
          ERROR_CODE
              + "Type of (derived) variable "
              + astEquation.getLhs().toString()
              + " is: "
              + derivedVarUnit.prettyPrint()
              + ". This does not match Type of RHS expression: "
              + unitFromExpression.prettyPrint()
              + " at: "
              + astEquation.get_SourcePositionStart()
              + ". Magnitudes are ignored in ODE Expressions");
    }
  }