This is a (really) hard exercise for my next exam. It's intended for scoping, binding and parameter-passing rules undestanding. I can't figure out even the first 3 numbers outputted, this is driving me crazy.
What is the output of this C-like program with dynamic scope, shallow binding and expression evaluation from left to right?
1 A : {
2
3 int x = 5;
4 int y = 7;
5
6 proc P(ref int y, valueresult int z, int R(name int)) {
7 z = y-- + R(++x + ++y);
8 write(x, y, 开发者_JS百科z);
9 z = R(z++);
10 }
11
12 B : {
13
14 int x = 3;
15
16 int Q(name int w) {
17 return (w + x++ + y++);
18 }
19
20 P(x, y, Q); // start here
21 write(y++, x++);
22 }
23
24 write(y, x);
25
26 }
A.x = 5
A.y = 7
B.x = 3
Calls P(3, 7, Q) - Inside P, y is a ref to B.x, which value is 3, z is 7. Due to dynamic scope, inside P, x is B.x.
Inside P, in the first instruction, we have the post-decrement y-- evaluated first, so the evaluated value would be 3 and B.x will change to 2.
R is called by name, so the return (w + x++ + y++) will become return ++x + ++y + x++ + y++. The entire first expression is expanded to something equivalent to z = y-- + (++x + ++y + x++ + y++).
In the expression ++x + ++y + x++ + y++, we have a pre-increment ++x, which will change B.x to 3 and give 3 as result. The ++y will change B.x to 4 and evaluate 4. The x++ will evaluate to 4 and change to 5 and the y++ will evaluate to 5 and change to 6.
So the returned value from Q is 3 + 4 + 4 + 5 = 16. This will be added to the previous z-- value which is 3, so 19 will be assigned to z and B.x will be 6.
The write will print x which is due to dynamic scope B.x, so will print 6. The y is a reference to the same B.x, so will print 6. The z is 19. So it will print 6, 6, 19.
In the third instruction of the P, we have z = R(z++) which due to call by name will expand to something equivalent to z = (z++ + x++ + y++).
So we get the z value, which is 19 and increment to 20 (post-increment). Add it to the value of B.x (6) and change B.x to 7. Add the 7 from y and increment y (which is B.x) to 8. So z = 19 + 6 + 7 = 32. B.x is 8.
Due to the valueresult of z, the A.y will be changed to 32.
Outside P, the write(y++, x++) will get the A.y value, which is 32 and print it. Then A.y will change to 33. B.x which is 8 will be printed and changed to 9. So it will print 32, 8.
Finally, the A.y will be printed (its value is 33). The A.x will be printed, which is 5. So it will print 33, 5.
Concluding, the program prints 6, 6, 19, 32, 8, 33, 5.
Here's what I've come up with - in a line-by-line trace:
before P(x,y,Q) A.x = 5 A.y = 7 B.x = 3
entering P A.x = 5 A.y = 7 B.x = 3 y = 3 z = 7
before z = y-- + R(++x + ++y) A.x = 5 A.y = 7 B.x = 3 y = 3 z = 7
entering R w = 9 A.x = 6 A.y = 7 B.x = 3
return (w + x++ + y++)
leaving R w = 9 A.x = 6 A.y = 8 B.x = 4 returns 19
after z = y-- + R(++x + ++y) A.x = 6 A.y = 8 B.x = 4 y = 4 z = 22
write(x, y, z)
6 4 22
before z = R(z++) A.x = 6 A.y = 8 B.x = 4 y = 4 z = 22
entering R w = 22 A.x = 6 A.y = 8 B.x = 4
return (w + x++ + y++)
leaving R w = 22 A.x = 6 A.y = 9 B.x = 5 returns 34
after z = R(z++) A.x = 6 A.y = 9 B.x = 5 y = 5 z = 34
after P(x,y,Q) A.x = 6 A.y = 34 B.x = 5
write(y++, x++)
34 5
after write(y++,x++) A.x = 6 A.y = 35 B.x = 6
write(y, x)
35 6
精彩评论