BASIC (Basic Programming Language) - Nakazoto/CenturionComputer GitHub Wiki

BASIC

Surprisingly, Centurion did include BASIC in some form on the OS. However, it is not like the typical BASIC we think about. It is instead compiled into an executable, but that executable can only be run if the Basic Monitor has been loaded. Other than that, the BASIC language does behave like fairly typical Integer BASIC. It is interesting to note that Centurion BASIC does support UPSI and PUPSI, meaning it has the ability to pass values back and forth with JCL scripts. This really elevates the usefulness of BASIC on the Centurion.

INSERT SCREENSHOT HERE

Hellorld! Example

The following is an example BASIC program that prints "Hellorld!" 10 times on the screen.

10 FOR I = 1 TO 10
20 PRINT "HELLORLD!"
30 NEXT I

Compiling

To actually compile this program, it must first be typed up in an ASCII file. Follow the steps below to create the ASCII file, edit it, and then compile and execute the program. These steps are written with the Operating System loaded onto the fixed disk (1) and the default disk set to 1.

  1. .NEW ZHELLO ON 1 'A' 1S
    • Can be skipped if using CED as it will create the file for you
    • File name must have "Z" at the beginning
  2. .NEW @SCRE0 ON 1 'E' 1T
    • Only needs to be done if file doesn't already exist
  3. S.CED
    • CED is a wonderful line editor that can be used to write code into ZHELLO
  4. P.BASIC HELLO 1 CRT0 X
  5. .LOAD BASIC
    • Must be run once to load the basic monitor.
  6. .RUN XHELLO

The compiler is a single pass translator which produces a Centurion executable consisting of a stub to call the BASIC runtime engine followed by the program logic converted to Reverse Polish Notation bytecode. The BASIC runtime engine executes the bytecode which follows the stub.

BASIC Language Reference

This was reverse engineered using Ren's excellent disassembler.

Line format

Lines must start with a line number greater than zero and less then 32768. Lines must be in sequential order in the source file.

Comments are indicated by ! which will result in the compiler ignoring the rest of the line, or * which will result in the compiler skipping to the next statement indicated by : or the end of the line.

Types

There are three main types:

  • Integer - 16 bit 2's complement integers.
  • Real - 48 bit fixed point 6 decimal place real numbers.
  • Strings - Any character between pairs of ' or " characters.

Type specifiers

  • % specifies an integer value or variable/function
  • $ specifies a string value or variable/function

The default type for variables and numeric literals is Real.

Variables

Functions

There are 32 functions available in the language. Not all of them are implemented in the runtime environment.

Function Usage Notes
ABS ABS(arg) Absolute Value
ADDR ADDR(arg) Not implemented
ASCII ASCII(arg) The ascii code for the first character of a string
CHR CHR(arg) The character (string) from the ascii code
DATE DATE
END END(arg)
ERR ERR(arg)
EXP EXP(arg) The natural exponential function
FALSE FALSE The logical false value
FILEID FILEID(arg)
INT INT(arg) The integer value of arg
JP JP(arg) See FILEID
KEYX KEYX(arg) Not implemented
LC LC(arg) The lower case representation of arg
LEN LEN(arg) The string length of arg
LOG LOG(arg) The natural logarithm of arg
PEEK PEEK(H$, N$) Find the first occurence of N$ in H$. Zero indexed. Returns -1 if not found
POKE POKE(arg, arg, arg) Not implemented
RECLEN RECLEN
REP REP(arg, arg)
RND RND(arg)
SGN SGN(arg)
SHL SHL(arg, arg) Not implemented
SHR SHR(arg, arg) Not implemented
SSTR SSTR(S$, I%, L%) The substring of with length L% starting from position I% (zero indexed)
SSW SSW(S%) Returns TRUE if the sense switch S% is set, FALSE otherwise
STATUS STATUS
TAB TAB(arg)
TRACE TRACE(arg)
TRUE TRUE The logical true value
UC UC(S$) The upper case representation of S$
UPSI UPSI(arg)

Expressions

The following operators are available, with their precedence (1 is highest):

Operator Precedence Notes
OR 9 Integer bitwise OR
XOR 9 Integer bitwise XOR
&, AND 8 Integer bitwise AND
NOT 7 Integer bitwise NOT
<=, LE 6 String or numeric comparison
<>, NE 6 String or numeric comparison
<, LT 6 String or numeric comparison
=, EQ 6 String or numeric comparison
>=, GE 6 String or numeric comparison
>, GT 6 String or numeric comparison
// 5 String Concatenation
+ 4 Addition
- 4 Subtraction
* 3 Multiplication
/ 3 Division
**, ^ 2 Exponentiation
() 1 Parenthesis
() 1 Array index
() 1 Function application

The expression syntax in EBNF-like grammar.

expr      = andexpr [{("OR" | "XOR") andexpr}].
andexpr   = notexpr [{("&" | "AND") notexpr}].
notexpr   = ["NOT"] compexpr.
compexpr  = slashexpr [("<=" | "<>" | "<" | "=" | ">=" | ">" | "EQ" | "GE" | "GT" | "LE" | "LT" | "NE") slashexpr].
slashexpr = addexpr [{"//" addexpr}].
addexpr   = [("-" | "+")] multexpr [{("+" | "-") multexpr}].
multexpr  = expexpr [{("*" | "/") expexpr}].
expexpr   = priexpr [{("**" | "^") priexpr}].
priexpr   = "(" expr ")"
          | numlit
          | stringlit
          | function
          | dimvar
          | ident.
function  = fnident ["(" expr [{"," expr}] ")" ].
dimvar    = dimident "(" expr ["," expr] ")".

Note:

  • Exponentiation has the wrong associativity, it should be right associative.
  • Operands are converted to the correct type if possible at runtime.
  • Unary Plus and Minus when applied to literals are a separate operation. To create a negative numeric literal, then a string representation is required, such as "-1234" which will be converted to a negative number at runtime.
  • The grammar does not support Unary Plus and Minus very well.

Statements

Statement Usage Notes
CALL
CHAIN
CLOSE
CURSOR
DATA
DECLARE
DEF
DIM
DLTKEY
END END Indicates the end of the program source. Any source following the END statement is ignored. The compiler will insert an END statement if none is present in the source
ELSE The negative branch of an IF statement
FILE
FNEND
FORMAT
FOR
FREE
GETKEY
GOSUB
GOTO
HOLD
IF
INPUT
LET
LINELENGTH
LOCAL
MOVE
NEWKEY
NEXTKEY
NEXT
NOTE
ON
OPEN
OUTPUT
POINT
PRINT
PJP
PUPSI
RANDOMIZE
READ
RECORD
REM
RESTORE
RETURN
REWRITE
STOP
WRITE
⚠️ **GitHub.com Fallback** ⚠️