The compiler contains a number of tools for testing signal procedures and transducers from the keyboard by allowing you to manually enter signal values and print their results. The support for this is found in the scheme48-run-time package. This package contains the function definitions required to allow compiled GRL code to run within the Scheme48 environment. In addition, it contains a number of useful macros for reading, writing, and testing, signal expressions.
To use package, simply open it from whatever package you are working in:
,open scheme48-run-time
Not that this package doesn't export the basic GRL definitions, so you still need to open a package like standard-girl to get ahold of them.
The following transducers can be used to read and write signal values to the terminal. They each read or print their associated values once per cycle of the program's main control loop. Note: running prompt with the clock overrun warning enabled (see below) is very irritating. You probably want to disable it when using prompt.
In addition, the following transducers are provided to facillitate parsers and command interpreters:
The following convenience macros are included to aid debugging. The differ from the compile-and-run and compile procedures only in that they allow full signal expressions as arguments.
The GRL run-time clock can operate within Scheme48 in either fixed mode or free running mode. In fixed mode, you set the clock period manually. The run-time system then sleeps at the end of each clock cycle until the designated period has elapsed. If the clock cycle takes longer than designated time, then a clock overrun warning is optionally issued. In free running mode, the GRL code is allow to update as fast as it can (no sleeping) and the run time system estimates the mean clock period. In either mode, the scheme variable measured-clock-period always contains the measured length of the previous clock period.
Here's a simple example of loading up GRL and trying out a signal. The things you type is listed in boldface. The rest is typed by the system.
The first thing we have to do is load the compiler, so we load the packages file and open the standard-girl and scheme48-run-time packages.
Welcome to Scheme 48 0.52.1 (suspended image). Copyright (c) 1993, 1994 by Richard Kelsey and Jonathan Rees. Copyright (c) 1996 by NEC Research Institute, Inc. Copyright (c) 1998, 1999 by Northwestern University. Please report all bugs to bug-scheme48@cs.nwu.edu
The first thing we have to do is load the compiler, so we load the packages file and open the standard-girl and scheme48-run-time packages.
> ,config ,load C:\WINDOWS\Desktop\GiRL\packages.scm
C:\WINDOWS\Desktop\GiRL\packages.scm
> ,open standard-girl scheme48-run-time Load structure standard-girl (y/n)? y [nice-features C:\WINDOWS\Desktop\GiRL\features.scm] [list-library C:\WINDOWS\Desktop\GiRL\list-library.scm Analyzing... Calls will be compiled in line: (del-assoc! del-assoc del-assv! del-assv del-assq! del-assq delete-duplicates! delv-duplicates! delq-duplicates! delete-duplicates delv-duplicates delq-duplicates delete! delete delv! delv delq! delq reverse-append xcons) ] [match-patterns C:\WINDOWS\Desktop\GiRL\match-patterns.scm] [girl-language C:\WINDOWS\Desktop\GiRL\primitives.scm ...] [girl-library C:\WINDOWS\Desktop\GiRL\library/utilities.scm] [rulesets C:\WINDOWS\Desktop\GiRL\library/rulesets.scm] [behavior-utilities C:\WINDOWS\Desktop\GiRL\library/behavior-utilities.scm] [standard-girl] Load structure scheme48-run-time (y/n)? y [scheme48-run-time C:\WINDOWS\Desktop\GiRL\scheme48-run-time.scm]
OK. Now the compiler is loaded. We're going to try out the low-pass-filter transducer. It needs to know the clock period in order to compute the appropriate filter gains, so we'll start by declaring a 100ms (10Hz) clock period. Of course, we won't be able to type numbers at 10Hz, so we'll also turn off the clock overrun warning.
> (set-clock-period! 100) > (enable-clock-overrun-warning! #f)
Now we can try out a low pass filter. Let's start by just trying to compile it.
> (try-compilation (low-pass-filter (prompt-float "Enter number: ")
100))
An error occurred while compiling. Signal name: "signal" UID: 21 Source code: (low-pass-filter (prompt-float "Enter number: ") 100)
Compiler subgoal stack:
Inferring type of #{Transducer-signal 21 "signal"}
Error: Invalid argument type(s) passed to low-pass-filter.
Wanted: (float float)
Got:
(float integer)
Unfortunately, the type checker got persnickety because we passed an integer into a float parameter, so we quit out of the debugger using ,reset (or control-D when running under GNU Emacs on Unix or control-R in the windows-based version) and add ".0" to the time constant. This time it works and we get to see the code it compiled.
1> ,resetTop level > (try-compilation (low-pass-filter (prompt-float "Enter number: ") 100.0)) (begin (define (run) (let* ((signal 0.)) (let* ((signal-2 0.) (decay (exp (* -1. (/ clock-period 100.)))) (input-gain (- 1. decay))) (while #t (update-girl-time!) (before-signal-update) (comment "Signal signal, transducer prompt-float") (newline) (display "Enter number: ") (set! signal (read)) (comment "Signal signal, transducer low-pass-filter") (set! signal-2 (+ (* decay signal-2) (* input-gain signal))) (after-signal-update))))))
Since it worked, we'll try running it now.
> (try-signals (low-pass-filter (prompt-float "Enter number: ") 100.0))Enter number: 100Enter number: 100Enter number: <user interrupts with control-break (windows) or control-C control-C (unix/emacs)> Interrupt: keyboard
Of course, it's rather boring if you don't tell it to print anything, so we reset and add a call to show-value:
1> ,resetTop level > (try-signals (show-value (low-pass-filter (prompt-float "Enter number: ") 100.0)))Enter number: 100(low-pass-filter (prompt-float "Enter number: ") 100.) = 63.2121Enter number: 100(low-pass-filter (prompt-float "Enter number: ") 100.) = 86.4665Enter number: 100(low-pass-filter (prompt-float "Enter number: ") 100.) = 95.0213Enter number: 100(low-pass-filter (prompt-float "Enter number: ") 100.) = 98.1684Enter number: -100(low-pass-filter (prompt-float "Enter number: ") 100.) = -27.0979Enter number: -100(low-pass-filter (prompt-float "Enter number: ") 100.) = -73.1808Enter number: -100(low-pass-filter (prompt-float "Enter number: ") 100.) = -90.1338Enter number: 0(low-pass-filter (prompt-float "Enter number: ") 100.) = -33.1584Enter number: 0(low-pass-filter (prompt-float "Enter number: ") 100.) = -12.1983Enter number: 0(low-pass-filter (prompt-float "Enter number: ") 100.) = -4.4875Enter number: <interrupt> Interrupt: keyboard 1> ,resetTop level >