#
# Required version of omake
#
OMakeVersion(0.9.6, 0.9.6)

########################################################################
# Copyright (C) 2003-2005 Jason Hickey and Mojave Group
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this file, to deal in the File without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the File, and to permit persons to whom the File
# is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the File.
#
# THE FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# FILE OR THE USE OR OTHER DEALINGS IN THE FILE.

########################################################################
# This file defines the Pervasives module--the standard module
# open to every program.  This is a bootstrap file.  The syntax
# here is mainly normal, but it is assumed that the basic classes
# are empty at this point.  You never need to assume this again.
#
class Pervasives

########################################################################
# Common utilities
#

shell-success(argv) =
   return $(equal $(shell-code $(argv)), 0)

last(array) =
   return $(nth $(sub $(length $(array)), 1), $(array))

########################################################################
# \begin{doc}
#
# \section{Pervasives}
#
# \verb+Pervasives+ defines the objects that are defined in all
# programs.  The following objects are defined.
#
# \subsection{Object}
#
# Parent objects: none.
#
# The \verb+Object+ object is the root object.
# Every class is a subclass of \verb+Object+.
#
# It provides the following fields:
#
# \begin{itemize}
# \item \verb+$(o.object-length)+: the number of fields and methods in the object.
# \item \verb+$(o.object-mem <var>)+: returns \verb+true+ iff the \verb+<var>+ is a field
#    or method of the object.
# \item \verb+$(o.object-add <var>, <value>)+: adds the field to the object,
#    returning a new object.
# \item \verb+$(o.object-find <var>)+: fetches the field or method from the object;
#    it is equivalent to \verb+$(o.<var>)+, but the variable can be non-constant.
# \item \verb+$(o.object-map <fun>)+: maps a function over the object.  The function
#    should take two arguments; the first is a field name, the second is the
#    value of that field.  The result is a new object constructed from the
#    values returned by the function.
# \item \verb+o.object-foreach+: the \verb+foreach+ form is equivalent to \verb+map+,
#    but with altered syntax.
#
#    \begin{verbatim}
#    o.foreach(<var1>, <var2>)
#       <body>
#    \end{verbatim}
#
#    For example, the following function prints all the fields of an
#    object \verb+o+.
#
#    \begin{verbatim}
#    PrintObject(o) =
#       o.foreach(v, x)
#          println($(v) = $(x))
#    \end{verbatim}
#
#    The \verb+export+ form is valid in a \verb+foreach+ body.  The following
#    function collects just the field names of an object.
#
#    \begin{verbatim}
#    FieldNames(o) =
#       names =
#       o.foreach(v, x)
#          names += $(v)
#          export
#       return $(names)
#    \end{verbatim}
# \end{itemize}
#
# \end{doc}
#
Object. +=
   class Object

   object-length() =
      return $(obj-length $(this))

   object-mem(v) =
      return $(obj-mem $(this), $(v))

   object-add(v, x) =
      return $(obj-add $(this), $(v), $(x))

   object-find(v) =
      return $(obj-find $(this), $(v))

   object-map(f) =
      return $(obj-map $(this), $(f))

   object-foreach(body, v, x) =
      return $(obj-map $(this), $(v), $(x), $(body))

#
# The runtime doesn't know to include the Object module, so do it now.
#
extends $(Object)

