dib manual
(deer project, 2008, Antonio Maschio @ )
Last updated: December 05, 2008

This is not a BASIC primer, but the user manual of dib, the Dartmouth BASIC
interpreter written in C for the gcc.

Index
-----

0. A foreword
1. A bit of personal history as introduction
2. The dib interpreter
        2.1 Origins
        2.2 dib's invoking options
                2.2.1 Options explained
                2.2.2 Customizable items
        2.3 A datum is a datum is a datum...
        2.4 Default features
        2.5 Extended features
        2.6 Error messages
                2.6.1 standard error messages
                2.6.2 extended error warnings
                2.6.3 system error messages
        2.7 The examples
        2.8 The vim 'bs' syntax file
                2.8.1 Installing dib.vim
                2.8.2 Mapping the dib syntax
3. Conclusions
4. Bibliography

-----------------------------------------------------------------------------

0. A FOREWORD
   ----------

Sometimes I read on some mailing list about programming, or on newsgroups
dealing with this or that programming language, or on specific programmers'
web pages, that "BASIC was a primitive language"; well, this may be true, in 
some arcane sense, especially if you consider some modern complicated language
like java, C++ or Delphi or peculiar languages such as Prolog, Lisp, Forth.
But I contest this sentence 1) because BASIC 'was' not, BASIC 'is'; 2) because
BASIC is not primitive: it's simple. It's a rather different question.
Imagine you have to solve a math problem, say a system of linear equations,
and suppose you've got to write a program for this; which language will you
choose? Your 'favorite' may be too big for such task. Well, in the best case 
you know this language very well, and you will end up without spending hours 
in writing the program, but in the worst case you're lucky if you have not to 
plunge into a 1000 pages user manual or learn tens of system calls.
Why not using Dartmouth BASIC? No more than a bunch of lines (containing even 
the problem data) and the solution is there. No manuals, no system calls.

Yes, BASIC is an unstructured language - and someone said that a programmer
exposed to BASIC is likely to never learn well another language (this ain't
true, obviously) - so I guess that, if BASIC is unstructured, it expects you
to give it a structure. And the structure you create may make it spaghetti-code
looking, or make a superb listing of it. Dartmouth BASIC gives you two dozens 
of statements and a consistent way to use them. It gives you a simple structure 
for each statement and you have to build a wider structure for your program.
It's up to you: BASIC has no soul, it waits for you to give it one. 

After all, BASIC is a language that can be used by anyone, that won't force you 
to format numbers output, that uses matrices like numbers, that solves systems 
of equations in a bunch of statements, that remains familiar and usable for 
years. Some of us wouldn't ask for more.

Yes, using such a language today is quite unrealistic. I had to write my own
interpreter to do it, and this is not what I call a friendly way.
But hail to those guys who conceived such a language in 1964!!


1. A BIT OF PERSONAL HISTORY AS INTRODUCTION
   -----------------------------------------

In the fall of 1980 I was fourteen, and I began my High School. A schoolmate, 
who had later to became my best friend, received a magnificent Commodore 64 
with monitor for Christmas, or so. For the rest of that year, and the following 
1981, I tried to convince my parents of the extraordinary need I had for such a
computer and that I couldn't even imagine how to get through University without
it! Lost words. My father, whose sight was very long, told me he could get his 
High School degree with a 5 inches slide-rule. Thus, a computer was not a need.

What could I do? I spent a lot of time in my friend's room, staring at the 
wonderful colors of the screen, and learning my first BASIC words while 
listening to him reading sources and watching him typing commands. Once back 
home, the only way to relax was playing my guitar, because even my calculator 
was not programmable. I was in a sort of "need of programming"...

Anyway, in 1982, my father finally made me a gift for my 16th birthday: 
the CBM64! I wasn't surprised at all, since I think I had stressed him a lot 
for that (in Italy, those were the days of microcomputers, and first computer 
magazines - BIT, Microcomputer, and others - each full of listings in BASIC for
this or that computer, were flourishing in our newsstands, fighting a sort of 
battle of the dwarves between the CBM64 and the ZX Spectrum).
The first thing I wrote was a program to draw a function y=f(x) in the 
Cartesian space, plotted in high resolution on the screen (I'm afraid I was 
not so smart to do it all alone: probably, I took the original source from a 
magazine and changed it a bit). Anyway, the pride I felt showing the results 
to my father pushed me to learn more about programming; I bought then the C64 
monitor, the 1541 disk drive and [4].

I began studying [4], learning that machine language was available through some
hacking, learning about sprites, the three independent music oscillators (a
system called SID), all the peculiar memory addresses, but I didn't go beyond 
BASIC for two reasons: first, machine language seemed to me too difficult and 
strange and second, I thought BASIC was a wonderful language to do quite 
everything (though programs ran slowly!). I bought then [3] and began studying 
it seriously. The book was very professional, and all (or quite so) was
applicable to my home computer, so I felt like a very mature programmer! One
thing baffled me: the fact that all MAT statements were completely missing 
from my home computer, while I was sure it was more recent than the one 
described in the book!

In 1985 I began my University years, and for many years I couldn't do anything 
else with the Commodore unit. I studied Pascal and Fortran 77, using the VAX 
mainframe of the University Calculus Room, equipped with UNIX (circa 1987-88); 
much later, I could use PCs with DOS (circa 1990-91, I believe version 2.x), 
and so the CBM64 was left behind, with all its power. At home, abandoned, the 
C64 went ruined, and one day my mother got rid of it without even telling me. 
The day I knew what happened was a very sad day!

In 1993 my parents bought me a PC with Windows 3.11: it served me to do some
word processing for my thesis, but it was also a starting point in serious
computing. When I finally got my degree in civil engineering, in 1994, I began 
working, and years began to fly.

In 1998 I installed linux on my PC and began studying C, bash and prolog, and 
BASIC was not in my mind. So I lost any contact with it: line numbering, GOTOs,
the absence of specific functions and procedure calls, and other minor things,
confronted to the "new" languages I was learning, led me to forget BASIC, 
because it was old.

				***	***

Time takes its time to work, but it works. In the summer of 2004, I visited Ron
Nicholson's site by chance, and discovered his chipmunk basic interpreter. 
Ah!: BASIC was not dead, after all!
Next, reading some documents found in Internet ([1] in particular) I learned 
that BASIC was born in the Dartmouth College in 1964 (many years before C!), 
that its first versions were compiled and that they dealt with matrices (a 
feature that was stripped from all subsequent BASICs). These facts were so 
appalling that I took the C64 manual and the Gottfried book out of their dust; 
reading them again revealed me one mere thing: I didn't cease to love BASIC. 

Next step was conceiving a BASIC interpreter on my own, to be developed on my 
brand new emac 1.42 equipped with Mac OS X. Why not? There are dozens of 
compilers and interpreters in the world, one more will do no harm. The reason 
that led me to forget BASIC is now the reason that leads me to love it: 
because it's old!


2. THE dib INTERPRETER
   -------------------

2.1 ORIGINS
    -------

Development step #0: deer

Well, even before there was a minimal BASIC interpreter to work with, I began 
working on the Operating System Emulator, deer. The name popped up all alone 
even since, and was never changed. The fact I used bash for it is no surprise:
what language has such facilities to deal with strings? And what should I deal
with? Strings.

