Copyright © 1998, 2001 by Ian Horswill, see comment within this file.

Back

Back-end code generators

Package scheme48-run-time

The scheme48-run-time package serves two purposes:

The package exports two useful macros:

(try-compilation signal-expression ...)
This is the same as compile, except that its arguments are signal expressions.  Thus you can say (try-compilation (delay x 100)), which would not work with compile because delay isn't a scheme procedure and so can't be called from the keyboard.  The try-compilation macro converts the delay call into a new signal and passes it to compile.
(try-signals signal-expression ...)
Try-signals is the same as try-compilation except that it runs the compiled code.

The package also exports a number of useful macros and signal-procedures for use in debugging:

(prompt text)
(prompt-boolean text)
(prompt-vector
text)
(prompt-float-vector
text)
(prompt-boolean-vector
text)
These are transducers that read their signal values from the keyboard on each clock tick.  Before reading, they print the text as a prompt.  Note that the compiler schedules the order of signal update itself, so you don't have any control over the order in which multiple prompts will be read.  The order may also change if you change your other code.
(show-value signal-expression)
(show-values
signal-expression ...)
(maybe-show-value
signal-expression)
Macros.  Prints the value of signal expression(s) in the Lisp listener window every clock cycle.  In order to distinguish multiple calls to show-value, the messages are prefixed with text of the expression passed to show-value.  Thus, if you say (show-value foo), it will print "foo = 5", but if you say (show-value (+ foo 10)), if will print "(+ foo 10) = 5", etc. (this is the reason it needs to be a macro rather than a procedure).  Maybe-show-value is the same, but only prints if the signal is non-false.  If you use maybe-show-value, then you are relying on the fact that although the GRL compiler believes everything is statically typed, scheme48 isn't, and so you can have signals whose types change from clock cycle to clock cycle.  Needless to say, this code will not work when compiled to BASIC.
(trace-value signal-expression)
Macro.  Same as show-value, but returns the value of signal-expression.

The C++ back end

(compile-to-c++ class-name target-file signals ...)
Compiles signals to a C++ class named class-name that is a subclass of grl-agent.  This generates two files as output, target-file.h and target-file.cppClass-name and target-file should both be specified using strings.
(compile-to-c++ class-name  #f  signals ...)
Compiles signals to a C++ class named class-name that is a subclass of grl-agent.  The resulting code is printed to the screen rather than to files.  This is mostly useful for hand-checking the target code.  Note that this is the same as the previous incantation except that #f (i.e. the "false" object) is passed in for target-file.

The C++ back end is exported by package c++-generator.  The back end generates a C++ class definition for your program with minimal assumptions about the run-time environment. You should modify grl-agent.h and grl-agent.cpp to fit your operating system.

To run the program, write a main routine that creates an instance of the class and repeatedly calls its update() member.  Link this against your compiled program, grl-agent.cpp, and the C++ standard libraries.  Note that the compiled code is fully reentrant, so you can dynamically create and destroy as many instances of it as you want.  This is mostly useful for simulation studies, and particularly, for video games.

Special features

Bugs and misfeatures

#define float int

to grl.h.

The C back end

(compile-to-c-file target-file signals ...)
Compiles signals to C and places resulting code in target-file.
(compile-to-c signals ...)
Compiles signals to C and prints the resulting code to the screen.  Used for hand-checking the compiled code.

The C back end is exported by package c-generator.  The back end generates generic C code with minimal assumptions about the run-time environment. .  You should modify grl.h and grl-rts.c to fit your operating system.

To use the code, write a main() routine that does any setup you require, then calls run().  Compile this as well as the .c file created by the GRL compiler and link them against grl-rts and the C standard library.

Special features

Bugs and misfeatures

#define float int

to grl.h.

The BASIC back end

(compile-to-basic-file target-file signals ...)
Compiles signals to BASIC and places resulting code in target-file.
(compile-to-basic signals ...)
Compiles signals to BASIC and prints the resulting code to the screen.  Used for hand-checking the compiled code.

The BASIC back-end is exported by package basic-generator.  The back end has been tested with Tiger Basic.  Let us know if you need modifications to support a different compiler.  Text and binary I/O to streams is supported by this back-end.