#
# \begin{doc}
# \subsection{Map}
#
# Parent objects: \verb+Object+.
#
# A \verb+Map+ object is a dictionary from values to values.  The \verb+<key>+
# values are restricted to simple values: integers, floating-point numbers,
# strings, files, directories, and arrays of simple values.
#
# The Map object provides the following methods.
#
# \begin{itemize}
# \item \verb+$(o.mem <key>)+: returns \verb+true+ iff the \verb+<key>+ is defined
#    in the map.
# \item \verb+$(o.add <key>, <value>)+: adds the field to the map,
#    returning a new map.
# \item \verb+$(o.find <key>)+: fetches the field from the map.
# \item \verb+$(o.map <fun>)+: maps a function over the map.  The function
#    should take two arguments; the first is a field name, the second is the
#    value of that field.  The result is a new object constructed from the
#    values returned by the function.
# \item \verb+o.foreach+: the \verb+foreach+ form is equivalent to \verb+map+,
#    but with altered syntax.
#
#    \begin{verbatim}
#    o.foreach(<var1>, <var2>)
#       <body>
#    \end{verbatim}
#
#    For example, the following function prints all the fields of an
#    object \verb+o+.
#
#    \begin{verbatim}
#    PrintObject(o) =
#       o.foreach(v, x)
#          println($(v) = $(x))
#    \end{verbatim}
#
#    The \verb+export+ form is valid in a \verb+foreach+ body.  The following
#    function collects just the field names of the map.
#
#    \begin{verbatim}
#    FieldNames(o) =
#       names =
#       o.foreach(v, x)
#          names += $(v)
#          export
#       return $(names)
#    \end{verbatim}
# \end{itemize}
#
# There is also simpler syntax when the key is a string.  The table can be
# defined using definitions with the form \verb+$|key|+
# (the number of pipe symbols \verb+|+ is allowed to vary).
#
# \begin{verbatim}
#     $|key 1| = value1
#     $||key1|key2|| = value2    # The key is key1|key2
#     X = $|key 1|               # Define X to be the value of field $|key 1|
# \end{verbatim}
#
# The usual modifiers are also allowed.  The expression \verb+$`|key|+ represents
# lazy evaluation of the key, and \verb+$,|key|+ is normal evaluation.
#
# \end{doc}
#
Map. +=
    class Map
    extends $(Object)

    mem(v) =
        return $(map-mem $(this), $(v))

    add(v, x) =
        return $(map-add $(this), $(v), $(x))

    find(v) =
        return $(map-find $(this), $(v))

    map(f) =
        return $(map-map $(this), $(f))

    foreach(body, v, x) =
        return $(map-map $(this), $(v), $(x), $(body))

########################################################################
# \begin{doc}
# \subsection{Number}
#
# Parent objects: \verb+Object+.
#
# The \verb+Number+ object is the parent object for integers
# and floating-point numbers.
# \end{doc}
#
Number. +=
   class Number
   extends $(Object)

#
# \begin{doc}
# \subsection{Int}
#
# Parent objects: \verb+Number+.
#
# The \verb+Int+ object represents integer values.
# \end{doc}
#
Int. +=
   class Int
   extends $(Number)

#
# \begin{doc}
# \subsection{Float}
#
# Parent objects: \verb+Number+.
#
# The \verb+Float+ object represents floating-point numbers.
# \end{doc}
#
Float. +=
   class Float
   extends $(Number)

########################################################################
# \begin{doc}
# \subsection{Sequence}
#
# Parent objects: \verb+Object+.
#
# The \verb+Sequence+ object represents a generic object containing
# sequential elements.  It provides the following methods.
#
# \begin{itemize}
# \item \verb+$(s.length)+: the number of elements in the sequence.
# \item \verb+$(s.map <fun>)+: maps a function over the fields in the sequence.
#    The function
#    should take two arguments; the first is a field name, the second is the
#    value of that field.  The result is a new sequence constructed from the
#    values returned by the function.
# \item \verb+s.foreach+: the \verb+foreach+ form is equivalent to \verb+map+,
#    but with altered syntax.
#
#    \begin{verbatim}
#    s.foreach(<var>)
#       <body>
#    \end{verbatim}
#
#    For example, the following function prints all the elements of the sequence.
#
#    \begin{verbatim}
#    PrintSequence(s) =
#       s.foreach(x)
#          println(Elem = $(x))
#    \end{verbatim}
#
#    The \verb+export+ form is valid in a \verb+foreach+ body.  The following
#    function counts the number of zeros in the sequence.
#
#    \begin{verbatim}
#    Zeros(s) =
#       count = $(int 0)
#       s.foreach(v)
#          if $(equal $(v), 0)
#             count = $(add $(count), 1)
#             export
#          export
#       return $(count)
#    \end{verbatim}
# \end{itemize}
# \end{doc}
#
Sequence. +=
   class Sequence
   extends $(Object)

   length() =
      return $(sequence-length $(this))

   nth(i) =
      return $(sequence-nth $(this), $(i))

   rev() =
      return $(sequence-rev $(this))

   map(f) =
      return $(sequence-map $(f), $(this))

   foreach(body, v) =
      return $(sequence-map $(body), $(v), $(this))

