1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
|
@c -*-texinfo-*-
@c This is part of the GNU MDK Reference Manual.
@c Copyright (C) 2000, 2001, 2003, 2004, 2006
@c Free Software Foundation, Inc.
@c See the file mdk.texi for copying conditions.
@node mixguile, Problems, gmixvm, Top
@chapter @code{mixguile}, the Scheme virtual machine
@cindex @code{mixguile}
This chapter provides a reference to using @code{mixguile} and the
Scheme function library giving access to the MIX virtual machine in the
@sc{mdk} emulators (@code{mixguile}, @code{mixvm} and @code{gmixvm}). See
@ref{Using mixguile} for a tutorial, step by step introduction to
@code{mixguile} and using Scheme as an extension language for the
@sc{mdk} MIX virtual machines.
@menu
* Invoking mixguile:: Command line options.
* Scheme functions reference:: Scheme functions accessing the VM.
@end menu
@node Invoking mixguile, Scheme functions reference, mixguile, mixguile
@section Invoking @code{mixguile}
@cindex @code{mixguile} options
Invoking @code{mixguile} without arguments will enter the Guile REPL
(read-eval-print loop) after loading, if it exists, the user's
initialisation file (@file{~/.mdk/mixguile.scm}).
@code{mixguile} accepts the same command line options than Guile:
@example
mixguile [-s SCRIPT] [-c EXPR] [-l FILE] [-e FUNCTION] [-qhv]
[--help] [--version]
@end example
The meaning of these options is as follows:
@defopt -h
@defoptx --help
Prints usage summary and exits.
@end defopt
@defopt -v
@defoptx --version
Prints version and copyleft information and exits.
@end defopt
@defopt -s SCRIPT
Loads Scheme code from @var{script}, evaluates it and exits. This option
can be used to write executable Scheme scripts, as described in
@ref{Scheme scripts}.
@end defopt
@defopt -c EXPR
Evaluates the given Scheme expression and exits.
@end defopt
@defopt -l FILE
Loads the given Scheme file and enters the REPL (read-eval-print loop).
@end defopt
@defopt -e FUNCTION
After reading the script, executes the given function using the provided
command line arguments. For instance, you can write the following Scheme
script:
@example
#! /usr/bin/mixguile \
-e main -s
!#
;;; execute a given program and print the registers.
(define main
(lambda (args)
;; load the file provided as a command line argument
(mix-load (cadr args))
;; execute it
(mix-run)
;; print the contents of registers
(mix-pall)))
@end example
@noindent
save it in a file called, say, @file{foo}, make it executable, and run
it as
@example
$ ./foo hello
@end example
@noindent
This invocation will cause the evaluation of the @code{main} function
with a list of command line parameters as its argument (@code{("./foo"
"hello")} in the above example. Note that command line options to
mixguile must be written in their own line after the @code{\} symbol.
@end defopt
@defopt -q
Do not load user's initialisation file. When @code{mixguile} starts up,
it looks for a file named @file{mixguile.scm} in the user's @sc{mdk}
configuration directory (@file{~/.mdk}), and loads it if it exists. This
option tells @code{mixguile} to skip this initialisation file loading.
@end defopt
@node Scheme functions reference, , Invoking mixguile, mixguile
@section Scheme functions reference
As we have previously pointed out, @code{mixguile} embeds a MIX virtual
machine that can be accessed through a set of Scheme functions, that is,
of a Scheme library. Conversely, @code{mixvm} and @code{gmixvm} contain
a Guile interpreter, and are able to use this same Scheme library, as
well as all the other Guile/Scheme primitives and any user defined
function. Therefore, you have at your disposal a powerful programming
language, Scheme, to extend the @sc{mdk} virtual machine emulators (see
@ref{Using Scheme in mixvm and gmixvm} for samples of how to do it).
The following subsections describe available functions the MIX/Scheme
library.
@menu
* mixvm wrappers:: Functions invoking mixvm commands.
* Hooks:: Adding hooks to mixvm commands.
* Additional VM functions:: Functions accessing the MIX virtual machine.
@end menu
@node mixvm wrappers, Hooks, Scheme functions reference, Scheme functions reference
@subsection @code{mixvm} command wrappers
For each of the @code{mixvm} commands listed in @ref{Commands}, there is
a corresponding Scheme function named by prefixing the command name with
@code{mix-} (e.g., @code{mix-load}, @code{mix-run} and so on). These
command wrappers are implemented using a generic command dispatching
function:
@defun mixvm-cmd command argument
Dispatches the given @var{command} to the MIX virtual machine appending the
provided @var{argument}. Both @var{command} and @code{argument} must be
strings. The net result is as writing "@var{command} @var{argument}" at
the @code{mixvm} or @code{gmixvm} command prompt.
@end defun
For instance, you can invoke the @code{run} command at the @code{mixvm}
prompt in three equivalent ways:
@example
MIX > run hello
MIX > (mix-run "hello")
MIX > (mixvm-cmd "run" "hello")
@end example
@noindent
(only the two last forms can be used at the @code{mixguile} prompt or
inside a Scheme script).
The @code{mix-} functions evaluate to a unspecified value. If you want
to check the result of the last @code{mixvm} command invocation, use the
@code{mix-last-result} function:
@defun mix-last-result
Returns @var{#t} if the last @code{mixvm} command invocation was
successful, @var{#f} otherwise.
@end defun
@noindent
Using this function, we could improve the script for running a program
presented in the previous section by adding error checking:
@example
#! /usr/bin/mixguile \
-e main -s
!#
;;; Execute a given program and print the registers.
(define main
(lambda (args)
;; load the file provided as a command line argument
(mix-load (cadr args))
;; execute it if mix-load succeeded
(if (mix-last-result) (mix-run))
;; print the contents of registers if the above commands succeeded
(if (mix-last-result) (mix-pall))))
@end example
Please, refer to @ref{Commands} for a list of available commands. Given
the description of a @code{mixvm}, it is straightforward to use its
Scheme counterpart and, therefore, we shall not give a complete
description of these functions here. Instead, we will only mention those
wrappers that exhibit a treatment of their differing from that of their
command counterpart.
@defun mix-preg [register]
@defunx mix-sreg register value
The argument @var{register} of these functions can be either a string or
a symbol representing the desired register. For instance, the following
invocations are equivalent:
@example
(mix-preg 'I1)
(mix-preg "I1")
@end example
@end defun
@defun mix-pmem from [to]
The command @code{pmem} takes a single argument which can be either a
cell number or a range of the form @code{FROM-TO}. This function takes
one argument to ask for a single memory cell contents, or two parameters
to ask for a range. For instance, the following commands are equivalent:
@example
MIX > pmem 10-12
0010: + 00 00 00 00 00 (0000000000)
0011: + 00 00 00 00 00 (0000000000)
0012: + 00 00 00 00 00 (0000000000)
MIX > (mix-pmem 10 12)
0010: + 00 00 00 00 00 (0000000000)
0011: + 00 00 00 00 00 (0000000000)
0012: + 00 00 00 00 00 (0000000000)
MIX >
@end example
@end defun
@defun mix-sover #t|#f
The command @code{sover} takes as argument either the string @code{T} or
the string @code{F}, to set, respectively, the overflow toggle to true
or false. Its Scheme counterpart, @code{mix-sover}, takes as argument
a Scheme boolean value: @code{#t} (true) or @code{#f}.
@end defun
For the remaining functions, you simply must take into account that when
the command arguments are numerical, the corresponding Scheme function
takes as arguments Scheme number literals. On the other hand, when the
command argument is a string, the argument of its associated Scheme
function will be a Scheme string. By way of example, the following
invocations are pairwise equivalent:
@example
MIX > load ../samples/hello
MIX > (mix-load "../samples/hello")
MIX > next 5
MIX > (mix-next 5)
@end example
@node Hooks, Additional VM functions, mixvm wrappers, Scheme functions reference
@subsection Hook functions
Hooks are functions evaluated before or after executing a @code{mixvm}
command (or its corresponding Scheme function wrapper), or after an
explicit or conditional breakpoint is found during the execution of a
MIX program. The following functions let you install hooks:
@defun mix-add-pre-hook command hook
Adds a function to the list of pre-hooks associated with the given
@var{command}. @var{command} is a string naming the corresponding @code{mixvm}
command, and @var{hook} is a function which takes a single argument: a
string list of the commands arguments. The following scheme code defines
a simple hook and associates it with the @code{run} command:
@example
(define run-hook
(lambda (args)
(display "argument list: ")
(display args)
(newline)))
(mix-add-pre-hook "run" run-hook)
@end example
Pre-hooks are executed, in the order they are added, before invoking the
corresponding command (or its associated Scheme wrapper function).
@end defun
@defun mix-add-post-hook command hook
Adds a function to the list of pre-hooks associated with the given
@var{command}. The arguments have the same meaning as in
@code{mix-add-pre-hook}.
@end defun
@defun mix-add-global-pre-hook hook
@defunx mix-add-global-post-hook hook
Global pre/post hooks are executed before/after any @code{mixvm} command
or function wrapper invocation. In this case, @var{hook} takes two
arguments: a string with the name of the command being invoked, and a
string list with its arguments.
@end defun
@defun mix-add-break-hook hook
@defunx mix-add-cond-break hook
Add a hook funtion to be executed when an explicit (resp. conditional)
breakpoint is encountered during program execution. @var{hook} is a
function taking two arguments: the source line number where the hook has
occurred, and the current program counter value. The following code
shows a simple definition and installation of a break hook:
@example
(define break-hook
(lambda (line address)
(display "Breakpoint at line ") (display line)
(display " and address ") (display address)
(newline)))
(mix-add-break-hook break-hook)
@end example
Break hook functions are entirely implemented in Scheme using regular
post-hooks for the @code{next} and @code{run} commands. If you are
curious, you can check the Scheme source code at
@file{@emph{prefix}/share/mdk/mixguile-vm-stat.scm} (where @emph{prefix}
stands for your root install directory, usually @code{/usr} or
@code{/usr/local}.
@end defun
See @ref{Hook functions} for further examples on using hook functions.
@node Additional VM functions, , Hooks, Scheme functions reference
@subsection Additional VM functions
When writing non-trivial Scheme extensions using the MIX/Scheme library,
you will probably need to evaluate the contents of the virtual machine
components (registers, memory cells and so on). For instance, you may
need to store the contents of the @code{A} register in a variable. The
Scheme functions described so far are of no help: you can print the
contents of @code{A} using @code{(mix-preg 'A)}, but you cannot define a
variable containing the contents of @code{A}. To address this kind of
problems, the MIX/Scheme library provides the following additional
functions:
@defun mixvm-status
@defunx mix-vm-status
Return the current status of the virtual machine, as a number
(@code{mixvm-status}) or as a symbol (@code{mix-vm-status}). Possible
return values are:
@multitable {aamixvmaastatusaa} {aamixvmastatusaaaaaaa} {return valuesaaaaaaaaaaaaaaaaaaaaaaaaaa}
@item @code{(mixvm-status)} @tab @code{(mix-vm-status)} @tab
@item 0 @tab MIX_ERROR @tab Loading or execution error
@item 1 @tab MIX_BREAK @tab Breakpoint encountered
@item 2 @tab MIX_COND_BREAK @tab Conditional breakpoint
@item 3 @tab MIX_HALTED @tab Execution terminated
@item 4 @tab MIX_RUNNING @tab Execution stopped after @code{next}
@item 5 @tab MIX_LOADED @tab Program successfully loaded
@item 6 @tab MIX_EMPTY @tab No program loaded
@end multitable
@end defun
@defun mix-vm-error?
@defunx mix-vm-break?
@defunx mix-vm-cond-break?
@defunx mix-vm-halted?
@defunx mix-vm-running?
@defunx mix-vm-loaded?
@defunx mix-vm-empty?
Predicates asking whether the current virtual machine status is
@code{MIX_ERROR}, @code{MIX_BREAK}, etc.
@end defun
@defun mix-reg register
@defunx mix-set-reg! register value
@code{mix-reg} evaluates to a number which is the contents of the
specified @var{register}. @code{mix-set-reg} sets the contents of the
given @var{register} to @var{value}. The register can be specified
either as a string (@code{"A"}, @code{"X"}, etc.) or as a symbol
(@code{'A}, @code{'X}, etc.). For instance,
@example
guile> (mix-reg 'A)
2341
guile> (mix-set-reg! "A" 2000)
ok
guile> (define reg-a (mix-reg 'A))
guile> (display reg-a)
2000
guile>
@end example
@end defun
@defun mix-cell cell_no
@defunx mix-set-cell! cell_no value
Evaluate and set the contents of the memory cell number
@var{cell_no}. Both @var{cell_no} and @var{value} are Scheme numbers.
@end defun
@defun mix-loc
Evaluates to the value of the location counter (i.e., the address of the
next instruction to be executed).
@end defun
@defun mix-over
@defunx mix-set-over! #t|#f
@code{mix-over} evaluates to @code{#t} if the overflow toggle is set,
and to @code{#f} otherwise. The value of the overflow toggle can be
modified using @code{mix-set-over!}.
@end defun
@defun mix-cmp
@defunx mix-set-cmp! 'L|'E|'G
Evaluate and set the comparison flag. Possible values are the scheme
symbols @code{L} (lesser), @code{E} (equal) and @code{G} (greater).
@end defun
@defun mix-up-time
Evaluates to the current virtual machine uptime.
@end defun
@defun mix-lap-time
Evaluates to the current virtual machine lapsed time, i.e., the time
elapsed since the last @code{run} or @code{next} command.
@end defun
@defun mix-prog-time
Evaluates to the total time spent executing the currently loaded program.
@end defun
@defun mix-prog-name
Evaluates to a string containing the basename (without any leading path)
of the currently loaded MIX program.
@end defun
@defun mix-prog-path
Evaluates to a string containing the full path to the currently loaded
MIX program.
@end defun
@defun mix-src-path
Evaluates to a string containing the full path to the source file of the
currently loaded MIX program.
@end defun
@defun mix-src-line [lineno]
@defunx mix-src-line-no
@code{mix-src-line-no} evaluates to the current source file number
during the execution of a program. @code{mix-src-line} evaluates to a
string containing the source file line number @var{lineno}; when
invoked without argument, it evaluates to @code{(mix-src-line
(mix-src-line-no))}.
@end defun
@defun mix-ddir
Evaluates to a string containing the full path of the current device
directory.
@end defun
|