Changeset 13906


Ignore:
Timestamp:
Oct 30, 2019 10:41:59 AM (2 weeks ago)
Author:
molsson
Message:

AUTO catchup merge from trunk to branches/dev-mo-2278-merge

Location:
branches/dev-mo-2278-merge
Files:
18 edited
3 copied

Legend:

Unmodified
Added
Removed
  • branches/dev-mo-2278-merge

  • branches/dev-mo-2278-merge/CHANGELOG.txt

    r13856 r13906  
    2020
    2121# Fixed ; Minor ; Compiler; #5835
    22 Format string argument to the String function is now useable.
     22Format string argument to the String function is now respected during constant evaluations.
    2323
    2424# Change ; Minor ; Compiler; #5830
  • branches/dev-mo-2278-merge/Compiler/ModelicaCBackEnd/src/jastadd/CCodeGen/CCodeGenExpressions.jrag

    r13798 r13906  
    1717import java.util.Arrays;
    1818import org.jmodelica.common.ccodegen.CFuncParamDirection;
     19import org.jmodelica.util.values.CFormatSpecifier;
     20import org.jmodelica.util.collections.TransformerIterable;
    1921
    2022aspect CCodeGenExpressions {
     
    792794        genStringFormat_C(p, str, indent);
    793795        str.print(", ");
    794         genStringParts_C(p, str, indent);
     796        genStringParts_C(p, str, indent, null);
    795797        str.println(");");
    796798    }
     
    856858    @Override
    857859    public void FStringExp.genVarDecls_C(CodePrinter p, CodeStream str, String indent) {
    858         super.genVarDecls_C(p, str, indent);
     860        for (ASTNode ch : childrenToGenFor_C()) {
     861            ch.genVarDecls_C(p, str, indent);
     862        }
    859863        genTopStringDecl(p, str, indent);
    860864    }
     
    862866    @Override
    863867    public void FStringExp.genTempVars_C(CodePrinter p, CodeStream str, String indent) {
    864         super.genTempVars_C(p, str, indent);
     868        for (ASTNode ch : childrenToGenFor_C()) {
     869            p.printPreSteps(ch, str, indent);
     870        }
    865871        genTopStringInit(p, str, indent);
    866872    }
     
    873879    @Override
    874880    public void FStringExp.genTempFree_C(CodePrinter p, CodeStream str, String indent) {
    875         super.genTempFree_C(p, str, indent);
     881        for (ASTNode ch : childrenToGenFor_C()) {
     882            ch.genTempFree_C(p, str, indent);
     883        }
     884    }
     885
     886    private Iterable<ASTNode> FStringExp.childrenToGenFor_C() {
     887        // We want to generate for NTA CFormat but not for child Format.
     888        return new TransformerIterable<ASTNode, ASTNode>(this) {
     889            private ASTNode fmt = getFormatOpt();
     890            protected ASTNode transform(ASTNode a) throws SkipException {
     891                return (a == fmt) ? getCFormatOpt() : a;
     892            }
     893        };
    876894    }
    877895
     
    947965    public void FStringExp.genStringFormat_C(CodePrinter p, CodeStream str, String indent) {
    948966        if (hasFormat()) {
    949             p.print(getFormat(), str, indent);
     967            p.print(getCFormat(), str, indent);
    950968        } else {
    951969            if (hasLeftJustified()) {
     
    9871005        if (getValue().type().isReal())
    9881006            str.print(".*");
    989         str.print(getValue().type().formatSpecifier());
     1007        str.print(getValue().type().formatConversion());
    9901008        str.print("\"");
    9911009    }
    9921010
    993     public void FExp.genStringParts_C(CodePrinter p, CodeStream str, String indent) {
     1011    public void FExp.genStringParts_C(
     1012            CodePrinter p, CodeStream str, String indent, CFormatSpecifier format) {
    9941013        // TODO: This method should dispatch to the type!
    9951014        FType t = type();
     
    10041023            str.print(", JMI_TRUE, \"true\", \"false\")");
    10051024        } else {
    1006             if (t.isInteger())
    1007                 str.print("(int) ");
     1025            if (format != null) {
     1026                if (format.expectedType.isUnsigned()) {
     1027                    str.print("(unsigned int) ");
     1028                } else if (format.expectedType.isInteger()) {
     1029                    str.print("(int) ");
     1030                }
     1031            } else {
     1032                if (t.isInteger()) {
     1033                    str.print("(int) ");
     1034                }
     1035            }
    10081036            p.print(this, str, indent);
    10091037        }
     
    10111039
    10121040    @Override
    1013     public void FStringExp.genStringParts_C(CodePrinter p, CodeStream str, String indent) {
    1014         getValue().genStringParts_C(p, str, indent);
     1041    public void FStringExp.genStringParts_C(
     1042            CodePrinter p, CodeStream str, String indent, CFormatSpecifier format) {
     1043        try {
     1044            // This depends on non-parameters being evaluatable.
     1045            format = formatSpecifier();
     1046        } catch (ConstantEvaluationException e) {
     1047            // Assume that we don't have a format that converts real -> integer,
     1048            // and just go by the type.
     1049            format = null;
     1050        }
     1051        getValue().genStringParts_C(p, str, indent, format);
    10151052    }
    10161053
  • branches/dev-mo-2278-merge/Compiler/ModelicaCBackEnd/test/modelica/CCodeGenTests.mo

    r13168 r13906  
    10791079    StringCompare("      medium", String(enumVar, minimumLength=12, leftJustified=false));
    10801080
    1081     StringCompare("42",           String(intVar, format="%d"));
    1082     StringCompare("3.1400000",    String(realVar, format="%f"));
     1081    StringCompare("42",           String(intVar, format="d"));
     1082    StringCompare("3.1400000",    String(realVar, format="f"));
    10831083
    10841084annotation(__JModelica(UnitTesting(tests={
     
    1601916019        input Integer i;
    1602016020        input Boolean b;
    16021         input String fmt;
    1602216021        output Real y;
    1602316022        String s;
     
    1602916028        + String(x, significantDigits=i, leftJustified=b)
    1603016029        + String(x)
    16031         + String(x, format=fmt)
    1603216030       
    1603316031        + String(i, minimumLength=2, leftJustified=b)
    1603416032        + String(i, minimumLength=i, leftJustified=true)
    1603516033        + String(i, minimumLength=i, leftJustified=b)
    16036         + String(i, format=fmt)
    1603716034       
    1603816035        + String(b, minimumLength=2, leftJustified=b)
     
    1604116038    end f;
    1604216039   
    16043     Real y = f(-time, 3, true, "%g");
     16040    Real y = f(-time, 3, true);
    1604416041
    1604516042annotation(__JModelica(UnitTesting(tests={
     
    1605116048        template="$C_functions$",
    1605216049        generatedCode="
    16053 void func_CCodeGenTests_StringOperations9_f_def0(jmi_real_t x_v, jmi_real_t i_v, jmi_real_t b_v, jmi_string_t fmt_v, jmi_real_t* y_o) {
     16050void func_CCodeGenTests_StringOperations9_f_def0(jmi_real_t x_v, jmi_real_t i_v, jmi_real_t b_v, jmi_real_t* y_o) {
    1605416051    JMI_DYNAMIC_INIT()
    1605516052    JMI_DEF(REA, y_v)
     
    1605716054    JMI_DEF_STR_DYNA(tmp_1)
    1605816055    JMI_INI(STR, s_v)
    16059     JMI_INI_STR_DYNA(tmp_1, jmi_max(7 + 1.0, i_v) + jmi_max(7 + i_v, 2.0) + jmi_max(7 + i_v, i_v) + jmi_max(7 + i_v, i_v) + 7 + i_v + 7 + 6 + 16 + jmi_max(10, 2.0) + jmi_max(10, i_v) + jmi_max(10, i_v) + 16 + jmi_max(5, 2.0) + jmi_max(5, i_v) + jmi_max(5, i_v))
     16056    JMI_INI_STR_DYNA(tmp_1, jmi_max(7 + 1.0, i_v) + jmi_max(7 + i_v, 2.0) + jmi_max(7 + i_v, i_v) + jmi_max(7 + i_v, i_v) + 7 + i_v + 7 + 6 + jmi_max(10, 2.0) + jmi_max(10, i_v) + jmi_max(10, i_v) + jmi_max(5, 2.0) + jmi_max(5, i_v) + jmi_max(5, i_v))
    1606016057    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*.*g\", \"%*.*g\"), (int) i_v, (int) 1.0, x_v);
    1606116058    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*.*g\", \"%*.*g\"), (int) 2.0, (int) i_v, x_v);
     
    1606416061    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), COND_EXP_EQ(b_v, JMI_TRUE, \"%-.*g\", \"%.*g\"), (int) i_v, x_v);
    1606516062    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), \"%-.*g\", (int) 6, x_v);
    16066     snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), fmt_v, x_v);
    1606716063    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*d\", \"%*d\"), (int) 2.0, (int) i_v);
    1606816064    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), COND_EXP_EQ(JMI_TRUE, JMI_TRUE, \"%-*d\", \"%*d\"), (int) i_v, (int) i_v);
    1606916065    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*d\", \"%*d\"), (int) i_v, (int) i_v);
    16070     snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), fmt_v, (int) i_v);
    1607116066    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*s\", \"%*s\"), (int) 2.0, COND_EXP_EQ(b_v, JMI_TRUE, \"true\", \"false\"));
    1607216067    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), COND_EXP_EQ(JMI_TRUE, JMI_TRUE, \"%-*s\", \"%*s\"), (int) i_v, COND_EXP_EQ(b_v, JMI_TRUE, \"true\", \"false\"));
     
    1607816073}
    1607916074
    16080 jmi_real_t func_CCodeGenTests_StringOperations9_f_exp0(jmi_real_t x_v, jmi_real_t i_v, jmi_real_t b_v, jmi_string_t fmt_v) {
     16075jmi_real_t func_CCodeGenTests_StringOperations9_f_exp0(jmi_real_t x_v, jmi_real_t i_v, jmi_real_t b_v) {
    1608116076    JMI_DEF(REA, y_v)
    16082     func_CCodeGenTests_StringOperations9_f_def0(x_v, i_v, b_v, fmt_v, &y_v);
     16077    func_CCodeGenTests_StringOperations9_f_def0(x_v, i_v, b_v, &y_v);
    1608316078    return y_v;
    1608416079}
     
    1625316248")})));
    1625416249end StringOperations11;
     16250
     16251
     16252model StringOperations12
     16253    type E = enumeration(Alice, Bob, Eve);
     16254
     16255    function f
     16256        input Integer x;
     16257        input E e;
     16258        output Real y;
     16259    protected
     16260        String s;
     16261    algorithm
     16262        s := String(x, format="7u") +
     16263             String(x, format="-3d") +
     16264             String(e);
     16265        y := x + .5;
     16266    end f;
     16267   
     16268    Real y = f(integer(time), if time < 1 then E.Alice else E.Eve);
     16269
     16270annotation(__JModelica(UnitTesting(tests={
     16271    CCodeGenTestCase(
     16272        name="StringOperations12",
     16273        description="Check that integer-typed format strings generate the correct casts",
     16274        template="$C_functions$",
     16275        generatedCode="
     16276void func_CCodeGenTests_StringOperations12_f_def0(jmi_real_t x_v, jmi_real_t e_v, jmi_real_t* y_o) {
     16277    JMI_DYNAMIC_INIT()
     16278    JMI_DEF(REA, y_v)
     16279    JMI_DEF(STR, s_v)
     16280    JMI_DEF_STR_STAT(tmp_1, 37)
     16281    JMI_INI(STR, s_v)
     16282    JMI_INI_STR_STAT(tmp_1)
     16283    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), \"%7u\", (unsigned int) x_v);
     16284    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), \"%-3d\", (int) x_v);
     16285    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), \"%-s\", E_0_e[(int) e_v]);
     16286    JMI_ASG(STR, s_v, tmp_1)
     16287    y_v = x_v + 0.5;
     16288    JMI_RET(GEN, y_o, y_v)
     16289    JMI_DYNAMIC_FREE()
     16290    return;
     16291}
     16292
     16293jmi_real_t func_CCodeGenTests_StringOperations12_f_exp0(jmi_real_t x_v, jmi_real_t e_v) {
     16294    JMI_DEF(REA, y_v)
     16295    func_CCodeGenTests_StringOperations12_f_def0(x_v, e_v, &y_v);
     16296    return y_v;
     16297}
     16298
     16299")})));
     16300end StringOperations12;
     16301
     16302
     16303model StringOperations13
     16304    function f
     16305        input Real x;
     16306        output Real y;
     16307    protected
     16308        String s;
     16309    algorithm
     16310        s := String(x, format="%g");
     16311        y := x + .5;
     16312    end f;
     16313   
     16314    Real y = f(time);
     16315
     16316annotation(__JModelica(UnitTesting(tests={
     16317    CCodeGenTestCase(
     16318        name="StringOperations13",
     16319        description="Check that we handle case where initial '%' of format specifier is included in format argument of String()",
     16320        template="$C_functions$",
     16321        generatedCode="
     16322void func_CCodeGenTests_StringOperations13_f_def0(jmi_real_t x_v, jmi_real_t* y_o) {
     16323    JMI_DYNAMIC_INIT()
     16324    JMI_DEF(REA, y_v)
     16325    JMI_DEF(STR, s_v)
     16326    JMI_DEF_STR_STAT(tmp_1, 16)
     16327    JMI_INI(STR, s_v)
     16328    JMI_INI_STR_STAT(tmp_1)
     16329    snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), \"%g\", x_v);
     16330    JMI_ASG(STR, s_v, tmp_1)
     16331    y_v = x_v + 0.5;
     16332    JMI_RET(GEN, y_o, y_v)
     16333    JMI_DYNAMIC_FREE()
     16334    return;
     16335}
     16336
     16337jmi_real_t func_CCodeGenTests_StringOperations13_f_exp0(jmi_real_t x_v) {
     16338    JMI_DEF(REA, y_v)
     16339    func_CCodeGenTests_StringOperations13_f_def0(x_v, &y_v);
     16340    return y_v;
     16341}
     16342
     16343")})));
     16344end StringOperations13;
    1625516345
    1625616346package TestTerminate
  • branches/dev-mo-2278-merge/Compiler/ModelicaCompiler/src/jastadd/ModelicaCompiler.jrag

    r13781 r13906  
    22332233        if (target.getMakeFileFlag() != null) {
    22342234                ASTNode.beginStep("compileCCode()");
    2235                 String cFileName = fc.nameUnderscore();
     2235                String cFileName = cName(fc);
    22362236                CCompilerDelegator ccompiler = getCCompiler();
    22372237                CCompilerArguments ccArgs = new CCompilerArguments(cFileName, fc.myOptions(), target, fc.externalLibraries(), fc.externalLibraryDirectories(),
     
    22432243        hookCodeCompiled();
    22442244     }
     2245
     2246    private String ModelicaCompiler.cName(FClass fc) {
     2247        return fc.nameUnderscore(); // Hook to facilitate extensions.
     2248    }
    22452249
    22462250    /**
  • branches/dev-mo-2278-merge/Compiler/ModelicaFlatTree/src/jastadd/ConstantEvaluation/ConstantEvaluation.jrag

    r13719 r13906  
    2222import java.util.Map;
    2323import java.util.Set;
     24import java.util.IllegalFormatException;
    2425
    2526import org.jmodelica.util.BinaryOperation;
     
    3233import org.jmodelica.util.values.ConstantEvaluationNotReadyException;
    3334import org.jmodelica.util.values.FunctionEvaluationException;
     35import org.jmodelica.util.values.CFormatSpecifier;
    3436
    3537
     
    28462848       
    28472849        CValue cval = getValue().ceval(evaluator);
    2848         boolean isReal = getValue().type().isReal();
    2849         if (isReal) {
     2850        final CFormatSpecifier format = formatSpecifier(evaluator);
     2851       
     2852        if (!format.isValid()) {
     2853            throw new ConstantEvaluationException(format.errorMessage());
     2854        }
     2855       
     2856        // Do any necessary type conversions.
     2857        if (format.expectedType.isReal()) {
    28502858            cval = cval.convertReal();
     2859        } else if (format.expectedType.isInteger()) {
     2860            cval = cval.convertInteger();
    28512861        }
    28522862        Object value = cval.objectValue();
    2853         final String format = formatString(evaluator);
    2854         char formatChar = format.charAt(format.length() - 1);
    2855        
    2856         // Modelica allows Integer to Real conversion for formatting but not the other direction
    2857         boolean mustBeInteger = formatChar == 'd' || formatChar == 'i' || formatChar == 'o' ||
    2858             formatChar == 'x' || formatChar == 'X' || formatChar == 'u' || formatChar == 'c';
    2859         if (mustBeInteger && isReal) {
    2860             throw new ConstantEvaluationException(cval, "format the resulting value. The format '"+ format + "' requires value of Integer type but Real value is provided. ");
    2861         }
    2862 
    2863         if (getValue().type().isInteger()) {
    2864             // Java formatter do not convert types
    2865             final boolean convertToFloat = formatChar == 'e' || formatChar == 'E' ||
    2866                     formatChar == 'f' || formatChar == 'g' || formatChar == 'G';
    2867             if (convertToFloat) {
    2868                 return new CValueString(String.format((Locale) null, format, cval.realValue()));
    2869             }
    2870             if (formatChar == 'u') {
    2871                 String formatCorrect = format.substring(0, format.length()-1) + "s";
    2872                 long unsigned = ((long) cval.intValue()) & 0xffffffffL; // Java 8 Integer.toUnsignedLong
    2873                 return new CValueString(String.format((Locale) null, formatCorrect, unsigned));
    2874             }
    2875 
    2876             if (formatChar == 'i') {
    2877                 String formatCorrect = format.substring(0, format.length()-1) + "d";
    2878                 return new CValueString(String.format((Locale) null, formatCorrect, cval.intValue()));
    2879             }
     2863        if (format.expectedType.isUnsigned()) {
     2864            // Convert to the closest Java equivalent to an unsigned int.
     2865            // TODO: When we no longer need to support Java 7, use Integer.toUnsignedLong instead.
     2866            value = Long.valueOf(((Integer) value).longValue() & 0xffffffffL);
    28802867        }
    28812868       
    28822869        try {
    2883             return new CValueString(String.format((Locale) null, format, value));
    2884         } catch (java.util.IllegalFormatException e) {
    2885             throw new ConstantEvaluationException(cval,
    2886                     "format the resulting value. " + format + " is not a supported valid format string");
     2870            return new CValueString(String.format((Locale) null, format.javaFormat, value));
     2871        } catch (IllegalFormatException e) {
     2872            throw new ConstantEvaluationException("The format string \"" + format.format +
     2873                    "\" and the value " + value + " do not match in the string conversion: " + this, e);
    28872874        }
    28882875    }
     
    28972884    }
    28982885
    2899     syn String FStringExp.formatString(VariableEvaluator evaluator) {
    2900         StringBuilder buf = new StringBuilder("%");
     2886    syn CFormatSpecifier FStringExp.formatSpecifier() = formatSpecifier(defaultVariableEvaluator());
     2887
     2888    syn CFormatSpecifier FStringExp.formatSpecifier(VariableEvaluator evaluator) {
    29012889        if (hasFormat()) {
    2902             buf.append(getFormat().ceval(evaluator).stringValue());
     2890            return CFormatSpecifier.parseFormat(getFormat().ceval(evaluator).stringValue());
    29032891        } else {
    2904             int minLength = minimumLength(evaluator);
    2905             if (minLength > 0) {
    2906                 if (leftJustified(evaluator)) {
    2907                     buf.append('-');
    2908                 }
    2909                 buf.append(minLength);
    2910             }
    2911             if (getValue().type().isReal()) {
    2912                 buf.append('.');
    2913                 buf.append(significantDigits(evaluator));
    2914             }
    2915             buf.append(getValue().type().formatSpecifier());
    2916         }
    2917         return buf.toString();
     2892            FType t = getValue().type();
     2893            int m = minimumLength(evaluator);
     2894            boolean l = leftJustified(evaluator);
     2895            if (t.isReal()) {
     2896                int s = significantDigits(evaluator);
     2897                return CFormatSpecifier.realFormat(l, m, s);
     2898            } else if (t.isInteger()) {
     2899                return CFormatSpecifier.integerFormat(l, m);
     2900            } else {
     2901                return CFormatSpecifier.stringFormat(l, m);
     2902            }
     2903        }
    29182904    }
    29192905
    29202906    syn int FStringExp.minimumLength(VariableEvaluator evaluator)     =
    2921         hasMinimumLength() ? getMinimumLength().ceval(evaluator).intValue() : 0;
     2907        hasMinimumLength() ? getMinimumLength().ceval(evaluator).intValue() : 1;
    29222908    syn boolean FStringExp.leftJustified(VariableEvaluator evaluator) =
    29232909        hasLeftJustified() ? getLeftJustified().ceval(evaluator).booleanValue() : true;
    29242910    syn int FStringExp.significantDigits(VariableEvaluator evaluator) =
    29252911        hasSignificantDigits() ? getSignificantDigits().ceval(evaluator).intValue() : DEFAULT_PRECISION;
    2926     syn String FType.formatSpecifier() {
     2912    syn String FType.formatConversion() {
    29272913        throw new UnsupportedOperationException();
    29282914    }
    2929     eq FRealType.formatSpecifier()    = "g";
    2930     eq FIntegerType.formatSpecifier() = "d";
    2931     eq FBooleanType.formatSpecifier() = "s";
    2932     eq FEnumType.formatSpecifier()    = "s";
    2933     eq FStringType.formatSpecifier()  = "s";
     2915    eq FRealType.formatConversion()    = "g";
     2916    eq FIntegerType.formatConversion() = "d";
     2917    eq FBooleanType.formatConversion() = "s";
     2918    eq FEnumType.formatConversion()    = "s";
     2919    eq FStringType.formatConversion()  = "s";
    29342920    public static final int FStringExp.DEFAULT_PRECISION = 6;
    29352921
  • branches/dev-mo-2278-merge/Compiler/ModelicaFlatTree/src/jastadd/FlatAPI/FlatAPI.jrag

    r13622 r13906  
    44684468            return unboundCopy();
    44694469    }
     4470
     4471    /**
     4472     * The format string including the implicit leading "%", if the format argument is given.
     4473     */
     4474    syn lazy Opt<FExp> FStringExp.getCFormatOpt() {
     4475        // TODO: To save memory, this could be solved in the C code generation instead.
     4476        if (hasFormat()) {
     4477            FExp fmt = getFormat();
     4478            FExp exp = fmt.treeCopy();
     4479            if (!formatSpecifier().initialPercent) {
     4480                exp = new FStringAddExp(new FStringLitExp("%"), exp);
     4481            }
     4482            if (fmt.variability().fixedParameterOrLess()) {
     4483                try {
     4484                    exp.parent = this;
     4485                    exp = exp.ceval().buildLiteral();
     4486                } catch (ConstantEvaluationException e) {
     4487                    // If we can't evaluate, just leave it as is
     4488                }
     4489            }
     4490            return new Opt<FExp>(exp);
     4491        } else {
     4492            return new Opt<FExp>();
     4493        }
     4494    }
    44704495}
  • branches/dev-mo-2278-merge/Compiler/ModelicaFlatTree/src/jastadd/PrettyPrint.jrag

    r13846 r13906  
    18611861    }
    18621862
    1863     protected static final String FBuiltInFunctionCall.SEP = ", ";
    1864    
    1865     /**
    1866      * Pretty-print all arguments of function.
    1867      *
    1868      * Default implementation prints all direct FExp children (including those in Lists and Opts),
    1869      * separated by {@link #SEP}.
    1870      */
    1871     protected void FBuiltInFunctionCall.prettyPrintArguments(Printer p, CodeStream str, String indent) {
    1872         String pre = "";
    1873         for (FExp exp : myArgs()) {
    1874             str.print(pre);
    1875             p.print(exp, str, indent);
    1876             pre = SEP;
    1877         }
    1878     }
    1879    
     1863    protected static final String FBuiltInFunctionCall.SEP = ", ";
     1864
     1865    /**
     1866     * Pretty-print all arguments of function.
     1867     *
     1868     * Default implementation will in instance tree print the original arguments, and in
     1869     * flat tree print all direct FExp children (including those in Lists and Opts),
     1870     * in either case separated by {@link #SEP}.
     1871     */
     1872    protected void FBuiltInFunctionCall.prettyPrintArguments(Printer p, CodeStream str, String indent) {
     1873        String pre = "";
     1874        if (getNumOriginalArg() > 0) {
     1875            for (InstFunctionArgument arg : getOriginalArgs()) {
     1876                if (arg.isGiven()) {
     1877                    str.print(pre);
     1878                    p.print(arg, str, indent);
     1879                    pre = SEP;
     1880                }
     1881            }
     1882        } else {
     1883            for (FExp exp : myArgs()) {
     1884                str.print(pre);
     1885                p.print(exp, str, indent);
     1886                pre = SEP;
     1887            }
     1888        }
     1889    }
     1890
    18801891    protected void FInfArgsFunctionCall.prettyPrintArguments(Printer p, CodeStream str, String indent) {
    18811892        getFExps().prettyPrintWithSep(p, str, indent, SEP);
  • branches/dev-mo-2278-merge/Compiler/ModelicaFlatTree/src/jastadd/ast/FlatModelica.ast

    r13605 r13906  
    16061606 * String conversion operator.
    16071607 */
    1608 FStringExp : FBuiltInFunctionCall ::= Value:FExp [MinimumLength:FExp] [LeftJustified:FExp] [SignificantDigits:FExp] [Format:FExp];
     1608FStringExp : FBuiltInFunctionCall ::= Value:FExp
     1609                                      [MinimumLength:FExp]
     1610                                      [LeftJustified:FExp]
     1611                                      [SignificantDigits:FExp]
     1612                                      [Format:FExp]
     1613                                      /[CFormat:FExp]/;
    16091614
    16101615/**
  • branches/dev-mo-2278-merge/Compiler/ModelicaFlatTree/test/modelica/EvaluationTests.mo

    r13512 r13906  
    46824682
    46834683model StringConvertWithParam1
     4684    /* TODO: a constant with a binding expression depending on parameters isn't really allowed,
     4685             but we don't check it - need to find a better way to test this when that is fixed
     4686             perhaps a string param that becomes structural?
     4687     */
    46844688    parameter Integer len = 8;
    46854689    parameter Boolean left = false;
     
    46944698        flatModel="
    46954699fclass EvaluationTests.StringConvert.StringConvertWithParam1
    4696  structural parameter Integer len = 8 /* 8 */;
    4697  structural parameter Boolean left = false /* false */;
    4698  structural parameter Integer dig = 4 /* 4 */;
     4700 parameter Integer len = 8 /* 8 */;
     4701 parameter Boolean left = false /* false */;
     4702 parameter Integer dig = 4 /* 4 */;
    46994703 constant Real x = 1.23456789;
    47004704 constant String s = \"   1.23\";
     
    47054709
    47064710model StringConvertWithParam2
     4711    /* TODO: a constant with a binding expression depending on parameters isn't really allowed,
     4712             but we don't check it - need to find a better way to test this when that is fixed
     4713             perhaps a string param that becomes structural?
     4714     */
    47074715    parameter String fmtSize = "10.4";
    47084716    constant Real x = 1.23456789;
     
    47154723        flatModel="
    47164724fclass EvaluationTests.StringConvert.StringConvertWithParam2
    4717  parameter String fmtSize = \"10.4\" /* \"10.4\" */;
     4725 structural parameter String fmtSize = \"10.4\" /* \"10.4\" */;
    47184726 constant Real x = 1.23456789;
    47194727 constant String s = \"1.2346E+00\";
     
    48834891
    48844892model StringRealformatSpecifier_d
    4885     constant Real x = 1.23456789;
     4893    constant Real x = 1234.56789;
    48864894    constant String s = String(x, format = "3d");
    48874895
    48884896annotation(__JModelica(UnitTesting(tests={
    4889       ErrorTestCase(
    4890             name="StringRealformatSpecifier_d",
    4891             description="String() operator, Real, format using d specifier",
    4892             errorMessage="
    4893 Error at line 3, column 25, in file '...':
    4894   Could not evaluate binding expression for constant 's': 'String(x, \"3d\")'
    4895     Cannot format the resulting value. The format '%3d' requires value of Integer type but Real value is provided. CValueReal (1.23456789)
     4897    FlatteningTestCase(
     4898        name="StringRealformatSpecifier_d",
     4899        description="String() operator, Real, format using d specifier",
     4900        flatModel="
     4901fclass EvaluationTests.StringConvert.StringRealformatSpecifier_d
     4902 constant Real x = 1234.56789;
     4903 constant String s = \"1234\";
     4904end EvaluationTests.StringConvert.StringRealformatSpecifier_d;
    48964905")})));
    48974906end StringRealformatSpecifier_d;
     
    49144923
    49154924model StringRealformatSpecifier_i
    4916     constant Real x = 1.23456789;
     4925    constant Real x = 1234.56789;
    49174926    constant String s = String(x, format = "3i");
    49184927
    49194928annotation(__JModelica(UnitTesting(tests={
    4920     ErrorTestCase(
     4929    FlatteningTestCase(
    49214930        name="StringRealformatSpecifier_i",
    49224931        description="String() operator, Real, format using i specifier",
    4923         errorMessage="
    4924 Error at line 3, column 25, in file '...':
    4925   Could not evaluate binding expression for constant 's': 'String(x, \"3i\")'
    4926     Cannot format the resulting value. The format '%3i' requires value of Integer type but Real value is provided. CValueReal (1.23456789)
     4932        flatModel="
     4933fclass EvaluationTests.StringConvert.StringRealformatSpecifier_i
     4934 constant Real x = 1234.56789;
     4935 constant String s = \"1234\";
     4936end EvaluationTests.StringConvert.StringRealformatSpecifier_i;
    49274937")})));
    49284938end StringRealformatSpecifier_i;
     
    49454955
    49464956model StringRealformatSpecifier_o
    4947     constant Real x = 1.23456789;
     4957    constant Real x = 1234.56789;
    49484958    constant String s = String(x, format = "3o");
    49494959
    49504960annotation(__JModelica(UnitTesting(tests={
    4951     ErrorTestCase(
     4961    FlatteningTestCase(
    49524962        name="StringRealformatSpecifier_o",
    49534963        description="String() operator, Real, format using o specifier",
    4954         errorMessage="
    4955 Error at line 3, column 25, in file '...':
    4956   Could not evaluate binding expression for constant 's': 'String(x, \"3o\")'
    4957     Cannot format the resulting value. The format '%3o' requires value of Integer type but Real value is provided. CValueReal (1.23456789)
     4964        flatModel="
     4965fclass EvaluationTests.StringConvert.StringRealformatSpecifier_o
     4966 constant Real x = 1234.56789;
     4967 constant String s = \"2322\";
     4968end EvaluationTests.StringConvert.StringRealformatSpecifier_o;
    49584969")})));
    49594970end StringRealformatSpecifier_o;
     
    49764987
    49774988model StringRealformatSpecifier_x
    4978     constant Real x = 1.23456789;
     4989    constant Real x = 1234.56789;
    49794990    constant String s = String(x, format = "3x");
    49804991
    49814992annotation(__JModelica(UnitTesting(tests={
    4982     ErrorTestCase(
     4993    FlatteningTestCase(
    49834994        name="StringRealformatSpecifier_x",
    49844995        description="String() operator, Real, format using x specifier",
    4985         errorMessage="
    4986 Error at line 3, column 25, in file '...':
    4987   Could not evaluate binding expression for constant 's': 'String(x, \"3x\")'
    4988     Cannot format the resulting value. The format '%3x' requires value of Integer type but Real value is provided. CValueReal (1.23456789)
     4996        flatModel="
     4997fclass EvaluationTests.StringConvert.StringRealformatSpecifier_x
     4998 constant Real x = 1234.56789;
     4999 constant String s = \"4d2\";
     5000end EvaluationTests.StringConvert.StringRealformatSpecifier_x;
    49895001")})));
    49905002end StringRealformatSpecifier_x;
     
    50075019
    50085020model StringRealformatSpecifier_X
    5009     constant Real x = 1.23456789;
     5021    constant Real x = 1234.56789;
    50105022    constant String s = String(x, format = "3X");
    50115023
    50125024annotation(__JModelica(UnitTesting(tests={
    5013     ErrorTestCase(
     5025    FlatteningTestCase(
    50145026        name="StringRealformatSpecifier_X",
    50155027        description="String() operator, Real, format using X specifier",
    5016         errorMessage="
    5017 Error at line 3, column 25, in file '...':
    5018   Could not evaluate binding expression for constant 's': 'String(x, \"3X\")'
    5019     Cannot format the resulting value. The format '%3X' requires value of Integer type but Real value is provided. CValueReal (1.23456789)
     5028        flatModel="
     5029fclass EvaluationTests.StringConvert.StringRealformatSpecifier_X
     5030 constant Real x = 1234.56789;
     5031 constant String s = \"4D2\";
     5032end EvaluationTests.StringConvert.StringRealformatSpecifier_X;
    50205033")})));
    50215034end StringRealformatSpecifier_X;
     
    50385051
    50395052model StringRealformatSpecifier_u
    5040     constant Real x = 1.23456789;
     5053    constant Real x = -1234.56789;
    50415054    constant String s = String(x, format = "3u");
    50425055
    50435056annotation(__JModelica(UnitTesting(tests={
    5044     ErrorTestCase(
     5057    FlatteningTestCase(
    50455058        name="StringRealformatSpecifier_u",
    5046         description="String() operator, Real, format using u specifier",
    5047         errorMessage="
    5048 Error at line 3, column 25, in file '...':
    5049   Could not evaluate binding expression for constant 's': 'String(x, \"3u\")'
    5050     Cannot format the resulting value. The format '%3u' requires value of Integer type but Real value is provided. CValueReal (1.23456789)
     5059        description="String() operator,  Real, format using u specifier",
     5060        flatModel="
     5061fclass EvaluationTests.StringConvert.StringRealformatSpecifier_u
     5062 constant Real x = -1234.56789;
     5063 constant String s = \"4294966061\";
     5064end EvaluationTests.StringConvert.StringRealformatSpecifier_u;
    50515065")})));
    50525066end StringRealformatSpecifier_u;
     
    50695083
    50705084model StringRealformatSpecifier_c
    5071     constant Real x = 1.23456789;
     5085    constant Real x = 123.456789;
    50725086    constant String s = String(x, format = "3c");
    50735087
    50745088annotation(__JModelica(UnitTesting(tests={
    5075     ErrorTestCase(
     5089    FlatteningTestCase(
    50765090        name="StringRealformatSpecifier_c",
    5077         description="String() operator, Real, format using c specifier",
    5078         errorMessage="
    5079 Error at line 3, column 25, in file '...':
    5080   Could not evaluate binding expression for constant 's': 'String(x, \"3c\")'
    5081     Cannot format the resulting value. The format '%3c' requires value of Integer type but Real value is provided. CValueReal (1.23456789)
    5082 ")})));
    5083 
     5091        description="String() operator,  Real, format using c specifier",
     5092        flatModel="
     5093fclass EvaluationTests.StringConvert.StringRealformatSpecifier_c
     5094 constant Real x = 123.456789;
     5095 constant String s = \"  {\";
     5096end EvaluationTests.StringConvert.StringRealformatSpecifier_c;
     5097")})));
    50845098end StringRealformatSpecifier_c;
    50855099
     
    51005114end StringIntegerformatSpecifier_c;
    51015115
    5102 model StringIncorrectformat
    5103     constant Integer x = 1234;
    5104     constant String s = String(x, format = "*.1.3c");
     5116
     5117model StringConvertInvalidFormat1
     5118    parameter Real x = 1.23456789;
     5119    parameter String s = String(x, format = "1.2.3g");
    51055120
    51065121annotation(__JModelica(UnitTesting(tests={
    51075122    ErrorTestCase(
    5108         name="StringIncorrectformat",
    5109         description="String() operator, Real, format using c specifier",
     5123        name="StringConvert_StringConvertInvalidFormat1",
     5124        description="String() operator, Real, bad format string",
    51105125        errorMessage="
    5111 Error at line 3, column 25, in file '...':
    5112   Could not evaluate binding expression for constant 's': 'String(x, \"*.1.3c\")'
    5113     Cannot format the resulting value. %*.1.3c is not a supported valid format stringCValueInteger (1234)
    5114 ")})));
    5115 end StringIncorrectformat;
     5126Error at line 3, column 26, in file '...', INVALID_FORMAT_STRING:
     5127  Failed to parse format string \"1.2.3g\".
     5128")})));
     5129end StringConvertInvalidFormat1;
     5130
     5131
     5132model StringConvertInvalidFormat2
     5133    parameter Integer x = 1;
     5134    parameter String s = String(x, format = "ld");
     5135
     5136annotation(__JModelica(UnitTesting(tests={
     5137    ErrorTestCase(
     5138        name="StringConvert_StringConvertInvalidFormat2",
     5139        description="String() operator, Real, bad format string (different internal exception)",
     5140        errorMessage="
     5141Error at line 3, column 26, in file '...', INVALID_FORMAT_STRING:
     5142  Length modifiers are not allowed in format strings, but \"ld\" has length modifier \"l\".
     5143")})));
     5144end StringConvertInvalidFormat2;
    51165145
    51175146end StringConvert;
  • branches/dev-mo-2278-merge/Compiler/ModelicaFrontEnd/src/jastadd/errorcheck/ComplianceCheck.jadd

    r11639 r13906  
    283283
    284284    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_NON_FIXED_STRING_ARGUMENT =
    285             new SimpleErrorProducer("UNSUPPORTED_NON_FIXED_STRING_ARGUMENT", ProblemKind.COMPLIANCE, "%s with higher than parameter variability is not supported");
     285            new SimpleErrorProducer("UNSUPPORTED_NON_FIXED_STRING_ARGUMENT", ProblemKind.COMPLIANCE,
     286                    "Argument format of String operator is only supported as a fixed parameter expression.");
    286287
    287288    public void FStringExp.complianceCheck(ErrorCheckType checkType) {
    288289        super.complianceCheck(checkType);
    289         boolean func = inFunction();
    290         if (!func && hasMinimumLength()) {
    291             getMinimumLength().markAsStructuralParameter(checkType);
    292             if (!getMinimumLength().variability().parameterOrLess())
    293                 UNSUPPORTED_NON_FIXED_STRING_ARGUMENT.invoke(getMinimumLength(), "minimumLength");
    294         }
    295         if (!func && hasLeftJustified()) {
    296             getLeftJustified().markAsStructuralParameter(checkType);
    297            if (!getLeftJustified().variability().parameterOrLess())
    298                UNSUPPORTED_NON_FIXED_STRING_ARGUMENT.invoke(getLeftJustified(), "leftJustified");
    299         }
    300         if (!func && hasSignificantDigits()) {
    301             getSignificantDigits().markAsStructuralParameter(checkType);
    302             if (!getSignificantDigits().variability().parameterOrLess())
    303                 UNSUPPORTED_NON_FIXED_STRING_ARGUMENT.invoke(getSignificantDigits(), "significantDigits");
    304        }
     290        if (hasFormat()) {
     291            getFormat().markAsStructuralParameter(checkType);
     292            if (!getFormat().variability().parameterOrLess())
     293                UNSUPPORTED_NON_FIXED_STRING_ARGUMENT.invoke(getFormat());
     294        }
    305295    }
    306296
  • branches/dev-mo-2278-merge/Compiler/ModelicaFrontEnd/src/jastadd/errorcheck/ContentsCheck.jadd

    r13103 r13906  
    2222import org.jmodelica.common.URIResolver;
    2323import org.jmodelica.common.URIResolver.URIException;
     24import org.jmodelica.util.problemHandling.SimpleErrorOrWarningProducer;
    2425
    2526aspect ContentCheck {
     
    389390            if (!ch.variability().parameterOrLess()) {
    390391                NON_PARAMETER_SAMPLE_ARGUMENTS.invoke(ch);
     392            }
     393        }
     394    }
     395   
     396    public static final SimpleErrorOrWarningProducer ASTNode.INVALID_FORMAT_STRING =
     397            new SimpleErrorOrWarningProducer("INVALID_FORMAT_STRING", ProblemKind.SEMANTIC, "%s");
     398
     399    public void FStringExp.contentCheck(ErrorCheckType checkType) {
     400        if (hasFormat()) {
     401            try {
     402                CFormatSpecifier format = formatSpecifier();
     403                if (format.hasProblem()) {
     404                    INVALID_FORMAT_STRING.invoke(this, format.hasError(), format.errorMessage());
     405                }
     406            } catch (ConstantEvaluationException e) {
     407                // If we can't evaluate it, don't do a static error check of it.
    391408            }
    392409        }
  • branches/dev-mo-2278-merge/Compiler/ModelicaFrontEnd/src/java/org/jmodelica/util/problemHandling/SimpleErrorProducer.java

    r9003 r13906  
    66/**
    77 * If you have a error message which only consists of a string and format
    8  * arguments, then this is the right class for you. Simple create a static
     8 * arguments, then this is the right class for you. Simply create a static
    99 * final field instantiating this class and then invoke the error as needed!
    1010 */
  • branches/dev-mo-2278-merge/Compiler/ModelicaFrontEnd/src/java/org/jmodelica/util/problemHandling/SimpleWarningProducer.java

    r9003 r13906  
    55
    66/**
    7  * Convenient class which takes a string message on construction, an
     7 * Convenience class which takes a string message on construction, an
    88 * optional list of format arguments when invoked and produces a warning.
    99 */
  • branches/dev-mo-2278-merge/Compiler/ModelicaFrontEnd/src/java/org/jmodelica/util/values/ConstantEvaluationException.java

    r9590 r13906  
    1414    public ConstantEvaluationException() {
    1515        super("Unspecified constant evaluation failure");
     16        this.val = null;
     17    }
     18
     19    public ConstantEvaluationException(String msg) {
     20        super(msg);
     21        this.val = null;
     22    }
     23
     24    public ConstantEvaluationException(String msg, Throwable cause) {
     25        super(msg, cause);
    1626        this.val = null;
    1727    }
  • branches/dev-mo-2278-merge/Compiler/ModelicaFrontEnd/test/modelica/ComplianceTests.mo

    r11639 r13906  
    527527
    528528model StringOperator1
     529    function f
     530        input Real x;
     531        input String f;
     532        output String o;
     533    algorithm
     534        o := String(x, format=f);
     535    end f;
     536   
    529537    Integer len = if time < 0 then 4 else 3;
    530538    Integer digits = if time < 0 then 5 else 2;
     539    String s1 = String(time, format = fmt1);
     540    String s2 = String(time, format = fmt2);
     541    String s3 = f(time, "g");
     542    parameter String fmt1 = if selFmt1 == 1 then "u" else "g";
     543    parameter String fmt2 = "f";
     544    parameter Integer selFmt1(fixed = false);
     545initial equation
     546    selFmt1 = if len == 4 then 1 else 2;
    531547equation
    532548    assert(time>2.0, String(time, significantDigits=digits, minimumLength=len, leftJustified=time<1));
    533     annotation(__JModelica(UnitTesting(tests={
    534         ComplianceErrorTestCase(
    535             name="StringOperator1",
    536             description="Test compliance warnings for non fixed string operator arguments (significantDigits, minimumLength, leftJustified)",
    537             errorMessage="
    538 3 errors found:
    539 
    540 Compliance error at line 5, column 53, in file 'Compiler/ModelicaFrontEnd/test/modelica/ComplianceTests.mo', UNSUPPORTED_NON_FIXED_STRING_ARGUMENT:
    541   significantDigits with higher than parameter variability is not supported
    542 
    543 Compliance error at line 5, column 75, in file 'Compiler/ModelicaFrontEnd/test/modelica/ComplianceTests.mo', UNSUPPORTED_NON_FIXED_STRING_ARGUMENT:
    544   minimumLength with higher than parameter variability is not supported
    545 
    546 Compliance error at line 5, column 94, in file 'Compiler/ModelicaFrontEnd/test/modelica/ComplianceTests.mo', UNSUPPORTED_NON_FIXED_STRING_ARGUMENT:
    547   leftJustified with higher than parameter variability is not supported
     549    assert(time>2.0, String(time, format=String(len)+"."+String(digits)+"f"));
     550annotation(__JModelica(UnitTesting(tests={
     551    ComplianceErrorTestCase(
     552        name="StringOperator1",
     553        description="Test compliance warnings for non fixed string operator format argument",
     554        errorMessage="
     555
     556
     557Compliance error at line 7, column 31, in file '...', UNSUPPORTED_NON_FIXED_STRING_ARGUMENT:
     558  Argument format of String operator is only supported as a fixed parameter expression.
     559
     560Compliance error at line 15, column 5, in file '...':
     561  Parameters with fixed=false can not be used as structural parameters
     562
     563Compliance error at line 22, column 42, in file '...', UNSUPPORTED_NON_FIXED_STRING_ARGUMENT:
     564  Argument format of String operator is only supported as a fixed parameter expression.
    548565")})));
    549566end StringOperator1;
    550567
     568
     569model StringOperator2
     570    String s = String(time, format="%f");
     571
     572annotation(__JModelica(UnitTesting(tests={
     573    WarningTestCase(
     574        name="StringOperator2",
     575        description="Test warning for supplying the initial % of format specifier",
     576        errorMessage="
     577
     578
     579Warning at line 2, column 16, in file '...', INVALID_FORMAT_STRING:
     580  The format string argument should not include the initial '%': \"%f\".
     581")})));
     582end StringOperator2;
    551583
    552584
  • branches/dev-mo-2278-merge/Compiler/OptimicaFrontEnd/src/jastadd/OptimicaParser.jrag

    r13882 r13906  
    7070   
    7171    refine Parsers public short ParserHandler.functionCallListGoal() {
    72         return org.jmodelica.modelica.parser.ModelicaParser.AltGoals.function_call_list;
     72        return org.jmodelica.optimica.parser.ModelicaParser.AltGoals.function_call_list;
    7373    }
    7474
  • branches/dev-mo-2278-merge/RuntimeLibrary/src

Note: See TracChangeset for help on using the changeset viewer.