42 private Name resultName;
43 private String debugName;
44 private ArrayList<Name> dups;
45
46 private static final int F_TRANS = 0x10, F_OWNED = 0x03;
47
48 LambdaFormBuffer(LambdaForm lf) {
49 this(lf.arity, lf.names, lf.result);
50 debugName = lf.debugName;
51 assert(lf.nameRefsAreLegal());
52 }
53
54 private LambdaFormBuffer(int arity, Name[] names, int result) {
55 this.arity = arity;
56 setNames(names);
57 if (result == LAST_RESULT) result = length - 1;
58 if (result >= 0 && names[result].type != V_TYPE)
59 resultName = names[result];
60 }
61
62 LambdaForm lambdaForm() {
63 assert(!inTrans()); // need endEdit call to tidy things up
64 return new LambdaForm(debugName, arity, nameArray(), resultIndex());
65 }
66
67 Name name(int i) {
68 assert(i < length);
69 return names[i];
70 }
71
72 Name[] nameArray() {
73 return Arrays.copyOf(names, length);
74 }
75
76 int resultIndex() {
77 if (resultName == null) return VOID_RESULT;
78 int index = indexOf(resultName, names);
79 assert(index >= 0);
80 return index;
81 }
82
259 assert(oldName == originalNames[i]); // no multiple changes
260 assert(verifyFirstChange());
261 if (ownedCount() == 0)
262 growNames(0, 0);
263 names[i] = name;
264 if (firstChange > i) {
265 firstChange = i;
266 }
267 if (resultName != null && resultName == oldName) {
268 resultName = name;
269 }
270 }
271
272 /** Change the result name. Null means a void result. */
273 void setResult(Name name) {
274 assert(name == null || lastIndexOf(name) >= 0);
275 resultName = name;
276 }
277
278 /** Finish a transaction. */
279 void endEdit() {
280 assert(verifyFirstChange());
281 // Assuming names have been changed pairwise from originalNames[i] to names[i],
282 // update arguments to ensure referential integrity.
283 for (int i = Math.max(firstChange, arity); i < length; i++) {
284 Name name = names[i];
285 if (name == null) continue; // space for removed duplicate
286 Name newName = name.replaceNames(originalNames, names, firstChange, i);
287 if (newName != name) {
288 names[i] = newName;
289 if (resultName == name) {
290 resultName = newName;
291 }
292 }
293 }
294 assert(inTrans());
295 flags &= ~F_TRANS;
296 clearDuplicatesAndNulls();
297 originalNames = null;
298 // If any parameters have been changed, then reorder them as needed.
299 // This is a "sheep-and-goats" stable sort, pushing all non-parameters
300 // to the right of all parameters.
301 if (firstChange < arity) {
302 Name[] exprs = new Name[arity - firstChange];
303 int argp = firstChange, exprp = 0;
304 for (int i = firstChange; i < arity; i++) {
305 Name name = names[i];
306 if (name.isParam()) {
307 names[argp++] = name;
308 } else {
309 exprs[exprp++] = name;
310 }
311 }
312 assert(exprp == (arity - argp));
313 // copy the exprs just after the last remaining param
314 System.arraycopy(exprs, 0, names, argp, exprp);
315 // adjust arity
316 arity -= exprp;
317 }
318 assert(verifyArity());
319 }
320
321 private Name[] copyNamesInto(Name[] buffer) {
322 System.arraycopy(names, 0, buffer, 0, length);
323 Arrays.fill(buffer, length, buffer.length, null);
324 return buffer;
325 }
326
327 /** Replace any Name whose function is in oldFns with a copy
328 * whose function is in the corresponding position in newFns.
329 * Only do this if the arguments are exactly equal to the given.
330 */
331 LambdaFormBuffer replaceFunctions(NamedFunction[] oldFns, NamedFunction[] newFns,
332 Object... forArguments) {
333 assert(inTrans());
334 if (oldFns.length == 0) return this;
335 for (int i = arity; i < length; i++) {
336 Name n = names[i];
337 int nfi = indexOf(n.function, oldFns);
338 if (nfi >= 0 && Arrays.equals(n.arguments, forArguments)) {
|
42 private Name resultName;
43 private String debugName;
44 private ArrayList<Name> dups;
45
46 private static final int F_TRANS = 0x10, F_OWNED = 0x03;
47
48 LambdaFormBuffer(LambdaForm lf) {
49 this(lf.arity, lf.names, lf.result);
50 debugName = lf.debugName;
51 assert(lf.nameRefsAreLegal());
52 }
53
54 private LambdaFormBuffer(int arity, Name[] names, int result) {
55 this.arity = arity;
56 setNames(names);
57 if (result == LAST_RESULT) result = length - 1;
58 if (result >= 0 && names[result].type != V_TYPE)
59 resultName = names[result];
60 }
61
62 private LambdaForm lambdaForm() {
63 assert(!inTrans()); // need endEdit call to tidy things up
64 return new LambdaForm(debugName, arity, nameArray(), resultIndex());
65 }
66
67 Name name(int i) {
68 assert(i < length);
69 return names[i];
70 }
71
72 Name[] nameArray() {
73 return Arrays.copyOf(names, length);
74 }
75
76 int resultIndex() {
77 if (resultName == null) return VOID_RESULT;
78 int index = indexOf(resultName, names);
79 assert(index >= 0);
80 return index;
81 }
82
259 assert(oldName == originalNames[i]); // no multiple changes
260 assert(verifyFirstChange());
261 if (ownedCount() == 0)
262 growNames(0, 0);
263 names[i] = name;
264 if (firstChange > i) {
265 firstChange = i;
266 }
267 if (resultName != null && resultName == oldName) {
268 resultName = name;
269 }
270 }
271
272 /** Change the result name. Null means a void result. */
273 void setResult(Name name) {
274 assert(name == null || lastIndexOf(name) >= 0);
275 resultName = name;
276 }
277
278 /** Finish a transaction. */
279 LambdaForm endEdit() {
280 assert(verifyFirstChange());
281 // Assuming names have been changed pairwise from originalNames[i] to names[i],
282 // update arguments to ensure referential integrity.
283 for (int i = Math.max(firstChange, arity); i < length; i++) {
284 Name name = names[i];
285 if (name == null) continue; // space for removed duplicate
286 Name newName = name.replaceNames(originalNames, names, firstChange, i);
287 if (newName != name) {
288 names[i] = newName;
289 if (resultName == name) {
290 resultName = newName;
291 }
292 }
293 }
294 assert(inTrans());
295 flags &= ~F_TRANS;
296 clearDuplicatesAndNulls();
297 originalNames = null;
298 // If any parameters have been changed, then reorder them as needed.
299 // This is a "sheep-and-goats" stable sort, pushing all non-parameters
300 // to the right of all parameters.
301 if (firstChange < arity) {
302 Name[] exprs = new Name[arity - firstChange];
303 int argp = firstChange, exprp = 0;
304 for (int i = firstChange; i < arity; i++) {
305 Name name = names[i];
306 if (name.isParam()) {
307 names[argp++] = name;
308 } else {
309 exprs[exprp++] = name;
310 }
311 }
312 assert(exprp == (arity - argp));
313 // copy the exprs just after the last remaining param
314 System.arraycopy(exprs, 0, names, argp, exprp);
315 // adjust arity
316 arity -= exprp;
317 }
318 assert(verifyArity());
319 return lambdaForm();
320 }
321
322 private Name[] copyNamesInto(Name[] buffer) {
323 System.arraycopy(names, 0, buffer, 0, length);
324 Arrays.fill(buffer, length, buffer.length, null);
325 return buffer;
326 }
327
328 /** Replace any Name whose function is in oldFns with a copy
329 * whose function is in the corresponding position in newFns.
330 * Only do this if the arguments are exactly equal to the given.
331 */
332 LambdaFormBuffer replaceFunctions(NamedFunction[] oldFns, NamedFunction[] newFns,
333 Object... forArguments) {
334 assert(inTrans());
335 if (oldFns.length == 0) return this;
336 for (int i = arity; i < length; i++) {
337 Name n = names[i];
338 int nfi = indexOf(n.function, oldFns);
339 if (nfi >= 0 && Arrays.equals(n.arguments, forArguments)) {
|