@@ -138,6 +138,23 @@ abstract class Expression
138138 stringoperators .add ("->last" );
139139 }
140140
141+ public static Vector string2operators = new Vector ();
142+ static
143+ { string2operators .add ("->split" );
144+ string2operators .add ("->after" );
145+ string2operators .add ("->before" );
146+ string2operators .add ("->hasSuffix" );
147+ string2operators .add ("->hasPrefix" );
148+ string2operators .add ("->indexOf" );
149+ string2operators .add ("->lastIndexOf" );
150+ string2operators .add ("->isMatch" );
151+ string2operators .add ("->hasMatch" );
152+ string2operators .add ("->at" );
153+ string2operators .add ("->equalsIgnoreCase" );
154+ string2operators .add ("->allMatches" );
155+ string2operators .add ("->firstMatch" );
156+ }
157+
141158 public static Vector alloperators = new Vector ();
142159 static
143160 { alloperators .add ("=>" );
@@ -168,12 +185,12 @@ abstract class Expression
168185 } // and?
169186
170187 public static java .util .Map oppriority = new java .util .HashMap ();
171- { oppriority .put ("<=>" ,new Integer ( 0 ) );
172- oppriority .put ("=>" ,new Integer ( 1 ) );
173- oppriority .put ("#" ,new Integer ( 2 ) );
174- oppriority .put ("or" ,new Integer ( 3 ) );
175- oppriority .put ("xor" ,new Integer ( 3 ) );
176- oppriority .put ("&" ,new Integer ( 4 ) );
188+ { oppriority .put ("<=>" , 0 );
189+ oppriority .put ("=>" , 1 );
190+ oppriority .put ("#" , 2 );
191+ oppriority .put ("or" , 3 );
192+ oppriority .put ("xor" , 3 );
193+ oppriority .put ("&" , 4 );
177194 } // and?
178195
179196 // For extensions:
@@ -277,6 +294,9 @@ public static boolean isMath2Operator(String opx)
277294 public static boolean isStringOperator (String opx )
278295 { return stringoperators .contains (opx ); }
279296
297+ public static boolean isString2Operator (String opx )
298+ { return string2operators .contains (opx ); }
299+
280300 public abstract boolean isTailRecursion (BehaviouralFeature bf );
281301
282302 public void recursiveExpressions (BehaviouralFeature bf ,
@@ -3074,7 +3094,6 @@ static public Expression simplify(final String op,
30743094 }
30753095 // or a string: length - 2
30763096
3077-
30783097 if (op .equals ("->keys" ) && arg instanceof SetExpression )
30793098 { SetExpression se = (SetExpression ) arg ;
30803099 return SetExpression .keys (se );
@@ -3112,13 +3131,123 @@ static public Expression simplify(final String op,
31123131 return new UnaryExpression (op , arg );
31133132 }
31143133
3134+ if (Expression .isStringOperator (op ))
3135+ {
3136+ return Expression .simplifyStringExpression (op , arg );
3137+ }
3138+
31153139 return arg ;
31163140 }
31173141
3142+ public static Expression simplifyStringExpression (String op ,
3143+ Expression str )
3144+ { String ds = "" + str ;
3145+
3146+ if (ds .startsWith ("\" " ) && ds .endsWith ("\" " ) &&
3147+ ds .length () > 1 )
3148+ { String sval = ds .substring (1 , ds .length ()-1 );
3149+
3150+ if (op .equals ("->characters" ))
3151+ { Vector res = new Vector ();
3152+ for (int i = 0 ; i < sval .length (); i ++)
3153+ { String si = "\" " + sval .charAt (i ) + "\" " ;
3154+ res .add (new BasicExpression (si ));
3155+ }
3156+ return new SetExpression (res , true );
3157+ }
3158+
3159+ if (op .equals ("->char2byte" ))
3160+ { return new BasicExpression (Expression .char2byte (sval )); }
3161+
3162+ if (op .equals ("->toLowerCase" ))
3163+ { String nval = sval .toLowerCase ();
3164+ return new BasicExpression ("\" " + nval + "\" " );
3165+ }
3166+
3167+ if (op .equals ("->toUpperCase" ))
3168+ { String nval = sval .toUpperCase ();
3169+ return new BasicExpression ("\" " + nval + "\" " );
3170+ }
3171+
3172+ if (op .equals ("->trim" ))
3173+ { String nval = sval .trim ();
3174+ return new BasicExpression ("\" " + nval + "\" " );
3175+ }
3176+
3177+ if (op .equals ("->reverse" ))
3178+ { return new BasicExpression (
3179+ Expression .stringReverse (str + "" ));
3180+ }
3181+
3182+ if (op .equals ("->front" ))
3183+ { String nval = sval .substring (0 , sval .length ()-1 );
3184+ return new BasicExpression ("\" " + nval + "\" " );
3185+ }
3186+
3187+ if (op .equals ("->tail" ))
3188+ { String nval = sval .substring (1 );
3189+ return new BasicExpression ("\" " + nval + "\" " );
3190+ }
3191+
3192+ if (op .equals ("->first" ))
3193+ { if (sval .length () > 0 )
3194+ { return new BasicExpression ("\" " + sval .charAt (0 ) + "\" " ); }
3195+ else
3196+ { return new BasicExpression ("Invalid" ); }
3197+ }
3198+
3199+ if (op .equals ("->last" ))
3200+ { int n = sval .length ();
3201+ if (n > 0 )
3202+ { return new BasicExpression ("\" " + sval .charAt (n -1 ) + "\" " ); }
3203+ else
3204+ { return new BasicExpression ("Invalid" ); }
3205+ }
3206+ }
3207+ else if (Expression .isIntegerValue (str + "" ) &&
3208+ op .equals ("->byte2char" ))
3209+ { int code = Expression .convertInteger (str + "" );
3210+ String chrs = Expression .byte2char (code );
3211+ return new BasicExpression ("\" " + chrs + "\" " );
3212+ }
3213+
3214+ return new UnaryExpression (op , str );
3215+ }
3216+
3217+ public static Expression simplifyMath2Expression (String op ,
3218+ double val1 ,
3219+ double val2 )
3220+ {
3221+ if ("->pow" .equals (op ))
3222+ { return new BasicExpression (Math .pow (val1 , val2 )); }
3223+
3224+ if ("->gcd" .equals (op ))
3225+ { Expression res = new BasicExpression (
3226+ Expression .gcd ((long ) val1 ,
3227+ (long ) val2 ));
3228+ return res ;
3229+ }
3230+
3231+ if ("->roundTo" .equals (op ))
3232+ { return new BasicExpression (
3233+ Expression .roundTo (val1 ,
3234+ (int ) val2 ));
3235+ }
3236+
3237+ if ("->truncateTo" .equals (op ))
3238+ { return new BasicExpression (
3239+ Expression .truncateTo (val1 ,
3240+ (int ) val2 ));
3241+ }
3242+
3243+ return new BinaryExpression (op ,
3244+ new BasicExpression (val1 ),
3245+ new BasicExpression (val2 ));
3246+ }
3247+
31183248 public static Expression simplifyMathExpression (String op ,
31193249 double val )
3120- { Expression res = null ;
3121-
3250+ {
31223251 if (op .equals ("->abs" ))
31233252 { return new BasicExpression (Math .abs (val )); }
31243253
@@ -3176,7 +3305,7 @@ public static Expression simplifyMathExpression(String op,
31763305 if (op .equals ("->tanh" ))
31773306 { return new BasicExpression (Math .tanh (val )); }
31783307
3179- return res ;
3308+ return new UnaryExpression ( op , new BasicExpression ( val )) ;
31803309 }
31813310
31823311 public static Expression simplifyUnaryMinus (Expression e1 )
@@ -3379,9 +3508,10 @@ static public Expression simplify(final String op,
33793508 } // not for sorted collections, maps
33803509
33813510 if ("->at" .equals (op ) &&
3382- e1 instanceof SetExpression )
3511+ e1 instanceof SetExpression &&
3512+ Expression .isIntegerValue (e2 + "" ))
33833513 { SetExpression s1 = (SetExpression ) e1 ;
3384- int indx = Integer .parseInt ("" + e2 );
3514+ int indx = Integer .parseInt (e2 + "" );
33853515 return s1 .atExpression (indx );
33863516 } // not for sorted collections, maps
33873517
@@ -3401,6 +3531,21 @@ static public Expression simplify(final String op,
34013531 return SetExpression .antirestrict (s1 , s2 );
34023532 }
34033533
3534+ if (Expression .isMath2Operator (op ))
3535+ {
3536+ if (Expression .isNumber (e1 + "" ) &&
3537+ Expression .isNumber (e2 + "" ))
3538+ { double d1 = Expression .convertNumber (e1 + "" );
3539+ double d2 = Expression .convertNumber (e2 + "" );
3540+ return Expression .simplifyMath2Expression (op , d1 , d2 );
3541+ }
3542+ }
3543+
3544+ if (Expression .isStringOperator (op ))
3545+ {
3546+ return Expression .simplifyStringExpression (op , e1 );
3547+ }
3548+
34043549 return new BinaryExpression (op ,e1 ,e2 );
34053550 }
34063551
@@ -3558,20 +3703,31 @@ else if ("->intersection".equals(op) &&
35583703 res = SetExpression .intersectionSetExpressions (s1 , s2 );
35593704 } // not for sorted collections, maps
35603705 else if ("->at" .equals (op ) &&
3561- e1 instanceof SetExpression )
3706+ e1 instanceof SetExpression &&
3707+ Expression .isIntegerValue (e2 + "" ))
35623708 { SetExpression s1 = (SetExpression ) e1 ;
3563- int indx = Integer .parseInt ("" + e2 );
3709+ int indx = Integer .parseInt (e2 + "" );
35643710 res = s1 .atExpression (indx );
35653711 } // not for sorted collections, maps
3566- else
3712+ else if (Expression .isMath2Operator (op ) &&
3713+ Expression .isNumberValue (e1 + "" ) &&
3714+ Expression .isNumberValue (e2 + "" ))
3715+ { double d1 = Expression .convertNumber (e1 + "" );
3716+ double d2 = Expression .convertNumber (e2 + "" );
3717+ res = Expression .simplifyMath2Expression (op , d1 , d2 );
3718+ }
3719+ else if (Expression .isStringOperator (op ))
3720+ {
3721+ res = Expression .simplifyStringExpression (op , e1 );
3722+ }
3723+ else
35673724 { res = new BinaryExpression (op ,e1 ,e2 ); }
35683725
35693726 res .setBrackets (needsBrackets );
35703727
35713728 return res ;
35723729 }
35733730
3574-
35753731 public static Expression simplifyPlus (
35763732 Expression e1 , Expression e2 )
35773733 { if (e1 == null ) { return e2 ; }
@@ -6201,6 +6357,61 @@ public String cgParameter(CGSpec cgs, Vector partail)
62016357 return cg (cgs );
62026358 } // but omit initialisations for parameters
62036359
6360+ public static long gcd (long xx , long yy )
6361+ { long x = Math .abs (xx );
6362+ long y = Math .abs (yy );
6363+ while (x != 0 && y != 0 )
6364+ { long z = y ;
6365+ y = x % y ;
6366+ x = z ;
6367+ }
6368+
6369+ if (y == 0 )
6370+ { return x ; }
6371+
6372+ if (x == 0 )
6373+ { return y ; }
6374+
6375+ return 0 ;
6376+ }
6377+
6378+ public static double roundTo (double x , int n )
6379+ { if (n < 0 )
6380+ { return Math .round (x ); }
6381+ double y = x *Math .pow (10 ,n );
6382+ return Math .round (y )/Math .pow (10 ,n );
6383+ }
6384+
6385+ public static double truncateTo (double x , int n )
6386+ { if (n < 0 )
6387+ { return (int ) x ; }
6388+ double y = x *Math .pow (10 ,n );
6389+ return ((int ) y )/Math .pow (10 ,n );
6390+ }
6391+
6392+ public static int char2byte (String s )
6393+ { if (s == null || s .length () == 0 )
6394+ { return -1 ; }
6395+ return (int ) s .charAt (0 );
6396+ }
6397+
6398+ public static String byte2char (int b )
6399+ { try {
6400+ byte [] bb = {(byte ) b };
6401+ return new String (bb );
6402+ }
6403+ catch (Exception _e )
6404+ { return "" ; }
6405+ }
6406+
6407+ public static String stringReverse (String a )
6408+ { String res = "" ;
6409+ for (int i = a .length () - 1 ; i >= 0 ; i --)
6410+ { res = res + a .charAt (i ); }
6411+ return res ;
6412+ }
6413+
6414+
62046415 public static void main (String [] args )
62056416 { /* if (Expression.isLong("10000000000000L"))
62066417 { long xx = Expression.convertLong("10000000000000L");
0 commit comments