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