NMH BASIC Man Page
BASIC(1) General Commands Manual BASIC(1)
*** USAGE ***
BASIC [FILE ...]
*** DESCRIPTION ***
NMH-BASIC is a minimum BASIC interpreter for systems with
little core memory. On {PC,MS,whatever}DOS it requires
only 12 kilobytes to run. It provides a small but power-
ful command set, a builtin editor, and a simple tracing
facility. Programs may either be typed in interactively
or read from an external file or device.
NMH-BASIC is intended for quick and dirty prototyping and
writing small and non-time-critical application programs.
*** STARTUP PARAMETERS ***
NMH-BASIC treats each statup parameter that is passed to
it as a file name and attempts to open the requested
files. It prints each file name and the unit number as-
signed to it. When it fails to open a file, it prints an
exclamation mark (!) followed by the file name.
*** EDITING ***
There is a simple builtin editor that allows the program-
mer to enter and modify programs interactively.
NMH-BASIC program memory consists of a sequence of num-
bered lines. Each command that starts with a number will
not be executed immediately but is inserted into program
memory instead. When entering a line with a line number
that already exists, the given line will be replaced. En-
tering a line number with no following text will delete
the given line.
The length of each line is limited to 64 characters.
Longer lines will cause an error.
The LIST command may be used to view lines stored in pro-
gram memory.
The NMH-BASIC editor performs some on the fly error
checking. It checks only at scanner level, but this helps
to catch many typos while entering a program. When the
editor finds an error, it discards the current line.
*** PROGRAMS ***
A program consists of a number of lines, and each line
contains at least one BASIC statement, also known as a
command. Multiple statements may be placed in a single
line by separating them with colons (:).
*** EXPRESSIONS ***
An expression is everything that evaluates to a numeric
value at run time. NMH-BASIC recognizes the four basic
math operators (+, -, *, /) and some other arithmetic,
comparison, and logic operators. Operators are used to
combine factors (binary operators) or modify factors
(unary operators). Valid factors are: numbers, variables,
and function values.
Numbers are numeric literals in the range -32767 to
32767. They represent themselves.
Variables are two-character sequences that represent a
variable numeric value. There are 260 numeric integer
variables in NMH-BASIC that are named A0...Z9. The first
character must always be a letter, and the second one a
digit. Variables of the form X0 can also be written X.
Function values are the values returned by function
calls. A function is called by typing the function name,
followed by a left parenthesis, some function arguments,
and a right parenthesis.
NMH-BASIC accepts the following operators:
+------+------+---------------------------------------+
|Oper. | Type | Description |
+------+------+---------------------------------------+
| ( ) | 4 | expression grouping, array subscripts |
| # | U4 | logical NOT |
| - | U4 | unary minus, negative prefix |
+------+------+---------------------------------------+
| * | B3 | multiplication |
| / | B3 | division |
| \ | B3 | division remainder |
| + | B2 | addition |
| - | B2 | subtraction |
+------+------+---------------------------------------+
| = | B1 | equal to |
| <<> | B1 | not equal to |
| << | B1 | less than |
| >> | B1 | greater than |
| <<= | B1 | less than or equal to |
| >>= | B1 | greater than or equal to |
+------+------+---------------------------------------+
| = | B0 | assignment (only in LET commands) |
+------+------+---------------------------------------+
Types: U = unary, B = binary, number = precedence level
*** ARRAYS ***
Normally there are 260 integer variables. All these vari-
ables have a unique name (A0...Z9). Sometimes, however,
it is more practical to access variables like vector ele-
ments (through an index, or subscript). Each NMH-BASIC
variable may be treated as an array without making any
special declarations. `A', for example, may also be ad-
dressed as `A(0)', A1 is equal to A(1), A(9) is equal to
A9. Larger subscripts cause on overflow to the next vari-
able letter: the address of A(10) would be equal to the
one of B0. Z(10), finally, will cause a subscript error.
When more space is needed, or no variables letters must
be `wasted', there is the possibility to dimension an ar-
ray. Usually, the Z-variables are used to build an array,
because they cannot have common memory locations with
other variables.
The statement
DIM Z(200)
will increase the size of Z0 to 200 elements. Note that
the free space for program text will be decreased by this
operation.
Dimensioning a different variable will not occupy that
much dynamic memory because the space for variables is
used up first. Using A0 as an array with 200 elements
[DIM A(200)], for example, will not occupy any dynamic
memory, but will make the variables A1...T9 aliases of
A(1)...A(199).
*** STRING EXPRESSIONS ***
The second NMH-BASIC data type is the string. Strings
are fixed-length memory locations that can be filled with
characters. They are used to store ASCII text.
There is only one operation that may be performed on
strings: the concatenation, which is done by the + opera-
tor.
Valid factors in string expressions are text literals and
string variables.
A text literal is a string of characters enclosed by
apostrophes. A literal apostrophe may be insert by typ-
ing it two times in succession. Text literals, like nu-
meric literals, represent themselves.
A string variable is a variable letter followed by a dol-
lar sign ($). There are 36 string variables: A$...Z$ and
0$...9$. String variables may not be dimensioned, but
they can be treated as arrays. For example, A$(1) is the
same as B$ or B$(0). Typically 0$ is used as an array of
10 strings.
The length of NMH-BASIC strings is limited to 64 charac-
ters.
*** STATEMENTS ***
A statement (also called a "command") is the smallest ex-
ecutable element of a basic program. Each statement
starts with a keyword and is usually followed by some pa-
rameters and additional keywords. There are three kinds
of statements: simple statements, conditional statements,
and loop statements.
Most statements in NMH-BASIC are simple statements. Ex-
amples are:
LET I=195
GOTO 420
PRINT VAL(A$)
Conditional statements will only be executed when a con-
dition is true. There is only one form of the conditional
statement:
IF condition statement : ...
The keyword IF is followed by a condition. Only when
this condition evaluates to a true (non-zero) value, the
statement part will be executed. For example,
IF A<0 PRINT 'NEGATIVE'
will print 'NEGATIVE' only if A is less than zero.
Multiple conditions may be separated by commas. In this
case the statement(s) will only be executed, if all con-
ditions are true. E.g.:
IF A<1, B<1 PRINT 'BOTH NEGATIVE'
Note that all statements specified after IF are condi-
tional, so
IF 1 PRINT 'FOO' : PRINT 'BAR'
will print both FOO and BAR.
Loop statements consist of three parts, the introducing
statement (FOR), a body consisting of any number of
statements, and a scope terminator (NEXT). In NMH-BASIC
there is only one block statement and it looks like this:
FOR I=1 TO 100
PRINT I,
NEXT
It implements a counting loop. In the example the en-
closed statement "PRINT I," will be executed 100 times.
Each time the loop is passed, the variable I will be in-
creased by one (at the end of the loop). So this loop
will print the numbers from 1 to 100.
NEXT is the scope terminator. When it is reached, the
counting variable is incremented, and if it has not
passed the limit, the enclosed statements are executed
again.
When a step size if specified in FOR, the given step size
will be added to the counting variable instead of one.
E.g.
FOR I=1 TO 100 STEP 2 : PRINT I, : NEXT
will print only odd numbers and stop at 99. The step size
may be negative.
*** COMMANDS ***
CALL addr
Call the machine language subroutine at address
addr. Not implemented.
CLEAR
Clear all variables and array dimensions. After is-
suing CLEAR variables will be set to zero and string
variables will contain empty strings.
DATA list
Define a list of initialization data. List is a
space-separated list of constant data items of any
type (numeric or string). Data lists are read by
READ statements.
DIM var(size), ...
Define variable var as an array with size elements.
DIM does not actually allocate memory to arrays.
When A is dimensioned with 100 elements, for exam-
ple, the space used by the following variables (C,
D, ..., J) is used, so A(10) becomes an alias of B0
and A(20) an alias of C0, etc. Only when the end of
the array moves beyond Z9, the space for variables
is extended (and program memory is reduced).
END
End program execution and return to interactive
mode.
FOR var=start TO limit [STEP increment]
Introduce a counting loop. First the variable var is
set to the value start, and then all statements fol-
lowing FOR are executed. When a matching NEXT is
found, var is incremented by increment and then
checked against limit. When var is smaller than
limit, all statements between FOR and NEXT are exe-
cuted again.
When no increment is specified (the STEP clause is
omitted), a step size of one is assumed. When the
increment is negative, the loop is repeated until
var becomes less than the limit.
The start, limit, and increment parts may be any
valid expression. They will only be evaluated once
before the first iteration of the loop.
GOSUB line
Perform a jump (like GOTO) to the given line number,
remembering the return address. The return address
is pushed onto an internal stack. A RETURN statement
may be used to pop this address off the stack and
continue execution at the statement immediately af-
ter GOSUB. Subroutine calls may be nested.
GOTO line
Jump to the given line number. Execution continues
with the first statement in the specified line.
IF condition command : ...
Evaluate condition, and execute the command(s) only
if the condition evaluates to a true (non-zero)
value. When the condition is false, execution con-
tinues with the first statement in the following
line (if any). The condition may be any valid ex-
pression. Multiple conditions may be separated by
commas. In this case all conditions have to be true
in order for the command(s) to be executed.
INPUT #expr
Redirec input to the given unit number. All subse-
quent input will be read from the file or device as-
sociated with the unit number.
INPUT var, ...
Read input from the terminal (or redirected unit)
and assign each line of input to a variable. Input
will be automatically converted to the proper for-
mat.
When reading a string A$ from a unit that has
reached its EOF marker, the string will have the
character 255 in its first slot, i.e. ASC(A$) = 255.
The INPUT command does not emit a prompt. Use
PRINT 'prompt';
for that.
LET var=expr
Evaluate expr and assign the result to var. When
var is a text variable, expr must be a text expres-
sion, and otherwise it must be a numeric expression.
LET var(expr1) = expr2
Evaluate expr2 and assign the result to the expr1'th
slot of var.
LIST [line,[last]]
List all specified lines (default: all). When only
one line is given, list just that line.
LOAD #expr
Redirect input to the specified unit number and pass
each line of input to the interpreter. When the end
of input is reached, redirect input back to the ter-
minal.
When done, LOAD leaves the file pointer at the EOF
of the given unit.
LOAD does not erase the program memory, so multiple
programs can be merged with LOAD (merged programs
should not share common line numbers).
NEW
Erase the currently loaded program and clear all
variables and array dimensions.
NEXT
Terminate the scope of a FOR-NEXT loop. (See FOR.)
POKE addr, value
Write value to memory location addr. POKE only
writes a byte to the given address, so the upper
eight bits of value are ignored. DO NOT USE! This
will most probably crash the interpreter.
PRINT
Print a newline character.
PRINT #expr
Redirect all output to the given unit number.
PRINT expr [,|; expr ...] [,|;]
Evaluate each given expression (string or numeric),
and write its value to the output unit (default:
terminal). Expressions may be separated by commas
or semicolons. A comma emits a horizontal TAB and a
semicolon pastes output together.
A newline character is emitted after the last ex-
pression unless the print statement ends with a
comma or semicolon.
READ var, ...
Read DATA items into the specified variables. The
items are taken from a DATA list (see there) which
may be specified at any place in the program (but
are typically at the end).
Each item in the list must have the same type as the
corresponding variable in READ or an error will oc-
cur. Each READ operation advances the data pointer
by n items, where n is the number of variables in
the READ statement.
When the data pointer is moved past the end of the
list while READ executes, the operation will fail.
REM 'nasenbaer'
Everything after REM is ignored by the interpreter
(including colons!). If the text following REM is
not a valid NMH-BASIC program, it must be enclosed
in apostrophes.
RESTOR
Reset the data pointer to the beginning of the init
list (the first element of the first DATA statement
in the program (see also READ and DATA).
RETURN
Pop a return address off the internal return stack
and jump to that address. RETURN is used to return
from a subroutine that has previously been called by
GOSUB.
When the return stack is empty, RETURN causes an er-
ror.
RUN
Clear all variables and dimensions and then run the
program in program memory.
SAVE #expr
Redirect output to the given unit number and then
call LIST to write the program in program memory to
the associated file or device. After writing the
program, redirect output back to the terminal.
SAVE leaves the file pointer of the unit at the end
of the listing.
STEP
Used to specify an increment other than 1 in a FOR-
NEXT statement. See FOR.
STOP
List the line in which the STOP statement occurs and
stop program execution.
TO
Part of the FOR statement (q.v.).
SYSTEM
Exit from the interpreter. SYSTEM works in both, in-
teractive and program execution mode.
TROFF
Turn off tracing.
TRON
Turn on tracing. When running a program, print the
current line number in square brackets before exe-
cuting a new line.
*** FUNCTIONS ***
Functions that have a dollar sign ($) in their name re-
turn strings, all other functions return integers.
ASC(string)
Return the ASCII code of the first character in string.
Return 0 for an empty string.
ASC(X$)=255 indicates that the string variable X$ was
filled by an INPUT command reading a unit's EOF marker,
i.e. it can be used to check for the end of input on a
unit.
CHR$(value)
Return a one-character string that contains the character
corresponding to the ASCII code value.
CMPS(string1, string2)
Compare the characters in string1 and string2 and return
an integer that indicates the difference of the first
non-equal characters. A value less than zero means that
string1 comes before string2, when sorted alphabetically,
a value above zero means that string1 is comes after
string2, and zero indicates that both strings are equal.
The end of a string has the smallest possible value.
FRE(0)
Return the number of free bytes in program memory.
IOCTL(n, service)
Request the specified service for unit number n.
Possible values for service are:
100 rewind unit n (move to beginning of file)
101 append to unit n (move to EOF)
102 truncate unit n at current position
IOCTL returns a code that indicates the status of the re-
quested operation. Generally, zero means success and
non-zero means failure.
When a bad service number is passed to IOCTL, an error
occurs.
LEN(string)
Return the length of the given string. An empty string
will deliver zero.
MID$(string, position, length)
Extract a substring from string and return it. Position
specifies the first character to be extracted and length
gives the length of the desired substring.
When position is greater then the length of the string,
an empty string will be returned. When position+length
is greater than the length of string, all characters from
position up to the end of the string are returned.
The first character in a string is at position one, not
zero, but zero is treated as an alias for one.
PEEK(address)
Return the value at memory location address. PEEK only
reads bytes, and therefore its return value will always
be less than 256.
STR$(value)
Convert the specified value to a string and return it.
Negative numbers will have a leading minus sign.
VAL(string)
Compute the value of the specified string and return it.
A leading minus sign is recognized. Trailing non-digit
characters are ignored. Non-numeric input will return
zero.
*** ERROR CODES ***
When NMH-BASIC detects an error, it will print a three
letter code, followed by a colon and the line that caused
the error. When an error occurs in execution mode, the
program will be stopped.
LLO
Line too long - a line exceeds the maximum length of
64 characters.
OVF
Overflow - a numeric literal does not fit in 15 bits
+ 1 sign bit. The valid range for numeric literals
is -32767 to 32767.
SYN
Syntax error - the most common error with an infi-
nite number of possible causes . Frequently caused
by typos. Generally, the input that causes this er-
ror is not a valid basic statement.
ILN
Invalid line number - a GOTO or GOSUB statement con-
tains a non-existant line number.
DIV
Division by zero. Also caused by X \ 0.
SBO
String buffer overflow - the concatenation of two
strings is longer than 64 characters.
SUB
Bad subscript - caused by an attempt to access a
non-existant array element. This happens when an
element beyond Z(9) is referenced without first al-
locating storage to it via DIM.
MEM
Insufficient memory - caused by DIM or by inserting
lines into program memory.
NIM
Not implemented - oops.
STK
Stack error - the internal return stack has over-
flown. Caused by nesting subroutines or FOR-NEXT
loops too deeply.
NST
Nesting error - a RETURN statement occurs where a
NEXT has been expected, or vice versa. Also occurs
when a statement that is being LOADed attempts to
LOAD another program (LOAD may not be nested) or
when the return stack is not empty when a program
terminates.
TYP
Type mismatch - a variable in a READ statement has a
different type than the current item in the init
list (DATA).
EOD
End of data - a READ statement contains more vari-
ables than remaining items in the init list (DATA).
ARG
Bad argument - an invalid service code has been
passed to IOCTL.
STP
Stop - program execution terminated by a STOP com-
mand.
BRK
Break - caused by pressing Control-C or Control-
BREAK.
XXX
Argh! - interpreter in hopeless confusion - time to
bail out!
*** EXAMPLES ***
Print a sixbit ASCII table.
100 FOR I = 32 TO 95
110 PRINT CHR$(I); ' '; I - 32 ,
120 NEXT
Load (and merge) programs from units 3 and 4, then save
the merged program to unit 5. The IOCTL calls rewind and
truncate unit 5.
LOAD #3
LOAD #4
PRINT IOCTL(5, 100) , IOCTL(5, 102)
SAVE #5
Print data from unit 5. The IOCTL call rewinds the unit.
100 LET X = IOCTL(5, 100) : INPUT #5
110 INPUT A$ : IF ASC( A$ ) = 255 INPUT #0 : END
120 PRINT A$ : GOTO 110
*** NOTE ***
Some versions of the interpreter expect programs in DOS
file format, i.e. lines terminated with CR,LF. All ver-
sions of the interpreter do accept DOS format, some also
accept Unix (LF) format.
*** LICENSE ***
NMH-BASIC
By Nils M Holm, 1991-1994,2023
MAIL: fs29@rummelplatz.uni-mannheim.de (DEFUNCT!)
NMH-BASIC is free software, do whatever you want with it.
If it breaks something, don't blame me!
BASIC(1)
contact |
privacy