@@ -282,7 +282,14 @@ public void translate(RewriteDecl decl, SpecFile file) {
282
282
myOut (3 , "int r" + thus + " = target;" );
283
283
int level = translatePatternMatch (3 , decl .pattern , null , thus ,
284
284
environment );
285
-
285
+ if (decl .requires != null ) {
286
+ // FIXME: this is not necessarily always required
287
+ Environment reqEnvironment = new Environment ();
288
+ reqEnvironment .allocate (param , "this" );
289
+ translateStateUnpack (level ,decl .pattern ,thus ,false ,reqEnvironment );
290
+ int requires = translate (level , decl .requires , reqEnvironment , file );
291
+ myOut (level ++, "if(r" + requires + ") { // REQUIRES" );
292
+ }
286
293
// Add the appropriate activation
287
294
indent (level );
288
295
out .print ("int[] state = {" );
@@ -329,7 +336,7 @@ public void translate(RewriteDecl decl, SpecFile file) {
329
336
environment = new Environment ();
330
337
thus = environment .allocate (param , "this" );
331
338
myOut (3 , "int r" + thus + " = state[0];" );
332
- translateStateUnpack (3 , decl .pattern , thus , environment );
339
+ translateStateUnpack (3 , decl .pattern , thus , true , environment );
333
340
334
341
// second, translate the individual rules
335
342
for (RuleDecl rd : decl .rules ) {
@@ -876,40 +883,40 @@ protected boolean willSkip(Pattern pattern, Type declared) {
876
883
* @param environment
877
884
*/
878
885
protected void translateStateUnpack (int level , Pattern pattern , int source ,
879
- Environment environment ) {
886
+ boolean unpack , Environment environment ) {
880
887
if (pattern instanceof Pattern .Leaf ) {
881
888
translateStateUnpack (level , (Pattern .Leaf ) pattern , source ,
882
- environment );
889
+ unpack , environment );
883
890
} else if (pattern instanceof Pattern .Term ) {
884
891
translateStateUnpack (level , (Pattern .Term ) pattern , source ,
885
- environment );
892
+ unpack , environment );
886
893
} else if (pattern instanceof Pattern .BagOrSet ) {
887
894
translateStateUnpack (level , (Pattern .BagOrSet ) pattern , source ,
888
- environment );
895
+ unpack , environment );
889
896
} else {
890
897
translateStateUnpack (level , (Pattern .List ) pattern , source ,
891
- environment );
898
+ unpack , environment );
892
899
}
893
900
}
894
901
895
902
protected void translateStateUnpack (int level , Pattern .Leaf pattern ,
896
- int source , Environment environment ) {
903
+ int source , boolean unpack , Environment environment ) {
897
904
// Don't need to do anything!!
898
905
}
899
906
900
907
protected void translateStateUnpack (int level , Pattern .Term pattern ,
901
- int source , Environment environment ) {
908
+ int source , boolean unpack , Environment environment ) {
902
909
if (pattern .data != null ) {
903
910
int target = environment .allocate (Type .T_ANY (), pattern .variable );
904
- if (pattern .variable != null ) {
911
+ if (pattern .variable != null && unpack ) {
905
912
myOut (level , "int r" + target + " = state[" + target + "]; // " + pattern .variable );
906
913
}
907
- translateStateUnpack (level , pattern .data , target , environment );
914
+ translateStateUnpack (level , pattern .data , target , unpack , environment );
908
915
}
909
916
}
910
917
911
918
protected void translateStateUnpack (int level , Pattern .BagOrSet pattern ,
912
- int source , Environment environment ) {
919
+ int source , boolean unpack , Environment environment ) {
913
920
914
921
Pair <Pattern , String >[] elements = pattern .elements ;
915
922
int [] indices = new int [elements .length ];
@@ -919,31 +926,7 @@ protected void translateStateUnpack(int level, Pattern.BagOrSet pattern,
919
926
int item = environment .allocate (Type .T_ANY (), p_name );
920
927
if (pattern .unbounded && (i + 1 ) == elements .length ) {
921
928
if (p_name != null ) {
922
- String src = "s" + source ;
923
- myOut (level , "Automaton.Collection " + src
924
- + " = (Automaton.Collection) automaton.get(state["
925
- + source + "]);" );
926
- String array = src + "children" ;
927
- myOut (level , "int[] " + array + " = new int[" + src
928
- + ".size() - " + i + "];" );
929
- String idx = "s" + source + "i" ;
930
- String jdx = "s" + source + "j" ;
931
- myOut (level , "for(int " + idx + "=0, " + jdx + "=0; " + idx
932
- + " != " + src + ".size();++" + idx + ") {" );
933
- if (i != 0 ) {
934
- indent (level + 1 );
935
- out .print ("if(" );
936
- for (int j = 0 ; j < i ; ++j ) {
937
- if (j != 0 ) {
938
- out .print (" || " );
939
- }
940
- out .print (idx + " == r" + indices [j ]);
941
- }
942
- out .println (") { continue; }" );
943
- }
944
- myOut (level + 1 , array + "[" + jdx + "++] = " + src + ".get(" + idx
945
- + ");" );
946
- myOut (level , "}" );
929
+ String array = extractUnboundedTail (i , level , source , indices , unpack );
947
930
if (pattern instanceof Pattern .Set ) {
948
931
myOut (level , "Automaton.Set r" + item
949
932
+ " = new Automaton.Set(" + array + ");" );
@@ -960,17 +943,59 @@ protected void translateStateUnpack(int level, Pattern.BagOrSet pattern,
960
943
} else {
961
944
int index = environment .allocate (Type .T_VOID ());
962
945
indices [i ] = index ;
963
- if (p_name != null ) {
946
+ if (p_name != null && unpack ) {
964
947
myOut (level , "int r" + item + " = state[" + item + "]; // " + p_name );
965
948
}
966
- myOut (level , "int r" + index + " = state[" + index + "];" );
967
- translateStateUnpack (level , p .first (), item , environment );
949
+ if (unpack ) {
950
+ myOut (level , "int r" + index + " = state[" + index + "];" );
951
+ }
952
+ translateStateUnpack (level , p .first (), item , unpack , environment );
953
+ }
954
+ }
955
+ }
956
+
957
+ /**
958
+ * Extract all elements of an array which don't match any of the supplied
959
+ * indices.
960
+ *
961
+ * @param i
962
+ * @param level
963
+ * @param source
964
+ * @param indices
965
+ * @return
966
+ */
967
+ private String extractUnboundedTail (int i , int level , int source , int [] indices , boolean unpack ) {
968
+ String src = "c" + source ;
969
+ if (unpack ) {
970
+ myOut (level ,
971
+ "Automaton.Collection " + src + " = (Automaton.Collection) automaton.get(state[" + source + "]);" );
972
+ }
973
+ String array = src + "children" ;
974
+ myOut (level , "int[] " + array + " = new int[" + src
975
+ + ".size() - " + i + "];" );
976
+ String idx = "s" + source + "i" ;
977
+ String jdx = "s" + source + "j" ;
978
+ myOut (level , "for(int " + idx + "=0, " + jdx + "=0; " + idx
979
+ + " != " + src + ".size();++" + idx + ") {" );
980
+ if (i != 0 ) {
981
+ indent (level + 1 );
982
+ out .print ("if(" );
983
+ for (int j = 0 ; j < i ; ++j ) {
984
+ if (j != 0 ) {
985
+ out .print (" || " );
986
+ }
987
+ out .print (idx + " == r" + indices [j ]);
968
988
}
989
+ out .println (") { continue; }" );
969
990
}
991
+ myOut (level + 1 , array + "[" + jdx + "++] = " + src + ".get(" + idx
992
+ + ");" );
993
+ myOut (level , "}" );
994
+ return array ;
970
995
}
971
996
972
997
protected void translateStateUnpack (int level , Pattern .List pattern ,
973
- int source , Environment environment ) {
998
+ int source , boolean unpack , Environment environment ) {
974
999
975
1000
Pair <Pattern , String >[] elements = pattern .elements ;
976
1001
for (int i = 0 ; i != elements .length ; ++i ) {
@@ -979,9 +1004,13 @@ protected void translateStateUnpack(int level, Pattern.List pattern,
979
1004
if (pattern .unbounded && (i + 1 ) == elements .length ) {
980
1005
int target = environment .allocate (Type .T_VOID (), p_name );
981
1006
if (p_name != null ) {
982
- myOut (level , "Automaton.List r" + target
983
- + " = ((Automaton.List) automaton.get(state["
984
- + source + "])).sublist(" + i + ");" );
1007
+ if (unpack ) {
1008
+ myOut (level , "Automaton.List r" + target
1009
+ + " = ((Automaton.List) automaton.get(state["
1010
+ + source + "])).sublist(" + i + ");" );
1011
+ } else {
1012
+ myOut (level , "Automaton.List r" + target + " = l" + source + ";" );
1013
+ }
985
1014
}
986
1015
987
1016
// NOTE: calling translate unpack here is strictly unnecessary
@@ -990,10 +1019,10 @@ protected void translateStateUnpack(int level, Pattern.List pattern,
990
1019
991
1020
} else {
992
1021
int target = environment .allocate (Type .T_ANY (), p_name );
993
- if (p_name != null ) {
1022
+ if (p_name != null && unpack ) {
994
1023
myOut (level , "int r" + target + " = state[" + target + "]; // " + p_name );
995
1024
}
996
- translateStateUnpack (level , p .first (), target , environment );
1025
+ translateStateUnpack (level , p .first (), target , unpack , environment );
997
1026
}
998
1027
}
999
1028
}
0 commit comments