Skip to content

Commit 593696d

Browse files
committed
Possible bug fix #24
This is a candidate bug fix for restricting the way that translateStateUnpack() works. It's not been fully tested yet, and it's something of a kludge. But, frankly, changing the way that the JavaFilerWriter works is something of a dark art.
1 parent bf88416 commit 593696d

File tree

1 file changed

+71
-47
lines changed

1 file changed

+71
-47
lines changed

src/wyrl/io/JavaFileWriter.java

Lines changed: 71 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,10 @@ public void translate(RewriteDecl decl, SpecFile file) {
284284
environment);
285285
if (decl.requires != null) {
286286
// 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);
289291
myOut(level++, "if(r" + requires + ") { // REQUIRES");
290292
}
291293
// Add the appropriate activation
@@ -334,7 +336,7 @@ public void translate(RewriteDecl decl, SpecFile file) {
334336
environment = new Environment();
335337
thus = environment.allocate(param, "this");
336338
myOut(3, "int r" + thus + " = state[0];");
337-
translateStateUnpack(3, decl.pattern, thus, environment);
339+
translateStateUnpack(3, decl.pattern, thus, true, environment);
338340

339341
// second, translate the individual rules
340342
for (RuleDecl rd : decl.rules) {
@@ -881,40 +883,40 @@ protected boolean willSkip(Pattern pattern, Type declared) {
881883
* @param environment
882884
*/
883885
protected void translateStateUnpack(int level, Pattern pattern, int source,
884-
Environment environment) {
886+
boolean unpack, Environment environment) {
885887
if (pattern instanceof Pattern.Leaf) {
886888
translateStateUnpack(level, (Pattern.Leaf) pattern, source,
887-
environment);
889+
unpack, environment);
888890
} else if (pattern instanceof Pattern.Term) {
889891
translateStateUnpack(level, (Pattern.Term) pattern, source,
890-
environment);
892+
unpack, environment);
891893
} else if (pattern instanceof Pattern.BagOrSet) {
892894
translateStateUnpack(level, (Pattern.BagOrSet) pattern, source,
893-
environment);
895+
unpack, environment);
894896
} else {
895897
translateStateUnpack(level, (Pattern.List) pattern, source,
896-
environment);
898+
unpack, environment);
897899
}
898900
}
899901

900902
protected void translateStateUnpack(int level, Pattern.Leaf pattern,
901-
int source, Environment environment) {
903+
int source, boolean unpack, Environment environment) {
902904
// Don't need to do anything!!
903905
}
904906

905907
protected void translateStateUnpack(int level, Pattern.Term pattern,
906-
int source, Environment environment) {
908+
int source, boolean unpack, Environment environment) {
907909
if (pattern.data != null) {
908910
int target = environment.allocate(Type.T_ANY(), pattern.variable);
909-
if (pattern.variable != null) {
911+
if (pattern.variable != null && unpack) {
910912
myOut(level, "int r" + target + " = state[" + target + "]; // " + pattern.variable);
911913
}
912-
translateStateUnpack(level, pattern.data, target, environment);
914+
translateStateUnpack(level, pattern.data, target, unpack, environment);
913915
}
914916
}
915917

916918
protected void translateStateUnpack(int level, Pattern.BagOrSet pattern,
917-
int source, Environment environment) {
919+
int source, boolean unpack, Environment environment) {
918920

919921
Pair<Pattern, String>[] elements = pattern.elements;
920922
int[] indices = new int[elements.length];
@@ -924,31 +926,7 @@ protected void translateStateUnpack(int level, Pattern.BagOrSet pattern,
924926
int item = environment.allocate(Type.T_ANY(), p_name);
925927
if (pattern.unbounded && (i + 1) == elements.length) {
926928
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);
952930
if (pattern instanceof Pattern.Set) {
953931
myOut(level, "Automaton.Set r" + item
954932
+ " = new Automaton.Set(" + array + ");");
@@ -965,17 +943,59 @@ protected void translateStateUnpack(int level, Pattern.BagOrSet pattern,
965943
} else {
966944
int index = environment.allocate(Type.T_VOID());
967945
indices[i] = index;
968-
if (p_name != null) {
946+
if (p_name != null && unpack) {
969947
myOut(level, "int r" + item + " = state[" + item + "]; // " + p_name);
970948
}
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]);
973988
}
989+
out.println(") { continue; }");
974990
}
991+
myOut(level + 1, array + "[" + jdx + "++] = " + src + ".get(" + idx
992+
+ ");");
993+
myOut(level, "}");
994+
return array;
975995
}
976996

977997
protected void translateStateUnpack(int level, Pattern.List pattern,
978-
int source, Environment environment) {
998+
int source, boolean unpack, Environment environment) {
979999

9801000
Pair<Pattern, String>[] elements = pattern.elements;
9811001
for (int i = 0; i != elements.length; ++i) {
@@ -984,9 +1004,13 @@ protected void translateStateUnpack(int level, Pattern.List pattern,
9841004
if (pattern.unbounded && (i + 1) == elements.length) {
9851005
int target = environment.allocate(Type.T_VOID(), p_name);
9861006
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+
}
9901014
}
9911015

9921016
// NOTE: calling translate unpack here is strictly unnecessary
@@ -995,10 +1019,10 @@ protected void translateStateUnpack(int level, Pattern.List pattern,
9951019

9961020
} else {
9971021
int target = environment.allocate(Type.T_ANY(), p_name);
998-
if (p_name != null) {
1022+
if (p_name != null && unpack) {
9991023
myOut(level, "int r" + target + " = state[" + target + "]; // " + p_name);
10001024
}
1001-
translateStateUnpack(level, p.first(), target, environment);
1025+
translateStateUnpack(level, p.first(), target, unpack, environment);
10021026
}
10031027
}
10041028
}

0 commit comments

Comments
 (0)