This is librep.info, produced by makeinfo version 4.2 from librep.texi.

INFO-DIR-SECTION Programming Languages
START-INFO-DIR-ENTRY
* librep: (librep).		A flexible Lisp environment
END-INFO-DIR-ENTRY

   This is Edition 1.2, last updated 8 September 2000, of `The librep
Manual', for librep, Version 0.13.

   Copyright 1999-2000 John Harper.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.


File: librep.info,  Node: String Functions,  Next: Sleeping,  Prev: Environment Variables,  Up: The language

String Functions
================

 - Function: translate-string string map
     Applies the MAP to each character in the STRING. MAP is also
     string, each character represents the translation for an ASCII
     character of that characters position in the string. If the string
     is less than 256 chars long any undefined characters will remain
     unchanged.

     For example, if STRING contains the character `A', with ASCII code
     65, then it would be replaced by the 65th character in the string
     MAP.

     Note that the STRING really is modified, no copy is made

 - Variable: upcase-table
     A `translate-string' compatible translation map to convert
     lowercase characters to uppercase characters.

 - Variable: downcase-table
     A map to convert uppercase characters to lowercase.

 - Variable: flatten-table
     A translation map to convert newline characters to spaces.

     (translate-string "Foo" upcase-table)
         => "FOO"
     
     (translate-string "Foo" downcase-table)
         => "foo"

 - Function: complete-string template list #!optional ignore-case
     Return a string whose beginning matches the string TEMPLATE, and
     is unique in the set of all strings in LIST which also match
     TEMPLATE. If IGNORE-CASE is true, all matching ignores case of
     characters.

          (complete-string "foo" '("bar" "foobar" "forbarf" "foobat"))
              => "fooba"

 - Function: string-head-eq string-1 string-2
     Returns t if STRING-2 matches the beginning of STRING-1.

          (string-head-eq "foobar" "foo")
              => t
          
          (string-head-eq "foo" "foobar")
              => ()

 - Function: string-upper-case-p string
     Return true if STRING contains no lower case characters.

 - Function: string-lower-case-p string
     Return true if STRING contains no upper case characters.

 - Function: string-capitalized-p string
     Return true if the first character of STRING is upper case.

 - Function: string-upcase string
     Return a new string, an upper case copy of STRING.

 - Function: string-downcase string
     Return a new string, a lower case copy of STRING.

 - Function: capitalize-string string
     Return a new string, a copy of STRING with the first character in
     upper case.

 - Function: mapconcat function sequence separator
     Call FUNCTION for each member of SEQUENCE, concatenating the
     results. Between each pair of results, insert SEPARATOR.  Return
     the resulting string.


File: librep.info,  Node: Sleeping,  Next: Beeping,  Prev: String Functions,  Up: The language

Sleeping
========

 - Function: sleep-for seconds #!optional milliseconds
     Pause for a SECONDS (plus the optional MILLISECONDS component)
     long period of time. Input becoming available will _not_ break the
     sleep (*note Process I/O::).

     This function is exported by the `rep.system' module.


File: librep.info,  Node: Beeping,  Next: Messages,  Prev: Sleeping,  Up: The language

Beeping
=======

   Use this function to attract the user's attention.

 - Function: beep
     Ring a bell somewhere.


File: librep.info,  Node: Messages,  Next: Command Line Options,  Prev: Beeping,  Up: The language

