Changeset 13702
- Timestamp:
- Oct 8, 2019 5:15:12 PM (2 months ago)
- Location:
- branches/dev-mj-5835
- Files:
-
- 1 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/dev-mj-5835/CHANGELOG.txt
r13498 r13702 1 1 ================= Unreleased ================== 2 2 # Fixed ; Minor ; Compiler; #5835 3 Format string argument to the String function is now useable.3 Format string argument to the String function is now respected during constant evaluations. 4 4 5 5 # Change ; Minor ; Compiler; #5830 -
branches/dev-mj-5835/Compiler/ModelicaCBackEnd/src/jastadd/CCodeGen/CCodeGenExpressions.jrag
r13431 r13702 17 17 import java.util.Arrays; 18 18 import org.jmodelica.common.ccodegen.CFuncParamDirection; 19 import org.jmodelica.util.values.CFormatSpecifier; 20 import org.jmodelica.util.collections.TransformerIterable; 19 21 20 22 aspect CCodeGenExpressions { … … 792 794 genStringFormat_C(p, str, indent); 793 795 str.print(", "); 794 genStringParts_C(p, str, indent );796 genStringParts_C(p, str, indent, null); 795 797 str.println(");"); 796 798 } … … 856 858 @Override 857 859 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 } 859 863 genTopStringDecl(p, str, indent); 860 864 } … … 862 866 @Override 863 867 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 } 865 871 genTopStringInit(p, str, indent); 866 872 } … … 873 879 @Override 874 880 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 protected 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 }; 876 894 } 877 895 … … 947 965 public void FStringExp.genStringFormat_C(CodePrinter p, CodeStream str, String indent) { 948 966 if (hasFormat()) { 949 p.print(get Format(), str, indent);967 p.print(getCFormat(), str, indent); 950 968 } else { 951 969 if (hasLeftJustified()) { … … 987 1005 if (getValue().type().isReal()) 988 1006 str.print(".*"); 989 str.print(getValue().type().format Specifier());1007 str.print(getValue().type().formatConversion()); 990 1008 str.print("\""); 991 1009 } 992 1010 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) { 994 1013 // TODO: This method should dispatch to the type! 995 1014 FType t = type(); … … 1004 1023 str.print(", JMI_TRUE, \"true\", \"false\")"); 1005 1024 } else { 1006 if (t.isInteger()) 1025 if (format != null && format.expectedType.isUnsigned()) { 1026 str.print("(unsigned int) "); 1027 } else if ((format == null) ? t.isInteger() : format.expectedType.isInteger()) { 1007 1028 str.print("(int) "); 1029 } 1008 1030 p.print(this, str, indent); 1009 1031 } … … 1011 1033 1012 1034 @Override 1013 public void FStringExp.genStringParts_C(CodePrinter p, CodeStream str, String indent) { 1014 getValue().genStringParts_C(p, str, indent); 1035 public void FStringExp.genStringParts_C( 1036 CodePrinter p, CodeStream str, String indent, CFormatSpecifier format) { 1037 try { 1038 // This depends on non-parameters being evaluatable. 1039 format = formatSpecifier(); 1040 } catch (ConstantEvaluationException e) { 1041 // Assume that we don't have a format that converts real -> integer. 1042 } 1043 getValue().genStringParts_C(p, str, indent, format); 1015 1044 } 1016 1045 -
branches/dev-mj-5835/Compiler/ModelicaCBackEnd/test/modelica/CCodeGenTests.mo
r13168 r13702 1079 1079 StringCompare(" medium", String(enumVar, minimumLength=12, leftJustified=false)); 1080 1080 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")); 1083 1083 1084 1084 annotation(__JModelica(UnitTesting(tests={ … … 16041 16041 end f; 16042 16042 16043 Real y = f(-time, 3, true, " %g");16043 Real y = f(-time, 3, true, "g"); 16044 16044 16045 16045 annotation(__JModelica(UnitTesting(tests={ … … 16056 16056 JMI_DEF(STR, s_v) 16057 16057 JMI_DEF_STR_DYNA(tmp_1) 16058 JMI_DEF_STR_DYNA(tmp_2) 16059 JMI_DEF_STR_DYNA(tmp_3) 16058 16060 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)) 16060 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); 16061 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); 16062 snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), COND_EXP_EQ(JMI_FALSE, JMI_TRUE, \"%-*.*g\", \"%*.*g\"), (int) i_v, (int) i_v, x_v); 16063 snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*.*g\", \"%*.*g\"), (int) i_v, (int) i_v, x_v); 16064 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); 16065 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); 16067 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); 16068 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); 16069 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); 16071 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\")); 16072 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\")); 16073 snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*s\", \"%*s\"), (int) i_v, COND_EXP_EQ(b_v, JMI_TRUE, \"true\", \"false\")); 16074 JMI_ASG(STR, s_v, tmp_1) 16061 JMI_INI_STR_DYNA(tmp_1, 1 + JMI_LEN(fmt_v)) 16062 snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), \"%s\", \"%\"); 16063 snprintf(JMI_STR_END(tmp_1), JMI_STR_LEFT(tmp_1), \"%s\", fmt_v); 16064 JMI_INI_STR_DYNA(tmp_2, 1 + JMI_LEN(fmt_v)) 16065 snprintf(JMI_STR_END(tmp_2), JMI_STR_LEFT(tmp_2), \"%s\", \"%\"); 16066 snprintf(JMI_STR_END(tmp_2), JMI_STR_LEFT(tmp_2), \"%s\", fmt_v); 16067 JMI_INI_STR_DYNA(tmp_3, 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)) 16068 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*.*g\", \"%*.*g\"), (int) i_v, (int) 1.0, x_v); 16069 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*.*g\", \"%*.*g\"), (int) 2.0, (int) i_v, x_v); 16070 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), COND_EXP_EQ(JMI_FALSE, JMI_TRUE, \"%-*.*g\", \"%*.*g\"), (int) i_v, (int) i_v, x_v); 16071 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*.*g\", \"%*.*g\"), (int) i_v, (int) i_v, x_v); 16072 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), COND_EXP_EQ(b_v, JMI_TRUE, \"%-.*g\", \"%.*g\"), (int) i_v, x_v); 16073 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), \"%-.*g\", (int) 6, x_v); 16074 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), tmp_1, x_v); 16075 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*d\", \"%*d\"), (int) 2.0, (int) i_v); 16076 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), COND_EXP_EQ(JMI_TRUE, JMI_TRUE, \"%-*d\", \"%*d\"), (int) i_v, (int) i_v); 16077 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*d\", \"%*d\"), (int) i_v, (int) i_v); 16078 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), tmp_2, (int) i_v); 16079 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*s\", \"%*s\"), (int) 2.0, COND_EXP_EQ(b_v, JMI_TRUE, \"true\", \"false\")); 16080 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), COND_EXP_EQ(JMI_TRUE, JMI_TRUE, \"%-*s\", \"%*s\"), (int) i_v, COND_EXP_EQ(b_v, JMI_TRUE, \"true\", \"false\")); 16081 snprintf(JMI_STR_END(tmp_3), JMI_STR_LEFT(tmp_3), COND_EXP_EQ(b_v, JMI_TRUE, \"%-*s\", \"%*s\"), (int) i_v, COND_EXP_EQ(b_v, JMI_TRUE, \"true\", \"false\")); 16082 JMI_ASG(STR, s_v, tmp_3) 16075 16083 JMI_RET(GEN, y_o, y_v) 16076 16084 JMI_DYNAMIC_FREE() -
branches/dev-mj-5835/Compiler/ModelicaFlatTree/src/jastadd/ConstantEvaluation/ConstantEvaluation.jrag
r13506 r13702 22 22 import java.util.Map; 23 23 import java.util.Set; 24 import java.util.IllegalFormatException; 24 25 25 26 import org.jmodelica.util.BinaryOperation; … … 32 33 import org.jmodelica.util.values.ConstantEvaluationNotReadyException; 33 34 import org.jmodelica.util.values.FunctionEvaluationException; 35 import org.jmodelica.util.values.CFormatSpecifier; 34 36 35 37 … … 2794 2796 2795 2797 CValue cval = getValue().ceval(evaluator); 2796 boolean isReal = getValue().type().isReal(); 2797 if (isReal) { 2798 final CFormatSpecifier format = formatSpecifier(evaluator); 2799 2800 if (!format.isValid()) { 2801 throw new ConstantEvaluationException(format.errorMessage()); 2802 } 2803 2804 // Do any necessary type conversions. 2805 if (format.expectedType.isReal()) { 2798 2806 cval = cval.convertReal(); 2807 } else if (format.expectedType.isInteger()) { 2808 cval = cval.convertInteger(); 2799 2809 } 2800 2810 Object value = cval.objectValue(); 2801 final String format = formatString(evaluator); 2802 char formatChar = format.charAt(format.length() - 1); 2803 2804 // Modelica allows Integer to Real conversion for formatting but not the other direction 2805 boolean mustBeInteger = formatChar == 'd' || formatChar == 'i' || formatChar == 'o' || 2806 formatChar == 'x' || formatChar == 'X' || formatChar == 'u' || formatChar == 'c'; 2807 if (mustBeInteger && isReal) { 2808 throw new ConstantEvaluationException(cval, "format the resulting value. The format '"+ format + "' requires value of Integer type but Real value is provided. "); 2809 } 2810 2811 if (getValue().type().isInteger()) { 2812 // Java formatter do not convert types 2813 final boolean convertToFloat = formatChar == 'e' || formatChar == 'E' || 2814 formatChar == 'f' || formatChar == 'g' || formatChar == 'G'; 2815 if (convertToFloat) { 2816 return new CValueString(String.format((Locale) null, format, cval.realValue())); 2817 } 2818 if (formatChar == 'u') { 2819 String formatCorrect = format.substring(0, format.length()-1) + "s"; 2820 return new CValueString(String.format((Locale) null, formatCorrect, Integer.toUnsignedLong(cval.intValue()))); 2821 } 2822 2823 if (formatChar == 'i') { 2824 String formatCorrect = format.substring(0, format.length()-1) + "d"; 2825 return new CValueString(String.format((Locale) null, formatCorrect, cval.intValue())); 2826 } 2811 if (format.expectedType.isUnsigned()) { 2812 // Convert to the closest Java equivalent to an unsigned int. 2813 // TODO: When we no longer need to support Java 7, use Integer.toUnsignedLong instead. 2814 value = Long.valueOf(((Integer) value).longValue() & 0xffffffffL); 2827 2815 } 2828 2816 2829 2817 try { 2830 return new CValueString(String.format((Locale) null, format , value));2831 } catch ( java.util.IllegalFormatException e) {2832 throw new ConstantEvaluationException( cval,2833 " format the resulting value. " + format + " is not a supported valid format string");2818 return new CValueString(String.format((Locale) null, format.javaFormat, value)); 2819 } catch (IllegalFormatException e) { 2820 throw new ConstantEvaluationException("The format string \"" + format.format + 2821 "\" and the value " + value + " do not match in the string conversion: " + this, e); 2834 2822 } 2835 2823 } … … 2844 2832 } 2845 2833 2846 syn String FStringExp.formatString(VariableEvaluator evaluator) { 2847 StringBuilder buf = new StringBuilder("%"); 2834 syn CFormatSpecifier FStringExp.formatSpecifier() = formatSpecifier(defaultVariableEvaluator()); 2835 2836 syn CFormatSpecifier FStringExp.formatSpecifier(VariableEvaluator evaluator) { 2848 2837 if (hasFormat()) { 2849 buf.append(getFormat().ceval(evaluator).stringValue());2838 return CFormatSpecifier.parseFormat(getFormat().ceval(evaluator).stringValue()); 2850 2839 } else { 2851 int minLength = minimumLength(evaluator); 2852 if (minLength > 0) { 2853 if (leftJustified(evaluator)) { 2854 buf.append('-'); 2855 } 2856 buf.append(minLength); 2857 } 2858 if (getValue().type().isReal()) { 2859 buf.append('.'); 2860 buf.append(significantDigits(evaluator)); 2861 } 2862 buf.append(getValue().type().formatSpecifier()); 2863 } 2864 return buf.toString(); 2840 FType t = getValue().type(); 2841 int m = minimumLength(evaluator); 2842 boolean l = leftJustified(evaluator); 2843 if (t.isReal()) { 2844 int s = significantDigits(evaluator); 2845 return CFormatSpecifier.realFormat(l, m, s); 2846 } else if (t.isInteger()) { 2847 return CFormatSpecifier.integerFormat(l, m); 2848 } else { 2849 return CFormatSpecifier.stringFormat(l, m); 2850 } 2851 } 2865 2852 } 2866 2853 2867 2854 syn int FStringExp.minimumLength(VariableEvaluator evaluator) = 2868 hasMinimumLength() ? getMinimumLength().ceval(evaluator).intValue() : 0;2855 hasMinimumLength() ? getMinimumLength().ceval(evaluator).intValue() : 1; 2869 2856 syn boolean FStringExp.leftJustified(VariableEvaluator evaluator) = 2870 2857 hasLeftJustified() ? getLeftJustified().ceval(evaluator).booleanValue() : true; 2871 2858 syn int FStringExp.significantDigits(VariableEvaluator evaluator) = 2872 2859 hasSignificantDigits() ? getSignificantDigits().ceval(evaluator).intValue() : DEFAULT_PRECISION; 2873 syn String FType.format Specifier() {2860 syn String FType.formatConversion() { 2874 2861 throw new UnsupportedOperationException(); 2875 2862 } 2876 eq FRealType.format Specifier() = "g";2877 eq FIntegerType.format Specifier() = "d";2878 eq FBooleanType.format Specifier() = "s";2879 eq FEnumType.format Specifier() = "s";2880 eq FStringType.format Specifier() = "s";2863 eq FRealType.formatConversion() = "g"; 2864 eq FIntegerType.formatConversion() = "d"; 2865 eq FBooleanType.formatConversion() = "s"; 2866 eq FEnumType.formatConversion() = "s"; 2867 eq FStringType.formatConversion() = "s"; 2881 2868 public static final int FStringExp.DEFAULT_PRECISION = 6; 2882 2869 -
branches/dev-mj-5835/Compiler/ModelicaFlatTree/src/jastadd/FlatAPI/FlatAPI.jrag
r13456 r13702 4466 4466 return unboundCopy(); 4467 4467 } 4468 4469 /** 4470 * The format string including the implicit leading "%", if the format argument is given. 4471 */ 4472 syn lazy Opt<FExp> FStringExp.getCFormatOpt() { 4473 // TODO: To save memory, this could be solved in the C code generation instead. 4474 if (hasFormat()) { 4475 FExp fmt = getFormat(); 4476 FExp exp = new FStringAddExp(new FStringLitExp("%"), fmt.treeCopy()); 4477 if (fmt.variability().fixedParameterOrLess()) { 4478 try { 4479 exp.parent = this; 4480 exp = exp.ceval().buildLiteral(); 4481 } catch (ConstantEvaluationException e) { 4482 // If we can't evaluate, just leave it as is 4483 } 4484 } 4485 return new Opt<FExp>(exp); 4486 } else { 4487 return new Opt<FExp>(); 4488 } 4489 } 4468 4490 } -
branches/dev-mj-5835/Compiler/ModelicaFlatTree/src/jastadd/PrettyPrint.jrag
r13357 r13702 1849 1849 } 1850 1850 1851 protected static final String FBuiltInFunctionCall.SEP = ", "; 1852 1853 /** 1854 * Pretty-print all arguments of function. 1855 * 1856 * Default implementation prints all direct FExp children (including those in Lists and Opts), 1857 * separated by {@link #SEP}. 1858 */ 1859 protected void FBuiltInFunctionCall.prettyPrintArguments(Printer p, CodeStream str, String indent) { 1860 String pre = ""; 1861 for (FExp exp : myArgs()) { 1862 str.print(pre); 1863 p.print(exp, str, indent); 1864 pre = SEP; 1865 } 1866 } 1867 1851 protected static final String FBuiltInFunctionCall.SEP = ", "; 1852 1853 /** 1854 * Pretty-print all arguments of function. 1855 * 1856 * Default implementation will in instance tree print the original arguments, and in 1857 * flat tree print all direct FExp children (including those in Lists and Opts), 1858 * in either case separated by {@link #SEP}. 1859 */ 1860 protected void FBuiltInFunctionCall.prettyPrintArguments(Printer p, CodeStream str, String indent) { 1861 String pre = ""; 1862 if (getNumOriginalArg() > 0) { 1863 for (InstFunctionArgument arg : getOriginalArgs()) { 1864 if (arg.isGiven()) { 1865 str.print(pre); 1866 p.print(arg, str, indent); 1867 pre = SEP; 1868 } 1869 } 1870 } else { 1871 for (FExp exp : myArgs()) { 1872 str.print(pre); 1873 p.print(exp, str, indent); 1874 pre = SEP; 1875 } 1876 } 1877 } 1878 1868 1879 protected void FInfArgsFunctionCall.prettyPrintArguments(Printer p, CodeStream str, String indent) { 1869 1880 getFExps().prettyPrintWithSep(p, str, indent, SEP); -
branches/dev-mj-5835/Compiler/ModelicaFlatTree/src/jastadd/ast/FlatModelica.ast
r13357 r13702 1606 1606 * String conversion operator. 1607 1607 */ 1608 FStringExp : FBuiltInFunctionCall ::= Value:FExp [MinimumLength:FExp] [LeftJustified:FExp] [SignificantDigits:FExp] [Format:FExp]; 1608 FStringExp : FBuiltInFunctionCall ::= Value:FExp 1609 [MinimumLength:FExp] 1610 [LeftJustified:FExp] 1611 [SignificantDigits:FExp] 1612 [Format:FExp] 1613 /[CFormat:FExp]/; 1609 1614 1610 1615 /** -
branches/dev-mj-5835/Compiler/ModelicaFlatTree/test/modelica/EvaluationTests.mo
r13503 r13702 4682 4682 4683 4683 model 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 */ 4684 4688 parameter Integer len = 8; 4685 4689 parameter Boolean left = false; … … 4694 4698 flatModel=" 4695 4699 fclass EvaluationTests.StringConvert.StringConvertWithParam1 4696 structuralparameter Integer len = 8 /* 8 */;4697 structuralparameter Boolean left = false /* false */;4698 structuralparameter Integer dig = 4 /* 4 */;4700 parameter Integer len = 8 /* 8 */; 4701 parameter Boolean left = false /* false */; 4702 parameter Integer dig = 4 /* 4 */; 4699 4703 constant Real x = 1.23456789; 4700 4704 constant String s = \" 1.23\"; … … 4705 4709 4706 4710 model 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 */ 4707 4715 parameter String fmtSize = "10.4"; 4708 4716 constant Real x = 1.23456789; … … 4715 4723 flatModel=" 4716 4724 fclass EvaluationTests.StringConvert.StringConvertWithParam2 4717 parameter String fmtSize = \"10.4\" /* \"10.4\" */;4725 structural parameter String fmtSize = \"10.4\" /* \"10.4\" */; 4718 4726 constant Real x = 1.23456789; 4719 4727 constant String s = \"1.2346E+00\"; … … 4883 4891 4884 4892 model StringRealformatSpecifier_d 4885 constant Real x = 1 .23456789;4893 constant Real x = 1234.56789; 4886 4894 constant String s = String(x, format = "3d"); 4887 4895 4888 4896 annotation(__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=" 4901 fclass EvaluationTests.StringConvert.StringRealformatSpecifier_d 4902 constant Real x = 1234.56789; 4903 constant String s = \"1234\"; 4904 end EvaluationTests.StringConvert.StringRealformatSpecifier_d; 4896 4905 ")}))); 4897 4906 end StringRealformatSpecifier_d; … … 4914 4923 4915 4924 model StringRealformatSpecifier_i 4916 constant Real x = 1 .23456789;4925 constant Real x = 1234.56789; 4917 4926 constant String s = String(x, format = "3i"); 4918 4927 4919 4928 annotation(__JModelica(UnitTesting(tests={ 4920 ErrorTestCase(4929 FlatteningTestCase( 4921 4930 name="StringRealformatSpecifier_i", 4922 4931 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=" 4933 fclass EvaluationTests.StringConvert.StringRealformatSpecifier_i 4934 constant Real x = 1234.56789; 4935 constant String s = \"1234\"; 4936 end EvaluationTests.StringConvert.StringRealformatSpecifier_i; 4927 4937 ")}))); 4928 4938 end StringRealformatSpecifier_i; … … 4945 4955 4946 4956 model StringRealformatSpecifier_o 4947 constant Real x = 1 .23456789;4957 constant Real x = 1234.56789; 4948 4958 constant String s = String(x, format = "3o"); 4949 4959 4950 4960 annotation(__JModelica(UnitTesting(tests={ 4951 ErrorTestCase(4961 FlatteningTestCase( 4952 4962 name="StringRealformatSpecifier_o", 4953 4963 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=" 4965 fclass EvaluationTests.StringConvert.StringRealformatSpecifier_o 4966 constant Real x = 1234.56789; 4967 constant String s = \"2322\"; 4968 end EvaluationTests.StringConvert.StringRealformatSpecifier_o; 4958 4969 ")}))); 4959 4970 end StringRealformatSpecifier_o; … … 4976 4987 4977 4988 model StringRealformatSpecifier_x 4978 constant Real x = 1 .23456789;4989 constant Real x = 1234.56789; 4979 4990 constant String s = String(x, format = "3x"); 4980 4991 4981 4992 annotation(__JModelica(UnitTesting(tests={ 4982 ErrorTestCase(4993 FlatteningTestCase( 4983 4994 name="StringRealformatSpecifier_x", 4984 4995 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=" 4997 fclass EvaluationTests.StringConvert.StringRealformatSpecifier_x 4998 constant Real x = 1234.56789; 4999 constant String s = \"4d2\"; 5000 end EvaluationTests.StringConvert.StringRealformatSpecifier_x; 4989 5001 ")}))); 4990 5002 end StringRealformatSpecifier_x; … … 5007 5019 5008 5020 model StringRealformatSpecifier_X 5009 constant Real x = 1 .23456789;5021 constant Real x = 1234.56789; 5010 5022 constant String s = String(x, format = "3X"); 5011 5023 5012 5024 annotation(__JModelica(UnitTesting(tests={ 5013 ErrorTestCase(5025 FlatteningTestCase( 5014 5026 name="StringRealformatSpecifier_X", 5015 5027 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=" 5029 fclass EvaluationTests.StringConvert.StringRealformatSpecifier_X 5030 constant Real x = 1234.56789; 5031 constant String s = \"4D2\"; 5032 end EvaluationTests.StringConvert.StringRealformatSpecifier_X; 5020 5033 ")}))); 5021 5034 end StringRealformatSpecifier_X; … … 5038 5051 5039 5052 model StringRealformatSpecifier_u 5040 constant Real x = 1.23456789;5053 constant Real x = -1234.56789; 5041 5054 constant String s = String(x, format = "3u"); 5042 5055 5043 5056 annotation(__JModelica(UnitTesting(tests={ 5044 ErrorTestCase(5057 FlatteningTestCase( 5045 5058 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=" 5061 fclass EvaluationTests.StringConvert.StringRealformatSpecifier_u 5062 constant Real x = -1234.56789; 5063 constant String s = \"4294966061\"; 5064 end EvaluationTests.StringConvert.StringRealformatSpecifier_u; 5051 5065 ")}))); 5052 5066 end StringRealformatSpecifier_u; … … 5069 5083 5070 5084 model StringRealformatSpecifier_c 5071 constant Real x = 1 .23456789;5085 constant Real x = 123.456789; 5072 5086 constant String s = String(x, format = "3c"); 5073 5087 5074 5088 annotation(__JModelica(UnitTesting(tests={ 5075 ErrorTestCase(5089 FlatteningTestCase( 5076 5090 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=" 5093 fclass EvaluationTests.StringConvert.StringRealformatSpecifier_c 5094 constant Real x = 123.456789; 5095 constant String s = \" {\"; 5096 end EvaluationTests.StringConvert.StringRealformatSpecifier_c; 5097 ")}))); 5084 5098 end StringRealformatSpecifier_c; 5085 5099 … … 5100 5114 end StringIntegerformatSpecifier_c; 5101 5115 5102 model StringIncorrectformat 5103 constant Integer x = 1234; 5104 constant String s = String(x, format = "*.1.3c"); 5116 5117 model StringConvertInvalidFormat1 5118 parameter Real x = 1.23456789; 5119 parameter String s = String(x, format = "1.2.3g"); 5105 5120 5106 5121 annotation(__JModelica(UnitTesting(tests={ 5107 5122 ErrorTestCase( 5108 name="String Incorrectformat",5109 description="String() operator, Real, format using c specifier",5123 name="StringConvert_StringConvertInvalidFormat1", 5124 description="String() operator, Real, bad format string", 5110 5125 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; 5126 Error at line 3, column 26, in file '...', INVALID_FORMAT_STRING: 5127 Failed to parse format string \"1.2.3g\". 5128 ")}))); 5129 end StringConvertInvalidFormat1; 5130 5131 5132 model StringConvertInvalidFormat2 5133 parameter Integer x = 1; 5134 parameter String s = String(x, format = "ld"); 5135 5136 annotation(__JModelica(UnitTesting(tests={ 5137 ErrorTestCase( 5138 name="StringConvert_StringConvertInvalidFormat2", 5139 description="String() operator, Real, bad format string (different internal exception)", 5140 errorMessage=" 5141 Error 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 ")}))); 5144 end StringConvertInvalidFormat2; 5116 5145 5117 5146 end StringConvert; -
branches/dev-mj-5835/Compiler/ModelicaFrontEnd/src/jastadd/errorcheck/ComplianceCheck.jadd
r11639 r13702 283 283 284 284 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 %s of String operator is only supported as parameter expression."); 286 287 287 288 public void FStringExp.complianceCheck(ErrorCheckType checkType) { 288 289 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 // TODO: need to cover functions as well 293 if (!getFormat().variability().parameterOrLess()) 294 UNSUPPORTED_NON_FIXED_STRING_ARGUMENT.invoke(getFormat(), "format"); 295 } 305 296 } 306 297 -
branches/dev-mj-5835/Compiler/ModelicaFrontEnd/src/jastadd/errorcheck/ContentsCheck.jadd
r13103 r13702 389 389 if (!ch.variability().parameterOrLess()) { 390 390 NON_PARAMETER_SAMPLE_ARGUMENTS.invoke(ch); 391 } 392 } 393 } 394 395 public static final SimpleErrorProducer ASTNode.INVALID_FORMAT_STRING = 396 new SimpleErrorProducer("INVALID_FORMAT_STRING", ProblemKind.SEMANTIC, "%s"); 397 398 public void FStringExp.contentCheck(ErrorCheckType checkType) { 399 if (hasFormat()) { 400 try { 401 CFormatSpecifier format = formatSpecifier(); 402 if (!format.isValid()) { 403 INVALID_FORMAT_STRING.invoke(this, format.errorMessage()); 404 } 405 } catch (ConstantEvaluationException e) { 406 // If we can't evaluate it, don't do a static error check of it. 391 407 } 392 408 } -
branches/dev-mj-5835/Compiler/ModelicaFrontEnd/src/java/org/jmodelica/util/values/ConstantEvaluationException.java
r9590 r13702 14 14 public ConstantEvaluationException() { 15 15 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); 16 26 this.val = null; 17 27 } -
branches/dev-mj-5835/Compiler/ModelicaFrontEnd/test/modelica/ComplianceTests.mo
r11639 r13702 527 527 528 528 model 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 529 537 Integer len = if time < 0 then 4 else 3; 530 538 Integer digits = if time < 0 then 5 else 2; 539 String s = f(time, "g"); 531 540 equation 532 541 assert(time>2.0, String(time, significantDigits=digits, minimumLength=len, leftJustified=time<1)); 542 assert(time>2.0, String(time, format=String(len)+"."+String(digits)+"f")); 533 543 annotation(__JModelica(UnitTesting(tests={ 534 544 ComplianceErrorTestCase( 535 545 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 548 ")}))); 546 description="Test compliance warnings for non fixed string operator format argument", 547 errorMessage=" 548 2 errors found: 549 550 Compliance error at line 7, column 31, in file 'Compiler/ModelicaFrontEnd/test/modelica/ComplianceTests.mo', UNSUPPORTED_NON_FIXED_STRING_ARGUMENT: 551 Argument format of String operator is only supported as parameter expression. 552 553 Compliance error at line 15, column 42, in file 'Compiler/ModelicaFrontEnd/test/modelica/ComplianceTests.mo', UNSUPPORTED_NON_FIXED_STRING_ARGUMENT: 554 Argument format of String operator is only supported as parameter expression. 555 ")}))); 549 556 end StringOperator1; 550 557
Note: See TracChangeset
for help on using the changeset viewer.