-------------------------------------
Version 3 build 49 (11 February 2009)
-------------------------------------
Corrected error in flt$. All powers of ten where analysed to 1, for example 
flt$(100,2) -> 1,00*10E0
-------------------------------------
Version 3 build 48 (14 November 2008)
-------------------------------------
The 'stop' string also works when writing:
fil$("file.txt",w)
fil$(,STR," \n\r\t")
fil$(,,,"Workers go to strike")
This writes "Workers" to file.txt

The 'stop' string can also be specified when reading or writing:

fil$(,,"/","Workers go to strike! (For/ higher wages")
fil$("file.txt",r)
fil$(,STR)
fil$(,,".!?,;")

An empty stop string means: write all of the string.
(Or read to end of file, if file mode is reading).
In previous versions the default behaviour was to read until the end of
the line.
-------------------------------------
Version 3 build 47 (11 September 2008)
-------------------------------------
x^(y*(a+b))+-1*x^(a*y+b*y) returns 0 
Before, the exponents were regarded as different. If, during comparison, 
a subtree of lhs has pattern ?*(?+?) and the corresponding subtree of the rhs 
?+?, the lhs subtree is expanded to a sum (defactorised) and the comparison is
done on the transformed lhs and the rhs. Notice that the most expensive 
exponent survives:
x^(y*(a+b))+x^(a*y+b*y): 2*x^(y*(a+b))

0^-1 succeeded and returned 0, now it fails. (0/7^-1 already failed)

Strings starting with a zero and followed by another figure are not numbers 
00/7, 098

