🗐 MACHINE2.E for Euphoria 3.1.1



			MACHINE2.E for Euphoria 3.1.1

		 Version 1.10, September/19/2019, by Shian Lee.


			     1. Introduction


 This library provides basic utilities, bitwise operators and machine level
 interface routines, for any platform.

 Version 1.08 includes the new routines: bsearch(), hash() and checksum().

 Tip: in Euphoria 3.1.1 you can use the builtin floor() function to speedup
      'for' loops or any other calculation, for example:

      for i = 1 to floor(15000001 / 2) do ...
       is much faster then:
      for i = 1 to 15000001 / 2 do ...

      floor() converts real numbers to integers which perform *much* faster.

 Note: yesterday (Jan/10/2017) I downloaded the full version of FreeDOS 1.2,
       and it was great to find out that Euphoria 3.1.1 is included with
       FreeDOS 1.2! My favorite programming language with my favorite OS...!

 What's new in version 1.10:

 - type byte_string() - test if an object is an unsigned byte-string.
 - function encode()  - encode or decode data. (now works much faster!).
 - function sencode() - encode or decode a string sequence.


 Disclaimer
 ==========

 Use this library at your own risk. The author will not be responsible for
 any damage or data loss.

 This library is tested and optimized on FreeDOS 1.1 operating system. The
 code or the documentation might still contain errors or mistakes.


 In the descriptions below, to indicate what kind of object may be passed in
 and returned, the following prefixes are used:

 x     - a general object (atom or sequence)

 s     - a sequence

 a     - an atom

 i     - an integer

 fn    - an integer used as a file number

 st    - a string sequence, or single-character atom



		      2. Routines by Application Area


 2.1 Predefined Types
 ====================

 As well as declaring variables with these types, you can also call them just
 like ordinary functions, in order to test if a value is a certain type.

 boolean         - test if an object is a boolean integer

 dwords          - test if an object is a DWORD (32-bit) atom or sequence

 string          - test if an object is a string (a flat sequence)

 byte_string     - test if an object is an unsigned byte-string



 2.2 Sequence Manipulation
 =========================

 sum             - calculate the sum of a sequence

 flat            - flatten a sequence, don't add an end-of-string marker

 flatten         - flatten a sequence

 sencode         - encode or decode a string sequence

 EMPTY           - an empty sequence ({})



 2.3 Searching and Sorting
 =========================

 bsearch         - find an object in a sorted sequence

 hash		 - calculate the hash value of an object



 2.4 Math
 ========

 These routines can be applied to individual atoms or to sequences of values.

 abs             - return the absolute value of a number

 fix             - truncate the fractional part of a number

 sign            - return a value indicating the sign of a number, 0 is 0

 psign           - return a value indicating the sign of a number, 0 is 1

 nsign           - return a value indicating the sign of a number, 0 is -1

 zsign           - return a value indicating the sign of a number, 0 is TRUE



 2.5 Bitwise Operations
 ======================

 These routines treat numbers as collections of binary bits, and can be
 applied to individual atoms or to sequences of values. The arguments must be
 representable as 32-bit numbers, either signed or unsigned.

 eqv_bits        - perform logical EQV on corresponding bits

 imp_bits        - perform logical IMP on corresponding bits

 shl_bits        - return the result of shifting bits left

 shr_bits        - return the result of shifting bits right

 rol_bits        - return the result of rotating bits left

 ror_bits        - return the result of rotating bits right

 get_bit         - return the result of getting a bit value

 set_bit         - return the result of setting a bit value

 pack_bits       - convert a sequence of numbers to an integer

 unpack_bits     - convert an integer to a sequence of numbers

 FALSE           - the boolean value 0

 TRUE            - the boolean value 1



 2.6 File and Device I/O
 =======================

 putx            - output an object to a file or device

 get_xkey        - check for key pressed by the user, don't wait, return an
		   object

 wait_xkey       - wait for user to press a key, return an object

 pause           - suspend execution until user press a key

 clear_keyboard  - clear the keyboard buffer

 checksum	 - calculate the checksum value of data

 encode          - encode or decode data



 2.7 Operating System
 ====================

 delay           - suspend execution for a period of time

 TIME_SIGN       - return a value indicating the sign of time()



 2.8 Machine Level Interface
 ===========================

 peek2s          - read 2-byte signed values from memory

 peek2u          - read 2-byte unsigned values from memory

 poke2           - write 2-byte values into memory

 bin             - convert an atom or sequence to binary string

 oct             - convert an atom or sequence to octal string

 dec             - convert an atom or sequence to decimal string

 hex             - convert an atom or sequence to hexadecimal string

 int             - convert a string or sequence to an atom

 signed          - convert an atom or sequence to signed number

 unsigned        - convert an atom or sequence to unsigned number

 range_per_bits  - return range of numbers per bits

 crash           - specify a message to be printed and crash your program



 2.9 Misc
 ========

 iif             - return a value according to specified condition




		   3. Alphabetical Listing of all Routines



 -----------------------------------<abs>------------------------------------

 Syntax:      include machine2.e
	      x2 = abs(x1)

 Description: Return the absolute value of x1.

 Comments:    This function may be applied to an atom or to all elements of a
	      sequence.

 Example:

	      y = abs({0.5, -1.6, 9.99, -100, 0})
	      -- y is {0.5, 1.6, 9.99, 100, 0}


 See Also:    fix, sign, unsigned
	      Euphoria 3.1.1: floor


 -----------------------------------<bin>------------------------------------

 Syntax:      include machine2.e
	      s = bin(x)

 Description: Convert an atom or sequence to binary string. Negative numbers
	      are returned in two's complement, so -1 will return as
	      "0b11111111111111111111111111111111" (#FFFFFFFF). The fractional
	      part of x is truncated.

 Comments:    x must be representable as 32-bit number, either signed or
	      unsigned.

 Example:

	      s = bin(177)
	      -- s is "0b10110001"

	      s = bin({59, -59})
	      -- s is {"0b111011", "0b11111111111111111111111111000101"}


 See Also:    oct, dec, hex, int, dwords
	      Euphoria 3.1.1: int_to_bits, sprintf, and_bits


 ---------------------------------<boolean>----------------------------------

 Syntax:      include machine2.e
	      i = boolean(x)

 Description: Return 1 if x is 0 (false) or 1 (true). Otherwise return 0.

 Comments:    This serves to define the boolean type. You can also call it
	      like an ordinary function to determine if an object is a boolean.

 Example 1:

	      boolean z
	      z = 1


 Example 2:

	      if boolean(y) then
		  puts(SCREEN, "y is 0 or 1")
	      end if


 See Also:    dwords, byte_string, string, FALSE, TRUE, iif
	      Euphoria 3.1.1: integer, atom, sequence


 ---------------------------------<bsearch>----------------------------------

 Syntax:      include machine2.e
	      i = bsearch(x, s)

 Description: Find x as an element of s. Sequence s must be sorted in ascending
  	      order. If successful, return the index of the element of s that
  	      matches. If unsuccessful return the index of the element of s
  	      that x would have, if inserted now, as a negative number.

 Comments:    bsearch() is using a fast binary search algorithm which is useful
              for finding a record in a large associative array, i.e. a map or
              a dictionary.

	      i may or may not point to the first match if the element x
	      appears more then once in s.

	      bsearch() is faster then find() for lookup in a large sequence.

 Example 1:

	      i = bsearch(100, {1, 2, 3, 4, 5, 6, 100, 105, 900})
	      -- i is 7


 Example 2:

	      s = {"ab", "dc", "qt"}

	      i = bsearch("de", s)
	      -- i is -3 -- i.e. index 3 if s was {"ab", "dc", "de", "qt"}


 Example 3:

	      -- using bsearch() to get value from an associative array (a map)

	      constant KEYS = 1, VALUES = 2
	      s = {
		  {"basic", "c", "euphoria"}, -- sorted keys
		  {"simple", "hard", "rapid"} -- values
	      }

	      i = bsearch("euphoria", s[KEYS])
	      -- i is 3 -- i.e. the value is s[VALUES][3], "rapid"


 See Also:    hash
              Euphoria 3.1.1: find, match, compare, sort


 -------------------------------<byte_string>--------------------------------

 Syntax:      include machine2.e
	      i = byte_string(x)

 Description: Return 1 if x is an unsigned byte-string, i.e. a flat sequence
 	      without any (sub)sequences within it, which is made of numbers
 	      in the range 0 to 255. Otherwise return 0.

 Comments:    This serves to define the byte_string type. You can also call
 	      it like an ordinary function to determine if an object is a
 	      byte_string.

 Example 1:

	      byte_string z
	      z = {0, 2.5, 103}


 Example 2:

	      z = {65.1, 66.9, 67}

	      if byte_string(z) then
		  puts(SCREEN, z & " is a byte-string!")
	      end if


 Example 3:

	      i = byte_string({1, 2.5, 3, ""})   -- i is 0

	      i = byte_string({1, 2.5, 3, 260})  -- i is 0


 See Also:    string, dwords, boolean, flatten, EMPTY
	      Euphoria 3.1.1: sequence, atom


 --------------------------------<checksum>----------------------------------

 Syntax:      include machine2.e
	      a = checksum(fn, i)

 Description: Calculate the checksum value of data from file or device fn.
 	      When i is 0 (false) a 16-bit integer is returned. When i is 1
 	      (true) a 32-bit atom is returned.

 Comments:    fn must be a file-number which was opened in binary mode for
 	      reading, for example: fn = open(filename, "rb").
 	      Currently, files up to 2 Gb in size can be handled.

	      Checksum is useful for verifying data integrity, i.e. for
 	      verifying that data is not corrupted or accidentally modified, by
 	      saving an old checksum value and later comparing it to a new
 	      checksum value of the same data.

 	      It's much faster to calculate a 16-bit checksum value, yet 32-bit
 	      checksum value is a bit more reliable, which means that there is
 	      a lower probability to return the same checksum value for a
 	      different data.

	      checksum() is using the DJB hash algorithm by Daniel J. Bernstein.
	      It's not suitable for cryptography.

 Example:

	      fn = open("machine2.doc", "rb") -- open binary file for reading
	      if fn = -1 then
		  puts(1, "\nCannot open the file for reading!\n")
	      else
		  cs = checksum(fn, 0) -- calculate a 16-bit checksum value
		  close(fn)
		  printf(1, "\nThe checksum is: %.0f\n", cs)
	      end if


 See Also:    hash, encode, sencode


 -----------------------------<clear_keyboard>-------------------------------

 Syntax:      include machine2.e
	      clear_keyboard()

 Description: Clear the keyboard buffer.

 Comments:    The operating system can hold a small number of key-hits in its
	      keyboard buffer. clear_keyboard() is useful when you want to
	      discard any old key-hits and let the user input a new key.

 Example:

	      sleep(5) -- press a key -- any key-hit will be discarded

	      clear_keyboard()
	      puts(1, "\nPress 'y' to continue, or any other key to stop: ")
	      key = wait_key()


 See Also:    wait_xkey, get_xkey, pause
	      Euphoria 3.1.1: wait_key, get_key


 ----------------------------------<crash>-----------------------------------

 Syntax:      include machine2.e
	      crash(s)

 Description: Crash your program. s is a string to be printed on the screen.

 Comments:    crash() is useful when there is no actual run-time error, but
	      a programming bug or a critical hardware failure is trapped by
	      your program and you must stop your program from running.
	      Debugging information will still be stored in ex.err. You won't
	      lose any information by doing this.

	      s will be passed to crash_message(). You can leave s empty, "",
	      if you don't want to print any message, or if you already called
	      crash_message() before.

	      if crash_routine() is specified then control is passed to that
	      routine immediately after crash().

 Example:

	      crash("Bad argument in function get_version().\n")


 See Also:    Euphoria 3.1.1: crash_message, crash_routine, crash_file, abort


 -----------------------------------<dec>------------------------------------

 Syntax:      include machine2.e
	      s = dec(x)

 Description: Convert an atom or sequence to unsigned decimal string. Negative
	      numbers are returned in two's complement, so -1 will return as
	      "4294967295" (#FFFFFFFF). The fractional part of x is truncated.

 Comments:    x must be representable as 32-bit number, either signed or
	      unsigned.

 Example:

	      s = dec(177)
	      -- s is "177"

	      s = dec({59, -59})
	      -- s is {"59", "4294967237"}


 See Also:    bin, oct, hex, int, dwords
	      Euphoria 3.1.1: sprintf, value


 ----------------------------------<delay>-----------------------------------

 Syntax:      include machine2.e
	      delay(a)

 Description: Suspend execution for a 0.01 seconds.

 Comments:    On delay your program will go into a busy loop for a 0.01
	      seconds, during which time other processes may run, but they
	      will compete with your process for the CPU.

	      Under DOS32 you can improve the time() resolution by calling
	      tick_rate(100). On WIN32 and Linux/FreeBSD the time() resolution
	      is about 0.01 second.

 Example 1:

	      tick_rate(100)            -- set 100 ticks/second for DOS32
	      puts(1, "Waiting 0.5 second...\n")
	      delay(50)                 -- 50 * 0.01 seconds is 0.5 second
	      puts(1, "Done.\n")


 Example 2:

	      tick_rate(100)            -- set 100 ticks/second for DOS32
	      for char = 33 to 126 do
		 puts(1, char)
		 delay(char / 5)
	      end for


 See Also:    pause, TIME_SIGN
	      Euphoria 3.1.1: sleep, tick_rate, time


 ---------------------------------<dwords>-----------------------------------

 Syntax:      include machine2.e
	      i = dwords(x)

 Description: Return 1 if x is an atom or a sequence of atoms in the range
	      -2147483648 to +4294967295 (fractional numbers allowed).
	      Otherwise return 0.

 Comments:    This serves to define the dwords type. You can also call it like
	      an ordinary function to determine if an object is a dwords
	      (DWORD is a 32-bit number, either signed or unsigned).

	      Some functions, especially bitwise logical operators such as
	      and_bits(), are limited to 32-bit numbers. You can find out if
	      an argument is a 32-bit number by calling dwords().

 Example 1:

	      dwords y, z
	      y = -1
	      z = {#FF000002, y}


 Example 2:

	      x1 = -1.5
	      x2 = #FFFFFFFF

	      if dwords({x1, x2}) then
		  puts(1, "x1 and x2 are 32-bit numbers.")
	      end if


 See Also:    byte_string, boolean, fix, signed, unsigned, range_per_bits
	      Euphoria 3.1.1: atom, sequence, floor


 ----------------------------------<empty>-----------------------------------

 Syntax:      include machine2.e
	      EMPTY

 Description: EMPTY ({}) has been defined as a global constant.

 Example:

	      x = EMPTY  -- x is {}


 See Also:    flatten, FALSE
	      Euphoria 3.1.1: sequence


 ---------------------------------<encode>-----------------------------------

 Syntax:      include machine2.e
	      i = encode(st1, st2, s)

 Description: Encode or decode the data of file or device st1. st2 is the new
 	      file to create. s is a string sequence, a key (password) which is
 	      made of any integer type numbers. encode() is used for both
 	      encoding or decoding an already encoded file. An error status is
 	      returned, where error status can be one of:

 	      	0 -- success
 	      	1 -- can't open file or device st1 for read
 	      	2 -- can't open file or device st2 for write
 	      	3 -- an empty key (password)

 Comments:    Both files, st1 and st2 are opened in binary mode. File st1 is
  	      opened for reading and it must be exist. File st2 is opened for
  	      writing, if file st2 is already exist it will be overwritten, if
 	      not, then it will be created. Currently, files up to 2 Gb in size
 	      can be handled.

 	      An encoded file is a binary file (not text file), which you
 	      *must* open, copy or transfer in binary mode, otherwise the file
 	      might be modified by the operating system.

 	      Decoding an encoded file is possible *only* by using the exact
 	      key (password) that was used to encode that file!

              encode() is useful for encrypting data, it provides additional
	      layer of safety for storing sensitive user data. Using a long
	      key, s, with different characters, provides a much safer
	      encryption. Examples for a strong key:
	      "@!I'll do my homework NOW!@18"
	        or...
	      {-13454, 0, 93433, 190, 933444, 14, -452, -2243, 97442, -337844}.

	      Encoding (encrypting) of data is commonly used by spreadsheets,
	      editors, compression utilities, operating industrial machines,
	      precise scientific calculations, and in many other areas which
	      require safety. Using both encode() and checksum() provides even
	      higher safety.

	      encode() is using the DJB hash algorithm by Daniel J. Bernstein.
	      It may or *may not* be suitable for advanced cryptography. The
	      author of encode() algorithm is just me (Shian Lee).

 Example:

	      -- encode and decode an existing file.
	      -- you must encode and decode a file using the exact same key.
	      -- you can browse the encoded file using a binary-files viewer.

	      sequence source_file, encoded_file, key
	      integer status

	      source_file = "machine2.doc"
	      encoded_file = "@achine2.doc"

	      key = "*.Just on time Bro!.*"

	      puts(1, "encoding '" & source_file & "'...\n")
	      status = encode(source_file, encoded_file, key)
	      if status then
	      	  printf(1, "Error #%d !\n", status)
	      	  abort(1)
	      end if

	      puts(1, "decoding '" & encoded_file & "'...\n")
	      status = encode(encoded_file, source_file, key)
	      if status then
	      	  printf(1, "Error #%d !\n", status)
	      	  abort(1)
	      end if

	      puts(1, "Done.\n")


 See Also:    sencode, checksum, hash, pack_bits
              Euphoria 3.1.1: xor_bits, atom_to_float64


 ---------------------------------<eqv_bits>---------------------------------

 Syntax:      include machine2.e
	      x3 = eqv_bits(x1, x2)

 Description: Perform the logical EQV (Equivalence) operation on corresponding
	      bits in x1 and x2. A bit in x3 will be 1 only if the
	      corresponding bits in x1 and x2 are both 1 or both 0.

 Comments:    The arguments to this function may be atoms or sequences. The
	      rules for operations on sequences apply.

	      The arguments must be representable as 32-bit numbers, either
	      signed or unsigned.

	      If you intend to manipulate full 32-bit values, you should
	      declare your variables as atom, rather than integer. Euphoria's
	      integer type is limited to 31-bits.

	      Results are treated as signed numbers. They will be negative when
	      the highest-order bit is 1.

	      To understand the binary representation of a number you should
	      display it in binary or hexadecimal notation, with bin() or
	      hex().

 Example 1:

	      a = eqv_bits(#0F0F0000, #12345678)
	      -- a is #E2C4A987


 Example 2:

	      a = eqv_bits(#FF, {#123456, #876543, #2211})
	      -- a is {#FFEDCB56, #FF789A43, #FFFFDD11}


 Example 3:

	      a = eqv_bits(#FFFFFFFF, #FFFFFFFF)
	      -- a is -1
	      -- Note that #FFFFFFFF is a positive number,
	      -- but the result of a bitwise logical operation is interpreted
	      -- as a signed 32-bit number, so it's negative.


 See Also:    imp_bits, bin, hex, shl_bits
	      Euphoria 3.1.1: and_bits, int_to_bits, sprintf


 -----------------------------------<false>----------------------------------

 Syntax:      include machine2.e
	      FALSE

 Description: FALSE (0) has been defined as a global constant.

 Example:

	      x = FALSE  -- x is 0


 See Also:    TRUE, boolean, bin, EMPTY


 ------------------------------------<fix>-----------------------------------

 Syntax:      include machine2.e
	      x2 = fix(x1)

 Description: Return the integer portion of x1. (Truncate the fractional part).

 Comments:    This function may be applied to an atom or to all elements of a
	      sequence.

	      fix() does not round the number.

 Example:

	      y = fix({0.5, -1.6, 9.99, 100})
	      -- y is {0, -1, 9, 100}


 See Also:    abs, sign
	      Euphoria 3.1.1: floor, remainder, or_bits


 -----------------------------------<flat>-----------------------------------

 Syntax:      include machine2.e
	      s2 = flat(s1)

 Description: Flatten the elements of sequence s1.

 Comments:    A new sequence is created without any (sub)sequences within it.

	      flat() is faster and more efficient then flatten() and should be
	      used instead of flatten() wherever you don't need to specify an
	      end-of-string marker.

 Example:

	      s = flat({})                 -- {}

	      s = flat({99})               -- {99}

	      s = flat({1,3,5,7})          -- {1,3,5,7}

	      s = flat({{1,2,3}, {4,5,6}}) -- {1,2,3,4,5,6}

	      s = flat({0,{1},2,{{3,4,{5.5,6}},{{7,8}}},9,10,{11}})
		-- {0,1,2,3,4,5.5,6,7,8,9,10,11}


 See Also:    flatten, string, EMPTY
	      Euphoria 3.1.1: puts, sequence, append


 ---------------------------------<flatten>----------------------------------

 Syntax:      include machine2.e
	      s2 = flatten(s1, st)

 Description: Flatten the elements of sequence s1. st is a single atom or a
	      sequence of characters for an end-of-string marker.

 Comments:    A new sequence is created without any (sub)sequences within it.

 Example 1:

	      s = flatten({1,3,5,7}, "")          -- {1,3,5,7}


 Example 2:

	      s = flatten({{1,2,3}, {4,5,6}}, "") -- {1,2,3,4,5,6}

	      s = flatten({{1,2,3}, {4,5,6}}, -1) -- {1,2,3,-1,4,5,6,-1}

	      s = flatten({{1,2,3}, {4,5,6}}, "$!")
		-- {1,2,3,36,33,4,5,6,36,33}


 Example 3:

	      s = flatten({99}, "")               -- {99}


 Example 4:

	      s = flatten({}, "")                 -- {}


 Example 5:

	      s = flatten({0,{1},2,{{3,4,{5.5,6}},{{7,8}}},9,10,{11}}, "")
		-- {0,1,2,3,4,5.5,6,7,8,9,10,11}

	      s = flatten({0,{1},2,{{3,4,{5.5,6}},{{7,8}}},9,10,{11}}, -1)
		-- {0,-1,1,-1,2,-1,3,4,-1,5.5,6,-1,7,8,-1,9,10,-1,11,-1}


 See Also:    flat, string, sum, putx, EMPTY
	      Euphoria 3.1.1: append, prepend, repeat, reverse


 ---------------------------------<get_bit>----------------------------------

 Syntax:      include machine2.e
	      x2 = get_bit(x1, i)

 Description: Return the result of getting bit-i from x1. x2 will be 0 if
	      bit-i is 0 (false). x2 will be non-zero if bit-i is 1 (true).
	      i must be in the range 1 to 33.

 Comments:    x1 may be an atom or a sequence. The rules for operations on
	      sequences apply.

	      x1 must be representable as 32-bit numbers, either signed or
	      unsigned.

	      If you intend to manipulate full 32-bit values, you should
	      declare your variables as atom, rather than integer. Euphoria's
	      integer type is limited to 31-bits.

	      Results are treated as signed numbers. They will be negative when
	      the highest-order bit is 1.

 Example 1:

	      a = get_bit(#FF123400, 32)
	      -- a is -2147483648 i.e. #80000000 interpreted as negative number


 Example 2:

	      a = get_bit({#123456, #876543, #2211}, 5)
	      -- a is {#10, #0, #10}


 See Also:    set_bit, shr_bits, unpack_bits, bin, hex
	      Euphoria 3.1.1: and_bits, or_bits, int_to_bits


 ---------------------------------<get_xkey>---------------------------------

 Syntax:      include machine2.e
	      x = get_xkey()

 Description: Return the key that was pressed by the user, without waiting.
	      Return -1 if no key was pressed. Special codes are returned for
	      the function keys, arrow keys etc.

 Comments:    Because either a string-sequence or an atom might be returned,
	      you should probably assign the result to a variable declared as
	      object.

	      The operating system can hold a small number of key-hits in its
	      keyboard buffer. get_xkey() will return the next one from the
	      buffer, or -1 if the buffer is empty.

	      get_xkey() is useful for programs that run in Linux terminal or
	      in any other environment that may return a sequence of atoms for
	      a single key-hit (escape sequence, UTF-8 character, etc).

	      Run the xkey.ex program to see what key code is generated for
	      each key on your keyboard.

 See Also:    wait_xkey, clear_keyboard, pause
	      Euphoria 3.1.1: get_key, wait_key, getc


 -----------------------------------<hash>-----------------------------------

 Syntax:      include machine2.e
	      a2 = hash(x, a1)

 Description: Calculate the hash value of x. a2 will be a natural number in the
 	      range 1 to the absolute value of a1.

 Comments:    You can use hash() to create a hash table (also known as map,
 	      associative array, dictionary), and to calculate a checksum for
 	      verifying data integrity of an object.

 	      When creating a hash table, the hash value returned by hash() is
 	      used as an index of a record in the hash table, e.g. for
 	      a hash table of 1000 records: record_number = hash(x, 1000).
	      See also the example program demo\hash.ex.

	      It's much faster to calculate a hash value when a1 is a 16-bit
 	      integer, i.e. smaller then 65536. If a1 is fractional, e.g.
 	      1000.4, the calculation will be slower. If a1 is 0 your program
              will abort with a run-time error message.

	      hash() is using the DJB algorithm by Daniel J. Bernstein, which
	      is a short algorithm, yet fast and gives a good distribution for
	      a hash table. hash() is not suitable for cryptography.

 Example:

	      n = hash("ABcdefg", 1000) -- n is 498

	      n = hash("BAcdefg", 1000) -- n is 74


	      n = hash(-122, 1000) -- n is 452

	      n = hash(-123, 1000) -- n is 451


	      n = hash({1.5, 1.5}, #FFFF) -- n is 27346

	      n = hash({1.5, 1.6}, #FFFF) -- n is 27346

	      n = hash({1.6, 1.6}, #FFFF) -- n is 27349


	      n = hash({1, {-19.4, 0}, 30}, #FFFFFFFF) -- n is 386733994

	      n = hash({1, {-19.4, 0}, 30, {}}, #FFFFFFFF) -- n is 4172292562


 See Also:    checksum, bsearch
	      Euphoria 3.1.1 example program: demo\hash.ex


 -----------------------------------<hex>------------------------------------

 Syntax:      include machine2.e
	      s = hex(x)

 Description: Convert an atom or sequence to hexadecimal string. Negative
	      numbers are returned in two's complement, so -1 will return as
	      "#FFFFFFFF". The fractional part of x is truncated.

 Comments:    x must be representable as 32-bit number, either signed or
	      unsigned.

 Example:

	      s = hex(177)
	      -- s is "#B1"

	      s = hex({59, -59})
	      -- s is {"#3B", "#FFFFFFC5"}


 See Also:    bin, oct, dec, int, dwords
	      Euphoria 3.1.1: sprintf, value, and_bits


 -----------------------------------<iif>------------------------------------

 Syntax:      include machine2.e
	      x3 = iif(a, x1, x2)

 Description: Test the condition a. If a is non-zero (true) then return x1.
	      If a is 0 (false) then return x2.

 Comments:    A typical use for iif() is to assign a value to constant, or
	      to make a long code shorter and more readable.

	      iif() is slower then an if statement, and both arguments x1 and
	      x2 are *always* evaluated, so it's not recommended to use iif()
	      where speed and performances are your first priority.

 Example:

	      constant SLASH = iif(platform() = LINUX, '/', '\\')


 See Also:    Euphoria 3.1.1: REFMAN.DOC, 2.5.3 if statement


 --------------------------------<imp_bits>----------------------------------

 Syntax:      include machine2.e
	      x3 = imp_bits(x1, x2)

 Description: Perform the logical IMP (Implication) operation on corresponding
	      bits in x1 and x2. A bit in x3 will be 1 only if the
	      corresponding bits in x1 and x2 are both 1 or both 0, or when
	      corresponding bits in x1 are 0 and in x2 are 1.

 Comments:    The arguments to this function may be atoms or sequences. The
	      rules for operations on sequences apply.

	      The arguments must be representable as 32-bit numbers, either
	      signed or unsigned.

	      If you intend to manipulate full 32-bit values, you should
	      declare your variables as atom, rather than integer. Euphoria's
	      integer type is limited to 31-bits.

	      Results are treated as signed numbers. They will be negative when
	      the highest-order bit is 1.


	      A summery of bitwise logical operations, and a truth table:

		not_bits()     NOT - Bit-wise complement
		and_bits()     AND - Conjunction
		or_bits()      OR  - Disjunction (inclusive OR)
		xor_bits()     XOR - Exclusive OR
		eqv_bits()     EQV - Equivalence
		imp_bits()     IMP - Implication

		x1  x2  NOT(x1)  AND  OR   XOR  EQV  IMP
		--  --  -------  ---  ---  ---  ---  ---
		1   1   0        1    1    0    1    1
		1   0   0        0    1    1    0    0
		0   1   1        0    1    1    0    1
		0   0   1        0    0    0    1    1

 Example 1:

	      a = imp_bits(#0F0F0000, #12345678)
	      -- a is #F2F4FFFF


 Example 2:

	      a = imp_bits(#FF, {#123456, #876543, #2211})
	      -- a is {#FFFFFF56, #FFFFFF43, #FFFFFF11}


 See Also:    eqv_bits, bin, hex, shl_bits
	      Euphoria 3.1.1: and_bits, int_to_bits, sprintf


 -----------------------------------<int>------------------------------------

 Syntax:      include machine2.e
	      x = int(s)

 Description: Convert a string or sequence to unsigned atom. s may be the
	      result of a previous call to bin(), oct(), dec() or hex(); or a
	      string representation of an unsigned atom.

	      s must start with a prefix (except for decimal representation);
	      possible prefixes are:

	      "0b" - binary representation (digits 0-1)
	      "0o" - octal representation (digits 0-7)
	      "0x" or "#" - hexadecimal representation (digits 0-9,A-F)

 Comments:    Numbers returned by int() can be larger then 32-bits.

 Example:

	      a = int("177")
	      -- a is 177

	      a = int({"59", "-59", {" 7", "7z"}})
	      -- a is {59, 0, {0, 0}} -- invalid characters return 0

	      a = int("0b11110000")
	      -- a is 240

	      a = int("0o123456")
	      -- a is 42798

	      a = int({"0xFF35E", "#FF35E"})
	      -- a is {1045342, 1045342}

	      a = int("#1FFFFFFFF")
	      -- a is 8589934591 -- a is larger then 32-bit


 See Also:    bin, oct, dec, hex, dwords, signed
	      Euphoria 3.1.1: value, sprintf, bits_to_int


 ---------------------------------<nsign>------------------------------------

 Syntax:      include machine2.e
	      x2 = nsign(x1)

 Description: Return a value indicating the sign of x1 (1 if x1 is positive,
	      -1 if it is zero, or -1 if it is negative).

 Comments:    This function may be applied to an atom or to all elements of a
	      sequence.

 Example:

	      y = nsign({0.5, -1.6, 9.99, -100, 0})
	      -- y is {1, -1, 1, -1, -1}


 See Also:    sign, psign, zsign, abs, unsigned, signed


 -----------------------------------<oct>------------------------------------

 Syntax:      include machine2.e
	      s = oct(x)

 Description: Convert an atom or sequence to octal string. Negative numbers
	      are returned in two's complement, so -1 will return as
	      "0o37777777777" (#FFFFFFFF). The fractional part of x is
	      truncated.

 Comments:    x must be representable as 32-bit number, either signed or
	      unsigned.

 Example:

	      s = oct(177)
	      -- s is "0o261"

	      s = oct({59, -59})
	      -- s is {"0o73", "0o37777777705"}


 See Also:    bin, dec, hex, int, dwords
	      Euphoria 3.1.1: sprintf


 -------------------------------<pack_bits>----------------------------------

 Syntax:      include machine2.e
	      a = pack_bits(s1, s2)

 Description: Convert a sequence of numbers s1 to an integer. s2 defines the
	      size (in bits) for packing each number in s1, respectively.
	      s2 values must be in the range 0 to 32; You can also use negative
	      values (0 to -32) to unpack (and pack) signed numbers. The
	      (absolute) sum of s2 must be in the range 0 to 32.

 Comments:    s1 must be representable as 32-bit numbers, either signed or
	      unsigned.

	      If you intend to manipulate full 32-bit values, you should
	      declare your variables as atom, rather than integer. Euphoria's
	      integer type is limited to 31-bits.

	      Result is treated as signed number. It will be negative when the
	      highest-order bit is 1.

	      pack_bits()/unpack_bits() are useful for packing small numbers
	      into integer. e.g. for packing date() sequence into integer.

	      range_per_bits() will tell you how many bits are neccessary for
	      packing a signed or unsigned number.

 Example 1:

	      ints = {#FA3, #8, #12}
	      bits = {  12,  4,   8}    -- 12-bits/#FA3, 4-bits/#8, 8-bits/#12

	      i = pack_bits(ints, bits) -- i is 16398354 (#FA3812)
	      s = unpack_bits(i, bits)  -- s is {4003, 8, 18}; {#FA3, #8, #12}


 Example 2:

	      ints = {#40000000, #1}
	      bits = {       31,  1}    -- 31-bits/#40000000, 1-bits/#1

	      a = pack_bits(ints, bits) -- a is -2147483647 (#80000001)
	      s = unpack_bits(a, bits)  -- s is {1073741824,1};{#40000000, #1}


 Example 3:

	      ints = {-2000, 8, 18, -15}
	      bits = {  -12, 4, -8,  -5} -- 12-bits/-2000 (signed),
					 --  4-bits/8     (unsigned),
					 --  8-bits/18    (signed),
					 --  5-bits/-15   (signed)

	      i = pack_bits(ints, bits)  -- i is 274793041
	      s = unpack_bits(i, bits)   -- s is {-2000, 8, 18, -15}


 Example 4:

	      ints = {-1073741824, 1}
	      bits = {      -31,  -1}    -- 31-bits/-1073741824 (signed),
					 --  1-bits/1 (signed)

	      a = pack_bits(ints, bits)  -- a is -2147483647 (#80000001)
	      s = unpack_bits(a, bits)   -- s is {-1073741824, -1}
					 -- (signed range for 1-bits is -1..0)


 Example 5:

	      -- pack current date() into 32-bit atom

	      ints = date()         -- {year,month,day,hour,minute,second}
	      ints = ints[1..6]     -- ints is {117,1,7,15,8,27} for demo

	      bits = {7,4,5,5,6,5}  -- 7-bits/year, 4-bits/month, 5-bits/day,
				    -- 5-bits/hour, 6-bits/minute, 5-bits/sec

	      ints[6] /= 2          -- 2-second increments (0-29) saves 1 bit

	      a = pack_bits(ints, bits) -- a is -366511859 (#EA27790D)
	      s = unpack_bits(a, bits)

	      s[6] *= 2             -- (2-second increments)

		-- s is {117,1,7,15,8,26} -- (year is since 1900: 1900+117)


 See Also:    unpack_bits, range_per_bits, shl_bits, bin, hex, sum
	      Euphoria 3.1.1: and_bits, int_to_bits, bits_to_int


 ----------------------------------<pause>-----------------------------------

 Syntax:      include machine2.e
	      pause()

 Description: Suspend execution until user press a key.

 Comments:    On multi-tasking systems like Windows or Linux/FreeBSD, pause()
	      lets the operating system do other useful work while your
	      program is waiting for the user to press a key.

 Example 1:

	      puts(1, "Press few keys fast...\n\n")
	      sleep(2)

	      -- pause() clears previous keys pressed by the user
	      puts(1, "Program paused, press any key to continue...\n\n")
	      pause()
	      puts(1, "Program continue.\n")


 Example 2:

	      -- pause() is useful for debugging a program
	      for row = 1 to 200 do
		 printf(1, "This is line number %d\n", row)
		 if remainder(row, 20) = 0 then
		    pause()     -- pause to see what's on the screen...
		 end if
	      end for


 See Also:    delay
	      Euphoria 3.1.1: wait_key, sleep


 ---------------------------------<peek2s>-----------------------------------

 Syntax:      include machine2.e
	      a2 = peek2s(a1)
	      or ...
	      s = peek2s({a1, i})

 Description: Return a 2-byte (16-bit) signed value in the range -32768 to
	      +32767 from machine address a1, or return a sequence containing
	      i consecutive 2-byte signed values starting at address a1 in
	      memory.

 Comments:    Since machine addresses are 32-bit numbers, they can be too large
	      for Euphoria's integer type. Variables that hold an address
	      should therefore be declared as atoms.

	      It is faster to read several 2-byte values at once using the
	      second form of peek2s() than it is to read one 2-byte value at a
	      time in a loop.

	      Remember that peek2s() takes just one argument, which in the
	      second form is actually a 2-element sequence.

	      peek2s() is not as fast as peek() or peek4s().

 Example:     The following are equivalent:


	      -- method 1
	      s = {peek2s(100), peek2s(102), peek2s(104), peek2s(106)}

	      -- method 2
	      s = peek2s({100, 4})


 See Also:    peek2u, poke2
	      Euphoria 3.1.1: peek4s, peek, poke4


 ---------------------------------<peek2u>-----------------------------------

 Syntax:      include machine2.e
	      a2 = peek2u(a1)
	      or ...
	      s = peek2u({a1, i})

 Description: Return a 2-byte (16-bit) unsigned value in the range 0 to
	      65535 from machine address a1, or return a sequence containing
	      i consecutive 2-byte unsigned values starting at address a1 in
	      memory.

 Comments:    Since machine addresses are 32-bit numbers, they can be too large
	      for Euphoria's integer type. Variables that hold an address
	      should therefore be declared as atoms.

	      It is faster to read several 2-byte values at once using the
	      second form of peek2u() than it is to read one 2-byte value at a
	      time in a loop.

	      Remember that peek2u() takes just one argument, which in the
	      second form is actually a 2-element sequence.

	      peek2u() is not as fast as peek() or peek4u().

 Example:     The following are equivalent:


	      -- method 1
	      s = {peek2u(100), peek2u(102), peek2u(104), peek2u(106)}

	      -- method 2
	      s = peek2u({100, 4})


 See Also:    peek2s, poke2
	      Euphoria 3.1.1: peek4u, peek, poke4


 ----------------------------------<poke2>-----------------------------------

 Syntax:      include machine2.e
	      poke2(a, x)

 Description: If x is an atom, write a 2-byte (16-bit) value to memory address
	      a.

	      If x is a sequence, write a sequence of 2-byte values to
	      consecutive memory locations starting at location a.

 Comments:    The value or values to be stored must not exceed 16-bits in size.


	      It is faster to write several 2-byte values at once by poking a
	      sequence of values, than it is to write one 2-byte value at a
	      time in a loop.

	      The 2-byte values to be stored can be negative or positive. You
	      can read them back with either peek2s() or peek2u().

	      poke2() is not as fast as poke() or poke4().

 Example:

	      a = allocate(100)   -- allocate 100 bytes in memory

	      -- poke one 2-byte value at a time:
	      poke2(a, 13017)
	      poke2(a+2, #FF00)
	      poke2(a+4, -12345)

	      -- poke 3 2-byte values at once:
	      poke2(a, {13017, #FF00, -12345})


 See Also:    peek2s, peek2u
	      Euphoria 3.1.1: poke, poke4, peek, peek4u, peek4s


 ----------------------------------<psign>-----------------------------------

 Syntax:      include machine2.e
	      x2 = psign(x1)

 Description: Return a value indicating the sign of x1 (1 if x1 is positive,
	      1 if it is zero, or -1 if it is negative).

 Comments:    This function may be applied to an atom or to all elements of a
	      sequence.

 Example:

	      y = psign({0.5, -1.6, 9.99, -100, 0})
	      -- y is {1, -1, 1, -1, 1}


 See Also:    sign, nsign, zsign, abs, unsigned, signed


 -----------------------------------<putx>-----------------------------------

 Syntax:      include machine2.e
	      putx(fn, x, st)

 Description: This is just a shorthand way of saying: puts(fn, flatten(x, st))
	      - i.e. output, to file or device fn, object x.
	      st is a single byte (atom) or a sequence of bytes for an
	      end-of-string marker (Typically a new-line character, '\n').

 Comments:    putx() is not as fast and efficient as puts().

 Example 1:

	      putx(1, {"First name:", " Last name:"}, '\n')


 Example 2:

	      putx(out, 'A', "")  -- the single byte 65 will be sent to out


 Example 3:

	      x = {{"http",':','/','/'},"www",'.',{{"RapidEuphoria"},'.',"com"}}
	      putx(1, x, "")


 Example 4:

	      x = bin({#F, #FF, #FFFF, #FFFFFFFF})
	      putx(1, x, ",\n")


 See Also:    get_xkey, pause, flat, flatten
	      Euphoria 3.1.1: puts, print, printf, gets, open


 ---------------------------<range_per_bits>---------------------------------

 Syntax:      include machine2.e
	      s = range_per_bits(x)

 Description: Return a sequence of values describing the range of numbers per
	      x bits:
	      {minimum value of a signed number,
	      maximum value of a signed number,
	      maximum value of an unsigned number}

	      x must be in the range 0 to 32.

 Comments:    This routine makes it easy for you to find out how many bits
	      are neccessary for packing a signed or an unsigned number with
	      pack_bits().

	      The minimum value of an unsigned number is always 0.

 Example 1:

	      s = range_per_bits(32)
	      -- s is {-2147483648, 2147483647, 4294967295}
	      --  i.e. {-#80000000, #7FFFFFFF, #FFFFFFFF}


 Example 2:

	      s = range_per_bits({4, 8, 16, 31})
	      -- s is {
	      --        {-8, 7, 15},
	      --        {-128, 127, 255},
	      --        {-32768, 32767, 65535},
	      --        {-1073741824, 1073741823, 2147483647}
	      --      }


 See Also:    signed, unsigned, pack_bits, peek2s
	      Euphoria 3.1.1: integer, peek4s


 --------------------------------<rol_bits>----------------------------------

 Syntax:      include machine2.e
	      x2 = rol_bits(x1, i)

 Description: Return the result of rotating the bits of x1 left i number of
	      bits. i must be in the range 0 to 32.

 Comments:    x1 may be an atom or a sequence. The rules for operations on
	      sequences apply.

	      x1 must be representable as 32-bit numbers, either signed or
	      unsigned.

	      If you intend to manipulate full 32-bit values, you should
	      declare your variables as atom, rather than integer. Euphoria's
	      integer type is limited to 31-bits.

	      Results are treated as signed numbers. They will be negative when
	      the highest-order bit is 1.

 Example 1:

	      a = rol_bits(#FF123400, 8)
	      -- a is 305398015 (i.e. #123400FF interpreted as positive number)


 Example 2:

	      a = rol_bits({#123456, #876543, #2211}, 16)
	      -- a is {#34560012, #65430087, #22110000}


 See Also:    ror_bits, shl_bits, set_bit, pack_bits, bin, hex
	      Euphoria 3.1.1: and_bits, int_to_bits, bits_to_int


 -------------------------------<ror_bits>-----------------------------------

 Syntax:      include machine2.e
	      x2 = ror_bits(x1, i)

 Description: Return the result of rotating the bits of x1 right i number of
	      bits. i must be in the range 0 to 32.

 Comments:    x1 may be an atom or a sequence. The rules for operations on
	      sequences apply.

	      x1 must be representable as 32-bit numbers, either signed or
	      unsigned.

	      If you intend to manipulate full 32-bit values, you should
	      declare your variables as atom, rather than integer. Euphoria's
	      integer type is limited to 31-bits.

	      Results are treated as signed numbers. They will be negative when
	      the highest-order bit is 1.

 Example 1:

	      a = ror_bits(#FF123400, 8)
	      -- a is 16716340 (i.e. #FF1234 interpreted as a positive number)


 Example 2:

	      a = ror_bits({#123456, #876543, #2211}, 24)
	      -- a is {#12345600, #87654300, #221100}


 See Also:    rol_bits, shr_bits, set_bit, pack_bits, bin, hex
	      Euphoria 3.1.1: and_bits, int_to_bits, bits_to_int


 --------------------------------<sencode>-----------------------------------

 Syntax:      include machine2.e
	      s3 = sencode(s1, s2)

 Description: Encode or decode the data of (8-bit) byte-string s1. s2 is
 	      a string sequence, a key (password) which is made of any integer
 	      type numbers. The first time you call sencode() the data is
 	      encoded, and s3 will be a (8-bit) byte-string. The second
	      time you call sencode(), using the encoded data and the exact
	      same key, the data is decoded, and s3 will be equal to the
	      original s1 byte-string.

 Comments:    An encoded string sequence may be saved in a binary file (not
              text file), which you *must* open, copy or transfer in binary
	      mode, otherwise the file might be modified by the operating
	      system.

 	      Decoding an encoded string sequence is possible *only* by using
	      the exact key (password) that was used to encode that string!

              sencode() is useful for encrypting data, it provides additional
	      layer of safety for storing sensitive user data. Using a long
	      key, s, with different characters, provides a much safer
	      encryption. Examples for a strong key:
	      "@!I'll do my homework NOW!@18"
	        or...
	      {-13454, 0, 93433, 190, 933444, 14, -452, -2243, 97442, -337844}.

	      Encoding (encrypting) of a byte-string sequence may be useful for
	      hiding data in your executable file. It can also be useful for
	      hiding a specific field in a database; For example, you can hide
	      specific fields in Euphoria Database System (EDS), without the
	      need to encrypt an entire database and make it inaccessible to
	      anyone else.

	      sencode() is typically useful for encoding character strings
	      (unsigned byte-strings in the range 0 to 255) such as "abc" or
	      "\tA nice sunny day!\n".

	      It is also possible to encode an Euphoria object, using sprint()
	      and value(). Notice that in this case atoms are limited to a
	      maximum of 10 significant digits! (see example below).

	      sencode() is using the DJB hash algorithm by Daniel J. Bernstein.
	      It may or *may not* be suitable for advanced cryptography. The
	      author of sencode() algorithm is just me (Shian Lee).

 Example 1:

	      -- encode and decode a byte-string #1

	      sequence key, s, s1, s2

	      key = "x" -- (a single character key is very easy to break...!)

	      s = {0, 0, 0, 0, 0, 0, 0}

	      s1 = sencode(s, key)  -- encode byte-string

	      -- s1 is {236, 127, 44, 66, 39, 152, 116}

	      s2 = sencode(s1, key) -- decode byte-string (using the same key!)

	      ? equal(s, s2) -- 1 = decoded string is identical to source


 Example 2:

	      -- encode and decode a byte-string #2

	      sequence key, s, s1, s2

	      key = "@just on time!@"
	      s = "Back to Square One"

	      s1 = sencode(s, key)  -- encode byte-string

	      -- s1 is {246, 119, 57, 34, 47, 109, 216, 93, 222,
	      --        113, 28, 93, 59, 210, 111, 238, 250, 141}

	      s2 = sencode(s1, key) -- decode byte-string (using the same key!)

	      ? equal(s, s2) -- 1 = decoded string is identical to source


 Example 3:

	      -- encode and decode an Euphoria object. Notice that atoms are
	      -- limited to a maximum of 10 significant digits!

	      include misc.e -- sprint()
	      include get.e  -- value()

	      sequence key, s, s1, s2

	      key = "@##Look who's here...!!!!"
	      s = {-390.1234567, {"ABC", 0, {30194.95}}} -- Euphoria object

	      s1 = sencode(sprint(s), key) -- encode object

	      -- s1 is {207,231,156,119,159,95,118,70,133,98,137,237,8,75,
	      --        139,139,52,146,15,243,35,204,164,101,152,119,42,160,
	      --        201,231,127,253,215,244,139,27,168,100,21,107}

	      s2 = value(sencode(s1, key)) -- decode object
	      s2 = s2[2]

	      ? equal(s, s2) -- 1 = decoded object is identical to source


 See Also:    encode, hash, checksum, pack_bits
              Euphoria 3.1.1: sprint, value, xor_bits, atom_to_float64


 --------------------------------<set_bit>-----------------------------------

 Syntax:      include machine2.e
	      x2 = set_bit(x1, i1, i2)

 Description: Return the result of setting bit-i1 in x1 to value i2. If i2 is
	      0 bit-i1 will be 0 (false). If i2 is non-zero bit-i1 will be 1
	      (true). i1 must be in the range 1 to 33.

 Comments:    x1 may be an atom or a sequence. The rules for operations on
	      sequences apply.

	      x1 must be representable as 32-bit numbers, either signed or
	      unsigned.

	      If you intend to manipulate full 32-bit values, you should
	      declare your variables as atom, rather than integer. Euphoria's
	      integer type is limited to 31-bits.

	      Results are treated as signed numbers. They will be negative when
	      the highest-order bit is 1.

 Example 1:

	      a = set_bit(#FF123400, 2, 1)
	      -- a is -15584254 (i.e. #FF123402 interpreted as negative number)


 Example 2:

	      a = set_bit({#123456, #876543, #2211}, 5, 0)
	      -- a is {#123446, #876543, #2201}


 See Also:    get_bit, shl_bits, pack_bits, bin, hex
	      Euphoria 3.1.1: and_bits, or_bits, int_to_bits


 --------------------------------<shl_bits>----------------------------------

 Syntax:      include machine2.e
	      x2 = shl_bits(x1, i)

 Description: Return the result of shifting the bits of x1 left i number of
	      bits. i must be in the range 0 to 32.

 Comments:    x1 may be an atom or a sequence. The rules for operations on
	      sequences apply.

	      x1 must be representable as 32-bit numbers, either signed or
	      unsigned.

	      If you intend to manipulate full 32-bit values, you should
	      declare your variables as atom, rather than integer. Euphoria's
	      integer type is limited to 31-bits.

	      Results are treated as signed numbers. They will be negative when
	      the highest-order bit is 1.

 Example 1:

	      a = shl_bits(#0FFF1234, 8)
	      -- a is -15584256 (i.e. #FF123400 interpreted as negative number)


 Example 2:

	      a = shl_bits({#123456, #876543, #2211}, 16)
	      -- a is {#34560000, #65430000, #22110000}


 See Also:    shr_bits, rol_bits, set_bit, pack_bits, bin, hex
	      Euphoria 3.1.1: and_bits, int_to_bits, bits_to_int


 --------------------------------<shr_bits>----------------------------------

 Syntax:      include machine2.e
	      x2 = shr_bits(x1, i)

 Description: Return the result of shifting the bits of x1 right i number of
	      bits. i must be in the range 0 to 32.

 Comments:    x1 may be an atom or a sequence. The rules for operations on
	      sequences apply.

	      x1 must be representable as 32-bit numbers, either signed or
	      unsigned.

	      If you intend to manipulate full 32-bit values, you should
	      declare your variables as atom, rather than integer. Euphoria's
	      integer type is limited to 31-bits.

	      Results are treated as signed numbers. They will be negative when
	      the highest-order bit is 1.

 Example 1:

	      a = shr_bits(#FF123400, 8)
	      -- a is 16716340 (i.e. #FF1234 interpreted as a positive number)


 Example 2:

	      a = shr_bits({#123456, #876543, #2211}, 16)
	      -- a is {#12, #87, #0}


 See Also:    shl_bits, ror_bits, set_bit, pack_bits, bin, hex
	      Euphoria 3.1.1: and_bits, int_to_bits, bits_to_int


 -----------------------------------<sign>-----------------------------------

 Syntax:      include machine2.e
	      x2 = sign(x1)

 Description: Return a value indicating the sign of x1 (1 if x1 is positive,
	      0 if it is zero, or -1 if it is negative).

 Comments:    This function may be applied to an atom or to all elements of a
	      sequence.

 Example:

	      y = sign({0.5, -1.6, 9.99, -100, 0})
	      -- y is {1, -1, 1, -1, 0}


 See Also:    psign, nsign, zsign, abs, unsigned, signed
	      Euphoria 3.1.1: floor, and_bits


 ---------------------------------<signed>-----------------------------------

 Syntax:      include machine2.e
	      x2 = signed(x1, i)

 Description: Return the low-order i bits of x1 as a signed number. i must be
	      in the range 0 to 32. The fractional part of x1 is truncated.
	      Positive numbers are returned in two's complement, so #FFFFFFFF
	      will return as -1.

 Comments:    x1 may be an atom or a sequence. The rules for operations on
	      sequences apply.

	      x1 must be representable as 32-bit numbers, either signed or
	      unsigned.

 Example 1:

	      y = signed({0.5, 4294967295, 9.99, -100.6, 0, -#FF}, 32)
	      -- y is {0, -1, 9, -100, 0, -255}


 Example 2:

	      x = {#FFFFFFFF, #FFFF, #FF, #F}

	      y = signed(x, 32)  -- y is {-1, 65535, 255, 15}

	      y = signed(x, 16)  -- y is {-1,    -1, 255, 15}

	      y = signed(x,  8)  -- y is {-1,    -1,  -1, 15}


 See Also:    unsigned, unpack_bits, range_per_bits, fix, sign, peek2s
	      Euphoria 3.1.1: peek4s


 ---------------------------------<string>-----------------------------------

 Syntax:      include machine2.e
	      i = string(x)

 Description: Return 1 if x is a string, i.e. a flat sequence without any
	      (sub)sequences within it. Otherwise return 0.

 Comments:    This serves to define the string type. You can also call it like
	      an ordinary function to determine if an object is a string.

 Example 1:

	      string z
	      z = {1, 2.5, 3}


 Example 2:

	      z = {65.1, 66.9, 67}

	      if string(z) then
		  puts(SCREEN, z & " is a string!")
	      end if


 Example 3:

	      i = string({1, 2.5, 3, ""})  -- i is 0


 See Also:    byte_string, dwords, boolean, flatten, EMPTY
	      Euphoria 3.1.1: sequence, atom


 -----------------------------------<sum>------------------------------------

 Syntax:      include machine2.e
	      a = sum(s)

 Description: Return the sum of s. s must be a sequence. An error will occur
	      if s is an atom.

 Example 1:

	      a = sum({{1,2}, {3,4}, {5,6}})   -- a is 21 (i.e. 1+2+3+4+5+6)


 Example 2:

	      a = sum("")   -- a is 0


 Example 3:

	      a = sum("12")   -- a is 99 (i.e. ASCII-49 + ASCII-50)


 See Also:    flatten, EMPTY, unpack_bits
	      Euphoria 3.1.1: sequence, length


 -------------------------------<time_sign>----------------------------------

 Syntax:      include machine2.e
	      TIME_SIGN

 Description: TIME_SIGN (-1 or 1) has been defined as a global constant.

 Comments:    On some machines, time() can return a negative number. TIME_SIGN
	      is -1 if time() return a negative number, or 1 if time() return
	      a positive number.

 Example:

	      x = TIME_SIGN  -- x is -1 or 1 (depends on your machine)


 See Also:    delay
	      Euphoria 3.1.1: time()


 ----------------------------------<true>------------------------------------

 Syntax:      include machine2.e
	      TRUE

 Description: TRUE (1) has been defined as a global constant.

 Example:

	      x = TRUE  -- x is 1


 See Also:    FALSE, boolean


 ------------------------------<unpack_bits>---------------------------------

 Syntax:      include machine2.e
	      s2 = unpack_bits(a, s1)

 Description: Convert integer a to sequence of numbers s2. s1 defines the size
	      (in bits) for unpacking each number from a. s1 values must be in
	      the range 0 to 32; You can also use negative values (0 to -32)
	      to unpack signed numbers. The (absolute) sum of s1 must be in the
	      range 0 to 32.

 Comments:    a must be representable as 32-bit number, either signed or
	      unsigned.

	      If you intend to manipulate full 32-bit values, you should
	      declare your variables as atom, rather than integer. Euphoria's
	      integer type is limited to 31-bits.

	      pack_bits()/unpack_bits() are useful for packing small numbers
	      into integer. e.g. for packing date() sequence into integer.

 Example:

	      ints = {-2000, 8, 18, -15}
	      bits = {  -12, 4, -8,  -5} -- 12-bits/-2000 (signed),
					 --  4-bits/8     (unsigned),
					 --  8-bits/18    (signed),
					 --  5-bits/-15   (signed)

	      i = pack_bits(ints, bits)  -- i is 274793041
	      s = unpack_bits(i, bits)   -- s is {-2000, 8, 18, -15}


 Examples:    See pack_bits() for more examples.


 See Also:    pack_bits, signed, unsigned, shr_bits, range_per_bits, bin,
	      hex, sum
	      Euphoria 3.1.1: and_bits, int_to_bits, bits_to_int


 -------------------------------<unsigned>-----------------------------------

 Syntax:      include machine2.e
	      x2 = unsigned(x1, i)

 Description: Return the low-order i bits of x1 as an unsigned number. i must
	      be in the range 0 to 32. The fractional part of x1 is truncated.
	      Negative numbers are returned in two's complement, so -1 will
	      return as 4294967295.

 Comments:    x1 may be an atom or a sequence. The rules for operations on
	      sequences apply.

	      x1 must be representable as 32-bit numbers, either signed or
	      unsigned.

 Example 1:

	      y = unsigned({0.5, -1, 9.99, -100.6, 0, -#FF}, 32)
	      -- y is {0, 4294967295, 9, 4294967196, 0, 4294967041}


 Example 2:

	      x = {#FFFFFFFF, #FFFF, #FF, #F}

	      y = unsigned(x, 32)  -- y is {4294967295, 65535, 255, 15}

	      y = unsigned(x, 16)  -- y is {     65535, 65535, 255, 15}

	      y = unsigned(x,  8)  -- y is {       255,   255, 255, 15}


 See Also:    signed, unpack_bits, range_per_bits, fix, sign, peek2u
	      Euphoria 3.1.1: int_to_bits, peek4u


 --------------------------------<wait_xkey>---------------------------------

 Syntax:      include machine2.e
	      x = wait_xkey()

 Description: Return the next key pressed by the user. Don't return until a key
	      is pressed.

 Comments:    Because either a string-sequence or an atom might be returned,
	      you should probably assign the result to a variable declared as
	      object.

	      You could achieve the same result using get_xkey() as follows:

		  object k
		  while 1 do
		      k = get_xkey()
		      if not equal(k, -1) then
			  exit
		      end if
		  end while

	      However, on multi-tasking systems like Windows or Linux/FreeBSD,
	      this "busy waiting" would tend to slow the system down.
	      wait_xkey() lets the operating system do other useful work while
	      your program is waiting for the user to press a key.

	      wait_xkey() is useful for programs that run in Linux terminal or
	      in any other environment that may return a sequence of atoms for
	      a single key-hit (escape sequence, UTF-8 character, etc).

 See Also:    get_xkey, clear_keyboard, pause, delay
	      Euphoria 3.1.1: wait_key, get_key, getc, sleep


 ----------------------------------<zsign>-----------------------------------

 Syntax:      include machine2.e
	      x2 = zsign(x1)

 Description: Return a value indicating the sign of x1 (0 if x1 is positive,
	      1 if it is zero, or 0 if it is negative).

 Comments:    This function may be applied to an atom or to all elements of a
	      sequence.

 Example:

	      y = zsign({0.5, -1.6, 9.99, -100, 0})
	      -- y is {0, 0, 0, 0, 1}


 See Also:    sign, psign, nsign, abs, unsigned, signed