=head1 NAME

Physics::Unit::Implementation - This page discusses implementation issues of the Physics/Unit.pm
module.

=head1 Data Structures

=head2 %reserved_word

A list of reserved words in Unit expressions.

=head2 %unit_by_name

A list of all known unit names. The value of the hash is a reference
to the named unit object.

=head2 %prefix

A list of all the valid prefixes. The value of the hash is a
reference to the unit object. Note that the names here are also in
%unit_by_name.

These are special case unit names that can be attached to other units
with no intervening spaces.

=head2 %prototype

A list of all the known types. The values of this hash are references
to unit objects that exemplify these types. I.e., any other units
that have the same type will have the same dimensionality as the
example unit.

=head2 $NumBases

The number of base units.

=head2 @BaseName

The name of each of the base units. These names also appear in
%unit_by_name.


=head1 Initialization

InitBaseUnit is called to inform the library how many independent
dimensional quantities there are, and what the 'base' unit is for
each quantity.
The library is initialized to know about nine quantities.  More can
be added at run-time, if desired.

InitPrefix is called to initialize the prefixes.
Prefixes are just like dimensionless units, but they don't need to
be separated from the next unit by a space.
Prefix units can only have one name.

Next, InitUnit is called to define units in terms of other units.
Note:  no forward references are allowed here.





=head1 Private Implementation Routines

These are not part of the user-interface.  These are only for use
within the package.

=head2 NewOne()

Creates a new dimensionless unit.

=head2 AddNames()

This is called during the object's construction to add a list of
names to the 'names' array, and to set the reference in the
%unit_by_names cross-reference hash.

=head2 NewType()

   $u->NewType('type');

This is called when we are adding a new type to the system.  This
happens both in InitBaseUnits() and in InitTypes().

=head2 CreateUnit()

This is used by several of the interface utility functions to create
a new unit object from a unit definition (either a simple name, a
unit expression, or a unit object).

It differs from GetUnit in that it always creates a new, anonymous
unit, whereas GetUnit, if given a simple name, returns a reference
to a named unit.

=head2 CompareDim()

Compare the dimension arrays.
Return 0 if they are the same.

=head2 LookName()

Look up the name.  Returns:

  0 not defined
  1 reserved word
  2 unit name
  3 type name

=head2 DebugString()

Convert the unit to a factor - dimension vector format string, e.g.
the unit '3 meters' would be converted to something like

  3 [1, 0, 0]

=head2 CheckChange()

Complain if this unit has a name.  This is used by all the methods
that modify the value of the unit.


=head1 The Parser

Below are listed the private parser functions.
See also the grammar description in the Unit.pm documentation.

=head2 expr()

  expr : term
       | term '/' expr
       | term '*' expr
       | term 'per' expr

=head2 term()

  term : factor
       | term factor

A term is any number of factors separated (nominally) by whitespace.
Whitespace is an 'operator' that means the same thing as multiplication,
but has a higher priority than either '*', '/', or 'per'.

Examples of terms (the following lines each contain one term):

  3pi radians
  3e+4 globules


=head2 Factor()

  factor : prim
         | prim '**' integer

Note that a primary can be an integer, of course, so factors can
look like this:

  meter ** 3 ^ 5    # note, '**' and '^' are synonymous


=head2 prim()

  prim : number
       | word
       | '(' expr ')'
       | 'square' primary
       | 'sq' primary
       | 'cubic' primary
       | primary 'squared'
       | primary 'cubed'

The unary operators square, sq, cubic, squared, and cubed are
implemented as part of this function.  Thus they have quite a
high precedence, as I think they should.


=head2 get_token()

Only used by new above to parse the unit definition string.