Input ()k went in endless loop, because the k was interpreted as an operator.
Now it says "malformed input".
-------------------------------------
Version 3 build 46 (11 February 2008)
-------------------------------------
whl' now returns built_in_function_ok instead of function_fail. Although the 
loop exits when the rhs fails and there therefore is nothing meaningful to
"return", it led to ugly code when a whl' loop always had to be negated

    ... & ~(whl'(...)) & ...

or put into the lhs of an OR

    & ( whl'(...) |  ) &
    
til' is commented out. It has no future.    
------------------------------------
Version 3 build 45 (4 February 2008)
------------------------------------
New version because of 
(A) introduction of a new flag that makes it possible to write position-aware
    patterns and 
(B) introduction of control structures for implementing loops.

Function evalmacro did not unset the ready-bit on an inserted expression 
consisting of a variable with exclamation mark. It does now.

Introduction of flag [ for acquiring or requiring the current position during
a (string)match. Examples:

    a b c:? ([-1:[?endpos)
    
will assign the length of the subject, 3, to variable endpos.

    a b c d e:? [!endpos ?extramaterial
    
will assign d e to extramaterial.

Works in match and stringmatch alike, with some exceptions:
@(:[0) succeeds, but (:[0) fails. Reason: in the first case, the subject
is the nil element, but in the second case, the lhs is just an atom,
although a funny one. In a certain context, this atom plays the role
of nil element, but not in other contexts.

Found out that stringmatch had a measurable side effect on the subject

subject=abcdef
@(!subject:? (d & !subject:abcd) ?

This would succeed, because the string had been temporarily cut off after
the 'd'.
Now match and string match are much more alike and the problem is solved.

Introduction of two built-in functions: whl and til. whl repeatedly evaluates
its argument until it fails. whl always returns failure. til repeatedly
evaluates its argument until it succeeds and returns the result of the last
evaluation.
There are no plans to make if...else and switch equivalents in Bracmat.
It may be that whl and/or til are retracted later. They seem a bit superfluous.

`~a:?b will now assign `~a to b
@(`~a:?b) will assign a to b. !a will succeed
As before, this will assign something failing to a variable:
dummy ~a:dummy ?m
!m fails
~!m gives ~a

-----------------------------------
Version 2 build 42 (3 January 2008)
-----------------------------------

Better implementation of the evaluation of !(=a).
It is now possible to construct and run a loop as a datastructure with 
a closed loop of pointers. Performance-wise nothing is gained, however.
  (loop= !i+1:<10000000:?i&!(=))
& '$loop:(=?(loop.)) {Make closed datastructure}
& ~!loop {loop 10.000.000 times}
& :?(loop.) {Open the datastructure.(Otherwise you'll have a memory leak when 
             'loop' goes out of scope.)}

Several functions have been factorised. evalueer() has been restructured.

-----------------------------------
Version 2 build 41 (2 January 2008)
-----------------------------------

I've decided that a:(~@(a:a)) means about the same as a:(~@:(a:a)), i.e. it
fails because a is not not an atom. For the same reason a:(~@(a:b)) fails.
~@(a:a) in an evaluation context such as x&~@(a:a) succeeds. It merely means
a:a

Use #define STRINGMATCH_CAN_BE_NEGATED 1 to allow ~@(<subject>:<pattern>)
as a stringmatch that has its result negated after evaluation.

Use #define STRINGMATCH_CAN_BE_NEGATED 0 to interpret ~@(<subject>:<pattern>)
as the opposite of stringmatch, i.e. a normal match, the same as 
(<subject>:<pattern>) with the additional condition that <subject> is not an
atom. Notice, however, that ~@#(abc:? b ?) succeeds, as the ~ negates #, not @
(priority /#<>@)

Succeeding tests:
a b:(~@(? b:a %))
~@(a b:a ?)
~@(a:a)
12/34:@(?x:#?a (~#%@:?y) #?b)&!y:"/"

Failing tests:
a:(~@(a:a))
~@(a:b)
12/34:@(#?a (~#%@:?y) #?b:?x)&!y:"/" 
    (This fails because the pattern 
        #?a (~#%@:?y) #?b 
    is in the match context 12/34:<rhs>, not in a stringmatch context.
    Remember, the first @ says that subject is an atom, which it is in the 
    match context, but not in a stringmatch context.)
@(12/34:@(#?a (~#%@:?y) #?b:?x)&!y:"/") 
    (This fails because 12/34 is not an atom in a stringmatch context.)

-------------------------------------
Version 2 build 40 (29 December 2007)
-------------------------------------

Compilation with Norcroft RISC OS ARM C vsn 3.00 [Jul 12 1989]
This resulted in some formal corrections (signed vs unsigned int,
int vs long, too many arguments for format in printf,
#if BRACMATEMBEDDED changed to #if defined BRACMATEMBEDDED)

The changes of 20071217 were undone, because the solution did not work for
    ~(&~@(a:a))
New solution:
In lex(), undo setting of
    success == FALSE
on : node if ~@ flags are attached to this operator.
This is a special case. In ~@(a:b) the ~ operator must
not negate the @ but the result of the string match.

I am not convinced that this is the right decision. Perhaps we simply
should not allow other flags than @ on : if we want it to be interpreted
as a string match operation.

------------------------------------
Version 2 build 39 (17 December 2007)
------------------------------------
Resolved the following errors: 
~@(a:b) did not succeed and 
~@(a:a) did not fail.
Now they do.

------------------------------------
Version 2 build 38 (9 October 2007)
------------------------------------
Removed test print from getObjectDef.

------------------------------------
Version 2 build 37 (18 September 2007)
------------------------------------
    a b () () 
evaluated to 
    a b ()
instead of
    a b
Changed function handleLUCHT to correct this.

------------------------------------
Version 2 build 36 (20 August 2007)
------------------------------------
Broken functionality repaired:
The pattern (|? " "|`) did not only match a string starting with all blanks.
It matched any string with a blank. 

Differentiation: Originally, to indicate that a variable x depends on another
variable p, one wrote x=p, or x=s and s=p. If one wrote (x=), then y\Dx
resulted in stack overflow. The appropriate way to indicate dependeny is
dep=(x.p) (....)

The C-function range() has been abolished. Originally the idea was that Bracmat
not only should handle numbers and symbols, but also ranges. Thus, 2^>3 would
give >16 and -5*>2 would give <-10. This had to be given up as ranges become
more and more complicated to express. (>4*~>3 = ?)

Code implementing a string table (COMPILE==1) has been removed
COMPILE works not faster, but slower (about 10%) and uses more nodes.

The unfinished attempt at implementing objects that can be saved and re-read
(serialization) has been given up (OBJECTS==1) Flag: [

VAX-specific code removed.

Partly undoing of a change made in 200704:
There were problems with stringmatches like this one
@(aaab:((|a) aa) b)

Division by zero in

new$hash:?h
(h..ISO)$
(h..insert)$(a.b)

This made a division by zero, because (h..ISO) had rehashed the table
to a table with zero size. (hashes are born with non-zero size)
The computation of the loadfactor went wrong.

------------------------------------
Version 2 build 34 (4 April 2007)
------------------------------------
Tail recursion optimisation in complexiteit.

Solved bug in handling of strings with characters > 0x80 in expressions like
    a 

Solved bug in handling of e^(i*pi)

Solved bug in handling of i:-i

Solved bug in handling of -1*i^1/3

lst$ now lists ALL names. Previously, names starting with character above 0x7f
were hidden. Som hidden functions that were called from f0, f4 or f5 are
now declared inside these functions and therefore hidden.

get$ and fil$ first try to open a file interpreting the file name as a path
relative to the current working directory. If that fails, and if the program
is started with a fully qualified path+file name, this path is prepended to the
name of the file to be opened. If opening the file also fails with the new
path, get$ and fil$ fail. This functionality requires that 
1) the file mode is "reading"
2) the file name does not contain an absolute path
3) the program knows its path
If the program does not know its path, it may help to start the program with
a fully qualified path on the command line. This instruction can be put in
a shell script or batch file.
This improvement is especially helpful for opening the "help"-file.

In string matching the expression
    @(abcd:?u (?:%@ %@) (?z & ~))
now makes sure that the pattern (?:%@ %@) never is presented with more than two
characters. Before, the @ flag did not really work with string matching and the
: operator extinguished the cut condition that arises in its rhs.
This works now within a reasonable time:
(do=
  get$(help,STR):?S
& @( !S
   :   ?
       ( ?:(%@:~" ":~",") %@ %@ %@ %@ %@ %@ %@ %@ %@ %@ %@ %@ %@ %@ %@ %@ %@ %@ %@ %@ %@ %@:?x
       & '(? ()$x ?):(=?x)
       )
       !x
   )
& !x);
!do


In a string, characters that also have a meaning as an operator can be escaped:
nsc\'ere
is the same as
"nsc'ere"

The names of cat$'s local variables are now taken from the list of names of
predefined functions. Consequently, cat$ does not list its own local variables.
(Previously, listing of these names was circumvented by the rule that names
starting with high-bit-set characters are kept hidden.)

Defunct ego$ and goe$ are abolished.

------------------------------------
Version 2 build 26 (18 January 2007)
------------------------------------
Corrected error in string matching that caused @(:? ?) to fail.
Adaptations to let Visual C++ 8.0 behave nice: no warnings against now
deprecated str... functions and turning Windows API functionality off
when _CONSOLE is defined.

------------------------------------
Version 2 build 24 (12 October 2005)
------------------------------------
Corrected error in flt$. During rounding, the variable m could become > 10.
Consequently, the exponent must be increased by one and m must be divided by 10
in those cases.

------------------------------------
Version 2 build 23 (7 October 2005)
------------------------------------
Changed 'flg' function.
flg$<flags><atom> now returns ((=<flags>).<atom>)
This protects the flags from evaluation, so that it now is possible to handle
the '!'-flag using this function.

------------------------------------
Version 2 build 22 (18 November 2004)
------------------------------------
Changed handling of output of the clock() function (again). Back to the
assumption that clock_t is long int. When clock() returns -1, it is assumed
that clock() does not return reliable values (any more).
bez$ returns (<nodes>.<max nodes>.<max ref>) and does not print to stdout
anymore. The meaning of these numbers is:
<nodes> : number of allocated nodes and leaves.
<max nodes> : the maximum number of allocated nodes and leaves attained during
this session up to "now".
<max ref> : the maximum reference count seen on any node or leave during this
session up to "now". This number has a ceiling dependent on the number of bits
reserved for reference counting (currently 10).
epoc version had the problem of not deleting the last typed in character
when the user pressed the delete key. The delete key emits ascii 8
(back space). Now, ascii(8) moves the pointer in a newly created input buffer
one position back, deleting the previous entered character. At the same time,
the last typed character, which otherwise would still be visible, is wiped
out. (see mygetc)

------------------------------------
Version 2 build 21 (9 November 2004)
------------------------------------
Changed handling of output of the clock() function. Previously its return
value was type casted to long int. The program no longer makes any assumption
of clock_t's size.

------------------------------------
Version 2 build 20 (4 October 2004)
------------------------------------
Added new built-in function flg$ that splits off flags from an expression.
Changed the meaning of the '~' flag in flag functions when the '~' isn't
the only flag: ~#$a now evaluates to ~#a. Before, this function call
just failed.
Removed flags from variables that get values during string pattern matching.
Before, flags originating from the subject were inherited by all variables.
Example:
@(#~barQfoo:?x Q ?y)
Before, !x evaluated to ~#bar and !y evaluated to ~#foo. Now !x evaluates 
to bar and !y evaluates to foo. I'm not sure this change is especially
handy.

------------------------------------
Version 2 build 19 (27 September 2004)
------------------------------------
Replaced the non-ANSI strrev function with portable code.
No change in functionality.

------------------------------------
Version 2 build 18 (21 September 2004)
------------------------------------
Fixed memory leak in assignment to variable during string match.

------------------------------------
Version 2 build 17 (14 September 2004)
------------------------------------
Fixed error that caused 'val' to receive value -1 in @("-1":?val). Now the 
value is "-1".

------------------------------------
Version 2 build 16 (8 September 2004)
------------------------------------
Previously, string matching did not attribute the "NUMBER" flag to
variables in expressions like @("fasdf-1hhfgls":? #?val ?), which meant
that !val+1 would be handled like "-1"+1. Now 'val' gets the value minus one.

------------------------------------
Version 2 build 15 (7 September 2004)
------------------------------------
Serious error fixed: a b c:(a b|x) c  and @(a b c:(a b|x) c) failed!
If the sides of the OR operator where swapped the error would not occur.


------------------------------------
Version 2 build 14 (6 September 2004)
------------------------------------
In the combination of ~ and @, the ~ negated the @. In string pattern matching
the ~ must negate the outcome of the pattern matching. This is now fixed.


------------------------------------
Version 2 build 13 (3 September 2004)
------------------------------------
The hash member function 'forall' was unsafe, as it assumed that the contents
of the hash table would not change during the traversal. This has been fixed.
The hash table can even be deleted while the table is traversed, but the 
deletion takes place after the traversal is finished. The 'forall' function
is exited as soon as the function passed to forall fails.
Hash tables did grow as the load factor became too high, but never got
smaller as the load factor became sufficiently low. This has been fixed as 
well.

------------------------------------
Version 2 build 12 (31 August 2004)
------------------------------------
New function rev$ that reverses the order of characters in a string.
String-pattern matching much simplified. Now it behaves more like non-string
pattern matching. Instead of using complicated pre-match functions that try
to minimise costly substring manipulation, substring manipulation is made
"lazy". That means that copies of substrings are not allocated until they are
needed the first time. Until that time, only a bytecount and an offset into
the complete string are kept.


------------------------------------
Version 2 build 8 (26 February 2004)
------------------------------------
Fixed errors with allocation (function "bmalloc") and deallocation (function "fil").


------------------------------------
Version 2 build 7 (23 February 2003)
------------------------------------
Introduced case-insenstive string match. The flags ~<> in a pattern (without
/ and # flags) mean that subject and pattern must be compared without case
sensitivity. This only applies to ASCII characters and the upper 128 characters
in the ISO8859 (Latin 1) character set.

The string comparison in the sim$ function, which always has been case
insensitive in the lower range of the ASCII character set, is now case
insensitive in all of the Latin 1 character set.


------------------------------------
Version 2 build 6 (16 February 2003)
------------------------------------
Changed "#define ARM 1" to "#define ARM". No changes to functionality.
Created fresh executables for RiscOS and Epoc. (Ericsson MC218, Psion 5mx).


------------------------------------
Version 2 build 5 (24 November 2003)
------------------------------------
New functionality: pattern matching inside strings. Previously, to scan a string
one had first to explode the string into atoms. Now this step is not needed any
more. Example: find the value of the "width"-attribute in the following piece of 
HTML code:

 <table class="bgblue" width="600" cellspacing="0" cellpadding="0">

Suppose that this value has been assigned to the variable "string":

"<table class=\"bgblue\" width=\"600\" cellspacing=\"0\" cellpadding=\"0\">":?string;

Old solution:

get$(!string,MEM,VAP):?atoms;   {"Vaporise" the string.}

!atoms:? w i d t h "=" "\"" ?n "\"" ?;  {Find a string of digits delimited by apostrophes.}

str$!n:?N;                  {Stringise the digits into a number.}

out$!N;                     {Show the result.}

New solution:

@(!string:? "width=\"" #?N "\"" ?);     {Use @-flag on the match operator ':' to enable
                             pattern matching inside the string. Use spaces
                             to separate elements of the pattern. No need
                             to stringise the matched substring.}

out$!N;                     {Show the result.}





------------------------------------
Version 1 build 3 (10 November 2003)
------------------------------------
The evaluation of tay$((x+3/2)^(x+3/2),x,20):?aans gave a memory exception.
This was caused by the attempt to treat 'e' as a rational number in the function
substlog. Added a test.

Removed a serious error that has crippled the pattern matching algorithm since
June 2001: the code having to do with the bit DONOTSHORTEN on the return value
of the match function has been removed. The change amounts to setting the
defined constant KORT to 0. The aim of the introduction of DONOTSHORTEN was to
shortcut the search for a matching pattern, but it did its job too well: the
expression
   a b b:? %?x !x
would fail.

Added some functions that can be used when debugging (or just tracing) the
program:
   * results, reslts, hreslts - like result, reslt, hreslt, but with extra
     argument 'snijaf' (cutoff). The function results can be used to trace the
     arguments of the match function.
   * checksum, getchecksum, setChecksum - can be used to spot out-of-bounds
     writing of memory allocated with bmalloc.
   * Changed some loops with constant test (while(1) or while(TRUE)) to loops
     performing real test. Also removed some 'continue's and 'break's.


-------------------------------
Version 1 build 2 (4 July 2003)
-------------------------------
Overhaul of macros:
   * More comments on each macro's meaning.
   * MACRO
      - The macro MACRO is changed to a defined constant
         (#define MACRO --> #define MACRO 1
          #ifdef MACRO --> #if MACRO)
      - It is now only defined if another predefined constant, COMPILE,
        is not 0.
   * ALLOCVAR
      - The macro ALLOCVAR is changed to a defined constant
         (#define ALLOCVAR --> #define ALLOCVAR 1
          #ifdef ALLOCVAR --> #if ALLOCVAR)
      - It is now only defined if another predefined constant, COMPILE,
        is not 0.
   * Renamed BIG_ENDIAN to BIGENDIAN (The old name clashed with a predefined
     name on some systems.)
   * gcc on linux offers a way to determine the correct value for the constant
     BIGENDIAN. This is used in build 2.

Added column for notes to the comment explaining flags (flgs) and operators
(ops).

Added test on validity of the FILE * variable fpo in the function errorprintf.
Added test on validity of the FILE * variable errorStream in the function
redirectError.


-------------------------------
Version 1 build 1 (3 June 2003)
-------------------------------
Initial version under GPL


