The easiest way to start up Kawa is to run the ‘kawa
’ program.
This finds your java interpreter, and sets up ‘CLASSPATH
’ correctly.
If you have installed Kawa such $PREFIX/bin
is in your $PATH
,
just do:
kawa
However, ‘kawa
’ only works if you have a Unix-like environment.
On some platforms, ‘kawa
’ is a program that uses the GNU
‘readline
’ library to provide input line editing.
To run Kawa manually, you must start a Java Virtual Machine.
How you do this depends on the Java implementation.
For Sun's JDK s and some other implementations, you must have the
Java evaluator (usually named java
) in your PATH
.
You must also make sure that the kawa/repl.class
file,
the rest of the Kawa packages, and the standard Java
packages can be found by searching CLASSPATH.
See the section called “Getting and running Java”.
Then you do:
java kawa.repl
In either case, you will then get the ‘#|kawa:1|#
’ prompt,
which means you are
in the Kawa read-eval-print-loop. If you type a Scheme
expression, Kawa will evaluate it. Kawa will then print the
result (if there is a non-"void" result).
You can pass various flags to Kawa, for example:
kawa -e '(display (+ 12 4))(newline)'
or:
java kawa.repl -e '(display (+ 12 4))(newline)'
Either causes Kawa to print ‘16
’, and then exit.
At startup, Kawa executes an init file from the user's home
directory.
The init file is named .kawarc.scm
on Unix-like systems
(those for which the file separator is '/'
),
and kawarc.scm
on other systems.
This is done before the read-eval-print loop
or before the first -f
or -c
argument. (It is not run
for a -e
command, to allow you to set options to override
the defaults.)
If there are no command-line arguments following the options,
then Kawa enters an interactive read-eval-print loop,
but only if none of the ‘-c
’, ‘-e
’, ‘-f
’, ‘-s
’,
‘-C
’, or ‘--
’ options were specified.
If there are command-line arguments after processing options,
then the first remaining argument names either a
file that is read and evaluated, or a compiled class.
In the former case, the whole file is read and compiled as a module
before being loaded (unlike the -f
flag which reads and
evaluates the file command by command.)
If the argument is the fully-qualited name of a class,
then the class is loaded, an instance allocated,
and its run
method invoked. If the class was compiled from
a Kawa Scheme module, then invoking run
has the
effect of evaluating the module body.
-e
expr
Kawa evaluates
expr
, which contains one or more Scheme expressions. Does not cause the~/.kawarc.scm
init file to be run.-c
expr
Same as ‘
-e
’, except that it does cause theexpr
~/.kawarc.scm
init file to be run.-f
filename-or-url
Kawa reads and evaluates expressions from the file named by
filename-or-url
. If the latter is ‘-
’, standard input is read (with no prompting). Otherwise, it is equivalent to evaluating ‘(load "
’. Thefilename-or-url
")filename-or-url
is interpreted as a URL if it is absolute - it starts with a "URI scheme" likehttp:
.-s
--
The remaining arguments (if any) are passed to ‘
command-line-arguments
’ and (thecdr
of)(command-line
), and an interactive read-eval-print loop is started. This uses the same "console" as where you started up Kawa; use ‘-w
’ to get a new window.--script
filename-or-url
--script
N
filename-or-url
-
The global variable ‘
command-line-arguments
’ is set to the remaining arguments (if any). Kawa reads and evaluates expressions from the file named byfilename-or-url
. Ifscript
is followed by an integerN
, thenN
lines are skipped first.Skipping some initial lines is useful if you want to have a non-Kawa preamble before the actual Kawa code. One use for this is for Kawa shell scripts (see the section called “Running Command Scripts”).
-w
Creates a new top-level window, and runs an interactive read-eval-print in the new window. See the section called “Running a Command Interpreter in a new Window”. Same as
-e (scheme-window #t)
. You can specify multiple ‘-w
’ options, and also use ‘-s
’.--help
Prints out some help.
--version
Prints out the Kawa version number, and then exits.
--server
portnum
Start a server listening from connections on the specified
portnum
. Each connection using the Telnet protocol causes a new read-eval-print-loop to started. This option allows you to connect using any Telnet client program to a remote "Kawa server".
--scheme
Set the default language to Scheme. (This is the default unless you select another language, or you name a file with a known extension on the command-line.)
--r5rs
--r6rs
--r7rs
Provide better compatibility with the specified Scheme standards. (This is a work-in-progress.) For example
--r6rs
aims to disable Kawa extensions that conflict with R6RS. It does not aim to disable all extensions, only incompatible extensions. So far these extensions disable the colon operator and keyword literals. Selecting--r5rs
makes symbols by default case-insensitive.--elisp
--emacs
--emacs-lisp
Set the default language to Emacs Lisp. (The implementation is quite incomplete.)
--lisp
--clisp
--clisp
--commonlisp
--common-lisp
Set the default language to CommonLisp. (The implementation is very incomplete.)
--krl
Set the default language to KRL. See the section called “KRL - The Kawa Report Language for generating XML/HTML”.
--brl
Set the default language to KRL, in BRL-compatibility mode. See the section called “KRL - The Kawa Report Language for generating XML/HTML”.
--xquery
Set the default language to the draft XML Query language. See the Kawa-XQuery page for more information.
--xslt
Set the default language to XSLT (XML Stylesheet Language Transformations). (The implementation is very incomplete.) See the Kawa-XSLT page for more information.
--pedantic
Try to follow the approprate language specification to the letter, even in corner cases, and even if it means giving up some Kawa convenience features. This flags so far only affects the XQuery parser, but that will hopefully change.
--warn-undefined-variable
Emit a warning if the code references a variable which is neither in lexical scope nor in the compile-time dynamic (global) environment. This is useful for catching typos. (A
define-variable
form can be used to silence warnings. It declares to the compiler that a variable is to be resolved dynamically.) This defaults to on; to turn it off use the--no-warn-undefined-variable
flag.--warn-unknown-member
Emit a warning if the code references a named member (field or method) for which there is no match in the compile-time type of the receiver. This defaults to on; to turn it off use the
--no-warn-unknown-member
flag.--warn-invoke-unknown-method
Emit a warning if the
invoke
function calls a named method for which there is no matching method in the compile-time type of the receiver. This defaults to the value of--warn-unknown-member
, to turn it off use the--no-warn-invoke-unknown-method
flag.--warn-unused
Emit a warning if a variable is unused or code never executed. This defaults to on; to turn it off use the
--no-warn-unused
flag.--warn-unreachable
Emit a warning if the code can never be executed. This defaults to on; to turn it off use the
--no-warn-unreachable
flag.--warn-void-used
Emit a warning if an expression depends on an expression that is void (always has zero values), including call to
void
functions and method. Also warn if an expression depends on a conditional (if
) that has no “else” clause. Examples include using the value ofset-car!
as an argument to a function, or to initialize a variable. This defaults to on; to turn it off use the--no-warn-void-used
flag.--warn-as-error
Treat a compilation warning as if it were an error and halt compilation.
An option can be followed by a value, as
in --warn-invoke-unknown-method=no
.
For boolean options, the values yes
, true
, on
, or 1
enable the option, while no
, false
, off
,
or 0
disable it.
You can also negate an option by prefixing it with no-
:
The option --no-warn-unknown-member
is the same as --warn-unknown-member=no
.
These options can also be used in the module source, using
module-compile-options
or with-compile-options
.
(In that case they override the options on the command line.)
name
=value
Set the global variable with the specified
name
to the givenvalue
. The type of thevalue
is currently unspecified; the plan is for it to be like XQuery's untyped atomic which can be coerced as needed.{
namespace-uri
}local-name
=value
Set the global variable with the specified namespace uri and namespace-local name to the given value.
These options are processed when invoking the kawa
application (i.e. the kawa.repl
application).
If you want a Kawa application compiled with --main
to process these these assignments, call the
process-command-line-assignments
utility function.
--output-format
format
--format
format
Change the default output format to that specified by
format
. See the section called “Named output formats” for more information and a list.
out:base=
integer
The number base (radix) to use by default when printing rational numbers. Must be an integer between 2 and 36, and the default is of course 10. For example the option
out:base=16
produces hexadecimal output. Equivalent to setting the*print-base*
variable.out:radix=no|yes
If true, prints an indicator of the radix used when printing rational numbers. The default is
no
. Equivalent to setting the*print-radix*
variable.out:doctype-system=
system-identifier
If
out:doctype-system
is specified then aDOCTYPE
declaration is written before writing a top-level XML element, using the specifiedsystem-identifier
.out:doctype-public=
public-identifier
Ignored unless
out:doctype-system
is also specified, in which case thepublic-identifier
is written as the public identifiers of theDOCTYPE
declaration.out:xml-indent=
kind
Controls whether extra line breaks and indentation are added when printing XML. If
kind
isalways
oryes
then newlines and appropriate indentation are added before and after each element. Ifkind
ispretty
then the pretty-printer is used to only add new lines when an element otherwise won't fit on a single line. Ifkind
isno
(the default) then no extra line breaks or indentation are added.out:line-length=
columns
out:right-margin=
columns
Specifies the maximum number of number of columns in a line when the pretty-printer decides where to break a line. (The two options are equivalent.)
--target
version
The
version
can be a JDK or Java specification version:5
,6
, or7
. The JDK versions1.5
and1.6
are equivalent to5
or6
, respectively. Specify a JVM (classfile) version to target. This is useful if (for example) you use Java 6, but want to create.class
files that can run on Java 5. In that case specify--target 5
.
The following options control which calling conventions are used:
--full-tailcalls
Use a calling convention that supports proper tail recursion.
--no-full-tailcalls
Use a calling convention that does not support proper tail recursion. Self-tail-recursion (i.e. a recursive call to the current function) is still implemented correctly, assuming that the called function is known at compile time.
--no-inline
Disable inlining of known functions and methods. The generated code runs slower, but you can more reliably trace procedures. Normally Kawa will assume that a procedure
fn
declared using a(define (fn args) body)
form is constant, assuming it isn't modified in the current module. However, it is possible some other module might modify the binding offn
. You can use the--no-inline
to disable the assumption thatfn
is constant.
The default is currently --no-full-tailcalls
because
it is usually faster.
It is also closer to the Java call model, so may be better for people
primarily interested in using Kawa for scripting Java systems.
Both calling conventions can co-exist: Code compiled
with --full-tailcalls
can call code compiled
with --no-full-tailcalls
and vice versa.
These options can also be used in the module source, using
module-compile-options
or with-compile-options
.
(In that case they override the options on the command line.)
The options ‘-C
’, ‘-d
’, ‘-T
’, ‘-P
’, ‘--main
’
‘--applet
’, and --servlet
are used to compile a Scheme file;
see the section called “Compiling to a set of .class files”.
The options ‘--module-static
’, --module-nonstatic
,
--no-module-static
, and --module-static-run
control how a module is mapped to a Java class; see the section called “How a module becomes a class”.
The option ‘--connect
’ is only used by
the ‘portnum
kawa
’ front-end program.
The following options are useful if you want to debug or understand how Kawa works.
--debug-dump-zip
Normally, when Kawa loads a source file, or evaluates a non-trivial expression, it generates new internal Java classes but does not write them out. This option asks it to write out generated classes in a ‘
.zip
’ archive whose name has the prefix ‘kawa-zip-dump-
’.--debug-print-expr
Kawa translates source language forms into an internal
Expression
data structure. This option causes that data structure to be written out in a readable format to the standard output.--debug-print-final-expr
Similar to the previous option, but prints out the
Expression
after various transformations and optimizations have been done, and just before code generation.--debug-error-prints-stack-trace
Prints a stack trace with any error found during compilation.
--debug-warning-prints-stack-trace
Prints a stack trace with any warning found during compilation.
JDK 6 (or later) includes a complete web server library.
--http-auto-handler
context-path
appdir
Register a web application handler that uses files in the directory
appdir
to handle HTTP (web) requests containing the givencontext-path
. That is it handles requests that start withhttp://localhost:
. (This assumes theport
context-path
context-path
starts with a/
.) See the section called “Self-configuring web page scripts”.--http-start
port
Start the web server, listing on the specified
port
.
The kawa
front-end can pass options to the java
launcher,
using -J
or -D
options.
These must be given before any other arguments.
For example:
kawa -J-Xms48m -Dkawa.command.name=foo foo.scm --
is equivalent to (ignoring classpath issues):
java -Xms48m -Dkawa.command.name=foo kawa.repl foo.scm --
-J
jvm-option
Passes the
jvm-option
to thejava
command, before the class-name (kawa.repl
) and Kawa options.-D
variable-name
=variable-value
Sets the JVM property
variable-name
tovariable-value
. Equivalent to-J-D
.variable-name
=variable-value
If you write a Kawa application it is convenient to be able
to execute it directly (from the command line or clicking an icon, say),
without have to explicitly run kawa
or java
.
On Unix-like systems the easiest way to do this is to
write a small shell script that runs your Kawa application.
For modest-sized applications it is convenient if the shell script
and the Kawa code can be in the same file.
Unix-like systems support a mechanism where a script can
specify a program that should execute it. The convention
is that the first line of the file should start with the two characters
‘#!
’ followed by the absolute path of the program that should
process (interpret) the script.
(Windows has batch files, which are similar.)
This is convention works well for script languages that use ‘#
’
to indicate the start of a comment, since the interpreter will
automatically ignore the line specifying the interpreter filename.
Scheme, however uses ‘#
’ as a multi-purpose prefix,
and Kawa specifically uses ‘#!
’ as a prefix for
various the section called “Special named constants” such as #!optional
.
Kawa does recognize the three-character sequence ‘#!/
’ at the
beginning of a file as special, and ignores it.
Here is an example:
#!/usr/local/bin/kawa (format #t "The command-line was:~{ ~w~}~%" (command-line))
If you copy this text to a file named /home/me/bin/scm-echo
,
set the execute permission, and make sure it in your PATH
,
then you can execute it just by naming it on command line:
$ chmod +x /home/me/bin/scm-echo $ PATH=/home/me/bin:$PATH $ scm-env a b The command-line was: "/home/me/bin/scm-echo" "a" "b"
The system kernel will automatically execute kawa
, passing it the
filename as an argument.
Note that the full path-name of the kawa
interpreter
must be hard-wired into the script. This means you may have to edit
the script depending on where Kawa is installed on your system.
Another possible problem is that the interpreter must be an
actual program, not a shell script. Depending on how you configure
and install Kawa, kawa
can be a real program or a script.
You can avoid both problems by the env
program, available on
most modern Unix-like systems:
#!/usr/bin/env kawa (format #t "The command-line was:~{ ~w~}~%" (command-line))
This works the same way, but assumes kawa
is in the
command PATH
.
If you need to specify extra arguments to kawa
,
you can run arbitrary shell command inside Scheme block comments.
Here is an example:
#!/bin/sh #| exec kawa out:base=16 out:radix=yes "$0" "$*" |# (format #t "The command-line is:~{ ~w~}.~%" (command-line)) (display "It has ") (display (apply + (map string-length (command-line)))) (display " characters.") (newline)
The trick is to hide the shell code from Kawa inside
a #|...|#
block-comment. The start of the block comment
is a line starting with a #
, so it is treated as a comment by the shell.
You can then invoke kawa
(or java
directly)
as you prefer, setting up class-path and jars as needed,
and passing whatever arguments you want.
(The shell replaces the "$0"
by the name the script, and
replaces the "$@"
by the remaining arguments passed to the script.)
You need to make sure the shell finishes before it reaches
the end of the block comment or the Scheme code, which would confuse it.
The example uses exec
, which tells the shell to replace
itself by kawa
;
an alternative is to use the shell exit
command.
If you copy the above file to /tmp/sch-echo
and make
that file executate, you can run it directly:
$ /tmp/scm-echo "a b" "c d" The command-line is: "/tmp/scm-echo" "a b c d". It has #x14 characters.
When the Kawa reader sees the initial #/
it sets
the command name to the file name, so it can be used by a future
call to (command-name)
. If you want to override
this you can use the -Dkawa.command.name=
option.
name
Using comments this way has the advantage that you have the option of running the script “manually” if you prefer:
$ kawa /tmp/scm-echo out:base=8 "x y" The command-line is: "/tmp/scm-echo" "out:base=8" "x y". It has 26 characters.
An argument consisting of just a \
(backslash)
causes Kawa to read the second line looking for
options. (Quotes and backslahes work like in the shell.)
These replace the backslash in the command line.
This is a less verbose mechanism, but it requires an
absolute path to kawa
, due to shell limitations.
#!/usr/bin/bin/kawa \ --scheme --full-tailcalls (format #t "The command-line is:~{ ~w~}.~%" (command-line))
In this case the efective command line received by Kawa will
be --scheme
, --full-tailcalls
, followed by the
script filename, followed by other arguments specified when
running the script.
The backslash used this way originated in
scsh where it is called the meta-arg.
(Unlike scsh, Kawa's #!
is not a block comment,
but a rest-of-line, though the backslash causes the following line
to also be skipped.)
An alternative method is to use the --script2
option,
which tells Kawa to execute the script after ignoring
the initial two lines. For example:
#!/bin/sh exec kawa --commonlisp out:base=16 --script2 "$0" "$@" (setq xx 20) (display xx) (newline)
This slightly more compact than using block-comments as shown earlier,
but it has the disadvantage that you can't explicitly
use kawa
or java
to run the script unless you
make sure to pass it the --script2
option.
If you compile your Kawa application to class files (or better:
a jar
file), you probably still want to write a small
shell script to set things up. Here is one method:
#!/bin/sh export CLASSPATH=/my/path exec kawa -Dkawa.command.name="$0" foo "$@"
Using the kawa
front-end is a convenience, since it automatically
sets up the paths for the Kawa classes, and (if enabled) if
provides readline support for the default input port.
Setting the kawa.command.name
property to "$0"
(the filename used to invoke the script) enables
(command-line
) to use the script name as the command name.
You can invoke java
directly, which is necessary when
running a jar
file:
#!/bin/sh exec java -cp /path/to/kawa -Dkawa.command.name="$0" foo.jar "$@"
(It is in principle possible to compile a Kawa application to
“a native executable”, for example using gcj
.
However, this is no longer supported, as gcj is no longer
being actively developed.)
An alternative interface runs the Java read-eval-print-loop inside a new window. This is in some ways nicer. One reason is that it provides better editing. (Mouse selection, arrow keys, and “standard” control keys should all work.)
You can also create new windows. They can either have different top-level environments or they can share environments. To try it, do:
java kawa.repl -w
Kawa normally keeps running as long as there is an active
read-eval-print loop still awaiting input or there is an unfinished
other computation (such as requested by a ‘-e
’ of ‘-f
’ option).
To close a read-eval-print-loop, you can type the special
literal #!eof
at top level. This is recognized as end-of-file.
Unfortunately, due to thread-related complications, just typing
an end-of-file character (normally ctrl/D until Unix), will not work.
If the read-eval-print-loop
is in a new window, you can select ‘Close
’ from the ‘File
’ menu.
To exit the entire Kawa session, call the
exit
procedure (with 0 or 1 integer arguments).
All Scheme functions and source files are invisibly compiled into internal Java byte-codes. (A traditional interpreter is used for macro-expansion. Kawa used to also interpret “simple” expressions in interactive mode, but always compiling makes things more consistent, and allows for better stack traces on errors.)
To save speed when loading large Scheme source files, you probably want to pre-compile them and save them on your local disk. There are two ways to do this.
You can compile a Scheme source file to a single archive file.
You do this using the compile-file
function.
The result is a single file that you can move around and load
just like the .scm
source file. You just specify the name
of the archive file to the load
procedure.
Currently, the archive is a "zip" archive and has extension ".zip";
a future release will probably use "Java Archive" (jar) files.
The advantage of compiling to an archive is that it is simple
and transparent. A minor disadvantage is that it causes the
Java "verifier" to be run when functions are loaded from it,
which takes a little extra time.
Alternatively, you can compile a Scheme source file to a
collection of ‘.class
’ files.
You then use the standard Java class loading mechanism to load the code.
The Java "verifier" does not need to get run, which makes
loading a little faster.
The compiled class files do have to be installed somewhere
in the CLASSPATH
.
You can also compile your Scheme program to native code using GCJ.
Invoking ‘kawa
’ (or ‘java kawa.repl
’) with
the ‘-C
’ flag will compile
a ‘.scm
’ source file into one or more ‘.class
’ files:
kawa --main -C myprog.scm
You run it as follows:
kawa [-doutdirectory
] [-Pprefix
] [-Ttopname
] [--main | --applet | --servlet] -Cinfile
...
Note the ‘-C
’ must come last, because ‘Kawa
’ processes the
arguments and options in order,
Here:
-C
infile
...The Scheme source files we want to compile.
-d
outdirectory
The directory under which the resulting ‘
.class
’ files will be. The default is the current directory.-P
prefix
A string to prepend to the generated class names. The default is the empty string.
-T
topname
The name of the "top" class - i.e. the one that contains the code for the top-level expressions and definitions. The default is generated from the
infile
andprefix
.--main
Generate a
main
method so that the resulting "top" class can be used as a stand-alone application. See the section called “Compiling to a standalone application”.--applet
The resulting class inherits from
java.applet.Applet
, and can be used as an applet. See the section called “Compiling to an applet”.--servlet
The resulting class implements
javax.servlet.http.HttpServlet
, and can be used as an servlet in a servlet container like Tomcat.
When you actually want to load the classes, the outdirectory
must be in your ‘CLASSPATH
’.
You can use the require
syntax or the load
function to load the code,
by specifying the top-level class, either as a file name
(relative to outdirectory
) or a class name.
E.g. if you did:
kawa -d /usr/local/share/java -P my.lib. -T foo -C foosrc.scm
you can use either:
(require my.lib.foo)
or:
(load "my.lib.foo")
Using require
is preferred as it imports the definitions
from my.lib.foo
into the compile-time environment,
while load
only imports the definitions into run-time environment.
If you are compiling a Scheme source file (say ‘foosrc.scm
’)
that uses macros defined in some other file (say ‘macs.scm
’),
you need to make sure the definitions are visible to the compiler.
One way to do that is with the ‘-f
’:
kawa -f macs.scm -C foosrc.scm
Many of the options described earlier are
relevant when compiling. Commonly used options include language selection,
the --warn-xxx
options, and --full-tailcalls
.
compile-file
source-file
compiled-archive
Compile the
source-file
, producing a.zip
archivecompiled-file
.For example, to byte-compile a file ‘
foo.scm
’ do:(compile-file "foo.scm" "foo")This will create ‘
foo.zip
’, which contains byte-compiled JVM.class
files. You can move this file around, without worrying about class paths. To load the compiled file, you can laterload
the named file, as in either(load "foo")
or(load "foo.zip")
. This should have the same effect as loading ‘foo.scm
’, except you will get the faster byte-compiled versions.
Many Java projects use Ant
for building Java projects. Kawa includes a <kawac>
Ant ask that simplifies compiling Kawa sources files to classes.
See the build.xml
in the Kawa source distribution for examples.
See the kawac
task documentation for details.
A Java application is a Java class with a special method
(whose name is main
). The application can be invoked directly
by naming it in the Java command.
If you want to generate an application from a Scheme program,
create a Scheme source file with the definitions you need, plus
the top-level actions that you want the application to execute.
For example, assuming your Scheme file is
MyProgram.scm
, you have two ways at your disposal to
compile this Scheme program to a standalone application:
-
Compile in the regular way decribed in the previous section, but add the
--main
option.kawa --main -C MyProgram.scm
The
--main
option will compile all Scheme programs received in arguments to standalone applications. -
Compile in the regular way decribed in the previous section, but add the
main: #t
module compile option to your module.;; MyProgram.scm (module-name <myprogram>) (module-compile-options main: #t)
kawa -C MyProgram.scm
This way you can compile multiple Scheme programs at once, and still control which one(s) will compile to standalone application(s).
Both method will create a MyProgram.class
which you can either
load
(as decribed in the previous section), or invoke as an application:
java MyProgram [args
]
Your Scheme program can access the command-line arguments args
by using the global variable ‘command-line-arguments
’,
or the R6RS function ‘command-line
’.
If there is no explicit module-export
in a module compiled
with --main
then no names are exported. (The default
otherwise is for all names to be exported.)
An applet is a Java class that inherits from java.applet.Applet
.
The applet can be downloaded and run in a Java-capable web-browser.
To generate an applet from a Scheme program, write the Scheme
program with appropriate definitions of the functions ‘init
’,
‘start
’, ‘stop
’ and ‘destroy
’. You must declare these
as zero-argument functions with a <void>
return-type.
Here is an example, based on the scribble applet in Flanagan's "Java Examples in a Nutshell" (O'Reilly, 1997):
(define-private last-x 0) (define-private last-y 0) (define (init) :: void (let ((applet (this))) (applet:addMouseListener (object (java.awt.event.MouseAdapter) ((mousePressed e) (set! last-x (e:getX)) (set! last-y (e:getY))))) (applet:addMouseMotionListener (object (java.awt.event.MouseMotionAdapter) ((mouseDragged e) (let ((g (applet:getGraphics)) (x (e:getX)) (y (e:getY))) (g:drawLine last-x last-y x y) (set! last-x x) (set! last-y y))))))) (define (start) :: void (format #t "called start.~%~!")) (define (stop) :: void (format #t "called stop.~%~!")) (define (destroy) :: void (format #t "called destroy.~%~!"))
You compile the program with the ‘--applet
’ flag in addition to the
normal ‘-C
’ flag:
java kawa.repl --applet -C scribble.scm
You can then create a ‘.jar
’ archive containing your applet:
jar cf scribble.jar scribble*.class
Finally, you create an ‘.html
’ page referencing your applet
and its support jar
s:
<html><head><title>Scribble testapp</title></head> <body><h1>Scribble testapp</h1> You can scribble here: <br> <applet code="scribble.class" archive="scribble.jar, kawa-1.14.1.jar" width=200 height=200> Sorry, Java is needed.</applet> </body></html>
The problem with using Kawa to write applets is that the Kawa .jar
file is quite big, and may take a while to download over a network connection.
Some possible solutions:
Try to strip out of the Kawa
.jar
any classes your applet doesn't need.Java 2 provides a mechanism to install a download extension.
Consider some alternative to applets, such as Java Web Start.
Using GCJ with Kawa is no longer supported, as GCJ is no longer being actively maintained.
You can compile your Scheme program to native code using GCJ, as long as you have built Kawa using GCJ.
First, you need to compile the Scheme code to a set of .class
files;
see the section called “Compiling to a set of .class files”.
kawa --main -C myprog.scm
Then to create an executable myprog
do:
gckawa --main=myprog myprog*.class -o myprog
The gckawa
is a simple shell script that calls gcj
.
The reason for the wildcard in myprog*.class
is that sometimes
Kawa will generate some helper classes in addition to myprog.class
.
The --main
option tell gcj
which class contains
the main
method it should use. The -o
option names
the resulting executable program. The -lkawa
option tells
the linker it should link with the kawa shared library, and
the -L$PREFIX/bin
option tells the linker where it can
find that library.