So bash was a natural choice (even if my second thought was to use C or java - 
it's still hanging around my brain). The emulator came out evening after 
evening, in a very natural way, and soon I realized I had a working environment
but no interpreter to test it. That's why, after quite a year, I left deer 
behind and looked around for ideas on how to build my own BASIC interpreter.

During the following steps I've never ceased to carve and smooth deer code, 
adding commands and beautifying code here and there. 

Development step #1: dbasic3

The first conception of the interpreter was named dbasic3, because I meant to 
write a Dartmouth BASIC interpreter version III. After a few weeks, I had 
written nothing more than an engine(called version 0.1) to read file lines and 
execute them directly, and some code for GOTO, GOSUB..RETURN, FOR..TO..NEXT and
END. I had some ideas on how to store source code lines (through malloc) but
the algebraic parser was still beyond my power. 

So I started looking around, and one day, surfing in Ron Nicholson's site (the 
author of Chipmunk BASIC) I found a reference to dds_basic, an appalling tiny 
BASIC interpreter written in obfuscated C as Public Domain by Diomidis 
Spinellis, a Greek guru who won the 1991 International Obfuscated C Code 
Contest (http://www.ioccc.org/all/summary.txt) with such program. ds_basic
has the following features:

    * it's interactive (OLD, NEW, RUN, SAVE...)
    * it deals with integers
    * it has the four basic operators (+,-,/,*)
    * it has one-letter variables A..Z
    * it's got a complete minimal set of statements 
      (FOR..TO, GOSUB..RETURN, GOTO, END, INPUT, PRINT)
    * it doesn't do any error check; as long as sources are correct, 
      it's fast and furious.
    * it's, with a source code less than 1000 characters long, amazing!

After decoding the dds_basic.c source file, I analyzed the whole code, and 
boys if I was astonished! I made up my mind and stopped version 0.1 because 
I wanted to integrate dds_basic into my code.

After introducing some of dds:basic features into my version 0.1, I renamed it 
0.2 (it was still interactive), and enhanced some of dds_basic features (real
numbers, variables A0..Z9, some add-ons here and there and many many scattered 
TODOs).

Development step #2: dbasic

Version 0.2 was a first step, but I wanted to build my own software, leaving 
little of Spinellis' code into my own: so I decided to discard this version 
and build up a new revision, 0.3, which could benefit from the parser and other
functions by dds_basic, while the rest had to be written by me. I decided to 
make it non-interactive, because I wanted a real UNIX program. So I wrote only 
the code for reading lines and executing them. I imported the primitives I 
created for version 0.1, completed them with PRINT (still rough), DATA, READ, 
IF..THEN, INPUT, DEF (a draft), and set up a minimal expandable error detecting
system. Version 0.3 was ready. I renamed it dbasic, because I thought version 
III was beyond my power, so I arranged for a generic Dartmouth BASIC emulator.

Next versions 0.4 and 0.5 were nothing more than improvements over this 0.3, 
but each featured an indecent numbers of bugs corrections. In particular, 0.5 
was the first to incorporate the DIM statement, and the first to feature the 
header file dbasic.h.

(From time to time, when I speak to myself, I call my BASIC interpreter dbasic. This name was THE name. Read on.)

Development step #3: db66

One day, I suddenly realized with pain that another dbasic was around on the 
Internet, and I had to change its name. I hurryingly chose db66, because now I 
had clear in mind that I wanted to emulate version III of the original 
Dartmouth BASIC at all costs, because it was the first with a decent minimal 
commands set, even if I had no idea on how doing it. And since it and I were 
both born in 1966, db66 sounded good. But, in all, I didn't like this name 
that much.

In any case, this newly name baptised version 0.6, which was nothing more than 
version 0.5 with an improved mechanism to assign values to array variables; 
next version, 0.7, was the first to incorporate the MAT statements (while 
still... yes, buggy). In any case I'm particularly pride of the MAT INV 
statement, which I built diving again into matrix theory, something I liked a 
lot. The whole commands of version 0.7 worked well with correct BASIC programs,
but I couldn't care much of the error system, yet. Things were about to change
anyway...

Development step # 4: dib

Once version 0.7 was ready, I settled down a bit and decided to reconsider the
project name. db66 was not what I was looking for. So I began thinking:

    This is a GNU project.
    What does GNU mean? Gnu's Not Unix.
    A recursive name? Let's try.
    The first letter is a... 'd' (from Dartmouth)
    So it should sound like... d*** does something, or d*** is something.
    d*** is BASIC. 
    d-i-b. dib is BASIC.

Voilą, the name dib was born. It's simple, it's short, it fits perfectly in the
UNIX style, and above all, it's unique. I later realized that dib could also 
mean "Dartmouth invented BASIC", as an  homage to those two great men in 
Dartmouth and to all Kemeny's kids.

Version 0.8, which consisted of an improved and debugged 0.7 version (you 
cannot imagine how many bugs were still present...), with some enhancement 
(for instance the DEF statement was rewritten) was the first to exhibit the 
'dib' name.

Next version 0.9 (later renumbered 0.9a) was the first to implement a complete
revised error system, and the first to be fed with wrong BASIC programs, to 
test all the error conditions I could conceive. Again, an incredible number of 
bugs were corrected, leaving me the feeling I'll never end up with them...
Besides, I completely rewrote the parser, with an algorithm I conceived to 
realize the algebraic-to-RPN conversion technique. I'm proud of this, because 
it works well and it's robust.

During this development step I began writing down a number of programs and 
transcribing examples from the 1964 manual or from the 1974 Gottfried book, 
to be put into dib's package, and began even writing down the manual. 

Just before releasing the alpha version, I realized many inconsistencies were 
still present (bugs dealing with extremely rare conditions, rather than with 
default behaviors), and so I got through a heavy testing., which enhanced a 
curious fact: for each bug resolved, two arose. Will I ever end up with it? 
I also incorporated the GPL3 default statements to the project. Finally, 
version 1.0 alpha was ready to be turned to beta...

Development step #5: dib beta version

When I finally discovered what I thought was the last bug even in this beta 
(the last in a temporal meaning, of course: many are still there and wait for 
you to bring them up to surface, that's sure!), and after the very last touch 
to the number output function, for a more complete conforming to the Dartmouth 
BASIC output, dib was born, and began seeing the real world! 

                                ***     ***

Two texts were then fundamental: [1], that was important to target the output 
for the PRINT statement and to set up all default features; and [2], that 
helped me to clear all the differences among the six versions, and set up the 
extended features.

				***	***

dib is part of the Dartmouth Environment Elementary Renderer package (deer).

2.2 dib'S INVOKING OPTIONS
    ----------------------

dib must be invoked with the following syntax:

$ dib [options] file

Options are:
  -b                Set array base index to 1 (default is 0)
  -c                Continue execution in case of non-blocking errors
      --conditions  Print redistribution conditions from GPL3
  -d                Activate debug mode
  -h, --help        Display this information and exit
  -l                Display error list and exit
  -t                Print a time report after execution
  -v, --version     Display version and exit
      --warranty    Print warranty conditions from GPL3
  -x                Toggle extended BASIC features setting (default is off)
  -z                Print numbers lower than 1E-10 as zero

A version of this paragraph appears when dib is invoked as dib -h.

2.2.1 OPTIONS EXPLAINED
      -----------------

-b: sets option base to 1; at start, dib has a default 0 index base. In
    extended mode you can set option base to 1 with the OPTION BASE 1
    statement, which is not available in default mode.

-c: after an error, generally dib stops and prints a message; if you want it
    to go on, activate this option, but **at your risk**! In fact, the program
    may call variables not instantiated, or execute jumps or math expressions
    with values not correctly initialized, so a system error (like 
    "segmentation fault" or "BUS error") may appear onto you terminal.
    See paragraph 2.6.

-d: activate debug mode; when debug mode is on, the current line is printed 
    before it is executed; this of course alters the output behavior, but you 
    can trace the program flow, and maybe understand why your BASIC code is not
    working.
    Note: in extended mode, the final line containing END is not required by
    a source file (see ahead); but, in order for the parser to work, if no END
    is met into the source code, a superimposed END statement is implicitly put
    at line 119881 (one above last available line), and this line appears in 
    the debugging session, even if the programmer doesn't expect it.

-h; print the standard UNIX help and exit (also --help).

-l: print the whole error messages list with the relative error code end exit; 
    since a system error causes dib to exit with 100+error code, you can get 
    this exit status in a shell program, and recover the error code active when
    dib was interrupted. If you forget what error message is associated to a 
    particular error code, here's the -l option coming in handy. No program is 
    executed.
 
-t: after the program is terminated, print a timer report in the form:

    TIME:   N SECS.

    where N is the number of seconds execution took (generally zero). It is
    in the style of the 1964 Dartmouth BASIC manual (see for instance p. 19).
    The time (in seconds) is taken starting from the beginning of the BASIC
    code to its mere end, letting out all dib's set-up routines; this results 
    in a pure "BASIC code execution time". No conversion to minutes or hours is
    done if the execution time is longer than 60.

-v; print the standard UNIX version banner, and exit (also --version).

-x: this option enables the extended features. See paragraph 2.5.

-z: all numbers lower than 1E-10 are printed as zero, useful when they may 
    clutter the output, e.g. with matrices. In this case, you can distinguish 
    "pure" zeroes from these approximations because the latter are always 
    preceded by their sign, positive or negative, so that 0 means a zero as 
    calculated by dib, -0 means an approximation (for instance -2.3E-14) as 
    does +0 (for instance 2.3E-14); you can change the limit of 1E-10 changing 
    the EPSILON constant in dib.h.

To know terms of warranty and conditions, type 'dib --warranty' and 
'dib --conditions' (these commands print extracts of license, as required
by the GPL v3).

2.2.2 CUSTOMIZABLE ITEMS
      ------------------

In the file dib.h there are some values you can safely change to suit dib to
your needs:

- 'ef' is the variable flag that controls extended features activation; it's by
  default FALSE; you can change it to TRUE to have extended features always
  activated; if you do it, option -x will disable extended features, rather
  than enable them.

- 'ob' is the option base index; it's by default 0; you can change it to 1
  if you want to have option base index always starting from 1; if you do,
  option -b will have no effect, and the only way to set option base 0 from
  here is using OPTION BASE 0 in extended mode.

- 'false_' (mind the final underscore) is the flag that controls error
  short-circuit; by default it's TRUE, which means that dib stops at every
  error met; if you set it to FALSE, dib will stop only when a blocking 
  error is met (see ahead); if you do it, option -c will set false_ to TRUE
  rather than setting it to FALSE.

- 'EPSILON' is the limit for numbers to be printed as zero. By default it is
  1E-10, so that all numbers lower than EPSILON are printed as zero; you can
  put here any value you like, provided it's not lower than 1E-75, which is
  the lowest number for dib distinguishable from zero.

Don't change other variables, parameters, constants: you may mess up things
and end up with an useless program.


2.3 A DATUM IS A DATUM IS A DATUM...
    --------------------------------

Numbers
-------
As the original BASIC, dib deals with a single number type: real. Any number
is written as an integer if the internal representation of the real is made
of all zeroes after the dot; e.g.:

10 PRINT 1.0

will print 

 1

Notice the space before the number; a place for the sign is always printed
in Dartmouth BASIC and, if positive, a space - not a plus - is printed.
Sometimes reals behave like integers if they have too many zeroes after the dot
and before a non-zero digit; e.g.:

10 PRINT 1.000000002

will print 

 1.

Notice the dot after the number, meaning that the number is not really an
integer, but a "masked" real.
Any number may be input using the ten digits, the prepended minus, the dot and
the letter E for powers of ten (.2 is accepted, 1E2 too, E2 is not). Follow 
instructions on the 1964 manual, dib is built on the same basics.

Number limits are set as follows:
- the max (positive) real is 1E75, identified (in the source) as INFF
- the min (negative) real is -1E75, identified as MINFF
- the smallest absolute value of a real is 1E-75, identified as ZERO
These values have been set after reading on [9], page 5, point 8, that "The 
maximum exponent allowable in the GE-235 is 75".
There are some issues, here; the INFF/MINFF/ZERO limits are not set into
values themselves, but only in printing; so the internal value is preserved
for further calculations; this causes dib to be... ah... clever than the
original (see ahead, errors 30/31). 

According to [11], the use of booleans was not in the Original Dartmouth BASIC;
dib, on the contrary, treats any expression as a truth value, since truth 
values are simply real numbers (set as TRUE=-1 and FALSE=0); of course, this is 
meaningful only if you print out a truth value, e.g. PRINT 3>2 (which is quite
useless) or if you use a variable as truth value, e.g. IF A THEN (which was,
probably, not available in the original BASIC); in the first case the output
will be -1, in the second case, the part after THEN will be executed if A is
different than 0 (any value). Remember that this may not be available in other
dialects.

Variables
---------
dib has the standard variable names as the original BASIC, nothing more. So
A..Z and A0..Z9 are the ranges of all the available variable names. Double
letters or even longer names are forbidden - e.g. AB or TANKVOLUME (but see 
next subparagraph called "Capitals"). 

There are no string variables.

Arrays
------
dib uses arrays in the same way of the original basic, with a DIM statement
to instantiate some memory space for the array; any undeclared array is
automatically instantiated to a 10 or 10x10 array (the dimension depends on
the array you invoke, that is A(2) will instantiate a vector, while A(2,4) will
instantiate a matrix). Of course, any reference to an uninstantiated array 
with indexes greater than 10 will raise an error.
Note: the automatic instantiation is not taken into account with the MAT
commands; when using a MAT command, you have to instantiate the arrays before
(this is the same behavior, of course, of the original BASIC).

Arrays declared with DIM Z(N) or DIM Z(N,B), where B is 0 or 1 according to
OPTION BASE (0 or 1), behave in the same way with all commands. In effect the 
former are pure vertical arrays, the latter are degenerated matrices, 
constituted by a column only. (This kind of vectors are those used for solving
equations systems of the kind AX = B, where A is a square matrix, B is the
vector of known terms, and X is the solution vector, both vertical and as
high as the matrix height (the system is solved premultiplicating both sides
by the inverted matrix A-1: (A-1)AX = (A-1)B to get X = (A-1)B; the solutions
vector is simply obtained multiplicating the inverse by the knowns vector in
this order: matrix A must be square, size NxN, and B must be a vertical vector
of size N.) The only difference between the two is that DIM Z(N) defines an 
object of type "vector", while DIM Z(N,B) defines an object of type "matrix", 
but this is of little or no importance for the programmer.
An array declared with DIM Z(B,N) where B is 0 or 1 according to OPTION BASE
(0 or 1), is a horizontal array, in effect a degenerated matrix constituted by
a row only, which is an object of type "matrix". It can be transposed to a 
vertical one ("vector" or "matrix") and back, as well as a unidimensional 
vector (vertical) may be transposed to a horizontal vector.
Remember that with option base set to 1 (or using the -b option at start), you
cannot dimension vectors with indexes starting from 0!

A final note: with OPTION BASE set to 0, you may be tempted to dimension
peculiar arrays like DIM A(0) or DIM A(0,0); your intention would probably be
that of having a degenerated one-element array. Well, this won't work in dib,
depending on the particular internal rapresentation of arrays: such an array
would be interpreted as an uninstatiated array, and redimensioned to a 10 or
10x10 array the first time A(0) or A(0,0) is invoked; any reference to A(0) 
or A(0,0) will of course be preserved, but beware when you use MAT PRINT on 
such arrays!

Arrays can be redimensioned, even using different cases, like DIM A(6) and
DIM A(4,4) in the same program. I don't know if this feature is common in other 
BASIC interpreters or compilers. In any case, the DTSS emulator by T. Kurtz 
admits this feature, and so does dib.

Arrays cannot contain strings.

Precedence
----------

Precedence among all the operators (not all available in default mode - see
ahead), is set according to the following schema (higher to lower)

level 7: ()
level 6: NOT
level 5: ^
level 4: * / \ MOD
level 3: + -
level 2: < > = <= >= <>
level 1: AND OR XOR
level 0: EQV IMP

The Original BASIC version II had a bug, causing an expression like -3^2 to 
yield 9 (as if ^ had a lower precedence than unary minus); version III did
correct it, and -3^2 yielded correctly -9). dib, accordingly to version III,
yields -9, because ^ has a higher precedence than unary minus.

Screen
------
A program line is 75 characters wide and so is screen output; anything beyond 
the 75th character in program lines will be lost; should they fall beyond the
screen limit during output, numbers will be printed on a new line, strings will
be cut.
Screen columns are numbered 0 to 74, and this is quite different from the 
underlying screen, which, in any real terminal or terminal emulation is at 
least 80-characters wide. 
This reflects the original input space of the Dartmouth BASIC, so you should 
never use program lines longer that 75 **in all** (line numbers included). Use 
an editor with characters count like vim.
I took any care to simulate the output **exactly** as in the original BASIC. 
Some differences arise with calculation results, because modern CPUs behave
better than ancient ones...

Program lines formatting
------------------------
A program line is a text line with the first character(s) being digits, and 
followed by a single statement with its arguments.
You can put any blank space into the line, even in the middle of a statement:

10 PRINT "HELLO, WORLD!"
10	PRINT	"HELLO, WORLD!"
10PR INT"HELLO, WORLD!"
10 P R I N      T "HELLO, WORLD!"

Previous lines are all equivalent, since all spaces/tabs are discarded during 
the line processing (of course, not for spaces/tabs into strings!).
This said, you can format your listing to make it more readable, like:

10 FOR I=1 TO 10
20      PRINT I
30      FOR J=1 to I
40              PRINT "-->";I*J;
50      NEXT J
60 NEXT I
70 END

without any risk of misinterpretation. If you want to use an editor with
syntax coloring for BASIC, or use vim with the syntax file dib.vim, though 
- see par. 3.8 - take care to write all statements with consecutive letters, 
in order to achieve the colored syntax. PRINT will be colored, PR INT will not
(but will work).
Moreover, if you want to run your listings under different BASICs, be careful: 
they may not recognize broken statements.

I don't know if the original Dartmouth BASIC could accept broken statements 
like PR INT instead of PRINT; dib does, anyway.

Program lines may also be:
- void lines (or lines composed by spaces, tabs and blanks, which are simply 
  discarded); they are equivalent to lines with a line number only, which 
  delete (if present) the stored line with that very line number; in fact, 
  in case of two (or more) lines with the same line number, only the latter is 
  maintained; you can use this trick to do some debugging; simply rewrite at
  the bottom of the file the lines to be substituted without deleting them 
  really. Use a line number alone to temporarily disable a line.
- lines beginning with '#'; they are discarded too, to enable some BASIC
  scripting; simply copy the following line as the first line in the BASIC 
  source file (this is not an original Dartmouth BASIC feature, of course),
  whose name, for this example, is :

  #!/bin/sh dib 

  Put all the options you want. Then type from console:

  $ chmod +x 

  and from now on you will have a sort of executable in BASIC.

Lines may also be scattered in an unordered way: the reordering is done 
automatically during loading.

Capitals
--------
All statements must be written in capitals; PRINT and print are not the same,
the second raising an error, but dib, differently than the original BASIC,
will gently accept lower letters into strings. The following will behave as
expected:

10 PRINT "UPPER LETTERS"
20 PRINT "lower letters"

There is even a further note, here. I don't do any check about lower or
upper letters for variables, and the variables memory space of dib is enough
for all. So A and a are two distinct variables, A(1,1) and a(1,1) are two 
distinct arrays elements, FNA and FNa are two distinct functions!

Take this note with care, I) because this behavior differs from the original
BASIC; II) because it may make your listing incompatible for other BASIC 
interpreters and compilers; this said, you can count on twice the variables
number of the original BASIC, twice the number of arrays, twice the number
of functions... just in case you need it!