#
# \begin{doc}
# \subsection{Array}
#
# Parent objects: \verb+Sequence+.
#
# The \verb+Array+ is a random-access sequence.
# It provides the following additional methods.
#
# \begin{itemize}
# \item \verb+$(s.nth <i>)+: returns element \verb+i+ of the sequence.
# \item \verb+$(s.rev <i>)+: returns the reversed sequence.
# \end{itemize}
#
# \end{doc}
#
Array. +=
   class Array
   extends $(Sequence)

#
# \begin{doc}
# \subsection{String}
#
# Parent objects: \verb+Array+.
# \end{doc}
#
String. +=
    class String
    extends $(Array)

########################################################################
# \begin{doc}
# \subsection{Fun}
#
# Parent objects: \verb+Object+.
#
# The \verb+Fun+ object provides the following methods.
# \begin{itemize}
# \item \verb+$(f.arity)+: the arity if the function.
# \end{itemize}
# \end{doc}
#
Fun. +=
   class Fun
   extends $(Object)

   arity() =
      return $(sequence-length $(this))

########################################################################
# \begin{doc}
# \subsection{Rule}
#
# Parent objects: \verb+Object+.
#
# The \verb+Rule+ object represents a build rule.
# It does not currently have any methods.
# \end{doc}
#
Rule. +=
   class Rule
   extends $(Object)

#
# \begin{doc}
# \subsection{Target}
#
# Parent object: \verb+Object+.
#
# The \verb+Target+ object contains information collected for
# a specific target file.
#
# \begin{itemize}
# \item \verb+target+: the target file.
# \item \verb+effects+: the files that may be modified by a
#    side-effect when this target is built.
# \item \verb+scanner_deps+: static dependencies that must be built
#    before this target can be scanned.
# \item \verb+static-deps+: statically-defined build dependencies
#    of this target.
# \item \verb+build-deps+: all the build dependencies for the target,
#    including static and scanned dependencies.
# \item \verb+build-values+: all the value dependencies associated
#    with the build.
# \item \verb+build-commands+: the commands to build the target.
# \end{itemize}
#
# The object supports the following methods.
#
# \begin{itemize}
# \item \verb+find(file)+: returns a Target object for the given file.
#    Raises a \verb+RuntimeException+ if the specified target is
#    not part of the project.
# \item \verb+find-optional(file)+: returns a \verb+Target+ object
#    for the given file, or \verb+false+ if the file is not
#    part of the project.
# \end{itemize}
#
# NOTE: the information for a target is constructed dynamically,
# so it is possible that the \verb+Target+ object for a node will
# contain different values in different contexts.  The easiest way
# to make sure that the \verb+Target+ information is complete is
# to compute it within a rule body, where the rule depends on
# the target file, or the dependencies of the target file.
# \end{doc}
#
Target. +=
   class Target
   extends $(Object)

   target =
   effects =
   scanner-deps =
   static-deps =
   build-deps =
   build-values =
   build-commands =

   find(file) =
      return $(target $(file))

   find-optional(file) =
      return $(target-optional $(file))