Messages
========

   The `message' function will show the user a small message (typically
no more than a single column of text). In graphical applications it
_won't_ bring up a separate window, only displaying the text in a
status bar or something similar. In a console-based environment, the
message will be printed to the `stderr' stream, followed by a line
break.

 - Function: message #!optional display-now
     Displays a one-line message, the string MESSAGE. If DISPLAY-NOW,
     every effort will be made to display the message as soon as
     possible, possibly before the next scheduled screen update (if
     applicable).

     This function is exported by the `rep.system' module.


File: librep.info,  Node: Command Line Options,  Next: Shell Commands,  Prev: Messages,  Up: The language

Command Line Options
====================

   As noted earlier any unused command line arguments are made available
to scripts through the `command-line-args' variable (*note
Invocation::).

 - Variable: command-line-args
     The list of unused command line arguments, in their original order.

   The `get-command-line-option' function may be used to scan this list
of arguments. The `rep.system' module exports this function.

 - Function: get-command-line-option option #!optional requires-arg
     Returns t if OPTION was specified on the command line (OPTION is
     typically a phrase beginning with `--').

     If REQUIRES-ARG is true, the option requires a parameter, the
     value of which is returned. If a parameter isn't supplied an error
     is signalled.

     (setq command-line-args '("--foo" "bar"))
         => ("--foo" "bar")
     (get-command-line-option "--foo" t)
         => "bar"
     command-line-args
         => ()
     
     (setq command-line-args '("--foo=bar"))
         => ("--foo=bar")
     (get-command-line-option "--foo" t)
         => "bar"
     command-line-args
         => ()


File: librep.info,  Node: Shell Commands,  Next: Timers,  Prev: Command Line Options,  Up: The language

Executing Shell Commands
========================

   The subprocess handling of `librep' provides a comprehensive
interface to starting and controlling external processes (*note
Processes::). However it can be overkill when all that is required is
to invoke a shell command, with its I/O going to the same places as the
interpreter's.

 - Function: system command
     Execute the shell command COMMAND synchronously, returning its
     exit status. An error will be signalled if the shell process could
     not be started.

     The `stdin', `stdout' and `stderr' streams of the shell are left
     as in the interpreter process.

     The subprocesses environment is copied from the current value of
     the `process-environment' variable.

   Note that the exit status is _not_ the same as the return code of
the command. It depends on the operating system, but under UNIX the
return code can be found through right-shifting the exit status by
eight bits. Low non-zero values represent that the process was killed
by a signal.

   It is possible to interrupt a running shell process in the same way
as with a normal synchronous process (*note Synchronous Processes::).
Interrupt the interpreter, it will send progressively harder-to-ignore
signals to the child each interrupt, until it is eventually terminated.


File: librep.info,  Node: Timers,  Next: Debugging,  Prev: Shell Commands,  Up: The language

Asynchronous Timers
===================

   The `rep.io.timers' module (*note Modules::) allows a Lisp program
to create multiple asynchronous timers, each of which is primed to call
a specified function after a specified period of time. These functions
only work when the Lisp event loop is being used (i.e. at least one
`recursive-edit' is currently in progress).

 - Function: make-timer function #!optional seconds milliseconds
     Create and return a new timer object. It will be set to call the
     Lisp function FUNCTION after SECONDS seconds plus MILLISECONDS
     milliseconds. FUNCTION will be called with a single argument, the
     timer object that has just fired.

     If both SECONDS and MILLISECONDS are undefined, or zero, the timer
     will be created but won't call FUNCTION.

     After the time interval has passed, and FUNCTION has been called,
     the timer _will not_ be restarted. Use the `set-timer' function to
     reset it.

 - Function: delete-timer timer
     Prevent the timer object TIMER from calling the Lisp function
     associated with it. Use the `set-timer' function to reset it.

 - Function: set-timer timer #!optional seconds milliseconds
     Reset the timer object TIMER. If either/both of SECONDS and
     MILLISECONDS are defined the interval of the timer will be set to
     the specified time period. If neither are defined then the current
     interval of the timer is preserved.


File: librep.info,  Node: Debugging,  Next: Tips,  Prev: Timers,  Up: The language

Debugging
=========

   When you have written a Lisp program you will have to debug it
(unless all your programs work first time?). There are two main classes
of errors; syntax errors and semantic errors.

   Syntax errors occur when the text you've typed out to represent your
program is not a valid representation of a Lisp object (since a program
is simply an ordered set of Lisp objects). When you try to load your
program the Lisp reader will find the syntax error and tell you about,
unfortunately though it probably won't be able to tell you exactly
where the error is.

   The most common source of syntax errors is too few or too many
parentheses; the Jade or Emacs `Ctrl-Meta-f' and `Ctrl-Meta-b' commands
can be used to show the structure of the program as the Lisp reader
sees it.

   Semantic errors are what we normally call bugs--errors in logic, the
program is syntactically correct but doesn't do what you want it to.
For these types of errors librep provides hooks to allow interactive
debugging. The debugger supplied with librep uses these hooks to
implement a simple command line debugger; programs using librep as an
extension language may provide their own debugger interface.

   There are several ways to enter the Lisp debugger; functions can be
marked so that they cause the debugger to be entered when they are
called, breakpoints can be written in functions or it can be called
explicitly with a form to step through.

 - Command: trace symbol
     This command marks the symbol SYMBOL so that each time its value
     is dereferenced the debugger is entered when the next form is
     evaluated. This can be used to set breakpoints on functions (or
     variables).

     When called interactively SYMBOL is prompted for.

 - Command: untrace symbol
     The opposite of `trace'--unmarks the symbol.

 - Function: break
     This function causes the debugger to be entered immediately. By
     putting the form `(break)' at suitable points in your program
     simple breakpoints can be created.

 - Command: step form
     This function invokes the debugger to step through the form FORM.

     When called interactively FORM is prompted for.

 - Function: backtrace #!optional stream
     Prints a description of the current Lisp function call stack to
     STREAM (or `standard-output' if STREAM is undefined).

          (backtrace (current-buffer))
               -| #<subr backtrace> ((current-buffer)) nil
               -| #<closure eval-and-print> ((backtrace (current-buffer))) t
               => t

     Each line represents a stack frame, the first item is the called
     function, the second is the list of arguments applied to it. The
     third item is true if the list of arguments as displayed has
     already been evaluated.

   Whenever the Lisp debugger is entered the form waiting to be
evaluated is printed, preceded by the current depth of execution in
angular brackets. At this point the special debugger commands available
are,

`step'
`s'
     Step into the current form; this means that in a list form the
     debugger is used to evaluated each argument in turn.

`next'
`n'
     Continue evaluating forms normally until the next form at the
     current level is entered, then re-enter the debugger.

`continue'
`c'
     Continue execution normally. Note that this command is the one to
     use when an error has been trapped.

`return FORM'
`r FORM'
     Evaluate FORM then return this value as the result of the current
     form.

`print FORM'
`p FORM'
     Evaluate FORM, then print its value.

`form'
`f'
     Print the form being debugged.

`backtrace'
`b'
     Print a backtrace of the current Lisp call stack.

   Entering a null string repeats the previous `next', `step', or
`continue' command.

   After the form has been evaluated (i.e. after you've typed one of the
commands above) the value of the form is printed in the buffer,
prefixed by the string `=> '.

   Note that it is also possible to make certain types of errors invoke
the debugger immediately they are signalled, see *Note Errors::. Also
note that the debugger is unable to step through compiled Lisp code.


File: librep.info,  Node: Tips,  Prev: Debugging,  Up: The language

Tips
====

   This section of the manual gives advice about programming in
`librep'.

   For advice on getting the most out of the compiler, see *Note
Compilation Tips::.

* Menu:

* Comment Styles::              Different types of comments


File: librep.info,  Node: Comment Styles,  Up: Tips

Comment Styles
--------------

   As already described, single-line comments in Lisp are introduced by
a semi-colon (`;') character. By convention a different number of
semi-colons is used to introduce different types of comments,

`;'
     A comment referring to the line of Lisp code that it occurs on,
     comments of this type are usually indented to the same depth, on
     the right of the Lisp code. When editing in Jade's Lisp mode the
     command `Meta-;' can be used to insert a comment of this type.

     For example,

          (defconst op-call #x08)         ;call (stk[n] stk[n-1] ... stk[0])
                                          ; pops n values, replacing the
                                          ; function with the result.
          (defconst op-push #x10)         ;pushes constant # n

`;;'
     Comments starting with two semi-colons are written on a line of
     their own and indented to the same depth as the next line of Lisp
     code. They describe the following lines of code.

     For example,

          (let
              ((fname (concat file-name ?c)))
            ;; Be sure to remove any partially written dst-file.
            (when (file-exists-p fname)
              (delete-file fname)))

     Comments of this type are also placed before a function definition
     to describe the function. This saves wasting memory with a
     documentation string in a module's internal functions.

     For example,

          ;; Compile a form which occurred at the `top-level' into a
          ;; byte code form.
          ;; defuns, defmacros, defvars, etc... are treated specially.
          ;; require forms are evaluated before being output uncompiled;
          ;; this is so any macros are brought in before they're used.
          (defun comp-compile-top-form (form)
            ...

`;;;'
     This type of comment always starts in the first column of the
     line, they are used to make general comments about a program and
     don't refer to any function or piece of code in particular.

     For example,

          ;;; Notes:
          
          ;;; Instruction Encoding
          ;;; ====================
          ;;; Instructions which get an argument (with opcodes of zero up to
          ...

`;;;;'
     Each program should have a comment of this type as its first line,
     the body of the comment is the name of the file, two dashes and a
     brief description of what the program does. They always start in
     the first column.

     For example,

          ;;;; compiler.jl -- Simple compiler for Lisp files/forms

   If you adhere to these standards the indentation functions provide by
the Lisp mode will indent your comments to the correct depth.


File: librep.info,  Node: The REPL,  Next: librep Internals,  Prev: The language,  Up: Top

The REPL
********

   When you invoke the stand-alone librep interpreter without giving it
a script to execute the system is started in interactive mode. This
means that the "REPL" is entered--the read-eval-print loop.

   The REPL works as its name suggests. It reads Lisp forms from the
console, evaluates them, and then prints the result back to the
console. Here is an example REPL session:

     user> (+ 1 1)
     2
     user> (cons 'a 'b)
     (a . b)

The `user>' string is the prompt that the REPL prints when it is
waiting for an input form. This form may span several lines, e.g.:

     user> (cons 'a
     'b)
     (a . b)

The prompt above contains the string `user'. This is the name of the
module that the form will be evaluated in (*note Modules::).

   As well as allowing arbitrary Lisp forms to be entered and evaluated,
the REPL provides a rich set of meta-commands, these are used to
configure and inspect the state of the system, as well as providing
convenient shortcuts for common operations.

   A meta-command is differentiated from a normal Lisp form by preceding
it with a comma (`,') character. The name of the command should follow
the comma, with any argument forms after that. Note that unlike normal
Lisp forms, no parentheses are used to mark the command application.

   For example the `whereis' meta-command searches all loaded modules
for those exporting a particular symbol. It might be used as follows:

     user> ,whereis string-match
     string-match is exported by: rep.regexp

The following table lists all currently supported meta-commands:

`access STRUCT ...'
     Add the modules named STRUCT ... to the list of structures whose
     exported definitions may be accessed by the current module (using
     the `structure-ref' special form).

`accessible'
     Print the names of the modules whose contents may be accessed
     using the `structure-ref' form from the current module.

`apropos "REGEXP"'
     Print the definitions in the scope of the current module whose
     names match the regular expression REGEXP.

`bindings'
     Print all bindings in the current module.

`collect'
     Run the garbage collector.

`compile [STRUCT ...]'
     Compile any uncompiled functions in the modules named STRUCT ....
     If no named modules are given, use the current module.

`compile-proc PROCEDURE ...'
     Compile the functions called PROCEDURE ... in the current module.

`describe SYMBOL'
     Look for documentation describing the current meaning of SYMBOL,
     if any is found, print it.

`dis FORM'
     Disassemble the bytecode form or compiled function that is the
     result of evaluating FORM.

`expand FORM'
     Print FORM with any outermost macro calls recursively expanded.

`exports'
     Print the names of the variables exported from the current module.

`help'
     List all REPL commands.

`imports'
     Print the names of the modules imported by the current module.

`in STRUCT [FORM]'
     If FORM is given, temporarily switch to the module called STRUCT,
     evaluate FORM printing the result, then switch back to the
     original module.

     If FORM isn't given, simply switch the current module to be STRUCT.

`interfaces'
     Print all defined module interfaces, and their definitions.

`load STRUCT ...'
     Attempt to load the module called STRUCT.

`load-file "FILENAME" ...'
     Load the file of Lisp forms called FILENAME.

`locate SYMBOL'
     Recursively scan from the current module for the module providing
     the binding of SYMBOL.

`new STRUCT'
     Create a new module called STRUCT, and set it as the current
     module. It will import the `rep.module-system' module, but nothing
     else (i.e. no actual language).

`open STRUCT ...'
     Import the modules called STRUCT ... to the current module.  This
     is analogous to the `open' clause in the configuration form of the
     module's definition.

`profile FORM'
     Evaluate FORM, recording information about the frequency and
     duration of the calls it makes to subroutines (and the calls they
     make, and so on). This information is tabulated and printed after
     the evaluation has finished.

`quit'
     Terminate the Lisp interpreter.

`reload STRUCT ...'
     Reload the modules called STRUCT .... If modules of these names
     had previously been loaded, they will be deallocated when there
     are no remaining references to them.

     Note that importing the interface of one module into another does
     not create object references between the two modules (the
     references are purely symbolic). However, each closure (i.e.
     function) created in a module does contain a reference to the
     module it was created in.

`step FORM'
     Evaluate FORM in single-step mode (using the debugger).

`structures'
     Print the names of all currently defined modules.

`time FORM'
     Evaluate the form FORM, print the result and the time it took to
     perform the evaluation.

`unload STRUCT ...'
     Attempt to unload the modules called STRUCT .... As with
     reloading, unloading a module only removes the link between the
     module name and the module body. Only once no more references
     exist to the module body will it be freed.

`whereis SYMBOL'
     Scan all loaded modules for those that export a binding of SYMBOL,
     and print the results.


File: librep.info,  Node: librep Internals,  Next: Reporting bugs,  Prev: The REPL,  Up: Top

librep Internals
****************

   This chapter will document the internals of `librep', including how
to embed the interpreter into general applications, and how to write
dynamically-loadable C libraries. Unfortunately most of it hasn't been
written. As always, the best reference is the source, Luke!

* Menu:

* Intro To Internals::
* Data Type Representation::
* Garbage Collection Internals::
* Defining Lisp Subrs::
* Useful Functions::
* Shared Libraries::


File: librep.info,  Node: Intro To Internals,  Next: Data Type Representation,  Up: librep Internals

Introduction To librep Internals
================================


File: librep.info,  Node: Data Type Representation,  Next: Garbage Collection Internals,  Prev: Intro To Internals,  Up: librep Internals

Data Type Representation
========================


File: librep.info,  Node: Garbage Collection Internals,  Next: Defining Lisp Subrs,  Prev: Data Type Representation,  Up: librep Internals

Garbage Collection Internals
============================


File: librep.info,  Node: Defining Lisp Subrs,  Next: Useful Functions,  Prev: Garbage Collection Internals,  Up: librep Internals

Defining Lisp Subrs
===================


File: librep.info,  Node: Useful Functions,  Next: Shared Libraries,  Prev: Defining Lisp Subrs,  Up: librep Internals

Useful Functions
================


File: librep.info,  Node: Shared Libraries,  Prev: Useful Functions,  Up: librep Internals

Shared Libraries
================


File: librep.info,  Node: Reporting bugs,  Next: News,  Prev: librep Internals,  Up: Top

Reporting bugs
**************

   If the `librep' interpreter crashes it's probably a bug (unless
you're using the `rep-gtk' binding, in which case creating invalid GTK
widget hierarchies can easily crash the Lisp system). If the
interpreter hangs such that sending it interrupt signals doesn't fix
the problem, that's probably also a bug.

   To help me fix any bugs found please try to collect as much
meaningful information as possible. This will hopefully include stack
backtraces (of both the C and Lisp stacks if possible), what features
are loaded, what you did immediately before triggering the bug, a
description of your the system, etc...

   Please send any bug reports to the mailing list:
<librep-list@lists.sourceforge.net>. Alternatively, the author may be
contacted at: <jsh@users.sourceforge.net>.