Preparsing
----------

As said, dib is an interpreter, not a compiler. Nonetheless, some commands are
preparsed before execution:

- END statements are checked in default mode for the following conditions:
  there must be only one END and it must be the last statement in the code;
  if it's not so, an error will be raised and the program won't be executed.
  In extended mode, no check is done for END, neither for being unique nor for 
  being the last.
- DATA statements are parsed to gather all the data information. Data are
  sequentially stored into a vector, and READ proceeds reading it from start.
  RESTORE resets vector pointer to the first element. Thus, during execution,
  DATA is a statement without effect, and is simply discarded.
- DEF FN structures are parsed to gather all functions and all the variables
  that are used as arguments. Successive calls to the DEF FN function force
  a parsing of the function expression after instancing process variables.
  Thus, duting execution, DEF is a statement without effect, and is simply
  discarede.

All the errors that have some reference with END, DATA or DEF occur even before
the first program line is seen by dib.

Remarks
-------
The syntax that must be observed, apart from inner spaces, is simple, as in
the 1964 manual, and may be condensed into this terse sentence: 

                           one statement per line

The colon to divide multiple instructions on one line is NOT permitted, and 
this reflects exactly the Dartmouth BASIC original philosophy (this is true
for default mode, while extended features permit a limited use of multiple
instructions for assignments).
Errors in statements, in writing numbers, in functions, in relations and many
other syntax errors are exposed ahead.

