BASIC Interpreter#
Open 8bitworkshop IDE
History#
Dartmouth professors John G. Kemeny and Thomas E. Kurtz had the idea that every student should have access to a computer. But in those days, batch processing was the law of the land. Programmers would fill out a coding sheet, then a keypunch operator would create a deck of punch cards. The cards were fed into machines, and hours later you might receive results from your program – or if you were unlucky, an error report.
Kurtz had heard about time-sharing systems from John McCarthy at MIT. Such a system would allow students to use the computer interactively via their own terminals. Kemeny managed to acquire GE-225 and DATANET-30 computers, and together with a small army of undergrads, they developed the Dartmouth Time Sharing System (DTSS).
Kurtz convinced the trustees that computing should be as widely available as the open stack library at Dartmouth, and so the system was made free for students to use. The system was released in the spring of 1964, and by 1968, there were about sixty Teletype terminals connected via phone lines, each hammering out up to 10 characters per second on fan-fold paper.
Its centerpiece was the BASIC programming language, designed as a friendlier alternative to ALGOL and FORTRAN.
To reduce complexity, it had a small set of commands, one command per line.
Line numbers were required, used for GOTO
statements and for interactive editing.
FORTRAN’s loops and conditionals were simplified into FOR
and IF
statements.
BASIC was compiled directly into machine code, a process that often took less than a second.
There was some resistance among the faculty to the new machines, but the students dove in with gusto. Two hour-long lectures introduced students to BASIC programming. During their programming session at the terminal, they could automatically check their assignments with yet another BASIC program written by the faculty.
Students found creative uses for the computer, one writing a program to algorithmically check their music composition assignment. There were also the inevitable hacks and pranks and randomly-generated gibberish, often directed at fellow students or at the computer vendor, General Electric.
Thanks to the new INPUT
keyword, which paused the program to ask the user for input, games began to appear on the network.
Football and basketball simulations were popular, as well as “hot-seat” multiplayer games, later modified to play remotely over the regional Kiewit Network.
These games would soon find their way to the new BASIC-compatible time-sharing platforms from DEC and HP,
and then into various periodicals and books.
This era saw the beginning of several game genres: the cave explorer (Hunt the Wumpus), the procedural RPG (Super Star Trek) the space trading game (Star Trader) and the historical simulation (The Oregon Trail).
Even the DTSS’s EXPLAIN
feature might remind of you of the EXAMINE
command in text adventures,
given some of its snarky responses.
The next phase of BASIC began when Bill Gates and Paul Allen read about the Altair 8800 microcomputer in the January 1975 issue of Popular Electronics. They contacted the company and agreed to demonstrate a BASIC interpreter in a few weeks, having never seen an actual Altair unit in person.
Allen had written an Intel CPU simulator for a previous project, and he used this experience to develop an Altair simulator on a PDP-10. Using the simulator to test their code, the pair finished the 4KB BASIC interpreter on time, and flew the paper tape to demo in Albuquerque. BASIC booted up, and Microsoft was thus born.
Meanwhile, Microsoft licensed several variants of BASIC to Altair in exchange for royalties, and went on to do the same for the TRS-80, Commodore PET, Apple ][, MSX, and many other microcomputers.
Their dominance of BASIC lasted well into the PC/Windows era, with products like GW-BASIC, QuickBasic, QBasic, and Visual Basic. VB.NET, which is more-or-less a syntax alternative to C#, is still widely used in back-office applications. The Dartmouth BASIC bloodline survives in TrueBASIC, a commercial product.
These days, there are many modern hobbyist incarnations of BASIC, sharing the original core concepts of simplicity and fun. We’ve already integrated the Atari 2600 language batariBASIC into the 8bitworkshop IDE. New in this release is FastBasic, a BASIC interpreter for Atari 8-bit computers.
If you want to program like it’s the 1960s (or 1970s) you can read on and try our new vintage BASIC interpreter.
Programming#
OPTION DIALECT DARTMOUTH
10 PRINT "HELLO! LET'S PROGRAM IN BASIC."
20 INPUT "WOULD YOU MIND TYPING IN YOUR NAME";A$
30 PRINT "THANKS, ";A$;"! THIS WILL BE FUN!"
40 INPUT "NOW TELL ME YOUR FAVORITE NUMBER";N
50 LET B=N^2
60 PRINT "THAT'S A GOOD ONE! I LIKE";B;"MYSELF."
70 PRINT "NICE MEETING YOU, ";A$;"."
999 END
The original Dartmouth system required that a user press the ORIG button on the teleprinter,
enter their user number, enter “NEW” or “OLD” problem, enter a problem name,
then begin typing their program line-by-line.
Afterwards, RUN
would compile and execute the program, or give a list of errors to be corrected.
The 8bitworkshop IDE works a little differently. You can edit your BASIC program in the browser, and any errors are highlighted immediately when typing. When you make an edit and the program compiles successfully, your program is reloaded. If the program is already running, the IDE can often hot-load the program without restarting from scratch.
You can click on “Debug Tree” to inspect the program state, or highlight a variable name in the editor to see its value.
There is also a new “Restart at Line” button that lets you re-RUN
your program starting at a specific line.
(Watch out for uninitialized variables, loops, and such.)
Note the OPTION DIALECT
line at the beginning of the file.
This is a non-standard BASIC construct that tells the compiler to recognize a specific variant of BASIC.
This affects syntax, allowable keywords and functions, and print formatting.
Older dialects will limit the editor to uppercase characters.
There is no CRT, so no graphics. Instead, we offer a teleprinter interface with the speedy performance of the IBM 1403 line printer. (It’s nearly silent, although you can ring its bell by outputting ASCII code 7.)
Dialects#
The 8bitworkshop IDE supports several flavors of BASIC.
The BASIC dialect can be selected with the OPTION DIALECT
statement,
which should be the first line in your program.
There are several dialects supported:
- DARTMOUTH, DARTMOUTH4
BASIC 4th Edition or “the Fourth” (1968) ran on the Dartmouth BASIC Time Sharing System. It’s the ancestor of most of the other BASICs in this list. We support everything except the
MAT
(matrix math) statements and multiline function definitions.- DECPLUS, BASICPLUS
DEC BASIC-PLUS (1972). This was an extended riff on Dartmouth BASIC written for PDP-11 systems running RSTS/E. We support the
GOTO
exprOF
line, line… syntax, but not the other extended flow control directives likePRINT I IF I > 10
. There are some other quirks not supported, like the “&
” symbol substituted for aPRINT
statement, and thePRINT USING
statement (used for numeric formatting).- TINY
Tiny BASIC (1975) was a stripped-down integer-only interpreted BASIC (though we allow floats in our interpretation). It was designed as a freely-available implementation in response to Bill Gates’ “Open Letter To Hobbyists,” and led to the coining of the term “copyleft”. The first version was published in the PCC (People’s Computer Company) newsletter, which spun off a new periodical to publish source code – Dr. Dobb’s Journal. To make reimplementation easier, the parser was written in a bytecode language called IL.
- HP, HPTSB, HP2000
HP Time-Shared BASIC (1976). The games in What To Do After You Hit Return were written in this dialect, which supports a unique array-slice syntax for strings. Many BASIC games were ported to this dialect, including a popular cross-country pioneer simulation.
- ALTAIR41, ALTAIR
MITS Altair 8800 BASIC 4.1 (1977), Microsoft’s first product. David Ahl liked this one, so many classic games should work with it.
- BASIC80
Microsoft’s BASIC-80 (1977) for Z80 and 8080 CPUs. It ran on CP/M and later became TRS-80 Level III BASIC. This introduced the
WHILE ... WEND
syntax which persisted all the way to Visual BASIC.- ECMA55, MINIMAL
Minimal BASIC (1978) was an attempt to define an interoperable BASIC standard. Microsoft BASICs were becoming the de-facto standard, so it was ultimately withdrawn, although the ANSI standard remains. It is very similar to Dartmouth BASIC 4th edition, except without the CHANGE command, assignment chaining, and tick (’) comments.
- MODERN
A fictional BASIC which pulls out all of the stops, which is to say it doesn’t explicitly disallow anything without a good reason. Some things are disallowed, like using a variable before assignment, or using an array before dimensioning. Labels are supported, and line numbers are optional. Block IF/THEN/ELSE is supported, as are subroutines with SUB/CALL.
Examples#
The 8bitworkshop IDE includes many examples of classic BASIC programs. Some of these are historically relevant and reproduced from the original source code.
- Hello World
This is a simple “conversational program” which simulates a short dialogue between human and computer. At the time, this type of program was a disarming introduction to computers for those who have never seen one. It demonstrates the
PRINT
andINPUT
commands, string variables, and the^
exponentiation operator.- Lander
A lunar (or Earth) powered descent simulator, originally written in DEC’s FOCAL language by a high-school student in 1969. He submitted it to DEC’s newsletter where the editor David H. Ahl translated it into BASIC. (Benj Edwards wrote up a great article about it.) At each time step, the player enters a quantity of fuel to burn, and downward velocity slows proportionally. The goal is to reach near-zero velocity at the surface without running out of fuel.
- Hammurabi
Another early David Ahl conversion, from FOCAL program to the EduSystem 70 (PDP-8) and later to Microsoft BASIC. This version was found at Pete Turnbull’s web site.
- 23 Matches
A simple Nim-like game, where the last player to take an object loses, and the computer plays perfectly. David Ahl’s version added computer trash-talking, with insults like “meatball-nose” and “floppy ears.” Our version from the 1973 DEC EduSystem Handbook is more polite.
- Hunt the Wumpus
The classic (only?) dodecahedronal hunting game, written by Gregory Yob in 1973 as a response to the many two-dimensional games like Mugwump. This is a version from HP library tapes. It implores:
IF YOU DON'T KNOW WHAT A DODECAHEDRON IS, ASK SOMEONE
.- Craps
A gambling simulator adapted for “GTE Sylvania 1974 Family Day” found on a tape backup. This must have been part of a demonstration where families were present, since
NO PROFANITY!
is requested. One wonders what the non-censored version of the program was like.- Star Trader
Dave Kaufman’s 1974 multiplayer space trading game, which (along with another text-based space game) inspired a genre that now includes Elite, Trade Wars and Eve Online. The game was so big that it had to be split into multiple files, linked with the
CHAIN
command. Our BASIC interpreter doesn’t support that, so we renumbered and combined everything into a single file, and made a few other changes since we don’t supportPRINT USING
either. This game was published in the People’s Computing Company’s newsletter and in their 1975 compendium What To Do After You Hit Return.- Interest Calculator
A simple HP BASIC program from 1977 that computes interest payments. Soon, VisiCalc and other spreadsheet software would largely replace BASIC programming for these kinds of tasks.
- Haunted House
A silly and spooky adventure game from 1979, found on an old DEC tape backup.
- Sieve Benchmark
This is an implementation of the Byte Sieve, a popular Sieve of Eratosthenes benchmark published in a 1981 issue of BYTE magazine. Our implementation uses the
OPTION CPUSPEED MAX
command to run much faster than the interpreter’s default of 1,000 statements per second. Initial cocktail napkin simulations show that we run at about 30% the speed of John Ham’s Minimal BASIC to x86 Compiler.
Statements#
CHANGE
Convert a string to an array of character codes, or vice-versa. Not available in all dialects.
CLEAR
Clears all variables, arrays, and function definitions.
DATA
datum, datum…Creates data elements to be read back serially by READ. Elements are separated by commas, and can be numeric, or quoted or unquoted strings. (Compatibility issue: Whitespace is not trimmed on unquoted strings.)
DEF FN
a(
arg, arg…)
= definitionDefines a function with zero or more arguments. The function name must start with
FN
. The function body cannot call itself, although the compiler doesn’t check to see if functions call each other recursively.DIM
varname(
dim1, dim2…)
Reserves space for arrays. Unless declared otherwise, all array subscripts shall have a lower bound of zero and an upper bound of ten. Thus the default space allocation reserves space for 11 elements in one-dimensional arrays and 121 elements in two-dimensional arrays. In HP dialect, strings are allocated using the
DIM
statement.END
Terminates the program. In MINIMAL and HP dialects, an
END
must be the final statement in the program.FOR
varname=
initialTO
finalSTEP
stepDeclares a FOR loop, terminated by a NEXT statement. The numeric variable varname is set to initial before the first loop iteration. After each iteration, the variable is incremented by step (which can be negative) and then checked against final. The loop is repeated until the value is equal to or goes beyond the final value. In some dialects, this check is done before the first iteration, and so zero iterations are possible.
NEXT
varname, varname…Ends a FOR loop. In some dialects, varname is optional, and multiple variables can be specified.
GOTO
labelTransfers control of the program to a specified line number or label. In some dialects, this can be a computed value.
GOSUB
label …RETURN
Like
GOTO
, but pushes the program counter onto a return stack.RETURN
pops the topmost value off this stack and resumes execution.IF
condition [THEN
statement |GOTO
label ]ELSE
statementIf condition is non-zero, execute the statements after THEN, or transfer control to the label after the GOTO. In some dialects, ELSE can be specified, which binds to the rightmost THEN.
INPUT
prompt?,
ref,
ref …Pauses and accepts input from the keyboard. A quoted string prompt can be present. In any case, a “?” is printed before pausing for input. Each ref can be a simple variable or array element, numeric or string. If multiple values are specified, they are separated by commas before being accepted.
LET
ref=
expressionAssigns a computed expression to a variable, which can be a simple variable or array reference. The
LET
can be ommitted in most dialects. In HP dialect, the left side can be an array slice for strings.ON
index [GOTO
|GOSUB
] label1, label2 …Computes index and uses it to select one or more labels to GOTO or GOSUB. The value 1 specifies the first label, 2 the second, etc. Some dialects silently ignore out-of-bounds values.
OPTION BASE
[ 0 | 1 ]Selects whether arrays start at 0 or 1. The DIM statement specifies the highest valid index regardless of this setting.
OPTION DIALECT
identifierSelects a BASIC dialect to use for parsing and running the program.
OPTION CPUSPEED
[ number |MAX
]Sets the simulated BASIC interpreter speed in statements per second, or MAX for maximum speed.
OPTION
name valueSet other dialect options – see the table below. For example,
OPTION UPPERCASEONLY 0
enables lowercase on mainframe dialects.PRINT
expression [,
|;
] [ expression … ]Prints to the output. Each expression can be numeric or string. If numeric, most dialects put whitespace before and after the value, or a minus sign before. A comma separates expressions by tab groups, defined by the dialect, and usually 14-16 characters long. A semicolon places no extra whitespace between expressions. A new line is generated after the PRINT statement unless it ends with a comma or semicolon.
RANDOMIZE
Initialize the
RANDOM
number generator with a random seed. TheRND
function returns a predictable sequence of numbers until this statement is executed. This is consistent with the ECMA-55 standard.READ
ref,
ref …Reads data serially from DATA statements in the program.
RESTORE
labelResets the data pointer used by READ to the first DATA statement. Some dialects allow a label to be specified.
STOP
Halts the program.
WHILE
condition …WEND
Executes a loop as long as condition is non-zero. Only in BASIC80 and MODERN dialects.
Numeric Functions#
ABS(X)
The absolute value of X, i.e., if X < 0 then return -X.
ATN(X)
The arctangent of X in radians, i.e., the angle whose tangent is X. The range of the function is `-(pi/2) < ATN(X) < (pi/2)`
COS(X)
The cosine of X, where X is in radians.
EXP(X)
The exponential of X, i.e., the value of the base of natural logarithms (e = 2,71828...) raised to the power X.
INT(X)
The largest integer not greater than X; e.g. `INT(1.3)` = 1 and `INT(-1.3)` = -2.
LOG(X)
The natural logarithm of X; X must be greater than zero.
RND
The next pseudo-random number in an implementation-supplied sequence of pseudo-random numbers uniformly distributed in the range 0 <= `RND` < 1.
SGN(X)
The sign of X: -1 if X < 0, 0 if X = 0 and +1 if X > 0.
SIN(X)
The sine of X, where X is in radians.
SQR(X)
The nonnegative square root of X; X must be nonnegative.
TAN(X)
The tangent of X, where X is in radians.
FIX(
num)
Returns the integer part of the num argument, rounding up to zero if negative or down to zero if positive.
INT(
num)
Rounds down to an integer (floor).
RND
Returns a random number. The sequence is repeatable unless RANDOMIZE has been executed.
ROUND(
num)
Rounds to the nearest integer.
String Functions#
ASC(
string)
Returns the character code of the leftmost character of string.
CHR$(
num)
Converts a character code to a single-character string. Try 9 (tab), 10 (line feed), 12 (form feed) and 7 (bell).
HEX$(
num)
Converts a number to its hexidecimal notation.
INSTR(
needle,
haystack)
Returns the position of substring needle in the string haystack, or 0 if not found.
INSTR(
index,
needle,
haystack)
Returns the position of substring needle in the string haystack starting at index, or 0 if not found.
LEFT$(
string,
count)
Returns the leftmost count characters of a string.
LEN(
string)
Returns the length of a string.
LIN(
count)
Returns count line feeds for use in PRINT statements.
MID$(
string,
index,
count)
Returns count characters from string, starting at character index (1 is the leftmost character).
OCT$(
num)
Converts a number to its octal representation.
POS
Returns the current column position of the printed output.
RIGHT$(
string,
count)
Returns the rightmost count characters of a string.
SPC(
count)
Returns a string of count space characters, for use in PRINT statements.
SPACE$(
count)
Returns a string of count space characters.
STR$(
num)
Converts num to its string representation.
STRING$(
count,
char)
Returns a string of count repetitions of char, which can be either a numeric character code or another string.
TAB(
column)
Returns the number of spaces neccessary to advance to a given column, or an empty string if already past the desired column. For use in PRINT statements.
TIMER
Returns the number of seconds since a reference time.
UPS$(
string)
Converts string to uppercase.
VAL(
string)
Converts a string value to a numeric.
Compatibility#
The IDE’s BASIC compiler doesn’t emulate each dialect exactly. However, there is a rich tradition in BASIC of porting programs from one dialect to another, so for maximum verisimilitude you should try it yourself. Here are some of the issues that might pop up:
MAT
keyword and matrix operationsNot supported. A lot of games only use this feature to read in arrays of data, which can be easily done with loops.
CHAIN
For BASIC programs too big to fit into memory, this was a primitive way to pass variables between them (with the
COM
declaration). Instead, you can renumber and merge the files by hand.PRINT USING
andIMAGE
Dartmouth BASIC Sixth Edition introduced powerful numeric formatting features similar to that of FORTRAN. However, this is not implemented. You can use the
NFORMAT$
and string functions as a substitute.ENTER
On HP BASIC, the
ENTER
statement doesn’t time out, or allow a#
port variable. But it does return how fast it took for you to type.CONVERT
The HP BASIC
CONVERT
command can’t assign to array slices.ON ERROR GOTO
Error trapping is not supported.
THEN
clausesAll BASICs support the
IF
conditionTHEN
statement syntax, even though early BASICs only supported aGOTO
line number.PRINT
separatorsIf there is no delimiter between items, “;” is assumed.
- No integer types
Only floating point and string types (
A$
) are supported, just like in JavaScript. Integer (I%
) types are not supported.- Relational operators anywhere
Many BASICs only let you use relational operators in an IF statement. We allow them anywhere, and return a logical value of 0 for false and 1 for true – or -1 for true when bitwise logic operators are supported.
- No file support
Can’t open, read, write files.
- Error messages
Our error messages may be at times better or worse than actual vintage BASIC systems. They are certainly more verbose overall.
- Out-of-order line numbers
If line 200 comes before line 100 in the file, line 200 will be executed first. No error will be given for out-of-order line numbers. You also can’t jump to a line number that doesn’t exist, like in some interpreted BASICs.
- Multiple-line function definitions
Dartmouth BASIC 4th Edition supported complex multiline functions with a
DEF ... FNEND
block. We only support simple mathematical functions.- Embedded character codes
Strings in HP BASIC do not support embedded character codes like
"RING"'7"RING"
.
Dialect Feature Matrix#
dialectName |
TINY |
ECMA55 |
DARTMOUTH |
HP2000 |
DECPLUS |
ALTAIR41 |
BASIC80 |
MODERN |
---|---|---|---|---|---|---|---|---|
asciiOnly |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
- |
uppercaseOnly |
Y |
Y |
Y |
Y |
- |
Y |
- |
- |
optionalLabels |
- |
- |
- |
- |
- |
- |
- |
Y |
optionalWhitespace |
- |
- |
- |
- |
- |
Y |
Y |
- |
multipleStmtsPerLine |
- |
- |
- |
Y |
Y |
Y |
Y |
Y |
varNaming |
A |
A1 |
A1 |
A1 |
A1 |
* |
* |
* |
staticArrays |
- |
Y |
Y |
Y |
Y |
- |
- |
- |
sharedArrayNamespace |
Y |
Y |
- |
- |
- |
Y |
Y |
- |
defaultArrayBase |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
defaultArraySize |
0 |
11 |
11 |
11 |
11 |
11 |
11 |
0 |
defaultValues |
Y |
- |
- |
- |
Y |
Y |
Y |
- |
stringConcat |
- |
- |
- |
- |
Y |
Y |
Y |
Y |
maxDimensions |
0 |
2 |
2 |
2 |
2 |
128 |
255 |
255 |
maxDefArgs |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
maxStringLength |
255 |
255 |
255 |
255 |
255 |
255 |
255 |
2048 |
tickComments |
- |
- |
Y |
- |
Y |
- |
Y |
Y |
hexOctalConsts |
- |
- |
- |
- |
- |
- |
Y |
Y |
validKeywords |
11 |
26 |
31 |
31 |
39 |
44 |
51 |
all |
validFunctions |
0 |
12 |
17 |
23 |
39 |
37 |
46 |
all |
validOperators |
11 |
11 |
11 |
18 |
19 |
19 |
19 |
all |
printZoneLength |
1 |
15 |
15 |
15 |
14 |
15 |
14 |
16 |
numericPadding |
- |
Y |
Y |
Y |
Y |
Y |
Y |
- |
checkOverflow |
- |
Y |
Y |
- |
Y |
Y |
- |
Y |
testInitialFor |
- |
Y |
Y |
Y |
Y |
- |
Y |
Y |
optionalNextVar |
- |
- |
- |
- |
- |
Y |
Y |
Y |
multipleNextVars |
- |
- |
- |
- |
- |
Y |
Y |
Y |
bitwiseLogic |
- |
- |
- |
- |
- |
Y |
Y |
Y |
checkOnGotoIndex |
- |
Y |
Y |
- |
Y |
- |
- |
Y |
computedGoto |
Y |
- |
- |
Y |
- |
- |
- |
- |
restoreWithLabel |
- |
- |
- |
Y |
- |
- |
Y |
Y |
squareBrackets |
- |
- |
- |
Y |
- |
- |
- |
Y |
arraysContainChars |
- |
- |
- |
Y |
- |
- |
- |
- |
endStmtRequired |
- |
Y |
Y |
Y |
- |
- |
- |
- |
chainAssignments |
- |
- |
Y |
Y |
- |
- |
- |
Y |
optionalLet |
- |
- |
- |
Y |
Y |
Y |
Y |
Y |
compiledBlocks |
- |
Y |
Y |
Y |
Y |
- |
- |
Y |
|
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
Y |
- |
- |
- |
- |
- |
- |
Y |
|
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
- |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
- |
Y |
- |
Y |
- |
- |
Y |
|
- |
- |
- |
Y |
- |
- |
- |
Y |
|
- |
- |
- |
- |
Y |
Y |
Y |
Y |
|
- |
- |
- |
- |
Y |
- |
Y |
Y |
|
- |
- |
- |
- |
- |
- |
Y |
Y |
a = b |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
a <> b |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
a >< b |
Y |
- |
- |
- |
- |
- |
- |
Y |
a < b |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
a > b |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
a <= b |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
a >= b |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
a + b |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
a - b |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
a * b |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
a / b |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
a ^ b |
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
a ** b |
- |
- |
- |
Y |
Y |
- |
- |
Y |
a # b |
- |
- |
- |
Y |
- |
- |
- |
Y |
a NOT b |
- |
- |
- |
Y |
Y |
Y |
Y |
Y |
a AND b |
- |
- |
- |
Y |
Y |
Y |
Y |
Y |
a OR b |
- |
- |
- |
Y |
Y |
Y |
Y |
Y |
a MIN b |
- |
- |
- |
Y |
- |
- |
- |
Y |
a MAX b |
- |
- |
- |
Y |
- |
- |
- |
Y |
a == b |
- |
- |
- |
- |
Y |
- |
- |
Y |
a XOR b |
- |
- |
- |
- |
Y |
Y |
Y |
Y |
a IMP b |
- |
- |
- |
- |
Y |
Y |
Y |
Y |
a EQV b |
- |
- |
- |
- |
Y |
Y |
Y |
Y |
a \ b |
- |
- |
- |
- |
- |
Y |
Y |
Y |
a MOD b |
- |
- |
- |
- |
- |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
|
- |
- |
- |
Y |
- |
- |
- |
Y |
|
- |
- |
- |
Y |
Y |
Y |
Y |
Y |
|
- |
- |
- |
Y |
- |
- |
- |
Y |
|
- |
- |
- |
Y |
Y |
Y |
Y |
Y |
|
- |
- |
- |
Y |
- |
- |
- |
Y |
|
- |
- |
- |
Y |
- |
- |
- |
Y |
|
- |
- |
- |
Y |
Y |
- |
- |
Y |
|
- |
- |
- |
- |
Y |
- |
- |
Y |
|
- |
- |
- |
- |
Y |
- |
- |
Y |
|
- |
- |
- |
- |
Y |
Y |
Y |
Y |
|
- |
- |
- |
- |
Y |
Y |
Y |
Y |
|
- |
- |
- |
- |
Y |
Y |
Y |
Y |
|
- |
- |
- |
- |
Y |
Y |
Y |
Y |
|
- |
- |
- |
- |
Y |
Y |
Y |
Y |
|
- |
- |
- |
- |
Y |
Y |
Y |
Y |
|
- |
- |
- |
- |
Y |
Y |
Y |
Y |
|
- |
- |
- |
- |
- |
Y |
Y |
Y |
|
- |
- |
- |
- |
- |
Y |
Y |
Y |
|
- |
- |
- |
- |
- |
Y |
Y |
Y |
|
- |
- |
- |
- |
- |
Y |
Y |
Y |
|
- |
- |
- |
- |
- |
Y |
Y |
Y |
|
- |
- |
- |
- |
- |
Y |
Y |
Y |
|
- |
- |
- |
- |
- |
Y |
Y |
Y |
|
- |
- |
- |
- |
- |
Y |
Y |
Y |