|
Execute a few steps of the program by typing:
step[ENTER][ENTER][ENTER] |
at the interactive prompt. This should bring you to the following
statement:
line: integer
(# a:< string; b:< string; end:< boolean;
plural: (# exit (if value=1 then '' else 's' if)#);
punct: (# exit (if end then '.' else ',' if)#);
=>do (if value=0 then
'no more'->puttext
else
value->putint
if);
' bottle'+plural+' of beer'+a+punct+b->putline
#); |
Now take a look at the value :
.. and try to execute an ad-hoc imperative (which assigns the lesser
of zero and value to value and then prints
the result):
do (0,value)->min->value->putint |
Give the command step and press [ENTER]
several times to see the program execute step-by-step. As you can
see, the program is affected by the changes introduced by the
execution of the ad-hoc imperative, and since any imperative is
allowed (as long as it is statically correct) the do
command is a strong tool.
Basic breakpoints
At some point, when the source code window shows the file
beer.bg , click in the source code window on the
"->" arrow of value->putint , to
ensure that the source code window is the active window and that the
point (cursor, insertion point) is at that arrow. Since the arrow is
syntactically a top-level constituent of the assignment
value->putint , this position is identified with
the assignment itself, and that is useful because you can select the
menu item Breakpoint from the Gud menu, thus
setting a permanent breakpoint at that assignment. By the way, a
convenient method to access this menu is pressing the rightmost mouse
button along with the Control modifier, then the menu
pops up right there in over the source code window.
Now execute the command:
to continue running until the interpretation would start executing
that assignment. Press [ENTER] a couple of times to
watch what happens between each time the program reaches that point,
for example:
executing~1>
96 bottles of beer.
Take one down, pass it around,
executing~1> _ |
line: integer
(# a:< string; b:< string; end:< boolean;
plural: (# exit (if value=1 then '' else 's' if)#);
punct: (# exit (if end then '.' else ',' if)#);
=>do (if value=0 then 'no more'->puttext else value->putint if);
' bottle'+plural+' of beer'+a+punct+b->putline
#); |
By now the default command is go , so every
[ENTER] continues the execution in the running, not
single-stepping, mode.
Other kinds of breakpoints
There are some other variants of breakpoints, namely temporary
breakpoints and "after-breakpoints". A temporary
breakpoint simply gets deleted the first time it causes a break, and
this is sometimes convenient .. think of it as a way to "run until you
hit this spot" without changing the properties of "this spot."
Sometimes it is hard to say exactly what imperative will execute after
the execution of a given imperative finishes, perhaps because it is
the last imperative in the body of a method (pattern) which might be
invoked from many different places. In these cases it is convenient
to stop after the execution of an imperative, not before the
next one. This is the motivation for the
"Breakpoint After" and "Tmp. Brk. After"
menu entries, corresponding to the abreak and
tabreak commands.
The next section summarizes the execution control commands.
| |