Provided by: nickle_2.92_amd64 bug

NAME

       nickle - a desk calculator language

SYNOPSIS

       nickle [--help|--usage] [-f file] [-l library] [-e expr] [ script ] [--] [arg ...]

DESCRIPTION

       Nickle is a desk calculator language with powerful programming and scripting capabilities.
       Nickle  supports  a  variety  of  datatypes,  especially  arbitrary  precision   integers,
       rationals, and imprecise reals.  The input language vaguely resembles C.  Some things in C
       which do  not  translate  easily  are  different,  some  design  choices  have  been  made
       differently, and a very few features are simply missing.

USAGE

       An  un-flagged  argument  is treated as a Nickle script, and replaces standard input.  Any
       remaining arguments following the script are placed in the Nickle string  array  argv  for
       programmatic  inspection.   When  invoked without an expression or script argument, Nickle
       reads from standard input, and writes to standard output.

       Options are as follows:

       --help,--usage
              Print a help/usage message and exit.   This  is  a  built-in  feature  of  Nickle's
              ParseArgs  module,  and  thus  will  also  be  true of Nickle scripts that use this
              library.

       -f,--file file
              Load file into Nickle before beginning execution.

       -l,--library library
              Load library into Nickle before beginning execution.  See below for  a  description
              of the library facility.

       -e,--expr expr
              Evaluate expr before beginning execution.

       --     Quit parsing arguments and pass the remainder, unevaluated, to argv.

