Repository: asteroid-lang/asteroid (language: python)

Issue:
review documentation for 2.0.1 release
We need to review the documentation for the 2.0.1 release.  In particular the User Guide.  A lot of terminology has been refined and that should be reflected in the documentation.


Discussion / hints:

Fix patch:
diff --git a/asteroid/modules/patterns.ast b/asteroid/modules/patterns.ast
index e257a73f..59b010dc 100644
--- a/asteroid/modules/patterns.ast
+++ b/asteroid/modules/patterns.ast
@@ -101,7 +101,11 @@ __retval__ = ('boolean',str.isalnum(val_s[1]))
   with _ do
     return false.
   end
-
+------------------------------------------------------------------
+-- Note: patterns are evaluated in the user context therefore we 
+-- cannot have module access in patterns, except the patterns module
+function _mod2 with n do math@mod(n,2) end
+function _isclose with n do math@isclose(toreal(n), 0.0) end
 ------------------------------------------------------------------
 -- Common number sets
 ------------------------------------------------------------------
@@ -114,10 +118,10 @@ let neg_real = pattern with %[ (n:%real) if n < 0.0 ]%.
 let positive = pattern with %[ n if (n is *patterns@pos_int) or (n is *patterns@pos_real) ]%.
 let negative = pattern with %[ n if (n is *patterns@neg_int) or (n is *patterns@neg_real) ]%.
 let nat = pattern with %[ (n:%integer) if n >= 0 ]%.
