Using recursion, complete the body of the following static method.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * Refactors the given {@code Statement} by renaming every occurrence of
 * instruction {@code oldName} to {@code newName}. Every other statement is
 * left unmodified.
 * 
 * @param s
 *            the {@code Statement}
 * @param oldName
 *            the name of the instruction to be renamed
 * @param newName
 *            the new name of the renamed instruction
 * @updates s
 * @requires [newName is a valid IDENTIFIER]
 * @ensures <pre>
 * s = [#s refactored so that every occurrence of instruction oldName
 *   is replaced by newName]
 * </pre>
 */
public static void renameInstruction(Statement s, String oldName,
        String newName) {...}
Using the method above, complete the body of the following static method.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
 * Refactors the given {@code Program} by renaming instruction
 * {@code oldName}, and every call to it, to {@code newName}. Everything
 * else is left unmodified.
 * 
 * @param p
 *            the {@code Program}
 * @param oldName
 *            the name of the instruction to be renamed
 * @param newName
 *            the new name of the renamed instruction
 * @updates p
 * @requires <pre>
 * oldName is in DOMAIN(p.context)  and
 * [newName is a valid IDENTIFIER]  and
 * newName is not in DOMAIN(p.context)
 * </pre>
 * @ensures <pre>
 * p = [#p refactored so that instruction oldName and every call
 *   to it are replaced by newName]
 * </pre>
 */
public static void renameInstruction(Program p, String oldName,
        String newName) {...}
You may hand-draw your answer to this question. Recalling how much we care that you use correct punctuation when you write objects' values, and using the notation of slides 9 through 12 from Program, but fully drawing each abstract syntax tree involved, show the value of p at the end of the following code snippet.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Program p = new Program1();
Map<String, Statement> context = p.newContext();
Statement block = p.newBody();
Statement s = block.newInstance();
p.setName("Get-to-Edge-and-Wait-for-Infection");
s.assembleCall("walk");
block.addToBlock(0, s);
s.assembleCall("run");
block.addToBlock(block.lengthOfBlock(), s);
s.assembleWhile(Condition.NEXT_IS_NOT_WALL, block);
block.addToBlock(0, s);
p.swapBody(block);
s.assembleCall("move");
block.addToBlock(0, s);
s.assembleCall("move");
block.addToBlock(block.lengthOfBlock(), s);
context.add("run", block);
s.assembleCall("move");
block = block.newInstance();
block.addToBlock(0, s);
context.add("walk", block);
p.swapContext(context);
Consider the occurrence on line 19 of the code snippet above of block = block.newInstance(). What would probably have happened if that statement had been replaced by block.clear()? In other words, what is the difference between the two statements? You may hand-draw a diagram to show the difference. (Hint: which are the only two lines in the code snippet in which the statement executed would introduce an alias to a mutable object? (Hint: all contracts in our components catalog advertise every introduction of an alias to a mutable object.))