SYNTAX

       To  make the input language more useful in an interactive setting, newline only terminates
       statements at ``reasonable'' times.   Newline  terminates  either  expressions  or  single
       statements  typed  by  the  user  (with  the  exception  of a few statements which require
       lookahead: notably if() and twixt(), which have an optional else  part).  Inside  compound
       statements  or  function  definitions,  only  a ; terminates statements.  This approach is
       convenient and does not appear to cause problems in normal use.

       The syntax of Nickle programs is as  follows.   In  this  description,  name  denotes  any
       sequence  of  letters,  digits  and  _ characters not starting with a digit; E denotes any
       expression; S denotes any statement; and T denotes any type.  The syntax X,X,...,X denotes
       one or more comma-separated Xs, unless otherwise indicated.

       Comments:

       C-style  comments  are  enclosed  in  /* and */, and shell-style comments are denoted by a
       leading # at the start of a line.

       Operands:

       real number
              Can include exponent, need not include decimal point or sign.  Will be  treated  as
              exact  rationals.   If a trailing decimal part contains an opening curly brace, the
              brace is silently ignored; if it contains a curly-bracketed trailing portion, it is
              treated  as  a  repeating  decimal.   `Floating  point''  constants  are  currently
              represented internally as rationals: for floating constants with a given  precision
              (and   an  infinite-precision  exponent),  use  the  imprecise()  builtin  function
              described below.

       octal number
              Start with a 0 (e.g., 014 is the same as 12).

       hexidecimal number
              Start with "0x" (e.g., 0x1a is the same as 26).

       string As in C.  String constants are surrounded by double-quotes.  Backslashed characters
              (including  double-quotes)  stand  for  themselves, except "\n" stands for newline,
              "\r" for carriage return, "\b" for backspace, "\t" for tab and "\f" for formfeed.

       name   A variable reference.

       name() name(E,E,...,E)
              A function call with zero or more arguments.  Functions  are  fully  call-by-value:
              arrays and structures are copied rather than being referenced as in C.

       desc name  T name = value
              Definition  expressions:  a  new  name  is  made  available,  with the value of the
              definition being the value of the initializer in the second form, and uninitialized
              in  the  first  form.   The  descriptor  desc  is  not optional: it consists of any
              combination of visibility, storage class or type (in that order).   See  QUALIFIERS
              immediately  below  for  a  description  of  these  qualifiers.  A structured value
              expression is also possible: see VALUES below.

              In addition to being able to initialize a definition with a Nickle  value,  C-style
              array,  structure,  and  union  definitions  are  also  allowed:  For  example, the
              following
                int[*,*] name = {{0,1},{2,3}}
                int[2,2] name = {{0...}...}
              are permitted with the obvious  semantics.   This  is  the  context  in  which  the
              dimensions  in  a type may be expressions: see the discussion of array types above.
              See  the  discussion  of  array  and  structure  values  for  array  and  structure
              initializer syntax.

QUALIFIERS

       A declaration or definition may be qualified, as in C, to indicate details of programmatic
       behavior.  Unlike in C, these qualifiers, while optional, must appear in the given order.

       Visibility:

       public Any  definition  expression  (function  definition,   variable   definition,   type
              definition)  can  be  qualified with public to indicate that the name being defined
              should be visible outside  the  current  namespace,  and  should  be  automatically
              imported.  See Namespaces below for further info.

       protected
              Any   definition   expression   (function  definition,  variable  definition,  type
              definition) can be qualified with protected to indicate that the name being defined
              should  be  visible outside the current namespace, but should not be made available
              by import declarations.  See Namespaces below for further info.

       Lifetime:

       auto   An auto object is local to a  particular  block:  its  lifetime  is  at  least  the
              lifetime  of that block.  An auto object with an initializer will be re-initialized
              each time it is evaluated.  This is the default lifetime for local objects.

       static A static object is local to a particular function definition: its  lifetime  is  at
              least  the  lifetime  of that definition.  A new static object will be created each
              time its enclosing function definition is evaluated.

              In Nickle, the keyword static has to do only with lifetime (like the use of  static
              inside  C  functions), not with visibility (which is handled by separate qualifiers
              as described above, not like the use of static in global scope in C).

       global A global object is global to the entire program: its lifetime is  the  lifetime  of
              the  program.   A global object will be created and initialized when its definition
              is first seen.  This is the default lifetime for global objects.

              The distinction between static and global lifetime in Nickle is not possible in  C,
              because  C  functions are not first class objects with nested scope.  When deciding
              which to use in a Nickle program, think about what should happen if a definition is
              re-evaluated.

OPERATORS

       Here are the basic Nickle operators, grouped in order of decreasing precedence:

       A[E,E,...,E]
              Refers  to  the  E'th  element  of  the  array expression A, or the E1'th/E2'th/etc
              element  of  a  multi-dimensional  array.   Both  arrays  of  arrays  ala   C   and
              multidimensional arrays ala NAWK are possible.

       struct.tag
              Structure dereference.

       struct->tag
              Structure pointer dereference ala C.

       =============

       ++ --  Unary increment/decrement. May be either postfix or prefix.

       -      Unary negate

       ! E    Logical negation.

       E !    Factorial.  Requires a non-negative integer argument.

       * E    Pointer dereference.

       & E    Reference construction.

       =============

       (U) E  Construct a value of union type with tag U and value E.

       =============

       **     Exponentiation.  Both  operands  may  be fractional.  The left operand must be non-
              negative unless the right operand is integer.  The result type is the type  of  the
              left operand if the right operand is integer, and real otherwise.

              This  is  the only known type-unsound feature of Nickle: an expression like 2 ** -3
              will statically be of type  integer,  but  dynamically  will  generate  a  rational
              result.  This may cause a runtime type error later on: consider
                int x = 2 ** -3;

       =============

       * / // %
              Times,  divide, integer divide, and remainder.  The right operand of the last three
              operators must be nonzero.  The result type of the division operator will always be
              at  least rational: the result type of the integer division operator will always be
              int.  This is a notable departure from C, where  integer  division  is  implied  by
              integer operands.  Integer division is defined by
                x // y == y > 0 ? floor (x / y) : ceil(x / y)
              The remainder is always non-negative and is defined by: by
                x % y = x - (x // y) * y

       =============

       + -    Addition and subtraction.

       =============

       << >>  Bitwise  left  and right shift with integer operands.  Negative right operands work
              as expected.  These operators are defined by
                x << y = x * 2 ** y
                x >> y = x // 2 ** y
              Another way to look at this is that negative left operands are considered to be  in
              an  infinite twos-complement representation (i.e., sign-extended to infinity), with
              right shift sign-extending its left operand.

       =============

       <= >= < >
              Relational operators.

       =============

       == !=  Equality operators.

       =============
              Finally, in order of decreasing precedence:

       &      Bitwise AND.  Negative operands are considered to be in an infinite twos-complement
              representation (i.e., sign-extended to infinity).

       ^      Bitwise XOR.  Negative operands as in bitwise AND.

       |      Bitwise OR.  Negative operands as in bitwise AND.

       &&     Short-circuit logical AND.

       ||     Short-circuit logical OR.

       E ? E : E
              Conditional  expression:  if  first  expression  is  logical  true, value is second
              expression, else third.

       fork E Create (and return) a thread.  See Thread below for details.

       = += -= *= /= //= %= **= <<= >>= ^= &= |=
              Assignment operators.  Left-hand-side must be assignable.  x <op>= y is  equivalent
              to x = x <op> y

       E , E  Returns right-hand expression.

TYPES

       The  type declaration syntax of Nickle more strongly resembles the ``left'' variant of the
       Java syntax than the C syntax.  Essentially, a type consists of:

       poly integer rational real string continuation void
              A base type of the  language.   Type  void  is  actually  only  usable  in  certain
              contexts, notably function returns.  It is currently implemented as a ``unit'' type
              ala ML, and thus has slightly different behavior than  in  C.   Type  poly  is  the
              supertype  of  all  other  types  (i.e.,  it  can  be  used  to inhibit static type
              checking), and is the default type in most situations where a type need not appear.

       file semaphore thread
              Also builtin base types, but integral to the File and Thread ADTs: see below.

       More About Types:

       Nickle supports polymorphic data: As an expression is evaluated, a data type is chosen  to
       fit  the  result.   Any  Nickle  object  may  be  statically  typed,  in which case bounds
       violations will be flagged as errors at compile time.  Polymorphic variables and functions
       do  not  place  restrictions  on  the assigned data type; this is the default type for all
       objects.

       poly   This describes the union of all datatypes.  A variable with this type  can  contain
              any data value.

       int    Arbitrary precision integers.

       rational
              Arbitrary precision rational numbers.

       real   Arbitrary  exponent  precision floating point numbers.  As many computations cannot
              be  carried  out  exactly  as  rational  numbers,  Nickle  implements   non-precise
              arithmetic  using  its  own  machine-independent  representation for floating point
              numbers.  The builtin function imprecise(n) generates a real number with  256  bits
              of precision from the number n, while imprecise(n,p) generates a real number with p
              bits of precision.

       T[]    An array of type T, of one or  more  dimensions.   There  are  no  zero-dimensional
              arrays in Nickle.

       T[*]   A one-dimensional array of type T.  Unlike in C, the dimension of an array is never
              part of its type in Nickle.  Further, arrays and pointers are  unrelated  types  in
              Nickle.

       T[*,*,...,*]
              A  two  or more dimensional array of type T.  The stars ``*'' are not optional.  As
              the previous paragraphs make clear, ``T[]'' is not a zero-dimensional array.

       T[E,E,...,E]
              In definition contexts, integer values may be given for each dimension of an  array
              context.   These  are strictly for value-creation purposes, and are not part of the
              type.  An array type is determined only by the base type and number  of  dimensions
              of the array.

       T0() T0(T,T,...,T)
              A function returning type T0.  A function accepts 0 or more arguments.

       T0() T0(T,T,...,T ...)
              A  function  accepting zero or more required arguments, plus an arbitrary number of
              optional arguments.  The second sequence of three dots (ellipsis)  is  syntax,  not
              metasyntax: see the description of varargs functions for details.

       *T     A pointer to a location of type T.  Pointer arithmetic in Nickle operates only upon
              pointers to arrays: the pointer must be of the correct type, and  may  never  stray
              out  of bounds.  A pointer may either point to some location or be null (0).  As in
              C, the precedence of ``*'' is lower than the precedence of ``[]''  or  ``()'':  use
              parenthesis as needed.

       struct {T name; T name; ...}
              A  structure  with fields of the given name and type.  The types T are optional: in
              their absence, the type of the field is poly.

       union {T name; T name; ...}
              A ``disjoint union'' of the given types.  This is more like the variant record type
              of  Pascal  or  the datatype of ML than the C union type: the names are tags of the
              given type, exactly one of which applies to a given value at a given time.

       (T)    Parentheses for grouping.

       Typedef:

       As in C, new type names may be created with the typedef statement.  The syntax is
         typedef T typename;
       where T is a Nickle type.  The resulting typename may be used anywhere a type is expected.

VALUES

       Values of the base types of Nickle are as expected.  See the syntax for  constants  above.
       Values of type file, semaphore, and continuation may currently be created only by calls to
       builtin functions: no Nickle constants of these types exist.

       As noted in TYPES above,  Nickle  has  several  kinds  of  ``structured  value'':  arrays,
       functions,  pointers,  structures  and  disjoint  unions.   All  of these have some common
       properties.  When created, all of the component values are uninitialized (unless otherwise
       specified).   Attempts  to use an uninitialized value will result in either a compile-time
       error or a runtime exception.

       Arrays:

       [E]    creates a (zero-based) array with E elements.  E must be non-negative.

       [E]{V,V,...,V}
              Creates an array with E elements, initialized to the Vs.   If  there  are  too  few
              initializers, remaining elements will remain uninitialized.

       [E]{V,V,...,V...}
              The second ellipsis (three dots) is syntax, not metasyntax.  Create an array with E
              elements.  The first elements in the array will be initialized according to the Vs,
              with  any  remaining  elements receiving the same value as the last V.  This syntax
              may be used in the obvious fashion with any of the array initializers below.

       [*]{V,V,...,V}
              Creates an initialized array with exactly as many elements as initializers.   There
              must be at least one initializer.

       [E,E,...,E] [*,*,...,*]
              Creates  multidimensional arrays.  Integer expressions  and "*" cannot be mixed: an
              array's dimensions are entirely either specified or unspecified by the  definition.
              These  arrays  may  also be created initialized: see next paragraph for initializer
              syntax.

       (T[E]) (T[E,E,...,E]) (T[E]){E,E,...,E}

       (T[E,E,...,E]){{E,...},...,{E,...}}
              Alternate syntax for creating arrays of type T.  The initializers, in curly braces,
              are  optional.   The number of initializers must be less than or equal to the given
              number of elements in each dimension.  For multidimensional arrays, the extra curly
              braces  per dimension in the initializer are required; this is unlike C, where they
              are optional.

       (T[*]){E,E,...,E} (T[*,*,...,*]){{E,...},...,{E,...}}
              Creates arrays of type T, with each dimension's size given by the maximum number of
              initializers in any subarray in that dimension.

       Pointers:

       0      The null pointer, in contexts where a pointer is required.

       &V &A[E,E,...,E] &S.N
              Creates  a  pointer to the given variable, array element, or structure member.  The
              type of the pointer will be *T, where T is the type of the object pointed to.

       *P     The value pointed to by pointer P.  This can be viewed or modified as in C.

       Functions:

       (T func(){S;S;...S;}) (T func(T name,T name,...T name){S;S;...S;})
              Function expression: denotes a function of zero or more formal parameters with  the
              given types and names, returning the given result type.  The function body is given
              by the curly-brace-enclosed statement list.  All types are optional, and default to
              poly.   As noted above, functions are strictly call-by-value: in particular, arrays
              and structures are copied rather than referenced.

       T function name(T name,T name,...,T name){S;S;...S;}
              Defines a function of zero or more arguments.  Syntactic sugar for
                T(T,T,...T) name = (T func(T name,T name,...T name){S;S;...S;});

       T function name(T name, T name ...)
              The ellipsis here is syntax, not metasyntax: if  the  last  formal  argument  to  a
              function  is  followed  by three dots, the function may be called with more actuals
              than formals.  All ``extra'' actuals are packaged into  the  array  formal  of  the
              given  name,  and  typechecked  against  the  optional  type T of the last argument
              (default poly).

       Structures:

       (struct { T name; T name; ...T name; }){name = E; name = E; ...name=E;}
              Create a value of a structured type. The named fields are initialized to the  given
              values, with the remainder uninitialized.  As indicated, initialization is by label
              rather than positional as in C.

       Unions:

       (union { T name; T name; ...T name; }.name) E
              Create a value of the given union type, the variant given by .name, and  the  value
              given by E.  E must be type-compatible with name.

STATEMENTS

       The  statement  syntax  very closely resembles that of C.  Some additional syntax has been
       added to support Nickle's additional functionality.

       E;     Evaluates the expression.

       {S ... S}
              Executes the enclosed statements in order.

       if (E) S
              Basic conditional.

       if (E) S
              Conditional execution.

       else S Else is allowed, with the usual syntax and semantics.  In particular, an else binds
              to the most recent applicable if() or twixt().

       while (E) S
              C-style while loop.

       do S while (E);
              C-style do loop.

       for (opt-E; opt-E; opt-E) S
              C-style for loop.

       switch (E) { case E: S-list  case E: S-list ... default: S-list }
              C-style  case  statement.   The  case  expressions  are not required to be constant
              expressions, but may be  arbitrary.   The  first  case  evaluating  to  the  switch
              argument is taken, else the default if present, else the switch body is skipped.

       twixt(opt-E; opt-E) S

       twixt(opt-E; opt-E) S else S
              If  first  argument  expression evaluates to true, the body of the twixt() and then
              the second argument expression will be evaluated.  If the first argument expression
              evaluates to false, the else statement will be executed if present.  Otherwise, the
              entire twixt() statement will be skipped.

       The twixt() statement guarantees that all of these events will  happen  in  the  specified
       order  regardless  of the manner in which the twixt() is entered (from outside) or exited,
       including exceptions, continuations, and break.  (Compare with Java's ``finally'' clause.)

       try S;

       try S catch name (T name, ...) { S; ... };

       try S catch name (T name, ...) { S; ... } ... ;
              Execute the first statement S.  If an exception is raised during execution, and the
              name  matches  the  name  in a catch block, bind the formal parameters in the catch
              block to the actual parameters of the exception, and execute the body of the  catch
              block.   There may be multiple catch blocks per try.  Zero catches, while legal, is
              relatively useless.  After completion of a catch block, execution  continues  after
              the  try  clause.   As  with else, a catch binds to the most recent applicable try-
              catch block.

       raise name(name, name, ..., name)
              Raise the named exception with zero or more arguments.

       ;      The null statement

       break; Discontinue execution of the nearest enclosing for/do/while/switch/twixt statement.
              The leave expression will be executed as the twixt statement is exited.

       continue;
              Branch  directly  to  the  conditional  test  of the nearest enclosing for/do/while
              statement.

       return E;
              Return value E from the nearest enclosing function.

       Namespaces:

       Like Java and C++ Nickle has a notion of namespace, a collection of names  with  partially
       restricted visibility.  In Nickle, namespaces are created with the namespace command.

       opt-P namespace N { S ... }
              Places  all  names  defined  in  the  statements  S  into a namespace named N.  The
              optional qualifier P may be the keyword public, but beware: this  merely  indicates
              that  the  name N itself is visible elsewhere in the current scope, and has nothing
              to do with the visibility of items inside the namespace.

       extend namespace N { S ... }
              Reopen the given namespace N, and extend it with the names defined as public in the
              given statements S.

              Names  defined inside the namespace are invisible outside the namespace unless they
              are qualified with the keyword public.  Public names may be  referred  to  using  a
              path notation:
                namespace::namespace::...::namespace::name
              refers  to  the  given  name  as  defined  inside the given set of namespaces.  The
              double-colon syntax is unfortunate, as it is slightly different in meaning than  in
              C++,  but  all the good symbols were taken, and it is believed to be a feature that
              the namespace separator is syntactically different than the structure operator.  In
              Java, for example, the phrase
                name.name.name
              is  syntactically  ambiguous:  the  middle  name  may  be  either  a structure or a
              namespace.

       import N;
              The name N must refer to a namespace:  all  public  names  in  this  namespace  are
              brought into the current scope (scoping out conflicting names).

BUILTINS

       Nickle  has  a collection of standard functions built in.  Some of these are written in C,
       but many are written in Nickle.  Several collections of functions have associated  builtin
       datatypes: their namespaces, together with their types, should be viewed as ADTs.

       Top-Level Builtins:

       int printf(string fmt, poly args...)
              Calls File::fprintf(stdout, fmt, args ...) and returns its result.

       string function gets ()
              Calls File::fgets(stdin) and returns its result.

       string function scanf (string fmt, *poly args...)
              Calls File::vfscanf(stdin, fmt, args) and returns its result.

       string function vscanf (string fmt, (*poly)[*] args)
              Calls File::vfscanf(stdin, fmt, args) and returns its result.

       real imprecise(rational value)
              See the discussion of type real above.

       real imprecise(rational value, int prec)
              See the discussion of type real above.

       int string_to_integer(string s)

       int atoi(string s)
              The  argument  s  is  a  signed  digit  string,  and  the  result is the integer it
              represents.  If the string s is syntactically  a  hexadecimal,  octal,  binary,  or
              explicit base-10 constant, treat it as such.

       int string_to_integer(string s, int base)

       int atoi(string s, int base)
              Treat  s as a string of digits in the given base.  A base of 0 acts as with no base
              argument.  Otherwise, base specification syntax in the string is ignored.

       int putchar(int c)
              Place the given character on the standard output using File::putc(c,  stdout),  and
              return its result.

       int sleep(int msecs)
              Try  to  suspend  the  current thread for at least msecs milliseconds.  Return 1 on
              early return, and 0 otherwise.

       int exit(int status)
              Exit Nickle with the given status code.  Do not return anything.

       int dim(poly[*] a)
              Given a one-dimensional array a, dim() returns the number of elements of a.

       int[] dims(poly[] a)
              Given an arbitrary array a, dims() returns an array of integers giving the size  of
              each dimension of a.  Thus, dim(dims(a)) is the number of dimensions of a.

       *poly reference(poly v)
              Given an arbitrary value v, ``box'' that value into storage and return a pointer to
              the box.

       rational string_to_real(string s)

       rational atof(string s)
              Convert the real constant string s into its associated real number.

       number abs(real v)
              Return the absolute value of v.  The  result  type  chosen  will  match  the  given
              context.

       int floor(real v)
              Return  the largest integer less than or equal to v.  This will fail if v is a real
              and the precision is too low.

       int ceil(real v)
              Return the smallest integer greater than or equal to v.  This will fail if v  is  a
              real and the precision is too low.

       int exponent(real v)
              Return the exponent of the imprecise real v.

       rational mantissa(real v)
              Return the mantissa of the imprecise real v, as a rational m with 0 <= m <= 0.5 .

       int numerator(rational v)
              Return  the  numerator  of the rational number v: i.e., if v = n/d in reduced form,
              return n.

       int denominator(rational v)
              Return the denominator of the rational number v: i.e., if v = n/d in reduced  form,
              return d.

       int precision(real v)
              Return the number of bits of precision of the mantissa of the imprecise real number
              v.

       int sign(real v)
              Return -1 or 1 as v is negative or nonnegative.

       int bit_width(int v)
              Return the number of bits required to represent abs(v) internally.

       int is_int(poly v)
              Type predicate.

       int is_rational(poly v)
              Numeric type predicates are inclusive: e.g., is_rational(1) returns 1.

       int is_number(poly v)
              Type predicate.

       int is_string(poly v)
              Type predicate.

       int is_file(poly v)
              Type predicate.

       int is_thread(poly v)
              Type predicate.

       int is_semaphore(poly v)
              Type predicate.

       int is_continuation(poly v)
              Type predicate.

       int is_array(poly v)
              Type predicate.

       int is_ref(poly v)
              Type predicate: checks for pointer type.  This is arguably a  misfeature,  and  may
              change.

       int is_struct(poly v)
              Type predicate.

       int is_func(poly v)
              Type predicate.

       int is_void(poly v)
              Type predicate.

       int gcd(int p, int q)
              Return the GCD of p and q.  The result is always positive.

       int xor(int a, int b)
              Return a ^ b .  This is mostly a holdover from before Nickle had an xor operator.

       poly setjmp(continuation *c, poly retval)
              The  setjmp()  and longjmp() primitives together with the continuation type form an
              ADT useful for nearly arbitrary transfers of  flow-of-control.   The  setjmp()  and
              longjmp()  builtins are like those of C, except that the restriction that longjmp()
              always jump upwards is removed(!): a continuation saved via setjmp() never  becomes
              invalid during the program lifetime.

              The  setjmp()  builtin saves the current location and context into its continuation
              pointer argument, and then returns its second argument.

       void longjmp(continuation c, poly retval)
              The longjmp() builtin never returns to the call site, but instead returns from  the
              setjmp()  that  created  the  continuation,  with  return value equal to the second
              argument of longjmp().

       string prompt
              The prompt printed during interactive use when at top-level.  Default ">  ".   when
              waiting   for   the  rest  of  a  statement  or  expression,  and  when  debugging,
              respectively.  Default values are "> ", "+ ", and "- ".

       string prompt2
              The prompt printed during interactive use when waiting for the rest of a  statement
              or expression.  Default "+ ".

       string prompt3
              The prompt printed during interactive use when debugging.  Default "- ".

       string format
              The printf() format for printing top-level values.  Default "%g".

       string version
              The version number of the Nickle implementation currently being executed.

       string build
              The  build  date of the Nickle implementation currently being executed, in the form
              "yyyy/mm/dd", or "?" if the build date is unknown for some reason.

       file stdin
              Bound to the standard input stream.

       file stdout
              Bound to the standard output stream.

       file stderr
              Bound to the standard error stream.

       Exceptions:

       A few standard exceptions are predeclared and used internally by Nickle.

       exception uninitialized_value(string msg)
              Attempt to use an uninitialized value.

       exception invalid_argument(string msg, int arg, poly val)
              The arg-th argument to a builtin function had invalid value val.

       exception readonly_box(string msg, poly val)
              Attempt to change the value of a read-only quantity to val.

       exception invalid_array_bounds(string msg, poly a, poly i)
              Attempt to access array a at index i is out of bounds.

       exception divide_by_zero(string msg, real num, real den)
              Attempt to divide num by den with den == 0.

       exception invalid_struct_member(string msg, poly struct, string name)
              Attempt to refer to member name of the object struct, which does not exist.

       exception invalid_binop_values(string msg, poly arg1, poly arg2)
              Attempt to evaluate a binary operator with args arg1 and arg2, where at  least  one
              of these values is invalid.

       exception invalid_unop_values(string msg, poly arg)
              Attempt to evaluate a unary operator with invalid argument arg.

       Builtin Namespaces:

       Math   The  math  functions  available  in the Math namespace are implemented in a fashion
              intended to be compatible with the  C  library.   Please  consult  the  appropriate
              manuals for further details.

       real pi
              Imprecise  constant  giving  the  value  of the circumference/diameter ratio of the
              circle to the default precision of 256 bits.

       protected real e
              Imprecise constant giving the value of  the  base  of  natural  logarithms  to  the
              default  precision  of  256  bits.  Since e is protected, it must be referenced via
              Math::e, in order to avoid problems with using the fifth letter of the alphabet  at
              top level.

       real function sqrt(real v)
              Returns the square root of v.

       real function cbrt(real v)
              Returns the cube root of v.

       real function exp(real v)
              Returns e**v.

       real function log(real a)
              Returns  v  such that e**v == a.  Throws an invalid_argument exception if a is non-
              positive.

       real function log10(real a)
              Returns v such that 10**v == a.  Throws an invalid_argument exception if a is  non-
              positive.

       real function log2(real a)
              Returns  v  such that 2**v == a.  Throws an invalid_argument exception if a is non-
              positive.

       real function pi_value(int prec)
              Returns the ratio of the circumference of a circle to the diameter, with prec  bits
              of precision.

       real function sin(real a)
              Returns  the  ratio  of  the  opposite side to the hypotenuse of angle a of a right
              triangle, given in radians.

       real function cos(real a)
              Returns the ratio of the adjacent side to the hypotenuse of  angle  a  of  a  right
              triangle, given in radians.

       void function sin_cos(real a, *real sinp, *real cosp)
              Returns  with sin(a) and cos(a) stored in the locations pointed to by sinp and cosp
              respectively.  If either pointer is 0, do not store into  that  location.   May  be
              slightly faster than calling both trig functions independently.

       real function tan(real a)
              Returns  the  ratio of the opposite side to the adjacent side of angle a of a right
              triangle, given in radians.  Note that tan(pi/2) is not currently an error: it will
              return a very large number dependent on the precision of its input.

       real function asin(real v)
              Returns a such that sin(a) == v.

       real function acos(real v)
              Returns a such that cos(a) == v.

       real function atan(real v)
              Returns a such that tan(a) == v.

       real function atan2(real x, y)
              Returns a such that tan(a) == x / y.  Deals correctly with y == 0.

       real function pow(real a, real b)
              The implementation of the ** operator.

       File   The namespace File provides operations on file values.

       int function fprintf(file f, string s, ....)
              Print  formatted values to a file, as with UNIX stdio library fprintf().  fprintf()
              and printf() accept a reasonable sub-set of the stdio library version:  %c, %d, %e,
              %x,  %o,  %f,  %s,  %g work as expected, as does %v to smart-print a value.  Format
              modifiers may be placed between the percent-sign and the format  letter  to  modify
              formatting.  There are a lot of known bugs with input and output formatting.

              Format Letters:

              %c     Requires  a  small  integer  argument  (0..255),  and  formats  as  an ASCII
                     character.

              %d     Requires an integer argument, and formats as an integer.

              %x     Requires an  integer  argument,  and  formats  as  a  base-16  (hexadecimal)
                     integer.

              %o     Requires an integer argument, and formats as a base-8 (octal) integer.

              %e     Requires a number argument, and formats in scientific notation.

              %f     Requires a number argument, and formats in fixed-point notation.

              %s     Requires a string argument, and emits the string literally.

              %g     Requires  a  number, and tries to pick a precise and readable representation
                     to format it.

              Format Modifiers:

              digits All format characters will take an integer format  modifier  indicating  the
                     number  of  blanks  in  the  format field for the data to be formatted.  The
                     value will be printed right-justified in this space.

              digits.digits
                     The real formats will take a pair of integer format modifiers indicating the
                     field  width  and  precision  (number  of  chars after decimal point) of the
                     formatted value.  Either integer may be omitted.

              -      A precision value indicating infinite precision.

              *      The next argument to fprintf() is an integer indicating the field  width  or
                     precision of the formatted value.

       file function string_write()
              Return a file which collects written values into a string.

       int function close(file f)
              Close file f and return an indication of success.

       int function flush(file f)
              Flush the buffers of file f and return an indication of success.

       int function getc(file f)
              Get the next character from file f and return it.

       int function end(file f)
              Returns true if file f is at EOF, else false.

       int function error(file f)
              Returns true if an error is pending on file f, else false.

       int function clear_error(file f)
              Clears pending errors on file f, and returns an indication of success.

       file function string_read(string s)
              Returns a virtual file whose contents are the string s.

       string function string_string(file f)
              Return  the  string  previously  written  into  the  file f, which should have been
              created by string_read() or string_write().  Behavior on other files  is  currently
              undefined.

       file function open(string path, string mode)
              Open the file at the given path with the given mode string, ala UNIX stdio fopen().
              Permissible modes are as in stdio: "r", "w", "x", "r+", "w+" and "x+".

       integer function fputc(integer c, file f)
              Output the character c to the output file f, and return an indication of success.

       integer function ungetc(integer c, file f)
              Push the character c back onto the input  file  f,  and  return  an  indication  of
              success.

       integer function setbuf(file f, integer n)
              Set the size of the buffer associated with file f to n, and return n.

       string function fgets (file f)
              Get a line of input from file f, and return the resulting string.

       file function pipe(string path, string[*] argv, string mode)
              Start  up  the  program  at  the given path, returning a file which is one end of a
              "pipe" to the given process. The mode argument can be "r" to read from the pipe  or
              "w"  to  write  to  the  pipe.  The argv argument is an array of strings giving the
              arguments to be passed to  the  program,  with  argv[0]  conventionally  being  the
              program name.

       int  function  print  (file  f,  poly v, string fmt, int base, int width, int prec, string
       fill)
              Print value v to file f in format fmt with the given base, width, prec,  and  fill.
              Used internally by File::fprintf();

       int function fscanf(file f, string fmt, *poly args...)
              Fill  the  locations  pointed  to  by  the array args with values taken from file f
              according to string fmt.  The format specifiers are much as in UNIX stdio  scanf():
              the  "%d",  "%e",  "%f",  "%c"  and "%s" specifiers are supported with the expected
              modifiers.

       int function vfscanf (file f, string fmt, (*poly)[*] args)
              Given the file f, the format  fmt,  and  the  array  of  arguments  args,  fscanf()
              appropriately.

       Thread The  namespace  Thread  supports  various  operations  useful  for programming with
              threads, which provide concurrent flow of control  in  the  shared  address  space.
              There is one piece of special syntax associated with threads.

              fork(E)
                     Accepts  an  arbitrary  expression,  and evaluates it in a new child thread.
                     The parent thread receives the thread as the value of the fork expression.

              The remainder of the Thread functions are fairly standard.

       int function kill(thread list...)
              Kills every running thread in  the  array  list.   With  no  arguments,  kills  the
              currently running thread.  Returns the number of threads killed.

       int function trace(poly list...)
              Shows  the  state  of  every  running thread in the array list.  With no arguments,
              traces the default continuation.  Returns the number of threads traced.

       int function cont()
              Continues execution of any interrupted threads, and returns the number of continued
              threads.

       thread function current()
              Return the current thread.

       int function list()
              Reports the currently running thread to stdout.

       int function get_priority(thread t)
              Reports the priority of the given thread.

       thread function id_to_thread(int id)
              Returns the thread with the given id, if found, and 0 otherwise.

       poly function join(thread t)
              Waits for thread t to terminate, and returns whatever it returns.

       int function set_priority(thread t, int i)
              Attempts  to set the priority of thread t to level i, and returns the new priority.
              Larger priorities mean more runtime: a task with higher priority  will  always  run
              instead  of  a lower priority task.  Threads of equal highest priority will be pre-
              emptively multitasked.

       Semaphore
              The Semaphore namespace encapsulates operations on the semaphore built-in  ADT.   A
              semaphore  is  used  for  thread  synchronization.   Each signal() operation on the
              semaphore awakens the  least-recent  thread  to  wait()  on  that  semaphore.   The
              ``count'' of waiting processes may be set at semaphore creation time.

       semaphore function new(int c)
              Create  a  new  semaphore  with  an  initial count c of waiting processes.  If c is
              positive, it means that c threads may wait on the semaphore before one blocks.   If
              c  is  negative,  it sets a count of threads which must be waiting on the semaphore
              before further waits will not block.

       semaphore function new()
              Call semaphore(0) and return its result.

       int signal(semaphore s)
              Increment semaphore s.  If s is non-positive, and some  thread  is  blocked  on  s,
              release the least-recently-blocked thread.  Return 1 on success.

       int wait(semaphore s)
              Decrement  semaphore  s.   If  s  is  negative,  block until released.  Return 1 on
              success.

       int test(semaphore s)
              Test whether wait() on semaphore s would cause the current thread to block.  If so,
              return 0.  Otherwise, attempt to decrement s, and return 1 if successful.

       String The String namespace contains a few basic operations on the string ADT.

       int function length(string s)
              Returns the number of characters in s.

       string function new(int c)
              Returns as a string the single character c.

       string function new(int cv[*])
              Returns a string comprised of the characters of cv.

       int function index(string t, string p)
              Returns  the integer index of the pattern string p in the target string t, or -1 if
              p is not a substring of t.

       string function substr(string s, int i, int l)
              Returns the substring of string s starting with the character at  offset  i  (zero-
              based) and continuing for a total of l characters.  If l is negative, the substring
              will consist of characters preceding rather than succeeding i.

       PRNG   The PRNG namespace provides pseudo-random number generation and manipulation.   The
              core  generator  is  the  RC4 stream cipher generator, properly bootstrapped.  This
              provide a stream  of  cryptographically-secure  pseudo-random  bits  at  reasonable
              amortized cost.  (But beware, initialization is somewhat expensive.)

       void function srandom(int s)
              Initialize the generator, using the (arbitrarily-large) integer as a seed.

       void function dev_srandom(int nbits)
              Initialize the generator, using nbits bits of entropy obtained from some reasonable
              entropy source.  On UNIX systems, this source is  /dev/urandom.   Asking  for  more
              initial  entropy  than the system has may lead either to bootstrapping (as on UNIX)
              or to hanging, so use cautiously.

       int function randbits(int n)
              Returns an n-bit pseudo-random number, in the range 0..(2**n)-1.  Useful for things
              like RSA.

       int function randint(int n)
              Returns a pseudo-random number in the range 0..n-1.

       void function shuffle(*(poly[*]) a)
              Performs an efficient in-place true shuffle (c.f. Knuth) of the array a.

       Command
              The  Command namespace is used by the top-level commands as described below.  It is
              also occasionally useful in its own right.

       string library_path
              Contains the current library search path, a colon-separated list of directories  to
              be searched for library files.

       int function undefine(string name)
              Implements  the  top-level undefine command. Remove the name denoted by string name
              from the namespace.  This removes all visible definitions of the name.

       int function undefine(string[*] names)
              Remove each of the names in the array names from the namespace.  This  removes  all
              visible definitions of each name.

       int function delete(string name)
              Attempt to remove the command with the given string name from the top-level command
              list, and return 1 if successful.

       int function lex_file(string path)
              Attempt to make the file at the given path the current source of Nickle  code,  and
              return  1  if  successful.   Note  that  this  effectively ``includes'' the file by
              pushing it onto a stack of files to be processed.

       int function lex_library(string filename)
              Like lex_file(), but searches the directories given by  the  library_path  variable
              for the first file with the given filename.

       int function lex_string(string code)
              Attempt to make the Nickle code contained in the string code be the next input.

       int function edit(string[*] names)
              Implements  the  top-level  edit  command.  The  names  in  the array are a path of
              namespace names leading to the symbol name, which is last.

       int function new(string name, poly func)
              Binds function func to the top-level command string name: i.e., makes  it  part  of
              the top-level command vocabulary.

       int function new_names(string name, poly func)
              Binds  function  func  to the top-level command string name: i.e., makes it part of
              the top-level command vocabulary.  Unlike new(), the string names given to func  at
              the  top  level  are  passed unevaluated as an array of string names or as a single
              string name.

       int function pretty_print(file f, string[*] names)
              Implements the top-level print command.  Each of the passed name strings is  looked
              up and the corresponding code printed to file f.

       int function display(string fmt, poly val)
              Uses printf() to display the value val in format fmt.

       History
              Nickle  maintains  a  top-level value history, useful as an adjunct to command-line
              editing when calculating.  The History namespace contains functions to access  this
              history.

       int function show(string fmt)
              Implements  the  history top-level command with no arguments.  Show the most recent
              history values with format fmt.

       int function show(string fmt, int count)
              Implements the history top-level command with one argument.  Show  the  last  count
              history values with format fmt.

       int function show(string fmt, int first, int last)
              Implements the history top-level command with two arguments.

       poly function insert(poly val)
              Insert val in the history list, and return it.

       Environ
              Many  operating systems have some notion of ``environment variables.''  The Environ
              namespace contains functions to manipulate these.

       int function check(string name)
              Returns 1 if the variable with  the  given  name  is  in  the  environment,  and  0
              otherwise.

       string function get(string name)
              Attempts  to  retrieve  and  return  the value of the environment variable with the
              given name.  Throws an invalid_argument exception if the variable is not available.

       int function unset(string name)
              Attempts to unset the environment variable with the  given  name,  and  returns  an
              indication of success.

       string function set(string name, string value)
              Attempts  to  set  the environment variable with the given name to the given value,
              and returns an indication of success.

COMMANDS

       Nickle has a set of commands which may be given at the top level.

       quit   Exit Nickle.

       quit E Exit Nickle with integer status code E.

       undefine NAME {,NAME}
              Remove these names from the system.

       load E Load a file given by the string name E.

       library E
              Load a library given by the string name E.  See the discussion  of  the  NICKLEPATH
              environment    variable    in    ENVIRONMENT   below,   and   the   discussion   of
              Command::library_path above.

       E # E  Print expr1 in base expr2 .

       print NAME
              Display a formatted version of the object denoted by NAME.  Comments  and  original
              formatting are lost.  If NAME is a variable, print the type as well as the value.

       edit NAME
              Invoke  $EDITOR  on  the  named object, and re-incorporate the results of the edit.
              This is most useful with functions.

       history
              Display the 10 most recently printed values.  They can be accessed with $n where  n
              is the number displayed to the right of the value in this list.

       history E
              Display the E most recent history values.

       history E,E
              Display history values from the first integer E through the second.

DEBUGGER

       When  an  unhandled exception reaches top level during execution, the user receives a dash
       prompt, indicating that debug mode is active.  In this mode, the command-line  environment
       is  that  in  which the unhandled exception was raised.  In addition a number of debugging
       commands are available to the user:

       trace  Get a stack backtrace showing the current state, as with the GDB where command.

       up     Move up the stack (i.e., toward the top-level expression) ala GDB.

       down   Move down the stack (i.e., toward the current context) ala GDB.

       done   Leave debugging mode, abandoning execution.

              In addition, the Debug namespace is scoped in in debugging mode.  This is primarily
              of use in debugging Nickle itself.

       collect()
              Run the garbage collector.

       dump(function)
              Print the compiled byte code for function.

ENVIRONMENT

       EDITOR The editor used by the edit command, described in COMMANDS above.

       NICKLERC
              The location of the user's .nicklerc file, which will be loaded at the beginning of
              nickle execution if possible.

       HOME   Used to find the user's .nicklerc if NICKLERC is not set.

       NICKLEPATH
              A colon-separated path whose elements are directories containing Nickle code.   The
              library  command  and the -l flag, described above, search this path for a filename
              matching the given file.  The default library path in the absence of this  variable
              is /usr/share/nickle.

       NICKLESTART
              The  filename  of  the file that should be loaded as a bootstrap on Nickle startup.
              The   default    in    the    absence    of    this    variable    is    to    load
              /usr/share/nickle/builtin.5c.

EXAMPLES

       An example (taken from the bc manual:

         real function exponent(real x) {
             real a = 1;
             int b = 1;
             real s = 1;
             int i = 1;
             while (1) {
                 a = a * x;
                 b = b * i;
                 real c = a / b;
                 if (abs(c) < 1e-6)
                     return s;
                 s = s + c;
                 i++;
             }
         }

       defines a function to compute an approximate value of the exponential function e ** x and

         for (i = 1; i < 10; i++)
             printf ("%g\n", exponent (i));

       prints approximate values of the exponential function of the first ten integers.

VERSION

       This  document describes version 1.99.2 of nickle, as well as some newer features.  It was
       distributed with version 2.92 of nickle.

BUGS

       See the discussion of the type of the exponentiation operator ** above.

       Due to a difficult-to-remove  grammar  ambiguity,  it  is  not  possible  to  use  a  bare
       assignment   expression  in  an  array  initializer:  it  is  confused  with  a  structure
       initializer.  For example:
         > int x = 0;
         > (int[*]){x = 1}
         ->     (int[*]) { x = 1 }
       Non array initializer
       The workaround is to parenthesize the assignment expression:
         > (int[*]){(x = 1)}
         [1]{1}
       Because this is so rare, so hard to fix, and so easy to work around, this bug is  unlikely
       to be fixed anytime soon.

       There  are a lot of known bugs with input and output formatting.  The obvious stuff works,
       other stuff does not.

       The semantics of division are unfortunately different from those of C.  This  is  arguably
       because  C  is  broken  in  this  area: we cannot currently see any obvious fix.  C allows
       automatic implicit coercion of  floating  to  integral  types,  but  we  consider  this  a
       misfeature.

       The implementation has not been thoroughly tested.

AUTHOR

       Nickle   is   the   work   of   Keith   Packard   <keithp@keithp.com>   and   Bart  Massey
       <bart_massey@iname.com>.

       Nickle is
       Copyright 1988-2006 Keith Packard and Bart Massey.  All Rights Reserved.

       Permission is hereby granted, free of charge, to any  person  obtaining  a  copy  of  this
       software  and  associated  documentation  files  (the "Software"), to deal in the Software
       without restriction, including without limitation the rights to use, copy, modify,  merge,
       publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
       to whom the Software 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 Software.

       THE  SOFTWARE  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 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
       SOFTWARE.

       Except as contained in this notice, the names of the authors or their  institutions  shall
       not be used in advertising or otherwise to promote the sale, use or other dealings in this
       Software without prior written authorization from the authors.

                                          @RELEASE_DATE@                                NICKLE(1)