ALPHABET-INTRO(2)                               ALPHABET-INTRO(2)

     NAME
          Alphabet - experimental typed shell

     DESCRIPTION
        Values, type characters and signatures
          Each Alphabet typeset defines one Limbo data type,
          conventionally named Value.  It is usually a discriminated
          union (pick), with each arm of the pick representing one of
          the types in the typeset.  Each one of these types is given
          a character. These characters are used to describe all
          value- and module-types within alphabet.  The set of typeset
          characters implemented by a typeset is known as its
          alphabet.

          For example, in the alphabet root typeset (see alphabet-
          main(2)), a string is represented by the letter ``s'', held
          at the Limbo level as a ref Value.S.

          Each alphabet module has a type signature which describes
          its return type and the number and type of any flags or
          arguments that it allows.  Inside an alphabet typeset, this
          signature is represented as a simple string where the first
          character (always present) indicates the return type of the
          module. Subsequent characters up until the first minus (``-
          '') sign (or the end of the string) indicate the module's
          required argument types.  If the last character is an aster-
          isk (*), it allows an unlimited repetition of the preceding
          argument type.

          These may be followed by any number of options, each indi-
          cated with a minus character, followed by the option charac-
          ter and then the type characters of any arguments it
          requires.

          For instance, the following Alphabet declaration:
               /mount [-abc] [-x /string] /wfd /string -> /status
          can be represented by the signature ``rws-a-b-xs-c''.

        Typesets and proxies
          The root typeset (see alphabet-main(2)) is implemented
          internally to the alphabet module. All other types are
          defined by external typesets.

          An external alphabet typeset is conventionally represented
          by two header files defining the interface to the typeset,
          and two modules giving its implementation. Suppose we are to
          create a new typeset, say /foo . We would create the follow-
          ing files:

          /module/alphabet/foo.m

     Page 1                       Plan 9            (printed 12/22/24)

     ALPHABET-INTRO(2)                               ALPHABET-INTRO(2)

                    Foo.m declares the interface used by all modules
                    within the typeset.  The existing typeset inter-
                    face files (for instance alphabet/grid.m, docu-
                    mented in alphabet-grid(2)) provide examples of
                    this kind of interface.

          /appl/alphabet/footypes.b
                    This module translates between internal values
                    (each held as a Value as declared in foo.m) and
                    external values (each held as a Value as declared
                    in the parent typeset, in this case by the
                    alphabet module itself).  Since Limbo does not
                    provide a way of holding an arbitrary type
                    directly, internal values are instead stored in a
                    table by a local proxy (see below), and referred
                    to externally by their index there.

          /appl/alphabet/foo.b
                    Foo.b provides the basic type-manipulation primi-
                    tives needed by the typeset, for instance the
                    translation from type character to type name.  It
                    is also a convenient place to implement helper
                    functions to make using the typeset easier.  For
                    instance, it is conventional for a typeset's Value
                    adt to contain one eponymously named member func-
                    tion for each type character, making sure that the
                    Value is actually of that type and returning the
                    widened type, or raising an exception otherwise.
                    For instance, in the root typeset, v.s() returns
                    the type ref Value.S, or raises an error if v is
                    not of that type.

          /module/alphabet/footypes.m
                    Footypes.m provides an interface to the typeset
                    proxy module, footypes.b, that allows direct
                    access to values in the foo typeset, while still
                    allowing manipulation of those values by an
                    alphabet instance.

          The proxy module, footypes.b, must define at least one func-
          tion, proxy, which returns a channel through which all oper-
          ations on the typeset take place.  The Proxy module (see
          alphabet-proxy(2)) provides a generic implementation of such
          a translator; if footypes.b uses this, it needs only define
          the mapping between values in its parent typeset and its own
          values.

        alphabet-main(2)
          types()   Types is always the first function in a module to
                    be called.  It should do nothing but return the
                    type signature string of the module.

     Page 2                       Plan 9            (printed 12/22/24)

     ALPHABET-INTRO(2)                               ALPHABET-INTRO(2)

          init()    Init is called to allow the module to initialise
                    its global state. It is called once only.  It is
                    permissible for this function to raise a ``fail:''
                    exception on failure. The text following the
                    ``fail:'' prefix should describe the reason why.

          run(errorc, r, opts, args)
                    Run runs an actual instance of the module. It must
                    be re-entrant.  The signature of the run function
                    varies from typeset to typeset, but usually
                    includes the above arguments.  Args holds a list
                    of the arguments passed to the module; opts holds
                    all the flags that have been specified.  Each flag
                    is represented with a tuple, say: (c, optargs),
                    where c gives the option character, and optargs is
                    a list holding any arguments the flag requires.
                    The arguments and options passed to the module are
                    guaranteed to conform with the type signature
                    returned from types.  Note that each flag may be
                    passed multiple times to the module.

                    If the run succeeds, it should return the result-
                    ing value. If the module returns a value that was
                    passed in, and it contains a reference-count, the
                    count should be incremented before returning, If
                    the module succeeds, it is responsible for the
                    disposal of any arguments and option arguments
                    that it has been given.  Appropriate disposal
                    depends on the type of the argument, but v.free(0)
                    is always sufficient to dispose of value v.

                    If the run fails, it should return nil; its argu-
                    ments will automatically be freed in this case.

                    While processing the run request, the module
                    should send error and debugging diagnostics to the
                    errorc channel (it should take care never to send
                    an empty string).  If it spawns any new processes,
                    it can use the Report, r, (see alphabet-
                    reports(2)) to create new diagnostic channels for
                    these processes.  When such an diagnostic channel
                    is no longer in use, the module should send an
                    empty string on it.  It should take care that
                    Report.start is called before run returns.

     Page 3                       Plan 9            (printed 12/22/24)