Skip site navigation (1)Skip section navigation (2)

  
 
  

home | help
NICKLE(1)		     General Commands Manual		       NICKLE(1)

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  script-
     ing capabilities.	Nickle supports a variety of datatypes, especially arbi-
     trary  precision  integers, rationals, and imprecise reals.  The input lan-
     guage 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 ei-
     ther 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 de-
     notes  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  con-
	    tains a curly-bracketed trailing portion, it is treated as a repeat-
	    ing  decimal.  `Floating point'' constants are currently represented
	    internally as rationals: for floating constants with a given  preci-
	    sion  (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.   Back-
	    slashed  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 al-
	    lowed: 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 discus-
	    sion of array types above.	See the discussion of array  and  struc-
	    ture 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 fur-
	    ther 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  name-
	    space, 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	initial-
	    izer  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 ini-
	    tialized 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 prece-
     dence:

     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 re-
	    sult 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  er-
	    ror 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  no-
	    table 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  con-
	    sidered  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  imple-
	    mented  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 compu-
	    tations 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 im-
	    precise(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  dimen-
	    sion  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  argu-
	    ments.

     T0() T0(T,T,...,T ...)
	    A  function accepting zero or more required arguments, plus an arbi-
	    trary 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 op-
	    erates only upon pointers to arrays: the pointer must be of the cor-
	    rect 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  paren-
	    thesis 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 ap-
	    plies 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 cur-
     rently  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  uninitial-
     ized  value  will result in either a compile-time error or a runtime excep-
     tion.

     Arrays:

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

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

     [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 receiv-
	    ing  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  ini-
	    tializers.	There must be at least one initializer.

     [E,E,...,E] [*,*,...,*]
	    Creates  multidimensional arrays.  Integer expressions  and "*" can-
	    not 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 dimen-
	    sion.  For multidimensional arrays, the extra curly braces	per  di-
	    mension  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 para-
	    meters  with  the  given types and names, returning the given result
	    type.  The function body is given by the curly-brace-enclosed state-
	    ment 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  ar-
	    gument  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	initial-
	    ized  to the given values, with the remainder uninitialized.  As in-
	    dicated, 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	particu-
	    lar, 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 evaluat-
	    ing  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 state-
	    ment 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  en-
     tered  (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 ex-
	    ecution, 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  rela-
	    tively  useless.   After completion of a catch block, execution con-
	    tinues 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  name-
	    space  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  name-
	    spaces.   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 separa-
	    tor 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 struc-
	    ture or a namespace.

     import N;
	    The name N must refer to a namespace: all public names in this name-
	    space 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 func-
     tions 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 inte-
	    ger  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 ele-
	    ments of a.

     int[] dims(poly[] a)
	    Given an arbitrary array a, dims() returns an array of integers giv-
	    ing the size of each dimension of a.  Thus, dim(dims(a)) is the num-
	    ber of dimensions of a.

     *poly reference(poly v)
	    Given an arbitrary value v, ``box'' that value into storage and  re-
	    turn 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 impre-
	    cise 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 misfea-
	    ture, 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.  De-
	    fault "> ".  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 exe-
	    cuted.

     string build
	    The  build	date  of  the Nickle implementation currently being exe-
	    cuted, 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 piImprecise 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 loga-
	    rithms 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  excep-
	    tion 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 (hexa-
		   decimal) integer.

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

	    %e	   Requires  a	number argument, and formats in scientific nota-
		   tion.

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

	    %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-justi-
		   fied 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 af-
		   ter 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  suc-
	    cess.

     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  indica-
	    tion of success.

     integer function ungetc(integer c, file f)
	    Push the character c back onto the input file f, and return an indi-
	    cation 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 ar-
	    gument 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" speci-
	    fiers 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 program-
	    ming with threads, which provide concurrent flow of control  in  the
	    shared  address space.  There is one piece of special syntax associ-
	    ated 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 num-
	    ber 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.  Re-
	    turn 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 re-
	    turn 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  ma-
	    nipulation.   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 be-
	    ware, 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 ar-
	    ray a.

     CommandThe 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 defini-
	    tions 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  li-
	    brary_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	unevalu-
	    ated 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.

     HistoryNickle maintains a top-level value history, useful as an adjunct  to
	    command-line  editing  when calculating.  The History namespace con-
	    tains 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.

     EnvironMany operating systems  have  some	notion	of  ``environment  vari-
	    ables.''   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  vari-
	    able  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.

     historyDisplay 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 de-
	    fault library path in the  absence	of  this  variable  is	/usr/lo-
	    cal/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/local/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 func-
     tion 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 in-
     tegers.

VERSION
     This document describes version 1.99.2 of nickle, as  well  as  some  newer
     features.	It was distributed with version 2.97 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 obvi-
     ous 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 inte-
     gral 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 Soft-
     ware 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 CONNEC-
     TION 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  in-
     stitutions  shall	not  be  used in advertising or otherwise to promote the
     sale, use or other dealings in this Software without prior  written  autho-
     rization from the authors.

				 @RELEASE_DATE@ 		       NICKLE(1)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=nickle&sektion=1&manpath=FreeBSD+Ports+15.1.quarterly>

home | help