-let zero = pattern with %[ n if ((n is %real) and (math@isclose(toreal(n), 0.0)))
+let zero = pattern with %[ n if ((n is %real) and patterns@_isclose(n))
                            or ((n is %integer) and (tointeger(n) == 0)) ]%.
-let odd = pattern with %[ (n:%integer) if math@mod(n,2) == 1 ]%.
-let even = pattern with %[ (n:%integer) if math@mod(n,2) == 0 ]%.
+let odd = pattern with %[ (n:%integer) if patterns@_mod2(n) == 1 ]%.
+let even = pattern with %[ (n:%integer) if patterns@_mod2(n) == 0 ]%.
 ------------------------------------------------------------------
 -- Containers
 ------------------------------------------------------------------
diff --git a/docs/Reference Guide.rst b/docs/Reference Guide.rst
index 119d66eb..a7330573 100644
--- a/docs/Reference Guide.rst
+++ b/docs/Reference Guide.rst
@@ -1,12 +1,12 @@
 ..
       /******************************************************************
       This is the source file from which the reference guide is
-      generated.  We use cpp to insert live code snippets into the
+      generated.  We use pcpp to insert live code snippets into the
       document. In order to generate the reference guide run the
-      following command on a Unix-like system in the directory of
+      following command in the directory of
       this doc:
 
-      bash generate_docs
+      python generate_docs.py
 
       ******************************************************************/
 ..
@@ -55,7 +55,6 @@ As an example we break out of the indefinite loop below when ``i`` is equal to 1
       end
 
       assert (i==10).
-
 Expressions at the Statement Level
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
@@ -66,11 +65,9 @@ evaluated in a function body is considered the return value of the function.
 
 An example,
 ::
-      function inc
-         with i do
-            i+1.
-         end
-
+      function inc with i do
+         i+1.
+      end
 Notice that because the expression ``i+1`` is the last statement evaluated in the
 function body its value becomes the return value of the function.
 
@@ -95,8 +92,6 @@ the pattern matches the tuple ``(1,"chicken")``,
       for (1,bird) in tuple_list do
          assert(bird is "chicken").
       end
-
-
 Function-Definition
 %%%%%%%%%%%%%%%%%%%
 
@@ -118,7 +113,6 @@ The following is a definition of the ``sign`` function,
          with x if x < 0 do
             return -1.
       end
-
 Here the first function body returns ``1`` if the actual argument is greater or equal to zero.
 The second function body return ``-1`` if the actual argument is less than zero.
 
@@ -135,16 +129,14 @@ Consider the following code snippet,
 ::
       let x = 0.
 
-      function foo
-         with none do
-            global x.
-            let x = 1.
+      function foo with none do
+         global x.
+         let x = 1.
       end
 
       assert(x==0).
       foo().
       assert(x==1).
-
 The ``global`` statement within the function ``foo`` indicates that the ``let`` statement
 on the following line should assign a value to the global variable ``x``.
 
@@ -179,8 +171,6 @@ what kind of integer value the user supplied,
       else do
           io @println "Positive".
       end
-
-
 Let
 %%%
 
@@ -196,7 +186,7 @@ Here, the variable ``x`` will match the value stored in ``val``.  However, becau
 can write something like this,
 ::
   load system math.
-  let x:%[(k:%integer) if math @mod(k,2)==0]% = val.
+  let x: %[ (k:%integer) if math @mod (k,2) == 0 ]% = val.
 
 where ``x`` will only match the value of ``val`` if that value is an even integer value.  The fact that the left side of the ``=`` is a pattern allows
 us to write things like this,
@@ -227,15 +217,11 @@ Consider for example that you had loaded your own IO module but also would like
 system IO module.  In order to avoid a name clash you can use the ``as`` modifier to rename one
 of the modules,
 ::
-      load io. -- load my IO module
+      load "ref-programs/io.ast". -- load my IO module
       load system io as systemio. -- load the system IO module and rename it to systemio
       io @output "Foobar".
       systemio @println "Hello World!".
-
-When loading a module with a filename the basename of the filename becomes the module name. Consider,
-::
-      load "mymodules/m.ast". -- load the m module
-      m @f().  -- call function f in the module
+When loading a module with a filename the basename of the filename becomes the module name.
 
 Loop
 %%%%
@@ -262,8 +248,6 @@ in the ``with`` clauses.  If a pattern matches the associated statements will be
             throw Error("not a valid tuple").
       end
       assert(x == "LT").
-
-
 Repeat-Until
 %%%%%%%%%%%%
 
@@ -283,8 +267,6 @@ of a list,
          let [element|l] = l.
          io @println element.
       until l is [].
-
-
 Return
 %%%%%%
 
@@ -309,9 +291,8 @@ are accessed using the access operator ``@``. Here is a simple example,
       end
 
       let obj = A(1,2).       -- call default constructor
-      assert( obj @a == 1 ).  -- access first data member
-      assert( obj @b == 2 ).  -- access second data member
-
+      assert( obj@a == 1 ).  -- access first data member
+      assert( obj@b == 2 ).  -- access second data member
 We can use custom constructors to enforce that only certain types of values
 can be copied into an object,
 ::
@@ -320,20 +301,19 @@ can be copied into an object,
           data name.
           data age.
           function __init__ with (name:%string,age:%integer) do -- constructor
-             let this @name = name.
-             let this @age = age.
+             let this@name = name.
+             let this@age = age.
           end
           function __str__ with none do
-            return this @name+" is "+ tostring this @age+" years old".
+            return this @name+" is "+ tostring(this@age) +" years old".
           end
       end
 
       let betty = Person("Betty",21).  -- call constructor
-      assert( betty @name == "Betty" ).
-      assert( betty @age == 21 ).
+      assert( betty@name == "Betty" ).
+      assert( betty@age == 21 ).
 
       assert(tostring betty is "Betty is 21 years old").
-
 Note that object identity is expressed using the ``this`` keyword.
 Here we also supplied an instantiation of the ``__str__`` function that allows
 us to customize the stringification of the object.  See the last line
@@ -366,7 +346,6 @@ by the associated handler,
       catch Exception("ArithmeticError", s) do
           io @println s.
       end
-
 For more details on exceptions please see the User Guide.
 
 Throw
@@ -393,14 +372,10 @@ Here is an example that prints out a sequence of integer values in reverse order
 
       let i = 10.
 
-      while i do
+      while i >= 0 do
          io @println i.
          let i = i-1.
       end
-
-The loop terminates once ``i`` becomes zero which is the equivalent to a Boolean
-value ``false``.
-
 Expressions
 ^^^^^^^^^^^
 
@@ -422,7 +397,7 @@ Asteroid provides the uniform substructure access operator ``@`` for all structu
 which includes lists, tuples, and objects. For example, accessing the first
 element of a list is accomplished by the expression,
 ::
-      [1,2,3] @0
+      [1,2,3]@0
 
 Similarly, given an object constructed from structure ``A``, member values
 are accessed by name via the ``@`` operator,
@@ -433,9 +408,7 @@ are accessed by name via the ``@`` operator,
       end
 
       let obj = A(1,2).
-      assert( obj @a == 1 ).  -- access member a
-
-
+      assert( obj@a == 1 ).  -- access member a
 Head-Tail Operator
 %%%%%%%%%%%%%%%%%%
 
@@ -475,16 +448,17 @@ apply such as instantiating appropriate variable bindings in the current scope.
 
 Example,
 ::
-      if v is (x,y) do
-         io @println "success".
-         assert(isdefined "x").
-         assert(isdefined "y").
-      else
-         io @println "not matched".
-         assert(not isdefined "x").
-         assert(not isdefined "y").
-      end
+   load system io.
 
+   if (1,2) is (x,y) do
+      io @println "success".
+      assert(isdefined "x").
+      assert(isdefined "y").
+   else
+      io @println "not matched".
+      assert(not isdefined "x").
+      assert(not isdefined "y").
+   end
 The In Predicate
 %%%%%%%%%%%%%%%%%%%%
 
@@ -578,19 +552,19 @@ Here the pair ``(1,2)`` is matched against the pattern stored in the variable ``
 such that ``x`` is bound to the value ``2``.
 
 The optional ``bind`` term together with an appropriate list of variable names
-allows the user to selectively project variable bindings from a constraint pattern
+allows the user to selectively project variable bindings from patterns that have been
+constructed using the ``%[...]%`` scope operator.
 into the current scope.  The ``as`` keyword allows you to rename those bindings.
 Consider the following program,
 ::
       let Pair = pattern %[(x,y)]%.
 
-      -- bindings of the variables x and y are now visible as a and y respetively
       let *Pair bind [x as a, y] = (1,2).
       assert( a == 1).
       assert(y == 2).
 
-At the second  ``let`` statement we bind the ``x`` as ``a`` and ``y`` from the hidden scope
-of the constraint pattern into our current scope.
+At the second  ``let`` statement we bind the ``x`` as ``a`` and ``y`` from the scope
+of the  pattern into our current scope.
 
 Type Patterns
 %%%%%%%%%%%%%
@@ -639,17 +613,17 @@ evaluates to true.
 Example,
 ::
       load system math.
-      let k if (math @mod(k,2) == 0) = val.
+      let k if (math@mod(k,2) == 0) = val.
 
 Here ``k`` only matches the value of ``val`` if that value is an even number.
 
-Constraint Patterns
+Patterns with Scope
 %%%%%%%%%%%%%%%%%%%
 
 Syntax: ``%[ pattern ]% (BIND '[' ID (AS ID)? (',' ID (AS ID)?)*']')?``
 
-A constraint pattern is a pattern that does not create any bindings
-in the current scope.  Any pattern can be turned into a pure constraint pattern
+A pattern with scope is a pattern that does not create any bindings
+in the current scope.  Any pattern can be turned into a scoped pattern
 by placing it between the ``%[`` and ``]%`` operators.
 
 Example,
@@ -657,13 +631,13 @@ Example,
       let pos_int = pattern %[(x:%integer) if x > 0]%
       let i:*pos_int = val.
 
-The first line defines a constraint pattern for the positive integers.
+The first line defines a scoped pattern for the positive integers.
 Notice that the pattern internally uses the variable ``x`` in order to evaluate
 the conditional pattern but because it has been declared as a pure constraint
 pattern this value binding is not exported to the current scope during pattern matching.
 On the second line we constrain the pattern ``i`` to only the positive integer values using
-the pure constraint pattern stored in ``p``.  This pattern match will only succeed if ``val``
-evaluates to a postive integer.
+the scoped pattern stored in ``p``.  This pattern match will only succeed if ``val``
+is a postive integer.
 
 Asteroid Grammar
 ^^^^^^^^^^^^^^^^
@@ -1540,6 +1514,10 @@ An example:
       end
    end
    assert(evens is [2,4,6,8,10]).
+If a pattern only applies to a certain datatype then a constraint expression of the form ``:%<datatype>`` appears
+right after the pattern in the documentation.  If the pattern applies to multiple datatypes then the
+different datatypes are separated by or-bars, e.g. ``:%<datatype1>|%<datatype2>``.
+
 Common number sets
 %%%%%%%%%%%%%%%%%%
 
@@ -1634,7 +1612,7 @@ An example:
    load system io.
    load system pick.
 
-   let po = pick @pick([1 to 10]).
+   let po = pick @pick [1 to 10].
    let objects = po @pickitems 3.
    io @println objects.
 pick **@pick** l:%list
diff --git a/docs/Reference Guide.txt b/docs/Reference Guide.txt
index 225d5fb7..4a993f78 100644
--- a/docs/Reference Guide.txt
+++ b/docs/Reference Guide.txt
@@ -1,12 +1,12 @@
 ..
       /******************************************************************
       This is the source file from which the reference guide is
-      generated.  We use cpp to insert live code snippets into the
+      generated.  We use pcpp to insert live code snippets into the
       document. In order to generate the reference guide run the
-      following command on a Unix-like system in the directory of
+      following command in the directory of
       this doc:
 
-      bash generate_docs
+      python generate_docs.py
 
       ******************************************************************/
 #include "header.txt"
@@ -42,16 +42,7 @@ outside of a looping structure will lead to a runtime error.
 
 As an example we break out of the indefinite loop below when ``i`` is equal to 10,
 ::
-      let i = 0.
-
-      loop
-         let i = i+1.
-         if i==10 do
-            break.
-         end
-      end
-
-      assert (i==10).
+#include "../asteroid/test-suites/ref-programs/prgm-001.ast"
 
 Expressions at the Statement Level
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -63,10 +54,7 @@ evaluated in a function body is considered the return value of the function.
 
 An example,
 ::
-      function inc
-         with i do
-            i+1.
-         end
+#include "../asteroid/test-suites/ref-programs/prgm-002.ast"
 
 Notice that because the expression ``i+1`` is the last statement evaluated in the
 function body its value becomes the return value of the function.
@@ -83,15 +71,7 @@ The loop body is executed for each successful match.
 In the following program the body of the loop is executed exactly once when
 the pattern matches the tuple ``(1,"chicken")``,
 ::
-      let tuple_list = [
-              (0,"duck"),
-              (1,"chicken"),
-              (2,"turkey")
-              ].
-
-      for (1,bird) in tuple_list do
-         assert(bird is "chicken").
-      end
+#include "../asteroid/test-suites/ref-programs/prgm-003.ast"
 
 
 Function-Definition
@@ -109,12 +89,7 @@ Patterns are tried in the order they appear in the function definition.
 
 The following is a definition of the ``sign`` function,
 ::
-      function sign
-         with x if x >= 0 do
-            return 1.
-         with x if x < 0 do
-            return -1.
-      end
+#include "../asteroid/test-suites/ref-programs/prgm-004.ast"
 
 Here the first function body returns ``1`` if the actual argument is greater or equal to zero.
 The second function body return ``-1`` if the actual argument is less than zero.
@@ -130,17 +105,7 @@ from within functions.
 
 Consider the following code snippet,
 ::
-      let x = 0.
-
-      function foo
-         with none do
-            global x.
-            let x = 1.
-      end
-
-      assert(x==0).
-      foo().
-      assert(x==1).
+#include "../asteroid/test-suites/ref-programs/prgm-005.ast"
 
 The ``global`` statement within the function ``foo`` indicates that the ``let`` statement
 on the following line should assign a value to the global variable ``x``.
@@ -163,20 +128,7 @@ flow of control is transferred to the statements following the if-statement.
 As an example consider the following ``if`` statement that determines
 what kind of integer value the user supplied,
 ::
-      load system io.
-
-      let x = tointeger (io @input "Please enter an integer: ").
-
-      if x < 0 do
-          io @println "Negative".
-      elif x == 0 do
-          io @println "Zero".
-      elif x == 1 do
-          io @println "One".
-      else do
-          io @println "Positive".
-      end
-
+#include "../asteroid/test-suites/ref-programs/prgm-006.ast"
 
 Let
 %%%
@@ -193,7 +145,7 @@ Here, the variable ``x`` will match the value stored in ``val``.  However, becau
 can write something like this,
 ::
   load system math.
-  let x:%[(k:%integer) if math @mod(k,2)==0]% = val.
+  let x: %[ (k:%integer) if math @mod (k,2) == 0 ]% = val.
 
 where ``x`` will only match the value of ``val`` if that value is an even integer value.  The fact that the left side of the ``=`` is a pattern allows
 us to write things like this,
@@ -224,15 +176,9 @@ Consider for example that you had loaded your own IO module but also would like
 system IO module.  In order to avoid a name clash you can use the ``as`` modifier to rename one 
 of the modules,
 ::
-      load io. -- load my IO module
-      load system io as systemio. -- load the system IO module and rename it to systemio
-      io @output "Foobar".
-      systemio @println "Hello World!".
+#include "../asteroid/test-suites/ref-programs/prgm-007.ast"
 
-When loading a module with a filename the basename of the filename becomes the module name. Consider,
-::
-      load "mymodules/m.ast". -- load the m module
-      m @f().  -- call function f in the module
+When loading a module with a filename the basename of the filename becomes the module name. 
 
 Loop
 %%%%
@@ -250,15 +196,7 @@ Syntax: ``MATCH expression (WITH pattern DO stmt_list)* END``
 The ``match`` statement matches a value given by expression against a list of patterns
 in the ``with`` clauses.  If a pattern matches the associated statements will be executed,
 ::
-      match (1,2)
-         with (x,y) if x > y do
-            let x = "GT".
-         with (x,y) if x < y do
-            let x = "LT".
-         with _ do
-            throw Error("not a valid tuple").
-      end
-      assert(x == "LT").
+#include "../asteroid/test-suites/ref-programs/prgm-008.ast"
 
 
 Repeat-Until
@@ -272,14 +210,7 @@ expression evaluates to the equivalent of a Boolean ``true`` value.
 Here is an example of a program that prints out the elements
 of a list,
 ::
-      load system io.
-
-      let l = ["bmw", "volkswagen", "mercedes"].
-
-      repeat
-         let [element|l] = l.
-         io @println element.
-      until l is [].
+#include "../asteroid/test-suites/ref-programs/prgm-009.ast"
 
 
 Return
@@ -299,37 +230,12 @@ Unless a member function was declared as a constructor (an ``__init__`` function
 instantiated using a default constructor. The default constructor copies the arguments given to it into the data member fields in the order that the data members appear in the structure definition and as they appear in the parameter list of the constructor.  We often refer to instantiated structures as objects.  Member values of objects
 are accessed using the access operator ``@``. Here is a simple example,
 ::
-      -- define a structure of type A
-      structure A with
-          data a.
-          data b.
-      end
-
-      let obj = A(1,2).       -- call default constructor
-      assert( obj @a == 1 ).  -- access first data member
-      assert( obj @b == 2 ).  -- access second data member
+#include "../asteroid/test-suites/ref-programs/prgm-010.ast"
 
 We can use custom constructors to enforce that only certain types of values
 can be copied into an object,
 ::
-      -- define a structure of type Person
-      structure Person with
-          data name.
-          data age.
-          function __init__ with (name:%string,age:%integer) do -- constructor
-             let this @name = name.
-             let this @age = age.
-          end
-          function __str__ with none do
-            return this @name+" is "+ tostring this @age+" years old".
-          end
-      end
-
-      let betty = Person("Betty",21).  -- call constructor
-      assert( betty @name == "Betty" ).
-      assert( betty @age == 21 ).
-
-      assert(tostring betty is "Betty is 21 years old").
+#include "../asteroid/test-suites/ref-programs/prgm-011.ast"
 
 Note that object identity is expressed using the ``this`` keyword.
 Here we also supplied an instantiation of the ``__str__`` function that allows
@@ -356,13 +262,7 @@ in the ``try`` part generates a division-by-zero exception.  The
 exception object is pattern-matched in the ``catch`` clause and processed
 by the associated handler,
 ::
-      load system io.
-
-      try
-          let x = 1/0.
-      catch Exception("ArithmeticError", s) do
-          io @println s.
-      end
+#include "../asteroid/test-suites/ref-programs/prgm-012.ast"
 
 For more details on exceptions please see the User Guide.
 
@@ -386,17 +286,8 @@ after each loop iteration.
 
 Here is an example that prints out a sequence of integer values in reverse order,
 ::
-      load system io.
-
-      let i = 10.
-
-      while i do
-         io @println i.
-         let i = i-1.
-      end
+#include "../asteroid/test-suites/ref-programs/prgm-013.ast"
 
-The loop terminates once ``i`` becomes zero which is the equivalent to a Boolean
-value ``false``.
 
 Expressions
 ^^^^^^^^^^^
@@ -419,18 +310,12 @@ Asteroid provides the uniform substructure access operator ``@`` for all structu
 which includes lists, tuples, and objects. For example, accessing the first
 element of a list is accomplished by the expression,
 ::
-      [1,2,3] @0
+      [1,2,3]@0
 
 Similarly, given an object constructed from structure ``A``, member values
 are accessed by name via the ``@`` operator,
 ::
-      structure A with
-         data a.
-         data b.
-      end
-
-      let obj = A(1,2).
-      assert( obj @a == 1 ).  -- access member a
+#include "../asteroid/test-suites/ref-programs/prgm-014.ast"
 
 
 Head-Tail Operator
@@ -472,15 +357,7 @@ apply such as instantiating appropriate variable bindings in the current scope.
 
 Example,
 ::
-      if v is (x,y) do
-         io @println "success".
-         assert(isdefined "x").
-         assert(isdefined "y").
-      else
-         io @println "not matched".
-         assert(not isdefined "x").
-         assert(not isdefined "y").
-      end
+#include "../asteroid/test-suites/ref-programs/prgm-015.ast"
 
 The In Predicate
 %%%%%%%%%%%%%%%%%%%%
@@ -575,19 +452,19 @@ Here the pair ``(1,2)`` is matched against the pattern stored in the variable ``
 such that ``x`` is bound to the value ``2``.
 
 The optional ``bind`` term together with an appropriate list of variable names 
-allows the user to selectively project variable bindings from a constraint pattern 
+allows the user to selectively project variable bindings from patterns that have been 
+constructed using the ``%[...]%`` scope operator. 
 into the current scope.  The ``as`` keyword allows you to rename those bindings.
 Consider the following program,
 ::
       let Pair = pattern %[(x,y)]%.
 
-      -- bindings of the variables x and y are now visible as a and y respetively
       let *Pair bind [x as a, y] = (1,2).  
       assert( a == 1).
       assert(y == 2).
 
-At the second  ``let`` statement we bind the ``x`` as ``a`` and ``y`` from the hidden scope 
-of the constraint pattern into our current scope.
+At the second  ``let`` statement we bind the ``x`` as ``a`` and ``y`` from the scope 
+of the  pattern into our current scope.
 
 Type Patterns
 %%%%%%%%%%%%%
@@ -636,17 +513,17 @@ evaluates to true.
 Example,
 ::
       load system math.
-      let k if (math @mod(k,2) == 0) = val.
+      let k if (math@mod(k,2) == 0) = val.
 
 Here ``k`` only matches the value of ``val`` if that value is an even number.
 
-Constraint Patterns
+Patterns with Scope
 %%%%%%%%%%%%%%%%%%%
 
 Syntax: ``%[ pattern ]% (BIND '[' ID (AS ID)? (',' ID (AS ID)?)*']')?``
 
-A constraint pattern is a pattern that does not create any bindings
-in the current scope.  Any pattern can be turned into a pure constraint pattern
+A pattern with scope is a pattern that does not create any bindings
+in the current scope.  Any pattern can be turned into a scoped pattern
 by placing it between the ``%[`` and ``]%`` operators.
 
 Example,
@@ -654,13 +531,13 @@ Example,
       let pos_int = pattern %[(x:%integer) if x > 0]%
       let i:*pos_int = val.
 
-The first line defines a constraint pattern for the positive integers.
+The first line defines a scoped pattern for the positive integers.
 Notice that the pattern internally uses the variable ``x`` in order to evaluate
 the conditional pattern but because it has been declared as a pure constraint
 pattern this value binding is not exported to the current scope during pattern matching.
 On the second line we constrain the pattern ``i`` to only the positive integer values using
-the pure constraint pattern stored in ``p``.  This pattern match will only succeed if ``val``
-evaluates to a postive integer.
+the scoped pattern stored in ``p``.  This pattern match will only succeed if ``val``
+is a postive integer.
 
 Asteroid Grammar
 ^^^^^^^^^^^^^^^^
@@ -1384,6 +1261,10 @@ An example:
 ::
 #include "../asteroid/test-suites/ref-programs/patterns.ast"
 
+If a pattern only applies to a certain datatype then a constraint expression of the form ``:%<datatype>`` appears 
+right after the pattern in the documentation.  If the pattern applies to multiple datatypes then the 
+different datatypes are separated by or-bars, e.g. ``:%<datatype1>|%<datatype2>``.
+
 Common number sets
 %%%%%%%%%%%%%%%%%%
 
diff --git a/docs/User Guide.rst b/docs/User Guide.rst
index 802ff271..37f96a57 100644
--- a/docs/User Guide.rst
+++ b/docs/User Guide.rst
@@ -1,11 +1,12 @@
 ..
     /******************************************************************
-    This is the source file from which the user guide is generated.
-    We use cpp to insert live code snippets into the document.
-    In order to generate the user guide run the following command
-    on a Unix-like system in the directory of this doc:
+    This is the source file from which the reference guide is
+    generated.  We use pcpp to insert live code snippets into the
+    document. In order to generate the reference guide run the
+    following command in the directory of
+    this doc:
 
-    bash generate_docs
+    python generate_docs.py
 
     ******************************************************************/
 ..
diff --git a/docs/User Guide.txt b/docs/User Guide.txt
index 1e04b81a..005d236d 100644
--- a/docs/User Guide.txt
+++ b/docs/User Guide.txt
@@ -1,11 +1,12 @@
 ..
     /******************************************************************
-    This is the source file from which the user guide is generated.
-    We use cpp to insert live code snippets into the document.
-    In order to generate the user guide run the following command
-    on a Unix-like system in the directory of this doc:
+    This is the source file from which the reference guide is
+    generated.  We use pcpp to insert live code snippets into the
+    document. In order to generate the reference guide run the
+    following command in the directory of
+    this doc:
 
-    bash generate_docs
+    python generate_docs.py
 
     ******************************************************************/
 


Test patch:
diff --git a/asteroid/test-suites/ref-programs/io.ast b/asteroid/test-suites/ref-programs/io.ast
new file mode 100644
index 00000000..d96bf5b6
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/io.ast
@@ -0,0 +1,8 @@
+-- test module for test ref-programs/prgm-007.ast
+
+load system io.
+
+function output with a do
+   io @println a.
+end
+
diff --git a/asteroid/test-suites/ref-programs/pick.ast b/asteroid/test-suites/ref-programs/pick.ast
index 1ba8821b..2a48d130 100644
--- a/asteroid/test-suites/ref-programs/pick.ast
+++ b/asteroid/test-suites/ref-programs/pick.ast
@@ -1,7 +1,7 @@
    load system io.
    load system pick.
 
-   let po = pick @pick([1 to 10]).
+   let po = pick @pick [1 to 10].
    let objects = po @pickitems 3.
    io @println objects.
    
\ No newline at end of file
diff --git a/asteroid/test-suites/ref-programs/prgm-001.ast b/asteroid/test-suites/ref-programs/prgm-001.ast
new file mode 100644
index 00000000..6c8a6198
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-001.ast
@@ -0,0 +1,11 @@
+
+      let i = 0.
+
+      loop
+         let i = i+1.
+         if i==10 do
+            break.
+         end
+      end
+
+      assert (i==10).
diff --git a/asteroid/test-suites/ref-programs/prgm-002.ast b/asteroid/test-suites/ref-programs/prgm-002.ast
new file mode 100644
index 00000000..04b92def
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-002.ast
@@ -0,0 +1,5 @@
+
+      function inc with i do
+         i+1.
+      end
+
diff --git a/asteroid/test-suites/ref-programs/prgm-003.ast b/asteroid/test-suites/ref-programs/prgm-003.ast
new file mode 100644
index 00000000..eb5192b1
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-003.ast
@@ -0,0 +1,10 @@
+
+      let tuple_list = [
+              (0,"duck"),
+              (1,"chicken"),
+              (2,"turkey")
+              ].
+
+      for (1,bird) in tuple_list do
+         assert(bird is "chicken").
+      end
diff --git a/asteroid/test-suites/ref-programs/prgm-004.ast b/asteroid/test-suites/ref-programs/prgm-004.ast
new file mode 100644
index 00000000..97f5d43d
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-004.ast
@@ -0,0 +1,7 @@
+
+      function sign
+         with x if x >= 0 do
+            return 1.
+         with x if x < 0 do
+            return -1.
+      end
diff --git a/asteroid/test-suites/ref-programs/prgm-005.ast b/asteroid/test-suites/ref-programs/prgm-005.ast
new file mode 100644
index 00000000..f02a50e4
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-005.ast
@@ -0,0 +1,11 @@
+
+      let x = 0.
+
+      function foo with none do
+         global x.
+         let x = 1.
+      end
+
+      assert(x==0).
+      foo().
+      assert(x==1).
diff --git a/asteroid/test-suites/ref-programs/prgm-006-io.txt b/asteroid/test-suites/ref-programs/prgm-006-io.txt
new file mode 100644
index 00000000..021ea30c
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-006-io.txt
@@ -0,0 +1,2 @@
+10
+
diff --git a/asteroid/test-suites/ref-programs/prgm-006.ast b/asteroid/test-suites/ref-programs/prgm-006.ast
new file mode 100644
index 00000000..d5f46753
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-006.ast
@@ -0,0 +1,15 @@
+
+      load system io.
+
+      let x = tointeger (io @input "Please enter an integer: ").
+
+      if x < 0 do
+          io @println "Negative".
+      elif x == 0 do
+          io @println "Zero".
+      elif x == 1 do
+          io @println "One".
+      else do
+          io @println "Positive".
+      end
+
diff --git a/asteroid/test-suites/ref-programs/prgm-007.ast b/asteroid/test-suites/ref-programs/prgm-007.ast
new file mode 100644
index 00000000..694e3482
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-007.ast
@@ -0,0 +1,5 @@
+
+      load "ref-programs/io.ast". -- load my IO module
+      load system io as systemio. -- load the system IO module and rename it to systemio
+      io @output "Foobar".
+      systemio @println "Hello World!".
diff --git a/asteroid/test-suites/ref-programs/prgm-008.ast b/asteroid/test-suites/ref-programs/prgm-008.ast
new file mode 100644
index 00000000..4d90704b
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-008.ast
@@ -0,0 +1,10 @@
+
+      match (1,2)
+         with (x,y) if x > y do
+            let x = "GT".
+         with (x,y) if x < y do
+            let x = "LT".
+         with _ do
+            throw Error("not a valid tuple").
+      end
+      assert(x == "LT").
diff --git a/asteroid/test-suites/ref-programs/prgm-009.ast b/asteroid/test-suites/ref-programs/prgm-009.ast
new file mode 100644
index 00000000..e45d1e52
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-009.ast
@@ -0,0 +1,9 @@
+
+      load system io.
+
+      let l = ["bmw", "volkswagen", "mercedes"].
+
+      repeat
+         let [element|l] = l.
+         io @println element.
+      until l is [].
diff --git a/asteroid/test-suites/ref-programs/prgm-010.ast b/asteroid/test-suites/ref-programs/prgm-010.ast
new file mode 100644
index 00000000..11751f81
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-010.ast
@@ -0,0 +1,9 @@
+      -- define a structure of type A
+      structure A with
+          data a.
+          data b.
+      end
+
+      let obj = A(1,2).       -- call default constructor
+      assert( obj@a == 1 ).  -- access first data member
+      assert( obj@b == 2 ).  -- access second data member
diff --git a/asteroid/test-suites/ref-programs/prgm-011.ast b/asteroid/test-suites/ref-programs/prgm-011.ast
new file mode 100644
index 00000000..fa225023
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-011.ast
@@ -0,0 +1,18 @@
+      -- define a structure of type Person
+      structure Person with
+          data name.
+          data age.
+          function __init__ with (name:%string,age:%integer) do -- constructor
+             let this@name = name.
+             let this@age = age.
+          end
+          function __str__ with none do
+            return this @name+" is "+ tostring(this@age) +" years old".
+          end
+      end
+
+      let betty = Person("Betty",21).  -- call constructor
+      assert( betty@name == "Betty" ).
+      assert( betty@age == 21 ).
+
+      assert(tostring betty is "Betty is 21 years old").
diff --git a/asteroid/test-suites/ref-programs/prgm-012.ast b/asteroid/test-suites/ref-programs/prgm-012.ast
new file mode 100644
index 00000000..4974716b
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-012.ast
@@ -0,0 +1,7 @@
+      load system io.
+
+      try
+          let x = 1/0.
+      catch Exception("ArithmeticError", s) do
+          io @println s.
+      end
diff --git a/asteroid/test-suites/ref-programs/prgm-013.ast b/asteroid/test-suites/ref-programs/prgm-013.ast
new file mode 100644
index 00000000..10183b32
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-013.ast
@@ -0,0 +1,8 @@
+      load system io.
+
+      let i = 10.
+
+      while i >= 0 do
+         io @println i.
+         let i = i-1.
+      end
diff --git a/asteroid/test-suites/ref-programs/prgm-014.ast b/asteroid/test-suites/ref-programs/prgm-014.ast
new file mode 100644
index 00000000..de64cf6b
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-014.ast
@@ -0,0 +1,7 @@
+      structure A with
+         data a.
+         data b.
+      end
+
+      let obj = A(1,2).
+      assert( obj@a == 1 ).  -- access member a
diff --git a/asteroid/test-suites/ref-programs/prgm-015.ast b/asteroid/test-suites/ref-programs/prgm-015.ast
new file mode 100644
index 00000000..9af02587
--- /dev/null
+++ b/asteroid/test-suites/ref-programs/prgm-015.ast
@@ -0,0 +1,11 @@
+   load system io.
+
+   if (1,2) is (x,y) do
+      io @println "success".
+      assert(isdefined "x").
+      assert(isdefined "y").
+   else
+      io @println "not matched".
+      assert(not isdefined "x").
+      assert(not isdefined "y").
+   end
diff --git a/asteroid/test-suites/regression-tests/test012.ast b/asteroid/test-suites/regression-tests/test012.ast
index f5bc7a54..5733f2ea 100644
--- a/asteroid/test-suites/regression-tests/test012.ast
+++ b/asteroid/test-suites/regression-tests/test012.ast
@@ -1,6 +1,6 @@
 
 -- Palindrome list filter
-load io.
+load system io.
 
 function filter 
     with (x:%string) if x @explode() == x @explode() @reverse() do
diff --git a/asteroid/test-suites/regression-tests/test013.ast b/asteroid/test-suites/regression-tests/test013.ast
index 3b7251e2..4d6d9e80 100644
--- a/asteroid/test-suites/regression-tests/test013.ast
+++ b/asteroid/test-suites/regression-tests/test013.ast
@@ -1,4 +1,4 @@
 
-load io.
+load system io.
 let i:%integer = 1.
 io @print i.
diff --git a/asteroid/test-suites/regression-tests/test015.ast b/asteroid/test-suites/regression-tests/test015.ast
index 61c1b43b..c7a9b667 100644
--- a/asteroid/test-suites/regression-tests/test015.ast
+++ b/asteroid/test-suites/regression-tests/test015.ast
@@ -147,4 +147,4 @@ catch _ do
     io @println("FAILED.").
     throw Error("FAIL: unexpected error").
 end.
---------------------------------------------------END----
\ No newline at end of file
+--------------------------------------------------END----
diff --git a/asteroid/test-suites/regression-tests/test157.ast b/asteroid/test-suites/regression-tests/test157.ast
index ed8ccfdd..69217b05 100644
--- a/asteroid/test-suites/regression-tests/test157.ast
+++ b/asteroid/test-suites/regression-tests/test157.ast
@@ -85,10 +85,10 @@ end
 --                                      **********************
 --                                      **** ldexp        ****
 --                                      **********************
-assert( math@ldexp(7,7) == 896.0 ).
-assert( math@ldexp(-4,12) == -16384.0 ).
-assert( math@ldexp(11,-3) == 11.0/8.0 ).
-assert( math@ldexp(9,8) == 2304.0 ).
+assert( math@isclose( math@ldexp(7,7) , 896.0 )).
+assert( math@isclose( math@ldexp(-4,12) , -16384.0 )).
+assert( math@isclose( math@ldexp(11,-3) , 11.0/8.0 )).
+assert( math@isclose( math@ldexp(9,8) , 2304.0 )).
 
 try
     mathldexp("hello",7).
@@ -110,7 +110,7 @@ assert( math@prod( [1,2,3,4,5] ) == 120 ).
 assert( math@prod( (1,2,3,4,5) ) == 120 ).
 assert( math@prod( [-2,-2,-2,-2] ) == 16 ).
 assert( math@prod( [-2,-2,-2,-2,-2] ) == -32 ).
-assert( math@prod( (12.3,100.01,14.56,9.5) ) == 170150.61336 ).
+assert( math@isclose( math@prod(12.3,100.01,14.56,9.5) , 170150.61336) ).
 assert( math@prod( [1,2,3,4,5] ) == math@prod( (5,4,3,2,1) ) ).
 
 try
@@ -133,7 +133,7 @@ assert( math@sum( [1,2,3,4,5] ) == 15 ).
 assert( math@sum( (1,2,3,4,5) ) == 15 ).
 assert( math@sum( [-2,-2,-2,-2] ) == -8 ).
 assert( math@sum( [-2,-2,-2,-2,-2] ) == -10 ).
-assert( math@sum( (12.3,100.01,14.56,9.5) ) == 136.37 ).
+assert( math@isclose(  math@sum( (12.3,100.01,14.56,9.5) ) , 136.37) ).
 assert( math@sum( [1,2,3,4,5] ) == math@sum( (5,4,3,2,1) ) ).
 
 try
@@ -151,8 +151,8 @@ end
 --                                      **********************
 --                                      **** fsum         ****
 --                                      **********************
-assert( math@fsum( [0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1] ) == 1.0 ).
-assert( math@fsum( (1.0/5.0,1.0/5.0,1.0/5.0,1.0/5.0,1.0/5.0) ) == 1.0 ).
+assert( math@isclose( math@fsum( [0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1] ) , 1.0 )).
+assert( math@isclose( math@fsum( (1.0/5.0,1.0/5.0,1.0/5.0,1.0/5.0,1.0/5.0) ) , 1.0 )).
 
 try
     math@fsum( ["h","e","l","l","o"] ).
@@ -190,14 +190,14 @@ end
 --                                      **********************
 --                                      **** copysign     ****
 --                                      **********************
-assert( math@copysign(1.1,2.2) == 1.1 ).
-assert( math@copysign(1,2) == 1 ).
-assert( math@copysign(1.1,-2.2) == -1.1 ).
-assert( math@copysign(1,-2) == -1 ).
-assert( math@copysign(-1.1,2.2) == 1.1 ).
-assert( math@copysign(-1,2) == 1 ).
-assert( math@copysign(-1.1,-2.2) == -1.1 ).
-assert( math@copysign(-1,-2) == -1 ).
+assert( math@isclose( math@copysign(1.1,2.2) , 1.1 )).
+assert( math@isclose( math@copysign(1,2) , 1 )).
+assert( math@isclose( math@copysign(1.1,-2.2), -1.1 )).
+assert( math@isclose( math@copysign(1,-2) , -1 )).
+assert( math@isclose( math@copysign(-1.1,2.2) , 1.1 )).
+assert( math@isclose( math@copysign(-1,2) , 1 )).
+assert( math@isclose(  math@copysign(-1.1,-2.2) , -1.1 )).
+assert( math@isclose( math@copysign(-1,-2) , -1 )).
 
 try
     math@copysign( "a",-12 ).
@@ -278,10 +278,10 @@ end
 --                                      **********************
 --                                      **** atan2        ****
 --                                      **********************
-assert( math@atan2(12,10) == 0.8760580505981934 ).
-assert( math@atan2(0.5,1.666) == 0.29156692663601214 ).
-assert( math@atan2(-0.9,4.001) == -0.22126091552495672 ).
-assert( math@atan2(-1,-1) == -2.35619449019234484 ).
+assert( math@isclose( math@atan2(12,10) , 0.8760580505981934) ).
+assert( math@isclose( math@atan2(0.5,1.666) , 0.29156692663601214) ).
+assert( math@isclose( math@atan2(-0.9,4.001) , -0.22126091552495672) ).
+assert( math@isclose( math@atan2(-1,-1) , -2.35619449019234484) ).
 
 try
     math@atan2( 5.5,"hello" ).
@@ -299,11 +299,11 @@ end
 --                                      **********************
 --                                      **** remainder    ****
 --                                      **********************
-assert( math@remainder(12,10) == 2.0 ).
-assert( math@remainder(2,2) == 0.0 ).
-assert( math@remainder(2,4) == 2.0 ).
-assert( math@remainder(2,0.5) == 0.0 ).
-assert( math@remainder(0.5,0.11) == -0.05 ).
+assert( math@isclose( math@remainder(12,10) , 2.0 )).
+assert( math@isclose( math@remainder(2,2) , 0.0 )).
+assert( math@isclose( math@remainder(2,4) , 2.0 )).
+assert( math@isclose( math@remainder(2,0.5) , 0.0 )).
+assert( math@isclose( math@remainder(0.5,0.11) , -0.05 )).
 
 try
     math@remainder( 5.5,"hello" ).
@@ -321,11 +321,11 @@ end
 --                                      **********************
 --                                      **** expm1        ****
 --                                      **********************
-assert( math@expm1(0) == 0.0 ).
-assert( math@expm1(1) == 1.718281828459045 ).
-assert( math@expm1(2) == 6.38905609893065 ).
-assert( math@expm1(2.1) == 7.16616991256765 ).
-assert( math@expm1(-1.1) == -0.6671289163019205 ).
+assert( math@isclose( math@expm1(0) , 0.0 )).
+assert( math@isclose( math@expm1(1) , 1.718281828459045 )).
+assert( math@isclose( math@expm1(2) , 6.38905609893065 )).
+assert( math@isclose( math@expm1(2.1) , 7.16616991256765 )).
+assert( math@isclose( math@expm1(-1.1) , -0.6671289163019205 )).
 
 try
     math@expm1( "hello" ).
@@ -343,10 +343,10 @@ end
 --                                      **********************
 --                                      **** log2         ****
 --                                      **********************
-assert( math@log2(4) == 2.0 ).
-assert( math@log2(16) == 4.0 ).
-assert( math@log2(1024.0) == 10.0 ).
-assert( math@log2(2.1) == 1.070389327891398 ).
+assert( math@isclose( math@log2(4) , 2.0 )).
+assert( math@isclose( math@log2(16) , 4.0 )).
+assert( math@isclose( math@log2(1024.0) , 10.0 )).
+assert( math@isclose( math@log2(2.1) , 1.070389327891398 )).
 
 try
     math@log2( "hello" ).
@@ -364,10 +364,10 @@ end
 --                                      **********************
 --                                      **** log10        ****
 --                                      **********************
-assert( math@log10(10) == 1.0 ).
-assert( math@log10(100) == 2.0 ).
-assert( math@log10(1000.0) == 3.0 ).
-assert( math@log10(200.1) == 2.3012470886362113 ).
+assert( math@isclose( math@log10(10) , 1.0 )).
+assert( math@isclose( math@log10(100) , 2.0 )).
+assert( math@isclose( math@log10(1000.0) , 3.0 )).
+assert( math@isclose( math@log10(200.1) , 2.3012470886362113 )).
 
 try
     math@log10( "hello" ).
@@ -385,10 +385,10 @@ end
 --                                      **********************
 --                                      **** dist         ****
 --                                      **********************
-assert( math@dist( (1,1) , (1,2) ) == 1.0 ).
-assert( math@dist( (1,1) , (2,1) ) == 1.0 ).
-assert( math@dist((2,3,4,5,6),(6,7,3,4,5)) == 5.916079783099616 ).
-assert( math@dist((1,1),(100,175)) == 200.19240744843447 ).
+assert( math@isclose( math@dist( (1,1) , (1,2) ) , 1.0 )).
+assert( math@isclose( math@dist( (1,1) , (2,1) ) , 1.0 )).
+assert( math@isclose( math@dist((2,3,4,5,6),(6,7,3,4,5)) , 5.916079783099616 )).
+assert( math@isclose( math@dist((1,1),(100,175)) , 200.19240744843447 )).
 
 try
     math@dist( "hello","world" ).
@@ -406,11 +406,11 @@ end
 --                                      **********************
 --                                      **** hypot        ****
 --                                      **********************
-assert( math@hypot( 3 , 4 ) == 5.0 ).
-assert( math@hypot( 1 , 1 ) == math@sqrt(2) ).
-assert( math@hypot( 5 , 5 ) == math@sqrt(50) ).
-assert( math@hypot( 8 , 15 ) == 17.0 ).
-assert( math@hypot( 13 , 17 ) == math@sqrt( math@pow(13,2) + math@pow(17,2)) ).
+assert( math@isclose( math@hypot( 3 , 4 ) , 5.0) ).
+assert( math@isclose( math@hypot( 1 , 1 ) , math@sqrt(2) )).
+assert( math@isclose( math@hypot( 5 , 5 ) , math@sqrt(50) )).
+assert( math@isclose(math@hypot( 8 , 15 ) , 17.0 )).
+assert( math@isclose( math@hypot( 13 , 17 ) , math@sqrt( math@pow(13,2) + math@pow(17,2)) )).
 
 try
     math@hypot( "hello","world" ).
@@ -428,10 +428,10 @@ end
 --                                      **********************
 --                                      **** error        ****
 --                                      **********************
-assert( math@erf( 1.1 ) == 0.8802050695740817 ).
-assert( math@erf( -1.1 ) == -0.8802050695740817 ).
-assert( math@erf( 10 ) == 1.0 ).
-assert( math@erf( 0.13333 ) == 0.1495600366981686 ).
+assert( math@isclose( math@erf( 1.1 ) , 0.8802050695740817 )).
+assert( math@isclose( math@erf( -1.1 ) , -0.8802050695740817 )).
+assert( math@isclose( math@erf( 10 ) , 1.0 )).
+assert( math@isclose( math@erf( 0.13333 ) , 0.1495600366981686 )).
 
 try
     math@erf( "hello" ).
@@ -450,9 +450,9 @@ end
 --                                      **** errorc       ****
 --                                      **********************
 assert( math@isclose( math@erfc( 1.1 ) , 0.11979493042591827 )).
-assert( math@erfc( -1.1 ) == 1.8802050695740817 ).
-assert( math@erfc( 10 ) == 2.088487583762545e-45 ).
-assert( math@erfc( 0.13333 ) == 0.8504399633018314 ).
+assert( math@isclose( math@erfc( -1.1 ) , 1.8802050695740817 )).
+assert( math@isclose( math@erfc( 10 ) , 2.088487583762545e-45 )).
+assert( math@isclose( math@erfc( 0.13333 ) , 0.8504399633018314 )).
 
 try
     math@erfc( "hello" ).
@@ -470,10 +470,10 @@ end
 --                                      **********************
 --                                      **** gamma        ****
 --                                      **********************
-assert( math@gamma( 1.1 ) == 0.951350769866873 ).
-assert( math@gamma( -1.1 ) == 9.714806382902898 ).
-assert( math@gamma( 10 ) == 362880.0 ).
-assert( math@gamma( 0.13333 ) == 7.0407639878879245 ).
+assert( math@isclose( math@gamma( 1.1 ) , 0.951350769866873 )).
+assert( math@isclose( math@gamma( -1.1 ) , 9.714806382902898 )).
+assert( math@isclose( math@gamma( 10 ) , 362880.0 )).
+assert( math@isclose( math@gamma( 0.13333 ) , 7.0407639878879245 )).
 
 try
     math@gamma( "hello" ).
@@ -491,10 +491,10 @@ end
 --                                      **********************
 --                                      **** lgamma       ****
 --                                      **********************
-assert( math@lgamma( 1.1 ) == -0.04987244125984036 ).
-assert( math@lgamma( -1.1 ) == 2.273651152924464 ).
-assert( math@lgamma( 10 ) == 12.801827480081467 ).
-assert( math@lgamma( 0.13333 ) == 1.9517166852887797 ).
+assert( math@isclose( math@lgamma( 1.1 ) , -0.04987244125984036 )).
+assert( math@isclose( math@lgamma( -1.1 ) , 2.273651152924464 )).
+assert( math@isclose( math@lgamma( 10 ) , 12.801827480081467 )).
+assert( math@isclose( math@lgamma( 0.13333 ) , 1.9517166852887797 )).
 
 try
     math@lgamma( "hello" ).