########################################################################
# \begin{doc}
# \subsection{Node}
#
# Parent objects: \verb+Object+.
#
# The \verb+Node+ object is the parent object for files and directories.
# It supports the following operations.
# \begin{itemize}
# \end{doc}
#
Node. +=
    class Node
    extends $(Object)

    #
    # \begin{doc}
    # \item \verb+$(node.stat)+: returns a \verb+stat+ object for the file.  If the
    # file is a symbolic link, the \verb+stat+ information is for the destination of
    # the link, not the link itself.
    #
    #
    # \item \verb+$(node.lstat)+: returns a \verb+stat+ object for the file or symbolic link.
    # \end{doc}
    #
    stat() =
       return $(public.stat $(this))

    lstat() =
       return $(public.lstat $(this))

    #
    # \begin{doc}
    # \item \verb+$(node.unlink)+: removes the file.
    # \item \verb+$(node.rename <file>)+: renames the file.
    # \item \verb+$(node.link <file>)+: creates a hard link \verb+<dst>+ to this file.
    # \item \verb+$(node.symlink <file>)+: create a symbolic link \verb+<dst>+ to this file.
    # \end{doc}
    #
    unlink() =
       return $(public.unlink $(this))

    rename(file) =
       return $(public.rename $(this), $(file))

    link(file) =
       return $(public.link $(this), $(file))

    symlink(file) =
       return $(public.symlink $(this), $(file))

    #
    # \begin{doc}
    # \item \verb+$(node.chmod <perm>)+: change the permission of this file.
    # \item \verb+$(node.chown <uid>, <gid>)+: change the owner and group id of this file.
    # \end{doc}
    #
    chmod(perm) =
       return $(public.chmod $(this), $(perm))

    chown(uid, gid) =
       return $(public.chown $(this), $(uid), $(gid))
#
# \begin{doc}
# \end{itemize}
# \end{doc}
#

#
# \begin{doc}
# \subsection{File}
#
# Parent objects: \verb+Node+.
#
# The file object represents the name of a file.
# \end{doc}
#
File. +=
    class File
    extends $(Node)

#
# \begin{doc}
# \subsection{Dir}
#
# Parent objects: \verb+Node+.
#
# The \verb+Dir+ object represents the name of a directory.
# \end{doc}
#
Dir. +=
    class Dir
    extends $(Node)

########################################################################
# \begin{doc}
# \subsection{Channel}
#
# Parent objects: \verb+Object+.
#
# A \verb+Channel+ is a generic IO channel.
# It provides the following methods.
# \begin{itemize}
# \end{doc}
Channel. +=
    class Channel
    extends $(Object)

    #
    # \begin{doc}
    # \item \verb+$(o.close)+: close the channel.
    # \end{doc}
    #
    close() =
       public.close($(this))
#
# \begin{doc}
# \end{itemize}
# \end{doc}
#

########################################################################
# \begin{doc}
# \subsection{InChannel}
#
# Parent objects: \verb+Channel+.
#
# A \verb+InChannel+ is an input channel.  The variable \verb+stdin+ is the
# standard input channel.
#
# It provides the following methods.
# \begin{itemize}
# \end{doc}
#
InChannel. +=
    class InChannel
    extends $(Channel)

    #
    # \begin{doc}
    # \item \verb+$(InChannel.fopen <file>)+: open a new input channel.
    # \end{doc}
    #
    fopen(file) =
       return $(public.fopen $(file), r)
#
# \begin{doc}
# \end{itemize}
# \end{doc}
#

########################################################################
# \begin{doc}
# \subsection{OutChannel}
#
# Parent object: \verb+Channel+.
#
# A \verb+OutChannel+ is an output channel.  The variables \verb+stdout+
# and \verb+stderr+ are the standard output and error channels.
#
# It provides the following methods.
# \begin{itemize}
# \end{doc}
#
OutChannel. +=
    class OutChannel
    extends $(Channel)

    #
    # \begin{doc}
    # \item \verb+$(OutChannel.fopen <file>)+: open a new output channel.
    # \end{doc}
    #
    fopen(file) =
       return $(public.fopen $(file), w)

    #
    # \begin{doc}
    # \item \verb+$(OutChannel.append <file>)+: opens a new output channel,
    # appending to the file.
    # \end{doc}
    #
    append(file) =
       return $(public.fopen $(file), a)

    #
    # \begin{doc}
    # \item \verb+$(c.flush)+: flush the output channel.
    # \end{doc}
    #
    flush() =
        return $(public.flush $(this))

    #
    # \begin{doc}
    # \item \verb+$(c.print <string>)+: print a string to the channel.
    # \end{doc}
    #
    print(s) =
        return $(public.fprint $(this), $(s))

    #
    # \begin{doc}
    # \item \verb+$(c.println <string>)+: print a string to the channel,
    # followed by a line terminator.
    # \end{doc}
    #
    println(s) =
        return $(public.fprintln $(this), $(s))
