Provided by: nickle_2.77-1_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 expresion 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  formating  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.77 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.

                                                   2012/11/07                                          NICKLE(1)