Abstract. In this chapter we give an example of a CGI program written in Scheme using the LAML cgi library. |
![]() ![]() ![]() 1 Introduction We are going to develop a simple number guessing game. |
1.1 The game |
![]() ![]() ![]() 1.1 The game |
The game is operational, and it can be played from here if you are connected to the Internet.
The pure Scheme program is available via the tutorial example page.
![]() ![]() ![]() 2 Overall design Although this program is simple and small we have used a structure which, in some respects at least, can be used for larger and more realistic CGI programs. |
2.1 The overall design |
![]() ![]() ![]() 2.1 The overall design |
The name of the file must be number-guess.cgi, and it should be file protected to be executable (typically with chmod 755).#!/bin/sh string=? ; exec /pack/mzscheme/bin/mzscheme -r $0 "$@" ;; This program implements a number guessing game, ;; which is commonly used to illustrate simple WWW ;; server programming. (define example-tutorial-dir "/user/normark/scheme/examples/tutorial/") (load (string-append example-tutorial-dir "cgi-programming/number-guess.scm"))
This starts MzScheme via a shell script, and the load line is executed. It would be perfectly possible to place the entire Scheme program here, but we prefer in general to organize our software in a directory outside the .public_html catalogue. Therefore we load the number guessing program from the tutorial example directory in my LAML development directory, which happens to be /normark/scheme.
As another important point, we decide to organize the number guessing
system as a single program, which in the page-write
part branches between a game init part ( ) and a game
playing part (
). We could as well have written two separate CGI programs,
which probably would have been preferable in case the 'System' is larger.
Such an alternative organization would typically call for common definitions organized in a shared scheme
number guessing libary file.
![]() ![]() ![]() 3 The program In this section we describe the number guessing program details. |
3.1 The preamble part 3.2 The init game part 3.3 The game part |
![]() ![]() ![]() 3.1 The preamble part |
The first thing to do in the section laml-loading is to load laml.scm.In order to do so we must
set laml-dir ().
laml-dir is important, because it's value points at the root of the LAML system,
which is used. Being at cs.auc.dk it is natural to use the shared LAML system in /pack/laml/.
Alternatively, the directory address of your own LAML system can be used.
Next comes the section initial-constants. The variable number-guess-url-prefix and not least the derived function number-guess-url are used to address the number guessing program from a browser. The function returns an URL with actual URL parameters - following the question mark. The function make-url-parameters is from the cgi LAML library, and it makes a list of actual URL parameters. We will meet the function number-guess-url later on.
Next comes the additional-loading part of the program. Here the cgi library is loaded by
means of the lib-load procedure, and a number of other libraries are loaded too.
The encode-decode library ( In other-settings we set the variable cgi-testing to #f and we register the current
time in cur-time. The time is not used in this program, but it general this number is useful for
a variety of purposes (such as making file names 'unique'). In the section url-parameters we extract the URL parameters passed to the program.
The variable language-preference controls whether the Danish or English language
is used in the game, with english as the default.
The function text-choice uses the variable language-preference.
The variable mode is important because it controls the part of the program to be started; Possible values are
the symbols init or play, with init as the default. The function defaulted-get is a function from the LAML general library. The CGI library function extract-url-parameters decodes the URL parameters.
The variable url-pars is an association list (a list of cons pairs), such as ) is used by cgi.scm
for encoding and decoding URL parameters.
This ends the game preamble part.
((language . "english") (mode . "init"))
![]() ![]() ![]() 3.2 The init game part |
Also notice the form element, generated by form-1 at ( After a welcome text we call guess-part ( Let us now look at guess-part, which returns part of the body.
Most functions called by guess-part are so-called convenience functions,
made on top of the HTML mirror libraries.
The function text-line renders
an input field, in which the guess can be entered ( ). This
determines the program which will receive form input when
submitted. Thus, when we submit a new guess this detail determines the
receiving CGI program. Here, we reuse the same program for this
purpose (due the outer branching discussed above), but notice
that we switch to play mode. We pass the language-preference as the
language URL parameter.
), which renders the form used for the user's guess.
). The secret number is passed on using
a hidden field (
). In a better version of the program we should protect this field from being
read directly in the document source. The submit button is also made in this function (
).
![]() ![]() ![]() 3.3 The game part |
((secret-number . "42") (players-guess . "22"))We prepare a body with a new form element (as above) (