#
# \begin{doc}
# \end{itemize}
# \end{doc}
#

########################################################################
# \begin{doc}
# \subsection{Location}
#
# Parent objects: \verb+Location+.
#
# The \verb+Location+ object represents a location in a file.
# \end{doc}
#
Location. +=
    class Location
    extends $(Object)

########################################################################
# \begin{doc}
# \subsection{Position}
#
# Parent objects: \verb+Position+.
#
# The \verb+Position+ object represents a stack trace.
# \end{doc}
#
Position. +=
    class Position
    extends $(Object)

########################################################################
# \begin{doc}
# \subsection{Exception}
#
# Parent objects: \verb+Object+.
#
# The \verb+Exception+ object is used as the base object for exceptions.
# It has no fields.
# \end{doc}
#
Exception. +=
    class Exception
    extends $(Object)

#
# \begin{doc}
# \subsection{RuntimeException}
#
# Parent objects: \verb+Exception+.
#
# The \verb+RuntimeException+ object represents an exception from the
# runtime system.  It has the following fields.
#
# \begin{itemize}
# \item \verb+position+: a string representing the location where the
#    exception was raised.
# \item \verb+message+: a string containing the exception message.
# \end{itemize}
# \end{doc}
#
RuntimeException. +=
    class RuntimeException
    extends $(Exception)

    position = no position
    message = no message

########################################################################
# System objects.
#
Select. +=
   class Select
   extends $(Object)

Pipe. +=
   class Pipe
   extends $(Object)

Stat. +=
   class Stat
   extends $(Object)

