irc-bot/ocs-1.0.3/README

137 lines
4.1 KiB
Plaintext
Raw Normal View History

2009-03-02 18:49:21 -07:00
1. General
Ocs is an implementation of Scheme, as defined by R5RS. It is
written entirely in OCaml and can be trivially embedded in any
OCaml program.
Known deviations from R5RS:
- transcript-on and transcript-off are currently not implemented
- scheme-report-environment and null-environment ignore their
argument
Anything else that does not work as specified in R5RS is a bug.
2. Installation
Requirements:
- GNU make or pmake (BSD make)
- OCaml 3.x (versions 3.06 and newer tested)
Type make or gmake in the src directory. This should produce the
following:
- A bytecode library (ocs.cma)
- A native library (ocs.cmxa, ocs.a)
- A stand-alone, native interpreter (ocscm)
2.1 The 'ocscm' command
If invoked without arguments, the interpreter will run in interactive
mode.
If invoked with arguments, the interpreter will read and evaluate
the files listed as arguments and exit. The evaluation results are
not printed.
3. Implementation Details
Implementing Scheme in OCaml is so straightforward that it hardly
needs any documentation. The following mappings between languages
are done:
- Scheme is dynamically typed. Scheme values are represented by
the OCaml type Ocs_types.sval.
- In Scheme, top-level bindings are global and all variables are
mutable. Variables references are bound through environments
(Ocs_types.env) to global slots (Ocs_types.gvar) or frame indices
(the actual frames are visible at evaluation-time through
Ocs_types.thread).
- Scheme has capturable, first-class continuations. Most of the
evaluator is written in continuation-passing style in order to allow
this.
Where discussing types, the rest of this section assumes that the
types defined in the module Ocs_types are visible.
3.1 Evaluation
Scheme values (S-expressions) are of the type sval.
Before evaluation Scheme values are compiled to internal representations
of the type code. This is done by the function
Ocs_compile.compile : env -> sval -> code
The env type is used during compilation for variable bindings. A
new env is created for each new scope and frame. The base
environment with the basic language bindings can be created using
Ocs_top.make_env : unit -> env
Evaluation is done by
Ocs_eval.eval : thread -> (sval -> unit) -> code -> unit
where the second argument is a continuation to pass the result to.
The thread type is used during evaluation for storing the current
frame and display for local variables, the input/output ports and
the current dynamic extent. It does not represent a thread in the
concurrent sense, but rather the evaluation state, and is copied and
changed rather than modified in place. The initial thread to be
passed to the evaluator can be created using
Ocs_top.make_thread : unit -> thread.
3.2 Continuations and I/O
Any continuations captured are associated with the thread at the
time of capture, so if a continuation is used to escape a
with-input-from-file or with-output-to-file, the input/output port
is restored to those of the time of capture.
If a continuation is used to return to a with-input-from-file or
with-output-to-file, the port is once again set to the one
opened by the with-...-file call. However, if the thunk has
already exited once, the port will be closed and no longer be
valid for I/O calls.
3.3 Numbers
The full R5RS numeric tower is implemented, with the following
internal representations:
Exact numbers are
- 31- or 63-bit integers (OCaml int)
- Big_int objects from the Num library when unboxed integers are
too small
- Ratio objects from the Num library for rationals
Inexact numbers are
- 64-bit IEEE floats for reals (OCaml float)
- Pairs of 64-bit IEEE floats for complex numbers (OCaml Complex.t)
Since inexact numbers are represented internally as binary floating
point, conversions to exact numbers are most precise for fractions of
powers of two
(inexact->exact 2.125) ==> 17/8
compared to
(inexact->exact 0.3) ==> 5404319552844595/18014398509481984
And in fact many rationals will not satisfy
(= (inexact->exact (exact->inexact r)) r)
However
(rationalize (inexact->exact 0.3) (expt 2 -54)) ==> 3/10