Finally, I like the motto at page 21 of the 1964 manual, here reported:

                     TYPING IS NO SUBSTITUTE FOR THINKING

Many programmers (I'm the first) should learn from this.


2.4 DEFAULT FEATURES
    ----------------

Here you will find the list of all dib's default statements and features:

Available statements and specs
-----------------------------
  - PRINT
    display strings enclosed into double quotes, or expression built up from 
    numbers, variables and operators; arguments may be followed by comma or 
    semicolon; PRINT accepts even the classic string/value without comma or
    semicolon)

  - FOR..TO..STEP/NEXT 
    execute cycles with a depth of 26 levels (the original basic admitted, for 
    version II, 26 FOR cycles in total); NEXT must be followed by the variable 
    name.
  
  - IF..THEN 
    (followed by a valid address) executes jumps to a specific address if 
    condition after IF is true.
  
  - GOTO
    jumps to any legal address (jumping out of a FOR cycle with GOTO or IF/THEN
    causes a cycle break); of course, GO TO is accepted.
  
  - GOSUB/RETURN 
    (one level depth) jumps to a subroutine and get back.
  
  - LET
    (required) for single assignments.
  
  - END
    as the last statement, which is required.
  
  - INPUT
    enabled for multiple vars input, but unable to print input strings (e.g. 
    INPUT "Enter a number";N won't work).
  
  - DATA/READ/RESTORE 
    (only for numbers), with a maximum of 300 values
  
  - REM
    for comments; of course, REMARK is accepted; the apostrophe as a comment 
    in the middle of the line is available
  
  - DEFFN
    to define a function with one argument (e.g. DEF FNX(A)=...).
  
  - PAGE
    to clear terminal and simulate a new printing page.
  
  - STOP
    which acts as END but may be repeated anywhere.
  
  - DIM
    with one or two dimensions arrays, with A..Z names (A0..Z9 names as array 
    identifiers are not available).

  Notes:
  - line numbers range is 1-99999
  - operators are the classic fab-four (*/+-) plus powering (^)
  - relational operators are the classic six (= <> <= >= < >)
  - a strictly correct syntax is necessary for the parser to work; so (and this
    is not bad at all) no freedom is left in leaving behind closing 
    parentheses; no doubt: this enhances clarity and eases corrections.
  - the powering operator may be followed by unary operators - and + (e.g.
    12^-1E-2 or 3.2^+4.2 or A^-E1 are allowed); in any case, for a better
    reading, you may enclose exponent into parenthesis.
  - DIM A(N) dimensions a unidimensional array, which is by default a vertical
    array; this easies calculations of matrices by vectors; if you ever want
    to dimension a N-elements horizontal array, do it through DIM A(0,N-1) with
    base index set to 0 or DIM A(1,N) with base index set to 1; notice though 
    that DIM A(N) dimensions a vector, while DIM A(0,N) is not a vector but a 
    special case of a matrix. You can mix their use in any type of calculation,
    anyway.
  - variables list in INPUT may be separated by commas or semicolons, and even
    mixed up (e.g. INPUT A,B,C or INPUT A;B,C).

Available functions and specs
-----------------------------
  - ABS
  - ATN
  - COS
  - EXP (exponential)
  - INT (integer part)
  - LOG (neperian base)
  - RND (dummy parameter required between parentheses)
  - SGN
  - SIN
  - SQR
  - TAN

Available MAT statements and specs
----------------------------------
  - MAT A=B+C, MAT A=B-C, MAT A=B*C (where the lvalue cannot occur after the 
    '=' sign, e.g. MAT A=B*A is not valid)
  
  - MAT ZER
  
  - MAT CON
  
  - MAT TRN
  
  - MAT INV
  
  - MAT IDN
  
  - MAT PRINT
  
  - MAT INPUT (this statement belongs to version IV, to tell the truth)
  
  - MAT READ
  
  - MAT A=(k)*B (where the lvalue cannot occur after the '=' sign and k must be
    enclosed into parenthesis; k may be any valid expression fitting the line).

  Notes:  
    - A0..Z9 variables cannot be used into matrices
    - all matrices and vectors must have been declared with DIM, even if
      smaller in dimension than 10 in either side; this is the restriction n° 1
      presented at page 51 of the October 1964 manual for the II edition: "A
      matrix in a MAT instruction must have had a DIM declared", and I believe 
      this has not changed in the III edition of 1966. The restriction n° 2:
      "While the same matrix may appear in a MAT statement and in an arithmetic 
      statement, it must occur for the first time in a MAT statement") is not 
      observed by dib.
    - MAT A=B is not available. Use MAT A=(1)*B in its place.
    - MAT A=-B is not available; in case you need such an operation, do it
      as MAT A=(-1)*B.
    - MAT READ, ZER, CON, IDN may redefine arrays (which, if greater in 
      dimension than 10 in either side, must have already been instantiated 
      with DIM), but only to reduce the array size in either side.
    - MAT TRN transposes argument matrix, and must be used also with vectors;
    - MAT INV sets a system var, named DET, which contains the determinant;
      DET must not be called before a MAT INV, and if it contains zero after
      an inversion, the matrix is singular. 
      DET value retains its value until next MAT INV statement (it will be 
      replaced by next determinant value) or end of program.
    - MAT INPUT sets a system var, named NUM, which contains the number of
      input values (which may differ from the vector/matrix global number of
      elements); NUM may be called anytime, but it's meaningless if called
      before a MAT INPUT (i.e. it's null). Besides, if you use the compact
      form MAT INPUT A,B,C to input values for matrices A, B and C, at the
      end of the input process, NUM will refer to the last matrix (C here).
      So, if you input a bunch of numbers to fill A and partly B, NUM will
      be set to 0, because C received no values. If you need to check NUM for 
      every matrix input, set a MAT INPUT for each matrix.
    - As a means to understand how good the inversion of a matrix is,
      multiply the original matrix by its inverse; the closer are diagonal 
      elements to 1 and the closer are all other elements to zero, the better 
      is the inversion; in particular, I observed that if elements that should 
      be zero are in the order of magnitude from 1E-3 to 1E-6, the inversion is
      not much accurate, but in most cases satisfactory. If the order of 
      magnitude is smaller than 1E-7, the result is good. If order of magnitude
      is even smaller than 1E-10, no better result can be achieved by dib.
    - As a final remark, I observe with pride that my inversion algorithm can
      solve what Valentin Albillo calls "Mean Matrices" (ill-conditioned and
      unstable matrices that the HP-71B pocket computer cannot completely
      resolve). See [8].


2.5 EXTENDED FEATURES
    -----------------

By invoking dib with the -x option, a number of BASIC extensions are enabled; 
these extensions want to emulate further versions of the Dartmouth BASIC, but
without any specific reference (in particular, strings are not enabled, in this
dib's version, while they were in version IV of the Dartmouth BASIC).
The extended features are summarized here:

Available statements extensions and specs
-----------------------------------------
  - DIM
    now allows the dimensioning of arrays with A0..Z9 names
  
  - IF..GOTO
    with the same behavior of IF/THEN (followed by an address)
  
  - IF..THEN
    may be followed by some assignment (with or without LET)
  
  - IF..THEN GOTO
    is admitted
  
  - GOSUB/RETURN
    with an increased level depth (80 by default)
  
  - END
    is not required
  
  - LET
    is not required (even after THEN), and multiple assignments may be done
  
  - INPUT
    may accept a string before the variable list, and followed by comma,
    semicolon or directly by the list (e.g. INPUT "VALUES";A,B or 
    INPUT "VALUE",A,B or INPUT "VALUE"A,B)
  
  - ON..GOTO/ON..THEN
    equivalent
  
  - OPTION BASE
    followed by a number (0 sets zero as first index, any other value sets one 
    as first index)
  
  - RANDOMIZE
  
  - CHANGE..TO
    which works only from strings to arrays; the string must be explicitly 
    enclosed into double quotes and not contained into a variable
  
  - TAB()
    to set next printing position; as said, columns are numbered from 0 to 74 
    (i.e. TAB(10) sets column 10, which is the 11th, as next printing 
    position). TAB is a specifier of PRINT, and cannot be used alone or into
    a math expression.
  
  - CHR$()
    prints the ASCII character of the value calculated into the parenthesis; 
    CHR$ is a specifier o PRINT and cannot be used alone or into a math 
    expression.
  
  Notes:
    - line numbers range is now increased to 1-119880
    - some math and logical operators have been added: MOD, \ (integer 
      division), AND, OR, XOR, EQV, IMP (they all behave as infix operators), 
      NOT (it's a unary logical operator that precedes the expression whose 
      truth value must be reversed. Its priority is higher than any other, so 
      NOT A*B is equivalent to (NOT A)*B ).
      Other logical operators may be obtained in function of existing ones:
      - NXOR is equivalent to EQV
      - NAND is NOT AND; e.g.: A NAND B <=> NOT (A AND B)
      - NOR is NOT OR; e.g.: A NOR B <=> NOT (A OR B)
      Sometimes I see the XOR operator written as EOR in other BASICs, so this 
      name is enabled into dib's extended features, with the same exact meaning 
      of XOR.
    - The assignments after IF..THEN in extended mode may be separated by
      comma or colon, and even mixed; but only the colon may be compatible
      with other compilers and interpreters; e.g.:
      10 IF A = 1 THEN E = 14, T = 45
      may be not interpreted correctly by others compilers or interpreters,
      while
      10 IF A = 1 THEN E = 14: T = 45
      will be.
    - INPUT may be followed by a string, which will be printed before asking
      for variables input; after the string you can put a comma, as in
      INPUT "ENTER NUMBERS",A,B
      or a semicolon, as in
      INPUT "ENTER NUMBERS";A,B
      or nothing, as in 
      INPUT "ENTER NUMBERS"A,B
    - The logic of CHR$() followed by comma or semicolon and by something else
      is the same of the output processed by PRINT; if, however, CHR$() is 
      followed by another CHR$, or by comma/semicolon and nothing else, no 
      advancing in the printing position is done, so that CHR$() may be used 
      to build strings. 
      If used followed by nothing, a Carriage Return will be output each time.

Available functions extensions and specs
----------------------------------------
  - ACS
  - ACSH
  - ASC
  - ASN
  - ASNH
  - ATNH
  - CNORM(A) yields the column norm of matrix A
  - COSH
  - COT
  - DET(A) yields the determinant of argument square matrix A
  - DOT(A,B) yields the dot product (scalar) between two unidimensional vectors
  - FNORM(A) yields the Frobenius norm of matrix A (a.k.a. Euclidian norm)
  - GAMMA
  - PI returns the Greek pi value (3.14159...)
  - RND now does not require an argument
  - RNORM(A) yields the row norm of matrix A
  - SINH
  - TANH

  Notes:
    - ASC print the number equivalent to the ASCII character of the string
      argument, enclosed or not into parenthesis, i.e. the following lines yield
      the same value (65):
      10 PRINT ASC("ABBA")
      20 PRINT ASC(ABBA)
      The double quotes themselves cannot be used, since dib doesn't recognize
      any escape character. But if you remember that their ASCII value is 34,
      you can use it "as is", and print double quotes with CHR$(34).
    - FNORM yields the Frobenius norm, which is the square root of the sum of
      the squares of all the elements of the argument matrix
    - RNORM is the row norm, which is the largest sum of the absolute values
      of the elements in each row of the argument matrix
    - CNORM is the column norm, which is the largest sum of the absolute values
      of the elements in each column of the argument matrix
    - for FNORM, RNORM and CNORM, argument matrix is not required to be square,
      and also the norm of unidimensional vectors will be calculated.
    - DET(A) and DET are two different entities; in effect, DET(A) is a
      function, while DET is a variable. DET holds the determinant after
      a MAT INV(A) or a DET(A) is performed, and may be used anywhere until a 
      new MAT INV(A) or DET(A) is done. DET(A) recalculates the determinant of
      the argument matrix regardless of the existence of DET, and with no
      check about the fact an inversion has been done. In any case, after
      DET(A), DET is available, because dib performs an implicit inversion to
      test for determinant existence while calculating it.
    - DOT(A,B) takes two vectors (a.k.a. lists) as arguments; these vectors
      may be unidimensional vectors dimensioned with DIM A(N), or 
      unidimensional vectors dimensioned with DIM A(N,B) or DIM (B,N), where
      B is the OPTION BASE, 0 or 1; the latter may be considered vectors here,
      for the purpose of the DOT product, but in effect they are degenerated
      matrices, built up by, respectively one row or one column only.

Available MAT extensions and specs
----------------------------------

  Notes:
    - MAT A=B is available
    - variables A0..Z9 may be used as matrix names
    - MAT A may simultaneously occur to the left and to the right of the '=' 
      sign in additions, subtractions, multiplications and scalar 
      multiplications, e.g.: MAT A=B+A, MAT A=A-B, MAT A=B*A, MAT A=(k)*A, or 
      even MAT A=A+A.

If you want to always use dib's extended features, simply set ef=1 in the file
dib.h and recompile; from now on, the -x option will "turn off" extended 
features, rather than enabling them.


2.6 ERROR MESSAGES
    --------------

dib is, at present, an interpreter, not a compiler. Error treatment thus cannot be the same of a compiler.
Basing on this simple fact, I had to reconsider the whole error treatment, 
since, while a compiler does multiple passes to compile, being one of the 
first the syntax check, and so being able to print a long listing of error 
messages, an interpreter should stop after the first error, because going on 
would mean either instantiating not allocated variables, or calling not 
existing addresses, or doing useless loops, or something equally bad. 

I came up to the following decisions:
- set up a general error treatment system to stop at the first met error, but
  capable of reverting to a multiple error generator changing a flag only (use
  it at your risk!);
- use the same error strings of the original compiler, as exposed on [1];
- use an extended set of strings, partly derived from [5], and partly conceived
  by me, where the original compiler lacked proper messages, or to expand error 
  information to some extent

These decisions forced me to recalibrate errors, discerning which one could 
safely let the program flow and which one had to be considered definitely a 
stopper. In the following paragraphs, errors recognized by dib and their own
stop-code are reported (yes/no means that things are different with extended
features enabled).

If invoked with option -c, dib won't stop after meeting many errors (not all!),
and will continue until a definitely bad thing has happened, writing in the
meantime all the detected error messages. Errors which are considered
dangerous for the computer memory, or which prevent dib from going on, will 
immediately stop the interpretation.
If invoked with option -l dib will print on standard output the complete list
of error codes and their messages.


2.6.1 STANDARD ERROR MESSAGES
      -----------------------

Standard messages are exactly the same of the original 1964 Dartmouth BASIC, 
printed both in default and in extended mode.
In the following, "stopper" is an error big enough to prevent dib from going on.

  0. DIMENSION TOO LARGE [NOT USED] 
  (stopper: no)
  It occurred in Dartmouth BASIC when the size of an array was too large for 
  the available storage. In practice, this cannot be replicated in dib, because
  the available memory is predetermined in dib.h, and can be expanded at need 
  (and of course, depending on your system memory).
  
  1. ILLEGAL CONSTANT
  (stopper: no)
  It occurs when there's an incorrect form in a number:
    - more than 9 digits;
    - other than [+-.0123456789E] in a number.
  The first condition cannot be observed by dib, which makes use of the 
  strtod() C function, which has higher capabilities than Dartmouth BASIC's 
  original parser. In practice, you'll rarely meet this error, because strtod()
  is very very clever.
  
  2. ILLEGAL FORMULA
  (stopper: no)
  It occurs in case of:
    - missing (closing) parentheses; 
    - illegal variable names;
    - missing multiplication operators (implicit multiplication is forbidden);
    - illegal numbers (in the original Dartmouth System it might not refer to 
      the preceding error 1; probably it occurred during execution in case of 
      overflow; if it's so, I cannot replicate it, due to the way gcc treats 
      overflow).
  
  3. ILLEGAL RELATION [NOT USED]
  (stopper: no)
  It occurs when there's not a valid relational expression between IF and THEN;
  There are some problems in catching this error for dib, because the parser 
  always interpret as wrong numbers what it cannot understand. For example, the
  following code fragment:
  	10 PRINT 3<<4
  	20 IF A=>6 THEN 10
  causes dib to emit the ILLEGAL CONSTANT error message at lines 10 and 20, 
  because it interprets the first as 3 < (<4), and <4 is an illegal constant, 
  and the second as A = (>6), and >6 is another illegal constant.
  So this error message is never issued.
  
  4. ILLEGAL LINE NUMBER
  (stopper: yes)
  It occurs when:
  - the line number is not available or obtainable
  - the line number is greater than 99999
  The second is detected as a superimposed limitation, because the effective 
  memory size may be increased at pleasure for both (to a certain extent); in 
  any case, the limitation is not considered if the extended features are 
  enabled, but the effective increment is low: the limit is set to 109890 
  (=110x999), of which only the first 99999 are available in standard mode.
  
  5. ILLEGAL INSTRUCTION
  (stopper: no)
  It occurs when there's some illegal instruction (not a valid BASIC statement) 
  after the line number or in a formula or in an expression.
  If you're familiar with Commodore BASIC, you'll remember the ubiquitous 
  ?SYNTAX ERROR; it's the exact correspondent.
  
  6. ILLEGAL VARIABLE
  (stopper: no)
  It occurs when an illegal variable is detected (for instance, a two-letters 
  variable name has been used, like AB).
  
  7. INCORRECT FORMAT
  (stopper: no)
  It occurs when a wrong statement has been written in FOR..NEXT..STEP or
  IF..THEN structures.
  
  8. END IS NOT LAST
  (stopper: yes/no)
  It occurs when:
  - END is not in the last line; 
  - there's more than one END statement.
  Both errors are not highlighted if the extended features are enabled.
  
  9. NO END INSTRUCTION
  (stopper: yes/no)
  Self explanatory. Not highlighted if the extended features are enabled.
  
  10. NO DATA
  (stopper: no)
  It occurs when:
  - there's a READ without DATA.
  - a RESTORE is called without DATA statements.
  It's perfectly legal having a DATA with no READ/RESTORE.
  
  11. UNDEFINED FUNCTION
  (stopper: no)
  It occurs when FNX is called without defining DEF FNX first. 
  A DEF FNX definition may appear anywhere (it's caught before execution), 
  but it *must* appear somewhere, in order for FNX to find what to calculate.
  
  12. UNDEFINED NUMBER
  (stopper: yes)
  It occurs when GOSUB, GOTO or THEN are given a non existent destination 
  line number.
  
  13. PROGRAM TOO LONG [NOT USED]
  (stopper: no)
  In Dartmouth BASIC, at least first versions, there was a limited number of
  program lines which were available. When a program reached that length, this
  error message appeared, maybe in conjunction with error 19 (see ahead).
  dib uses a huge list of pointers to string lines, whose index is the
  correspondent line number, so this error is meaningless and never issued.
  
  14. TOO MUCH DATA
  (stopper: yes)
  It occurs when there are more values for DATA than those available (this 
  limit is 300 for standard mode, and 999 for extended mode.
  
  15. TOO MANY LABELS [NOT USED]
  (stopper: no)
  It occurred in Dartmouth BASIC when there were too many strings in the 
  program (due to memory limitations). 
  I cannot use it, I don't want to use it!
  
  16. TOO MANY LOOPS
  (stopper: yes)
  It occurs when there are too nested FOR..NEXT loops than those available 
  (this limit is set to 26). Of course, you can use even thousands of 
  FOR..NEXT loops, if they are not nested!
  
  17. NOT MATCH WITH FOR
  (stopper: no)
  It occurs when:
  - there's a NEXT with a different variable than that used within FOR
  - there's a wrong NEXT nesting (e.g. FOR A, FOR B, NEXT A, NEXT B)
  
  18. FOR WITHOUT NEXT
  (stopper: no)
  The program ends and no NEXT has been found. 
  
  19. CUT PROGRAMS OR DIMS [NOT USED]
  (stopper: no)
  This error (which looks rather a warning) has some meaning only with tiny
  resources. Used in Dartmouth BASIC and not in dib.
  
  20. SUBSCRIPT ERROR
  (stopper: yes)
  A non existent array index has been called. It may even refer to differences
  in a DIM declaration or peculiar usages with MAT statements.
  
  21. ILLEGAL RETURN
  (stopper: no)
  It occurs when a RETURN not related to any GOSUB is found.
  
  
2.6.2 EXTENDED ERROR WARNINGS
      -----------------------
  
The following warnings are meant to report odd situations, and don't stop the 
program flow; they don't appear in the original 1964 BASIC manual, but I 
reputed them meaningful in a programming environment. Most of them are 
retrieved from the compiler assembler source, some from the DTSS simulator 
by T. Kurtz, and some have been invented by me. None of them is a stopper.
Numbers not addressed are unused, at present.
  
  22. OUT OF DATA
  It occurs when READ cannot read DATA values anymore. This is different from 
  the NO DATA error message: the latter means that no data has been found 
  (this may mean no DATA statement at all), while the former means that all 
  data have been read and there's nothing left. 
  As stated at page 7 of the 1964 manual, this causes the program to stop, with
  no peculiar message. So I enable this (non-stopper) warning only in extended
  mode.
  
  23. SQUARE ROOT OF NEGATIVE NUMBER
  24. LOG OF NEGATIVE NUMBER
  25. LOG OF ZERO
  26. ABSOLUTE VALUE RAISED TO POWER
  27. DIVISION BY ZERO
  These warnings are shown when you execute an illegal math operation; things 
  are 'adjusted' and the program flow is not interrupted.
  When I say 'adjusted' I mean:
  - absolute value of a negative number is taken before performing a 
    square root
  - the logarithm of zero or a negative number returns the lower value MINFF
  - a negative real cannot be raised to power, so its absolute value is taken
  - a division by zero returns the dividend (that is, it's not executed)
  This behavior reflects the original Dartmouth BASIC one.
  
  30. OVERFLOW
  31. UNDERFLOW
  The first warning appears when a number greater than INFF (or lower than 
  MINFF) is met, either as itself or as a result of a math operation.
  The second appears when the absolute value of a number is lower than ZERO 
  (but not zero), that is the lower limit of this emulator, either as itself 
  or as a result of a math operation.
  I said "as a result of a math operation"; to this, I must add that I let 
  the CPU perform all the intermediate calculations, so it's occasionally 
  possible that these warnings don't get printed; for example, if you multiply 
  1E50*1E50*1E-50 in an expression, the first intermediate result is surely 
  an overflow for dib, but not for a modern CPU; then, when next operation 
  returns a value not overflowing dib's capacity, no warning is issued 
  while evaluating this final result.
  
  32. ZERO TO A NEGATIVE POWER
  33. ZERO TO THE ZERO POWER
  The first warning appears when you try to calculate 0 to the power of a 
  negative number, and the result is set to INFF (which tends to simulate
  1/(0^e) or (1/0)^e, with 'e' positive, both leading to infinite).
  The second appears when both base and exponent are zero, and the result is
  set to 1 (because the function x^x approaches 1 as x approaches 0 from the 
  right - see [10]).
  
  34. GOSUBS NESTED TOO DEEPLY
  This warning appears when you go past the GOSUB..RETURN limit for inner
  subroutines; as default, you cannot perform a GOSUB into another GOSUB; from 
  the Oct. 1964 manual, page 43:
      "The user must be very careful not to write a program in which a GOSUB 
      appears inside a subroutine which itself is entered via a GOSUB; it just 
      won't work."
  In extended mode, this limit is increased to 80, but should you go past this
  limit, the message appears the same. I guess, anyway, you'll NEVER go past 80
  levels of GOSUBs!

  35. ARRAY INDEX MUST BE GREATER THAN ZERO
  This warning occurs in case you use index 0 in dimensioning arrays while
  option base is set to 1; in this case dib prints this warning before exiting)
  
  36. NO MATRIX INVERSION DONE YET
  Self explanatory. The determinant calculated after this warning (e.g. before 
  a matrix inversion) is meaningless.
  
  37. IGNORING ONE-ELEMENT LIST OR TABLE
  If you dimension a one-element array (vector or matrix) with option base 0, 
  using DIM A(0) or DIM A(0,0), the interpreter won't see this as a matrix 
  dimensioning, and will set an implicit 10 elements or 10x10 elements array 
  the first time you use a reference to the element; this happens only with 
  option base 0 and you won't lose the object: only be conscious you have a 
  whole array, not just a one-element array.
  You'll never see this warning with option base 1 if you try do dimension a 
  one-element array with DIM A(1) or DIM A(1,1).

  38. ASIN OR ACOS ARGUMENT MUST BE BETWEEN 1 AND -1
  39. ACSH ARGUMENT MUST BE GREATER THAN 1
  40. COTANGENT OF ZERO
  These messages catch the violation of the relative math functions domain,
  without stopping program flow. In case of violation, the yielded result is
  always zero except for error 40, which yields (of course) INFF.
  These messages appear only in extended mode, since hyperbolic functions
  are available only in extended mode.
  
  41. INVERSION OF A SINGULAR MATRIX IS NOT POSSIBLE
  This warning appears when either the Gauss factorization is not possible,
  because the matrix is singular, or the determinant is null, again because the
  matrix is singular. In either case, the determinant is null and the message
  warns the programmer in order to get rid of the result matrix values.


2.6.3 SYSTEM MESSAGES
      ---------------
Sometimes, things go in such way dib cannot manage them. In such cases, errors
are printed in lower letters, preceded by the identifier "dib:", and the 
program inevitably stops. Here's a list of all the system errors:

  dib: out of memory for arrays.
  dib: out of memory for DEF.
  dib: file not found.
  dib: unable to close file.n
  dib: line <> is beyond domain.
  dib: out of memory for line <>.
  dib: -<> is an illegal option.
  dib: missing file name.
  dib: out of memory for ultimate END.

These error messages are auto-explicative; the <> matches with a value which
is calculated or retrieved during execution, and incorporated into the message.
You're likely to never see last system error message.


2.7 THE EXAMPLES
    ------------
In the package there are four directories of examples:

- the directory named 1964/ gathers all the examples featured in the 1964
manual for version II of the Dartmouth BASIC. They are named according to the 
page number in which they appear. The output of those programs has served as 
target for refining the dib's PRINT statement. They must be run safely with
no options.

- the directory named OWN/ gathers all the specific examples I created for dib;
the subdirectory EXTEND/ contains examples which must be executed with the 
extended features enabled; 

- the directory MATRIX/ contains various examples of matrix calculations; the
subdirectory EXTEND/ contains examples which must be executed with the
extended features enabled.

- the directory GOTTFR/ gathers all the example of the 1st edition of [3]
which could be applied to dib with the -b option, to set option base to 1 
(the Pittsburgh machine on which these examples ran used a consistent index 
for arrays starting from 1); the subdirectory EXTEND/ contains examples which
must be executed with the extended features enabled.


2.8 THE vim 'dib' SYNTAX FILE
    -------------------------
In the package you will find the 'dib.vim' file. If you don't use vim, well, 
skip this paragraph and forget the file.
If you use vim as your current editor, here's some instructions for installing
the dib file (only for UNIX users).


2.8.1 INSTALLING dib.vim
      ------------------
Locate the .vim directory under your $HOME. Add the two lines

" dib (Dartmouth BASIC)
au BufNewFile,BufRead *.dib     setf dib

to filetype.vim (and create it if it doesn't exist); now step into .vim/syntax 
and copy here the file dib.vim. Done.


2.8.2 MAPPING THE DIB SYNTAX
      ----------------------
Of course, you may want to use vim on files created with deer, so the extension
is not present. In this case, I map the dib syntax within the vim/gvim resource
file (for me $HOME/.gvimrc), adding the following line:

:map  :set syn=dib

Of course you can map any key you want. From now on, load the file and hit F2:
the colored syntax will activate.


3. CONCLUSIONS
   -----------

In the end, there are some people I want to thank, because their work made my 
job easier (or even possible).

The first one is Diomidis Spinellis, the author of dds_basic, the program which 
gave me the idea and offered me a frame on which basing my code.
I learned a lot from his programming style, which is fine, essential, smart.

The second one is professor Tao Pang, from UNLV (University of Nevada, Las 
Vegas), for the book "An Introduction to Computational Physics - 2nd edition", 
Cambridge ed., 2006, a very useful manual for implementing a lot of scientific 
and mathematical routines and functions. I thank him again because he made 
available most of its software through the Internet, and indeed the first 
implementation of matinvert() was based on his elgs() and migs() functions, 
before making up my mind and implementing my own.

The third one is Jack W. Crenshaw, the author of "Math Toolkit for real-time
programming", CPM Books, 2000, an invaluable mine of math tools, humor, style;
he's a man with a vivid intelligence, capable of getting into the harder 
algorithm and turn it into a clear and easy tool. Every programmer should read
this book. And figure out: I bought it by chance!

Last one is my wife Anna, who supported my absence while I was hidden in my 
room trying to produce some working code; she complained, from time to time, 
but she loves me enough to stand it...

				***	***

I cannot leave without remembering with love professor Kemeny (in memory) and
professor Kurtz, who created the BASIC programming language many years ago, an
easy and lightweight language, suitable for math and financial subjects, which
guaranteed me an entry point in computer science. Thanks and thanks again.

				***	***

Finally, I propose this new acronym for BASIC:

                 Broad Analysis with Simple and Intuitive Coding

I hope you like dib.
It's GPL: Enjoy!


4. BIBLIOGRAPHY
   ------------

The following documents and references played an important role during the 
design and the coding of dib:

[1]  "Dartmouth BASIC manual" for version II, October 1964, available as a pdf 
     file at 
     http://www.bitsavers.org/pdf/dartmouth/BASIC_Oct64.pdf

[2]  "BASIC Sessions", by Thomas E. Kurtz, chapter XI of the book "History of
     programming languages", about the original BASIC environment, 1977 ca, 
     available as a pdf file of a typewriter transcript (titled "BASIC") at
     http://delivery.acm.org/10.1145/810000/808376/p103-kurtz.pdf?key1=808376&key2=4039224611&coll=&dl=ACM&CFID=15151515&CFTOKEN=6184618
     A pdf file of the chapter XI of the issued volume (which contains the same
     text) may be obtained through a free subscription at the acm.org portal.

[3]  "Programming with BASIC", by Byron S. Gottfried, edition 1, 1975 (Italian 
     version, as "Programmare in BASIC", Schaum 1982).

[4]  "Commodore 64 C= - Reference Guide for the Programmer, 1983 (Italian 
     version, as "Guida di riferimento per il programmatore"), Commodore 
     edition.

[5]  Listing of the source code for version II of the Dartmouth BASIC compiler
     available as a pdf file at 
     http://www.dtss.org/scans/BASIC/BASIC%20Compiler.pdf

[6]  News about John Kemeny may be found at 
     http://cis-alumni.org/JKemeney.html

[7]  News about Thomas Kurtz may be found at 
     http://cis-alumni.org/TKurtz.html

[8]  "Mean Matrices", an article by Valentin Albillo on ill-conditioned 
     matrices is available as a pdf file at 
     http://membres.lycos.fr/albillo/calc/pdf/DatafileVA014.pdf

[9]  "To Potential ALGOL Users", Sept. 29, 1964, a note to Dartmouth ALGOL
     users by Stephen J, Garland, revised by D. W. Scott March 3, 1965, 
     available as a pdf file at 
     http://bitsavers.vt100.net/pdf/dartmouth/ALGOL_Sep64.pdf

[10] Su, Francis E., et al. "Zero to the Zero Power." Mudd Math Fun Facts. 
     http://www.math.hmc.edu/funfacts/ffiles/10005.3-5.shtml
     where you can find an explanation to the fact that zero to the zero power 
     is 1. Check also 
     http://mathforum.org/dr.math/faq/faq.0.to.0.power.html
     where it's stated: 
     "Consensus has recently been built around setting the value of 0^0 = 1".

[11] The BASIC entry in 
     http://www.math.bas.bg/~bantchev/place/basic.html
     states that the Original BASIC didn't treat boolean values, so that
     it's conceivable that a phrase like "IF A THEN" would issue an error
     in Dartmouth BASIC.

				***	***

(written with gvim)

    Source: geocities.com/it/tonibin/deer/doc

               ( geocities.com/it/tonibin/deer)                   ( geocities.com/it/tonibin)                   ( geocities.com/it)