########################################################################
# The shell object.
#
# \begin{doc}
# \subsection{Shell}
#
# Parent objects: \verb+Object+.
#
# The \verb+Shell+ object contains the collection of builtin functions
# available as shell commands.
#
# You can define aliases by extending this object with additional methods.
# All methods in this class are called with one argument: a single array
# containing an argument list.
#
# \begin{itemize}
# \end{doc}
#
Shell. +=
   class Shell
   extends $(Object)

   #
   # \begin{doc}
   # \item \verb+echo+
   #
   # The \verb+echo+ function prints its arguments to the standard output channel.
   # \end{doc}
   #
   echo = $(echo)

   #
   # \begin{doc}
   # \item \verb+jobs+
   #
   # The \verb+jobs+ method prints the status of currently running commands.
   # \end{doc}
   #
   jobs = $(jobs)

   #
   # \begin{doc}
   # \item \verb+cd+
   #
   # The \verb+cd+ function changes the current directory.
   # Note that the current directory follows the usual scoping
   # rules.  For example, the following program lists the
   # files in the \verb+foo+ directory, but the current
   # directory is not changed.
   #
   # \begin{verbatim}
   #    section
   #       echo Listing files in the foo directory...
   #       cd foo
   #       ls
   #
   #    echo Listing files in the current directory...
   #    ls
   # \end{verbatim}
   # \end{doc}
   #
   cd = $(cd)

   #
   # \begin{doc}
   # \item \verb+bg+
   #
   # The \verb+bg+ method places a job in the background.
   # The job is resumed if it has been suspended.
   # \end{doc}
   #
   bg = $(bg)

   #
   # \begin{doc}
   # \item \verb+fg+
   #
   # The \verb+fg+ method brings a job to the foreground.
   # The job is resumed if it has been suspended.
   # \end{doc}
   #
   fg = $(fg)

   #
   # \begin{doc}
   # \item \verb+stop+
   #
   # The \verb+stop+ method suspends a running job.
   # \end{doc}
   #
   stop = $(stop)

   #
   # \begin{doc}
   # \item \verb+wait+
   #
   # The \verb+wait+ function waits for a running job to terminate.
   # It is not possible to wait for a suspended job.
   #
   # The job is not brought to the foreground.  If the \verb+wait+
   # is interrupted, the job continues to run in the background.
   # \end{doc}
   #
   wait = $(wait)

   #
   # \begin{doc}
   # \item \verb+kill+
   #
   # The \verb+kill+ function signal a job.
   #
   # \verb+kill [signal] <pid...>+.
   #
   # The signals are either numeric, or symbolic.
   # The symbolic signals are named as follows.
   #
   # ABRT, ALRM, HUP, ILL, KILL, QUIT, SEGV, TERM, USR1,
   # USR2, CHLD, STOP, TSTP, TTIN, TTOU, VTALRM, PROF.
   # \end{doc}
   #
   kill = $(kill)

   #
   # \begin{doc}
   # \item \verb+exit+
   #
   # The \verb+exit+ function terminates the current session.
   # \end{doc}
   #
   exit = $(exit)

   #
   # \begin{doc}
   # \item \verb+which+, \verb+where+
   #
   # See the documentation for the corresponding functions.
   # \end{doc}
   which(argv) =
      println($(which $(argv)))

   where(argv) =
      res = $(where $(argv))
      res.map($(println))
      return $(int 0)

   #
   # \begin{doc}
   # \item \verb+rehash+
   #
   # Reset the search path.
   # \end{doc}
   #
   rehash(argv) =
      rehash()

   #
   # \begin{doc}
   # \item \verb+history+
   #
   # Print the current command-line history.
   # \end{doc}
   #
   history(argv) =
      lines = $(public.history)
      lines.map($(println))
      return $(int 0)

   #
   # \begin{doc}
   # \item Win32 functions.
   #
   #     Win32 doesn't provide very many programs for scripting, except
   #     for the functions that are builtin to the DOS \verb+cmd.exe+.
   #     The following functions are defined on Win32 and only on Win32.
   #     On other systems, it is expected that these programs already
   #     exist.
   #
   # \begin{itemize}
   # \end{doc}
   #
   if $(equal $(OSTYPE), Win32)
       #
       # \begin{doc}
       # \item \verb+grep+
       #
       # \begin{verbatim}
       #    grep [-q] [-n] pattern files...
       # \end{verbatim}
       #
       # The \verb+grep+ function calls the \Prog{omake}
       # \verb+grep+ function.
       # \end{doc}
       #
       grep = $(builtin-grep)

       export
   #
   # \begin{doc}
   # \end{itemize}
   # \end{doc}
   #

   #
   # \begin{doc}
   # By default, \Prog{omake} uses internal versions of the following commands:
   # \verb+cp+, \verb+rm+, \verb+mkdir+, \verb+chmod+, \verb+test+, \verb+find+.
   # If you really want to use the standard system versions of these
   # commands, set the \verb+USE_SYSTEM_COMMANDS+ as one of the first
   # definitions in your \verb+OMakeroot+ file.
   #
   # \begin{itemize}
   # \end{doc}
   #
   if $(not $(defined USE_SYSTEM_COMMANDS))
       #
       # \begin{doc}
       # \item \verb+mkdir+
       #
       # \begin{verbatim}
       #     mkdir [-m <mode>] [-p] files
       # \end{verbatim}
       #
       # The \verb+mkdir+ function is used to create directories.
       # The -verb+-m+ option can be used to specify the permission
       # mode of the created directory.  If the \verb+-p+ option
       # is specified, the full path is created.
       # \end{doc}
       #
       mkdir = $(mkdir)

       #
       # \begin{doc}
       # \item \verb+cp+
       # \item \verb+mv+
       #
       # \begin{verbatim}
       #     cp [-f] [-i] [-v] src dst
       #     cp [-f] [-i] [-v] files dst
       #     mv [-f] [-i] [-v] src dst
       #     mv [-f] [-i] [-v] files dst
       # \end{verbatim}
       #
       # The \verb+cp+ function copies a \verb+src+ file to
       # a \verb+dst+ file, overwriting it if it already exists.
       # If more than one source file is specified, the final file
       # must be a directory, and the source files are copied
       # into the directory.
       #
       # \begin{itemize}
       # \item[-f] Copy files forcibly, do not prompt.
       # \item[-i] Prompt before removing destination files.
       # \item[-v] Explain what is happening.
       # \end{itemize}
       # \end{doc}
       #
       cp = $(cp)
       mv = $(mv)

       #
       # \begin{doc}
       # \item \verb+rm+
       #
       # \begin{verbatim}
       #    rm [-f] [-i] [-v] [-r] files
       #    rmdir [-f] [-i] [-v] [-r] dirs
       # \end{verbatim}
       #
       # The \verb+rm+ function removes a set of files.
       # No warnings are issued if the files do not exist, or if
       # they cannot be removed.
       #
       # Options:
       # \begin{itemize}
       # \item[-f] Forcibly remove files, do not prompt.
       # \item[-i] Prompt before removal.
       # \item[-v] Explain what is happening.
       # \item[-r] Remove contents of directories recursively.
       # \end{itemize}
       # \end{doc}
       #
       rm = $(rm)
       rmdir = $(rmdir)

       #
       # \begin{doc}
       # \item \verb+chmod+
       #
       # \begin{verbatim}
       #     chmod [-r] [-v] [-f] mode files
       # \end{verbatim}
       #
       # The \verb+chmod+ function changes the permissions on a set of
       # files or directories.  This function does nothing on Win32.
       # The \verb+mode+ may be specified as an octal number,
       # or in symbolic form \verb+[ugoa]*[+-=][rwxXstugo]+.
       # See the man page for \verb+chmod+ for details.
       #
       # Options:
       # \begin{itemize}
       # \item[-r] Change permissions of all files in a directory recursively.
       # \item[-v] Explain what is happening.
       # \item[-f] Continue on errors.
       # \end{itemize}
       # \end{doc}
       #
       chmod = $(chmod)

       #
       # \begin{doc}
       # \item \verb+test+
       #
       # \begin{verbatim}
       #    test \emph{expression}
       #    \verb+[+ \emph{expression} +]+
       #    \verb+[ --help+
       #    \verb+[ --version+
       # \end{verbatim}
       #
       # See the documentation for the \verb+test+ function.
       #
       # \end{doc}
       #
       test = $(builtin-test)
       [ = $(builtin-test-brack)

       #
       # \begin{doc}
       # \item \verb+find+
       #
       # \begin{verbatim}
       #    find \emph{expression}
       # \end{verbatim}
       #
       # See the documentation for the \verb+find+ function.
       #
       # \end{doc}
       #
       find = $(builtin-find)

       export
   #
   # \begin{doc}
   # \end{itemize}
   # \end{doc}
   #

#
# \begin{doc}
# \end{itemize}
# \end{doc}
#

#
# These are all documented in Omake_builtin_io_fun.
#
Token. =
   class Token

   loc =
   name =
   value =

   unit(loc, name) =
      this.loc = $(loc)
      this.name = $(name)
      return $(this)

   pair(loc, name, value) =
      this.loc = $(loc)
      this.name = $(name)
      this.value = $(value)
      return $(this)

Lexer. +=
   class Lexer
   extends $(Object)

   #
   # For interpreting the rules
   #
   rule = $(lex-rule)

   #
   # To use a lexer, you would normally hand it a channel
   #
   from-channel(channel) =
      this.channel = $(channel)
      return $(this)

   lex() =
      return $(lex-engine $(this.channel))

   lex-channel(channel) =
      return $(lex-engine $(channel))

Parser. +=
   class Parser
   extends $(Object)

   #
   # For interpreting the rules
   #
   rule         = $(parse-rule)

   #
   # You must set the lexer
   #
   lexer =

   #
   # Start symbols
   #
   start        = $(parse-start)

   #
   # Precedence operations
   #
   left         = $(parse-left)
   right        = $(parse-right)
   nonassoc     = $(parse-nonassoc)

   #
   # Manipulating the current precedence level
   #
   prec-min     = .min
   prec-max     = .max
   current-prec = .min

   #
   # Build the parser
   #
   build        = $(parse-build)

   #
   # Main parsing function
   #
   parse(sym) =
      return $(parse-engine $(sym))

   parse-channel(sym, channel) =
      lexer = $(lexer.from-channel $(channel))
      return $(parse-engine $(sym))

   parse-file(sym, file) =
      channel = $(fopen $(file), r)
      lexer = $(lexer.from-channel $(channel))
      result = $(parse-engine $(sym))
      close($(channel))
      return $(result)

