TeleBASIC Reference Guide
+*#+=.
-=++==-:.:- :@@@@@@%-.
+@@@%##@@@@@@#. .******###+.
:-: #@@%###*:=*+*#%@@@@@@@@@@@@@@%#+=:.
*@@@%+ .@@@@#-=#@@@@@@@@@@@@@@@@@@@@*=--+@@#+-.
-@@@%#*: ..-#@@@@@@@@@@@@@@@@@@@@%-=**:-@@@= :@@%*:
+@@%%%+*. :=#@@@@@@@@@@@@@@@@%@@@@@+ *@@:=%@@@@#%*#+-**.
#@@@*=.*@@@@@@@@@@@@%#*****=***##@:=-@@.**@@@+:=#-#@=
#@##++@@@@@#####***#%%@@@@ =@%#%#+:#:#=**#%*=@#:@@#
#@*+:=+**#@@@@@@@@@@@@@@@%--#%++-.=@:-:+#####%%#**-+#
@#+=+=+=:*++++**#@@@@@@@@@@**==*@+=@#=. .=+*###*=.
=@*@* -@@@@@@@@*-+%@@@@@%+#@@#**#=+#@@%%#*+-:
:@@= .@@@@@#%*. ....=@@@@#+-
@= ...==. -#++++##
: =+-
Dartmouth DTSS TeleBASIC (c) 1964,1966,1969,1970,1971,1979,2023
> What is TeleBASIC?
TeleBASIC is the flavour of BASIC (Beginners' All-purpose Symbolic
Instruction Code), used on Telehack (https://telehack.com/). TeleBASIC is
based on the original Dartmouth BASIC, but with a large number of additional
features, such as support for regular expressions, UNIX timestamps, many
common hashing/encoding algorithms, multi-dimensional arrays, and the
ability
to use alphanumeric indices.
Features from other types of BASIC such as HP2000 Access BASIC and Commodore
BASIC have been added for increased compatibility and functionality.
TeleBASIC has a wide user-base and is actively maintained by members of The
Telehack Foundation (https://github.com/orgs/telehack-foundation/people/).
> Table of Contents
1. Set Up Your Editor for BASIC Programming
2. Comparing/Logical Operators
3. Variables and Data Types
4. Arrays & Hashes
5. Command Overview
6. FAQ
7. ANSI Escape Sequences
> 1. Set Up Your Editor for BASIC Programming
-> Using External Text Editors
There are currently four user-made plugins, which enable syntax-highlighting
in various editors:
* Atom (https://telehack.com/r/tg9sD)
* Nova (https://telehack.com/r/gDAbA)
* Sublime Text 3 (https://telehack.com/r/lP7iz)
* Visual Studio Code (https://telehack.com/r/vxEjh)
-> Using PED
You can also use the text editor PED within Telehack - a massively augmented
version of the original program by Niek Albers. Extra features include
syntax highlighting, and the ability to run programs without closing the
editor.
These features are accessible via emacs-style meta-key shortcuts.
To see a list of features type M-x list-packages RET.
--> What does that mean?
The "M" refers to the "meta" key on your keyboard (most often, this is the
escape key) and "RET" refers to the "return" key.
For example, to enable BASIC syntax highlighting, you would press escape,
then x, then type "basic" and hit return.
Thus, the shorthand would be M-x basic RET.
Additionally, you do not need to type the full name of the command. It is
sufficient to simply type M-x ba RET.
To run a BASIC program within PED type M-x run RET.
Command-line options
====================
ped /nomouse disables mouse input support
ped /noexpand disables tab expansion
ped /basic enables BASIC syntax highlighting
ped /tablen=<n> set tab length to <n>
> 2. Comparing / Logical Operators
-> Comparing Operators
* = (equal to)
10 A% = 0 : IF A% = 0 THEN PRINT "It is equal!"
* > (greater than)
10 A% = 5 : IF A% > 0 THEN PRINT "It is greater!"
* >= (greater than or equal to)
10 A% = 0 : IF A% >= 0 THEN PRINT "It is greater or equal!"
* < (less than)
10 A% = -1 : IF A% < 0 THEN PRINT "It is less!"
* <= (less than or equal to)
10 A% = 0 : IF A% <= 0 THEN PRINT "It is less or equal!"
* <> (not equal to)
10 A% = 1 : IF A% <> 0 THEN PRINT "It is not equal!"
-> Logical Operators
* AND (bitwise "and" operation)
* OR (bitwise "or" operation)
* XOR (exclusive "or" operation)
* NOT (negation)
* EQV (material equivalence)
* IMP (implication)
--> Results Returned by Logical Operations
Operation |Value |Value |Result
---------------------+-----------------+-----------------+------------------
NOT |X | |NOT X
NOT |True | |False
NOT |False | |True
Operation |Value |Value |Result
---------------------+-----------------+-----------------+------------------
AND |X |Y |X AND Y
AND |True |True |True
AND |True |False |False
AND |False |True |False
AND |False |False |False
Operation |Value |Value |Result
---------------------+-----------------+-----------------+------------------
OR |X |Y |X OR Y
OR |True |True |True
OR |True |False |True
OR |False |True |True
OR |False |False |False
Operation |Value |Value |Result
---------------------+-----------------+-----------------+------------------
XOR |X |Y |X XOR Y
XOR |True |True |False
XOR |True |False |True
XOR |False |True |True
XOR |False |False |False
Operation |Value |Value |Result
---------------------+-----------------+-----------------+------------------
EQV |X |Y |X EQV Y
EQV |True |True |True
EQV |True |False |False
EQV |False |True |False
EQV |False |False |True
Operation |Value |Value |Result
---------------------+-----------------+-----------------+------------------
IMP |X |Y |X IMP Y
IMP |True |True |True
IMP |True |False |False
IMP |False |True |True
IMP |False |False |True
-> Arithmetic Operators
TeleBASIC supports the following standard mathematical operators:
(), ^, **, mod, /, *, +, and -.
> 3. Variables and Data Types
You can store either text or numeric values in variables.
Variable names can contain letters and digits, but they have to start with a
letter (e.g FOO, BAR123$).
You cannot use reserved keywords (e.g FOR, IF) as variable names. You also
cannot begin a variable name with one of the logical operator keywords (e.g.
ORIGIN is invalid because it begins with OR).
Variable names are most often suffixed with a type definition character
(called a "sigil"):
* $ represents a text (string) value
* % represents a numeric (integer) value
* ! represents a numeric (single-precision) value
Strings MUST include the $ sigil. If a variable is missing a sigil, then it
is a number.
For example:
10 NAME$ = "some name"
would represent a string variable NAME$, but
10 NAME = "some name"
...would throw a TYPE MISMATCH ERROR, since you cannot assign a string to a
numeric variable.
> 4. Arrays and Hashes
An array variable is basically a list of values. These can be accessed by
specifying an index number.
In traditional Dartmouth BASIC, we define a string array of size 10:
10 DIM MYLIST$(10)
Now we can modify the 5th Entry (note that the array index usually starts at
0, and can also be negative):
20 MYLIST$(4) = "some text"
TeleBASIC, however, does not require you to define the array's size before
accessing it, so DIM is not necessary.
In addition to this, TeleBASIC allows for creation of multi-dimensional
arrays, such as:
10 MYSTUFF( X, Y ) = 42
... and indices do not need to be numeric. Thus, you can create unordered
lists (hashes) such as:
10 FAV$("fruit") = "Apple"
20 FAV$("vehicle") = "Bicycle"
30 FAV$("language") = "TeleBASIC"
> 5. Command Overview
-> Index
--> A
* ACCESS Currently not implemented, does nothing
* ARG$ A string containing all command line arguments
* ARGC% The number of arguments passed to the program
* ARGV$(n) An array containing all of the arguments passed to the program
* ASC(s$) Returns the ASCII value of the first character in the string s$
* ATN(n) Returns the arctangent (in radians) of the specified value n
--> B
* BIN$(n) Returns the binary representation of the integer n as a string
* BRK(n) Currently not implemented, does nothing
--> C
* CALL Currently not implemented, does nothing
* CHR$(n) Convert an ASCII code n to its equivalent character
* CINT(n) Returns the nearest integer of the specified value
* CIRCLE Currently not implemented, does nothing
* COLOR(a, b) Changes the colours of the terminal
* CONT Continue execution after STOP, END, Control-C, or runtime error
* COS(n) Returns the trigonometric cosine of the angle n (in radians)
* CSNG(n) Convert a specified value n to a single precision number
--> D
* D2R(n) Convert degrees to radians
* DATA n... Store variables accessed by the program READ statements
* DEF FNname(Argument) = Expression Define a function
* DEFDBL (Variable) Currently not implemented, does nothing
* DEFINT (Variable) Currently not implemented, does nothing
* DEFSNG (Variable) Currently not implemented, does nothing
* DEFSTR (Variable) Currently not implemented, does nothing
* DIM (Variable) Currently not implemented, does nothing
* DIR$ Returns the filenames in your local directory, separated by spaces
* DO Currently not implemented, does nothing
* DRAW Currently not implemented, does nothing
--> E
* END End program execution silently, without additional output
* EOF(n) Returns file pointer information
* ERASE (arrays) To eliminate arrays from a program
* EXP(n) Return base of natural logarithms to the power of n
--> F
* FOR x = startValue TO maxValue [STEP n] Execute a series of instructions
* FRE Return available memory
--> G
* GOSUB (LineNumber) Branch to a subroutine and return
* GOTO (LineNumber) Branch unconditionally to a specified line number
--> H
* HEIGHT Returns your terminal height
* HEX$(n) Returns hexadecimal value of the specified number n
--> I
* IF expression THEN statements Make a decision regarding program flow
* INKEY$ Returns one character read from the terminal
* INPUT FileNo, var$ Reads a line from an open file
* INPUT var$ Read user input
* INPUT "prompt", var$ Read user input
* INPUT varA$, varB$, ... Read user input
* INPUT "prompt", varA$, varB$, ... Read user input
* INSTR(string$, search$, startPos) Returns the position of a substring
* INT (n) Truncate a value to a whole number
* ITM(fileNumber) Returns the number of a data item
--> L
* LEFT$(s$, n) Returns the leftmost n characters of s$
* LEN(s$) Returns the number of characters in the specified string
* LET Variable = Value Assigns a value to a variable
* LIN(n) Returns n newlines
* LOCATE y, x Change the cursor position to y, x
* LOG(n) Returns the natural logarithm of n
* LOG10(n) Returns the natural logarithm of n (base 10)
--> M
* MID$(s$, n, [l]) Returns a substring of l characters from s$ beginning
with the nth character
--> N
* NINT(n) Returns the nearest integer of the specified value
* NUM(s$) Returns the ASCII value of the first character in the string s$
--> O
* OCT$(n) Returns the octal value of n
* ON NUMBER% Jump conditionally to a line number based on value given
* OPEN filename$, AS fileNumber Opens a file
--> P
* PCLEAR0 Currently not implemented, does nothing
* PCLEAR1 Currently not implemented, does nothing
* PEEK(n) Read a value from the specified memory location n
* PLAY Currently not implemented, does nothing
* PMODE0 Currently not implemented, does nothing
* POKE n, m Write a byte of data m into the specified memory location n
* POLKEY$(n) Returns one character read from the terminal
* PORT% Returns the port from the currently logged in user
* POS(string$, search$, [startPos]) Returns the position of a substring
* PRINT expression Prints an expression to the screen
* PUT Currently not implemented, does nothing
--> R
* R2D(n) Converts n radians to degrees
* READ n... or a file and assign to variable
* REC(n) in the specified file
* RENUMBER [start,[inc] Renumbers the statements of the current program
* RESTORE statements to be reread
* RETURN Return from a subroutine
* RIGHT$(s$, n) Returns the rightmost n characters of s$
* RND(n) Returns a random number
--> S
* SCRATCH Delete a file from the disk
* SCREEN Currently not implemented, does nothing
* SGN(n) Returns the sign of the specified value n
* SIN(n) Returns the trigonometric sine of the angle n (in radians)
* SLEEP n Pauses the program for n seconds
* SOUND Currently not implemented, does nothing
* SOUNDRND Currently not implemented, does nothing
* SPACE$(n), SPC$(n), SPA(n) Returns n spaces
* SQR(n) Returns the square root of n
* STOP Halts the program and prints the current line
* STR$(n) Returns n as a string value
* STRING$(n, s$) Repeats the string s$ n times
* SYS(n) HP2000 Access BASIC system information
* SYSTEM End program execution silently, without additional output
--> T
* TAB(n), TAB$(n) Returns n spaces (not tabs!)
* TAN(n) Returns the trigonometric tangent of the angle n (in radians)
* TH_B64D$ Returns argument decoded from base64
* TH_B64E$ Returns argument encoded to base64
* TH_DEFGROUP$ Returns the user's defgroup, separated by spaces
* TH_EXEC Executes a shell command and returns to the program
* TH_GMTIME[$] Returns a human-readable UTC time for a timestamp
* TH_HASADMIN(sat$) Returns 1 if the user has admin on sat$
* TH_HASBADGE(badge$) Returns when the user earned badge$
* TH_HASLOGIN(host$) Returns 1 if the user has login on host$
* TH_HASROOT(host$) Returns 1 if the user has root on host$
* TH_HASSYSOP(bbs$) Returns 1 if the user has sysop on bbs$
* TH_HOSTNAME$ Returns current hostname or hostname of argument passed
* TH_LOCALTIME[$] Returns a human-readable local time for a timestamp
* TH_MD5BASE64$ Returns md5 hex of argument passed as base64
* TH_MD5HEX$ Returns md5 hex of argument passed as hex
* TH_MODEM$ Returns modem information depending on option passed
* TH_NETSTAT$ Returns a netstat, separated by spaces
* TH_PLAN$ Returns the user's .plan as a string
* TH_RE(txt$,pat$,count,case) Returns regex matches
* TH_RE$(txt$,pat$,ind$,case) Returns regex matches
* TH_REV$(s$) Returns the string s$ in reverse order
* TH_SED$(txt$,find$,replace$,opt$) Substitute matched substring
* TH_SPRINTF$(fmt$,[...]) Returns a formatted string
* TH_STATUS$ Returns the user's status as a string
* TH_SYSLEVEL Returns the user's Telehack system level
* TH_TIME Returns the current UNIX timestamp
* TH_UUD$(s$) Decodes a uuencoded string
* TH_UUE$(s$) Returns uuencoded form of input string
* TIM(n) Returns values of time and date depending on n
* TIME$ Returns the local system time
* TIMER Returns the number of seconds since midnight
* TROFF Stops tracing of program statements
* TRON Starts tracing of program statements
* TYP(n) Returns the type of the next record in a file
--> U
* UPS$(string) Returns the uppercase value of the given string
* USER$ Returns the current logged in user
--> V
* VAL(s$) Returns the numeric value of s$
--> W
* WIDTH Returns your terminal width
> Detailed Overview
-> ABS(n)
Returns the absolute value of the specified value n
10 PRINT ABS(-40)
40
-> ACCESS
Currently not implemented, does nothing
-> ARG$
A string variable this is populated with a string containing the command
line arguments when a BASIC program is run from the shell command prompt.
10 PRINT ARG$
@program foo bar
foo bar
-> ARGV$(n)
An array containing all of the arguments passed to the program (see example
for ARGC% below)
-> ARGC%
The number of arguments passed to the program
10 FOR I = 0 TO ARGC%-1
20 PRINT ARGV$(I)
30 NEXT I
@program foo "hello world" bar
[run program.bas foo "hello world" bar]
program.bas
foo
hello world
bar
-> ASC(s$)
Returns the ASCII value of the first character in the string s$
10 PRINT ASC("A")
65
See also NUM
-> ATN(n)
Returns the arctangent (in radians) of the specified value n
10 PI = 3.14159
20 PRINT ATN(1)
30 PRINT PI/4
0.785
0.785
-> BIN$(n)
Returns the binary representation of the integer n as a string
10 PRINT BIN$(123)
1111011
-> BRK(n)
Currently not implemented, does nothing
-> CALL
Currently not implemented, does nothing
-> CHR$(n)
Convert an ASCII code n to its equivalent character
10 PRINT CHR$(42)
*
-> CINT(n)
Returns n rounded to the nearest integer, with 0.5 rounding away from 0
10 PRINT CINT(5.6)
20 PRINT CINT(5.5)
30 PRINT CINT(5.4)
40 PRINT CINT(-5.5)
6
6
5
-6
See also NINT
-> CIRCLE
Currently not implemented, does nothing
-> COLOR(a, b)
Changes the background b and/or foreground a colour of the terminal
10 COLOR 3, 4
20 PRINT "Hello"
Prints Hello with blue b background and yellow a foreground text. A list of
possible colours can be found with the command SHOW COLORS.
-> CONT
Continue execution at the statement after STOP, END, Control-C, or runtime
error.
>10 print 123 : STOP : print 456
>run
1
10 print 123 : STOP : print 456
^
STOP AT LINE 10
>CONT
456
>10 STOP
>20 print "back on track"
>run
10 STOP
^
STOP AT LINE 10
>cont
back on track
Another example:
> 10 for x = 5 to 10
> 20 for y = 1 to 5
> 30 print 10 / (x-y)
> 40 next y
> 50 next x
>run
2.500
3.333
5
10
30 print 10 / (x-y)
^
DIVISION BY ZERO AT LINE 30
> print "This caused a problem:" x, y
This caused a problem: 5 5
> print "At line " sys(1)
At line 30
-> COS(n)
Returns the trigonometric cosine of the angle n, given in radians
10 PI = 3.14159
20 PRINT COS(PI/6)
30 PRINT SQRT(3)/2
0.866
0.866
-> CSNG(n)
Convert a specified value n to a single precision number
10 PRINT CSNG("3.45")
3.450
-> D2R(n)
Convert degrees to radians
10 PRINT D2R( 90 )
1.571
See also R2D
-> DATA n...
Store the numeric and string constants that are accessed by the program READ
statements
10 DATA 4.1, 5.6, 9.98
20 READ A, B, C
30 PRINT A, B, C
4.100 5.600 9.980
-> DEF FNname(Argument) = Expression
Define a function with the name FNname which accepts an Argument and returns
the defined Expression.
The function name must always begin with FN, followed by an optional space.
10 DEF FN square(x) = x^2
20 DEF FNcube(x) = x^3
30 DEF FNtood$(s$) = s$ + "tood"
40 PRINT FNsquare(5),FNcube(5),FNtood$("foo")
25 125 footood
-> DEFDBL (Variable)
Declare a variable as double precision number (currently not implemented,
does nothing)
-> DEFINT (Variable)
Declare a variable as integer number (currently not implemented, does
nothing)
-> DEFSNG (Variable)
Declare a variable as single precision number (currently not implemented,
does nothing)
-> DEFSTR (Variable)
Declare a variable as string (currently not implemented, does nothing)
-> DIM (Variable)
Define an array of a fixed size (currently not implemented, does nothing)
-> DIR$
Returns the filenames in your local directory, separated by spaces
10 PRINT DIR$
advent.gam againstip.txt basic15.a2 bbslist.txt c8test.c8 changelog.txt
colossus.txt command.txt crackdown.txt do-well.txt etewaf.txt finger.txt
fireworks.vt fnord.txt future.txt hammurabi.bas hckr_hnd.txt ien137.txt jfet.
a2 johnnycode.txt k-rad.txt learncode.txt leaves.txt lem.bas lostpig.gam
mastermind.bas notes.txt orange-book.txt oregon.bas porthack.exe privacy.txt
rogue.gam rootkit.exe satcom.man smile.c8 starwars.txt sysmon.txt telehack.
txt ttest.vt underground.txt unix.txt valentin.vt wardial.exe wumpus.bas
xmodem.exe zork.gam
-> DO
Currently not implemented, does nothing
-> DRAW
Currently not implemented, does nothing
-> END
End execution of the program silently, without additional output (in
contrast to STOP).
Note that SYSTEM is an alias for END.
10 PRINT "hello"
20 GOSUB 100
30 END
40 PRINT "WORLD"
50 RETURN
-> EOF(n)
Returns -1 if the file pointer in file number n is currently at the end of
the document, otherwise returns 0.
The reason for -1 being used to denote truth is that -1 is 11111111 in
binary,
and conversely, 0 is 00000000.
See also TYP.
-> ERASE arrays
Eliminate an array from the program. Accepts a list of arrays.
10 A(1) = 123
20 A(2) = 456
30 B$( "foo" ) = "bar"
40 B$( "bar" ) = "baz"
50 ERASE A, B$
60 PRINT A(1) A(2) "'" B$( "foo" ) "' '" B$( "bar" ) "'"
0 0 '' ''
-> EXP(n)
Return the base of natural logarithms to the power of the specified value n
10 PRINT EXP(13)
442413.392
-> FOR x = startValue TO maxValue [STEP n]
Execute a series of instructions a specified number of times in a loop,
optionally incrementing x by n each time.
Note that FOR I=A TO B STEP S: ... : NEXT I works like I=A; do { ... } while
((I+=S) < B); (in the C programming language), so the last NEXT I increases
I one step beyond B.
10 FOR I = 1 TO 40
20 PRINT I
30 NEXT I
40 REM the I variable is now 41
This would run 40 times and output every time the current counter,
incrementing I by 1 each time.
10 FOR I = 1 TO 40 STEP 2
20 PRINT I
30 NEXT I
This would run 40 times and output the current counter in each iteration,
and would increase I by 2 each time.
10 FOR I = 1 TO 0 STEP 0
20 PRINT I
30 NEXT I
This would create an endless loop, printing 1 over and over until
terminated.
-> FRE
Return the available system memory in bytes
10 PRINT FRE
1048576
-> GOSUB (LineNumber)
Branch to a subroutine and return
10 GOSUB 100
20 PRINT "Now I'm back from the subroutine"
30 END
100 REM Subroutine starts here
110 PRINT "I am now in the subroutine"
120 RETURN
I am now in the subroutine
Now I'm back from the subroutine
-> GOTO (LineNumber)
Branch unconditionally out of the normal program sequence to a specified
line number
10 PRINT "Hello World!"
20 GOTO 10
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
[...]
You might want to use a SLEEP statement here!
-> HEIGHT
Returns your terminal height
-> HEX$(n)
Returns a string which represents the hexadecimal value of the specified
number n
10 PRINT HEX$(127)
7F
-> IF expression THEN statements
Make a decision regarding program flow based on the result of a returned
expression
10 K = 3
20 J = 10
30 IF J > K THEN PRINT "J is bigger than K"
J is bigger than K
See section 2. Comparing/Logical Operators
-> INKEY$
Returns one character read from the terminal. It will wait until a character
is typed. For a non-blocking alternative, see POLKEY$
10 A$ = INKEY$
20 PRINT A$
-> INPUT var$
Shows the default prompt and reads input from the user and saves it into
var$.
10 INPUT A$
20 PRINT A$
The builtin INPUT$ variable has a similar effect, but can be used inside
expressions:
10 NEVERLEN = LEN(INPUT$)
20 PRINT "You would have won if you had typed" ( 1 + NEVERLEN ) "letters"
-> INPUT "prompt", var$
Shows prompt$ and reads input from the user and saves it into var$. Note
that the prompt must be a string literal, not a variable.
10 INPUT "Enter something>", A$
20 PRINT A$
-> INPUT varA$, varB$, ...
Shows the default prompt and reads input from the user, splits it at commas,
and saves it into varA$, varB$, ...
10 INPUT A$, B$, C$
20 PRINT A$, B$, C$
-> INPUT "prompt", varA$, varB$, ...
Shows prompt$ and reads input from the user, splits it at commas, and saves
it into varA$, varB$, ... Note that the prompt must be a string literal, not
a variable.
10 INPUT "Enter something>", A$, B$, C$
20 PRINT A$, B$, C$
-> INPUT FileNo, var$
Reads a line from an open file and saves it into var$
10 INPUT# 1, A
20 PRINT A
-> INSTR(string$, search$, [startPos])
Returns the position (indexed from 0) of search$ within string$, or -1 if
not
found. If provided, begin searching at index startPos
10 TEXT$ = "Hello, World! Hello, Telehack!"
20 PRINT INSTR(TEXT$, "llo")
30 PRINT INSTR(TEXT$, "llo", 3)
40 PRINT INSTR(TEXT$, "foo")
2
16
-1
See also POS
-> INT (n)
Truncate a value to a whole number (towards zero)
10 PRINT INT(5.6)
20 PRINT INT(-5.6)
5
-5
-> ITM(fileNumber)
Returns the number of the data item currently pointed to in the current
record of file fileNumber.
In TeleBASIC this will almost always be 1.
10 PRINT #1;A,B,C
20 READ #1,1;A
30 PRINT REC(1),ITM(1)
1 2
-> LEFT$(s$, n)
Returns the leftmost n characters of the specified string s$
If n is negative, returns everything except the rightmost ABS(n) characters
10 A$ = "Hello World"
20 PRINT LEFT$(A$, 5)
30 PRINT LEFT$(A$, -3)
Hello
Hello Wo
See also MID$ and RIGHT$
-> LEN(s$)
Returns the number of characters in the specified string
10 A$ = "Hello World"
20 PRINT LEN(A$)
11
-> LET Variable = Value
Assigns a value to a variable. Traditionally this is for use with
constants, which are not supported in TeleBASIC, and so LET is superfluous.
10 LET A = 12345
20 PRINT A
12345
-> LIN(n)
Returns n newlines
10 PRINT "A" LIN(2) "B"
A
B
-> LOCATE y, x
Change the cursor position to y, x
10 LOCATE 5, 5
-> LOG(n)
Returns the natural logarithm of n using Euler's Number
(https://en.wikipedia.org/wiki/E_(mathematical_constant)) as the base
10 PRINT LOG(6)
1.792
-> LOG10(n)
Returns the natural logarithm of n using 10 as the base (decimal).
10 PRINT LOG10(6)
0.778
-> MID$(s$, [n], [l])
Returns a substring of l characters from s$ beginning with the nth character
(indexed from 1)
If l is omitted or zero, the rest of the string is returned. If l is
negative, the end of the substring is indexed relative to the end of the
string
If n is omitted, zero, or negative, the start of the substring is indexed
relative to the end of the string.
10 A$ = "Hello World"
20 PRINT MID$(A$,3,3)
30 PRINT MID$(A$,3)
40 PRINT MID$(A$,3,-3)
50 PRINT MID$(A$,-3,3)
60 PRINT MID$(A$), MID$(A$,LEN(A$))
70 PRINT MID$(A$,-1)
llo
llo World
llo Wo
orl
d d
ld ld
See also LEFT$ and RIGHT$
-> NINT(n)
Returns n rounded to the nearest integer, with 0.5 rounding towards 0
10 PRINT NINT(5.6)
20 PRINT NINT(5.5)
30 PRINT NINT(5.4)
40 PRINT NINT(-5.5)
6
5
5
-5
See also CINT
-> NUM(s$)
Returns the ASCII value of the first character in the string s$
10 PRINT NUM("A")
65
See also ASC
Not to be confused with VAL(s$), which returns the numeric value of s$.
-> OCT$(n)
Returns the octal value of n
10 PRINT OCT$(66)
102
-> OPEN filename$, AS fileNumber
Opens a file
10 OPEN "filename.txt", AS #1
-> ON NUMBER%
Jump conditionally with GOTO/GOSUB, based on value given
10 NUMBER% = 2
20 ON NUMBER% GOTO 100,200,300
100 PRINT "Goto 100, will NOT jump here" : END
200 PRINT "Goto 200, will jump here" : END
300 PRINT "Goto 300, will NOT jump here" : END
Goto 200, will jump here
If NUMBER% <= 0, the operation is a no-op. Generally NUMBER% is rounded down
to nearest integer, but if 0 < NUMBER% < 1, it will be rounded up instead.
10 number% = 3.5
20 ON number% GOTO 100, 200, 300
30 PRINT number% "did not invoke GOTO" : END
100 PRINT number%, ": GOTO 100" : number% = number% - 0.5 : GOTO 20
200 PRINT number%, ": GOTO 200" : number% = number% - 1 : GOTO 20
300 PRINT number%, ": GOTO 300" : number% = number% - 1 : GOTO 20
3.500 : GOTO 300
2.500 : GOTO 200
1.500 : GOTO 100
1 : GOTO 100
0.500 : GOTO 100
0 did not invoke GOTO
-> PCLEAR0
Currently not implemented, does nothing
-> PCLEAR1
Currently not implemented, does nothing
-> PEEK(n)
Read a value from the specified memory location n
10 PRINT PEEK(1300)
83
-> PLAY
Currently not implemented, does nothing
-> PMODE0
Currently not implemented, does nothing
-> POKE n, m
Write a byte of data m into the specified memory location n
10 POKE 1300, 255
-> POLKEY$(n)
Returns one character read from the terminal. When no key is hit within n
seconds, it returns the empty string
10 A$ = POLKEY$(5)
20 REM This will wait 5 seconds, waiting for user input
30 PRINT A$
40 B$ = POLKEY$
50 REM The default wait is 1 second.
60 PRINT B$
-> PORT%
Returns the port from the currently logged in user. Not to be confused with
the current socket (e.g 23 for telnet)
10 PRINT USER$ + " is logged in on port: " + STR$(PORT%)
-> POS(string$, search$, [startPos])
Returns the position (indexed from 1) of search$ within string$, or 0 if not
found. If provided, begin searching at index startPos
10 TEXT$ = "Hello, World! Hello, Telehack!"
20 PRINT POS(TEXT$, "llo")
30 PRINT POS(TEXT$, "llo", 4)
40 PRINT POS(TEXT$, "foo")
3
17
0
See also INSTR
-> PRINT expression
Prints an expression to the screen
10 A = 5
20 B = 10
30 PRINT A + B
15
10 A$ = "Hello "
20 B$ = "World"
30 PRINT A$;
40 PRINT B$
50 PRINT A$ + B$
60 PRINT A$ B$
Hello World
Hello World
Hello World
& and ? are available aliases for PRINT
Adding a ; at the end of PRINT will suppress the newline
When PRINT is immediately followed by @[n],, the entire line is indented by
n spaces:
> n = 9
> & @n, "nicely indented"
nicely indented
-> PRINT #fileNumber[,recordNumber]; expression
Prints a expression into an open file, with optional record (line) number
10 OPEN "myfile.txt", AS #1
20 PRINT# 1, "Hello world"
30 CLOSE #1
-> PRINT #fileNumber[,recordNumber];END
Prints an EOF mark to a file, truncating the file at that record
10 PRINT #1;A$
20 PRINT #1,1;"Overwriting A$ in record 1"
30 PRINT #1,1;END : REM Truncates file at record 1
Observe the placement of the # in PRINT, AS, and CLOSE statements in the
above examples
-> PUT
Currently not implemented, does nothing
-> R2D(n)
Converts n radians to degrees
10 PRINT R2D(1.2)
68.755
See also D2R
-> READ n...
Read a value from DATA or a file and assign them to variables
10 DATA 4.1, 5.6, 9.98
20 READ A, B, C
30 PRINT A, B, C
4.100 5.600 9.980
-> READ #fileNumber[,recordNumber];variables
Read a value from DATA or a file and assign them to variables
10 READ #1;A$
20 READ #1,4;B$
-> REC(n)
Returns the current record number (line number) in the specified file.
Starts at 1
10 OPEN "telehack.txt", AS #1
20 INPUT# 1, DUMP$
30 INPUT# 1, DUMP$
40 INPUT# 1, DUMP$
50 PRINT REC(1)
60 CLOSE #1
3
-> RENUMBER [start,[inc]]
Renumbers the statements of the current program in memory. When optional
parameters are not specified, number starts at 10 and increments by 10 for
each line. Can be abbrieviated to REN or RENUM. Useful if you want to add
more lines between existing statements
>1 GOTO 2
>2 END
>REN
>LIST
10 GOTO 20
20 END
-> RESTORE
Allow DATA statements to be reread
10 DATA 4.1, 5.6, 9.98
20 READ A, B, C
30 PRINT A, B, C
40 RESTORE
50 READ A, B, C
60 PRINT A, B, C
4.100 5.600 9.980
4.100 5.600 9.980
-> RETURN
Return from a subroutine, for use with GOSUB.
10 GOSUB 30
20 END
30 PRINT "Hello"
40 RETURN
Hello
-> RIGHT$(s$, n)
Returns the rightmost n characters of the specified string s$
10 A$ = "Hello World"
20 PRINT RIGHT$(A$, 5)
World
See also LEFT$ and MID$
RIGHT$(s$,n) has peculiar semantics when LEN(s$) < n < 2*LEN(s$); if you
want up to n characters and can guarantee n > 0, you may want to use
MID$(s$, 1-n) instead:
> FOR i = 1 TO 14: PRINT i, RIGHT$("ABCDEF", i), MID$("ABCDEF",1-i): NEXT
1 F F
2 EF EF
3 DEF DEF
4 CDEF CDEF
5 BCDEF BCDEF
6 ABCDEF ABCDEF
7 F ABCDEF
8 EF ABCDEF
9 DEF ABCDEF
10 CDEF ABCDEF
11 BCDEF ABCDEF
12 ABCDEF ABCDEF
13 ABCDEF ABCDEF
14 ABCDEF ABCDEF
-> RND(n)
If n < 0, returns a random number in the interval [0, 1] seeded by n
If n = 0, returns a random number in the interval [0, 1]
If n > 0, returns a random number in the interval [0, n]
10 PRINT RND(-5)
20 PRINT RND(0)
30 PRINT RND(5)
0.249
0.912
2.376
-> SCRATCH
Delete a file from the disk
10 SCRATCH "FOOBAR.TXT"
ARE YOU SURE? Y/n y
FOOBAR.TXT removed.
Any input that is not Y (case insensitive) will cancel the operation.
Runs silently when run with variable assignment, i.e will not prompt for
confirmation
10 PRINT "HELLO"
20 SCRATCH "FOOBAR.TXT" ; FOO$
30 PRINT "WORLD"
HELLO
WORLD
-> SCREEN
Currently not implemented, does nothing
-> SGN(n)
Returns the sign of the specified value n
10 PRINT SGN(5)
20 PRINT SGN(0)
30 PRINT SGN(-7)
1
0
-1
-> SIN(n)
Returns the trigonometric sine of the angle n, given in radians
10 PI = 3.14159
20 PRINT SIN(PI/6)
0.500
-> SLEEP n
Pauses the program for n seconds
10 SLEEP 5
-> SOUND
Currently not implemented, does nothing
-> SOUNDRND
Currently not implemented, does nothing
-> SPACE$(n), SPC$(n), SPA(n)
Returns n spaces
10 PRINT "ABC" SPACE$(10) "ABC"
abc abc
-> SQR(n)
Returns the square root of n
10 PRINT SQR(36)
6
-> STOP
Halts the program and prints the current line. Useful for debugging
programs
-> STR$(n)
Returns n as a string value
10 PRINT STR$(12345)
12345
-> STRING$(n, s$)
Repeats the string s$ n times
10 PRINT STRING$(10, "A")
AAAAAAAAAA
-> SYS(n)
HP2000 Access BASIC system information (compatibility function).
0. Last error code (or 0). Not implemented.
1. Last error line number or 0.
2. Last file number accessed or 0 (tty) or -1 (none). Not implemented.
3. Returns 1 if BREAK key pressed. Not implemented.
4. Returns terminal type (always 0 for tty).
-> TAB(n), TAB$(n)
Returns n spaces (not tabs!)
10 PRINT "ABC" TAB$(10) "ABC"
abc abc
-> TAN(n)
Returns the trigonometric tangent of the angle n, given in radians
10 PI = 3.14159
20 PRINT TAN(PI/3)
30 PRINT SQRT(3)
1.732
1.732
-> TH_SYSLEVEL
Returns the user's Telehack system level. Optionally takes a username as
argument.
10 PRINT TH_SYSLEVEL
20 PRINT TH_SYSLEVEL("quantx")
12
81
The user executing the above code would evidently have 12 badges.
-> TH_HASBADGE(badge$)
Returns a UNIX timestamp of when the user earned badge$, or 0
10 PRINT TH_HASBADGE("ACCT")
1559673339
10 PRINT TH_HASBADGE("ACCT", "doesntexist")
0
-> TH_HASLOGIN(host$)
Returns 1 if the user has login on host$, otherwise 0
10 PRINT TH_HASLOGIN("mimsy")
1
10 PRINT TH_HASLOGIN("ames")
0
-> TH_HASROOT(host$)
Returns 1 if the user has root on host$, otherwise 0
10 PRINT TH_HASROOT("mimsy")
1
10 PRINT TH_HASROOT("ames")
0
-> TH_HASSYSOP(bbs$)
Returns 1 if the user has sysop on bbs$, otherwise 0
10 PRINT TH_HASSYSOP("maccavern")
1
10 PRINT TH_HASSYSOP("illuminati")
0
-> TH_HASADMIN(sat$)
Returns 1 if the user has admin on sat$, otherwise 0
10 PRINT TH_HASADMIN("sat_BT 5")
1
-> TH_DEFGROUP$
Returns the user's defgroup, separated by spaces
10 PRINT TH_DEFGROUP$
archer lorelei
-> TH_PLAN$
Returns the user's .plan as a string
10 PRINT TH_PLAN$
To write a BASIC program
<3
-> TH_TIME
Returns the current UNIX timestamp
10 PRINT TH_TIME
1675018633.67413
-> TH_LOCALTIME[$]
Returns a human-readable timestamp for the given UNIX timestamp, in the
user's timezone.
10 PRINT TH_LOCALTIME$(TH_TIME)
Wednesday, December 9, 2020 6:40:49 PM PST
Returns values of time and date if options are supplied, and no sigil:
* 0 - sec
* 1 - min
* 2 - hour
* 3 - mday
* 4 - mon
* 5 - year
* 6 - wday
* 7 - yday
* 8 - isdst
10 FOR I = 0 TO 8 : PRINT TH_LOCALTIME(I,0) : NEXT I
0
0
16
31
11
69
3
364
0
-> TH_GMTIME[$]
Returns a human-readable UTC time for the given UNIX timestamp with the same
options as TH_LOCALTIME[$]
-> TH_MODEM$
Returns modem information depending on option passed:
* 0 number
* 1 filename
* 2 hostname
* 3 description
* 4 baud rate
* 5 administrator
* 6 location
-> TH_HOSTNAME$
Returns current hostname or hostname of argument passed. Supports OSPROBER
plugin.
10 PRINT TH_HOSTNAME$
telehack
-> TH_NETSTAT$
Returns current netstat, or netstat of hostname passed as argument,
separated by spaces
adaptex cotds mimsy oddjob oracle tandem veritas
-> TH_MD5HEX$
Returns md5 hex of argument passed as hex
10 PRINT TH_MD5HEX$("FOO")
901890a8e9c8cf6d5a1a542b229febff
-> TH_MD5BASE64$
Returns md5 hex of argument passed as base64
10 PRINT TH_MD5BASE64$("FOO")
kBiQqOnIz21aGlQrIp/r/w
-> TH_B64E$
Returns argument encoded to base64
10 PRINT TH_B64E$("Telehack")
VGVsZWhhY2s=
-> TH_B64D$
Returns argument decoded from base64
10 PRINT TH_B64D$("VGVsZWhhY2s=")
Telehack
-> TH_EXEC
Executes a shell command and returns to the current BASIC program
10 TH_EXEC "echo foo" : TH_EXEC "echo bar"
foo
bar
10 TH_EXEC "fnord", OUT$ : PRINT OUT$
The iguana from Austin will go to Austin.
Note: variables assigned with TH_EXEC will have trailing CRLF characters,
much like back-ticks in bash scripts.
-> TH_RE(txt$,pat$,countmode,ignorecase)
Number context, returns a boolean (1 or 0) depending on regex match
10 IF TH_RE( "hello", "l{2}" ) THEN PRINT "it matches"
it matches
If countmode is true, returns number of matches:
10 PRINT TH_RE( "HELLO", "L", 1 )
2
-> TH_RE$(txt$,pat$,ind,ignorecase)
String context, returns single captured group of match
10 PRINT TH_RE$( "hello world", "he\w+" )
hello
If an index n is provided, the string returned will be the nth captured
group:
10 PRINT TH_RE$( "FOO BAR BAZ BINGO BANGO", "BA...", 2 )
BANGO
In the above example, the match returned is not "BAZ B", since the "B" in
"BAZ" has already been consumed by the first match.
If the index supplied is 0, it will return the final match. If no index is
supplied, it will return the first match.
-> TH_REV$(s$)
Returns the string s$ in reverse order
10 PRINT TH_REV$( "deliver" )
reviled
-> TH_SED$(txt$,find$,replace$,opt$)
Stream editor, replaces matched substring with substitution
Available options:
* "i" = case insensitive
* "g" = global mode
10 PRINT TH_SED$( "foo bAR", "oo|ar", "izz", "gi" )
fizz bizz
-> TH_SPRINTF$(fmt$,[...])
Returns a formatted string based on given parameters:
* %% - A percent sign
* %c - A character with the given decimal number
* %s - A string of characters
* %S - A string of characters, left aligned
* %d - A signed integer, in decimal
* %b - An unsigned integer, in binary
* %u - An unsigned integer, in decimal
* %o - An unsigned integer, in octal
* %x - An unsigned integer, in hexadecimal
* %a - Hexadecimal floating point
* %n - Interprets width as positional index (see example 2)
* %r - Returns a random value from the list as a string
* %e - A floating-point number, in scientific notation
* %f - A floating-point number, in fixed decimal notation
* %g - A floating-point number, in %e or %f notation
* %h - A floating-point number, in IEEE-754 notation
* %i - Exactly like %d, for compatibility, or something
* %y - Returns the decimal form of a hexadecimal unsigned int value
* %z - Returns decimal form of IEEE-754 input value
* %D - Like %d, but longer
* %U - Like %u, but longer
* %O - Like %o, but longer
* %F - Like %f, but longer
* %B - Like %b, but LOUDER
* %R - Like %r, but left-aligned
* %X - Like %x, but using upper-case letters
* %E - Like %e, but using an upper-case "E"
* %G - Like %g, but with an upper-case "E" (if applicable)
* %H - Like %h, but using upper-case letters
* %A - Like %a, but using upper-case letters
--> Example 1:
10 F$ = "%s likes to %s while %sing"
20 PRINT TH_SPRINTF$( F$, "Sam", "sing", "cook" )
30 PRINT TH_SPRINTF$( F$, "Izumi", "read", "relax" )
40 PRINT TH_SPRINTF$( F$, "Wumpus", "tood", "tood" )
Sam likes to sing while cooking
Izumi likes to read while relaxing
Wumpus likes to tood while tooding
--> Example 2:
10 PRINT TH_SPRINTF$( "%2n%1n%1n", "na", "Ba" )
Banana
--> Example 3:
10 PRINT TH_SPRINTF$("%42R...YOU LOSE","HEADS","TAILS")
TAILS ...YOU LOSE
--> Example 4:
10 F$ = "I got %08b problems but leading zeros ain't %08b."
20 PRINT TH_SPRINTF$( F$, 99, 1 )
I got 01100011 problems but leading zeros ain't 00000001.
--> Example 5:
10 DATA "Name", "Car", "Country"
20 DATA "----", "---", "-------"
30 DATA "Bill", "Volvo", "New Zealand"
40 DATA "Alex", "Ferrari", "Italy"
50 DATA "Wumpus", "Tesla", "United States"
60 FOR I = 1 TO 5
70 READ A$, B$, C$
80 PRINT TH_SPRINTF$("%10S%12S%12S", A$, B$, C$)
90 NEXT I
Name Car Country
---- --- -------
Bill Volvo New Zealand
Alex Ferrari Italy
Wumpus Tesla United States
-> TH_STATUS$
Returns the user's status as a string
-> TH_UUD$(s$)
Decodes a uuencoded string
10 PRINT TH_UUD$("#9F]O")
foo
-> TH_UUE$(s$)
Returns uuencoded form of input string
10 PRINT TH_UUE$("foo")
#9F]O
-> TIM(n)
Returns values of time and date depending on n
* 0 - Current minute (0-59)
* 1 - Current hour (0-23)
* 2 - Current day (1-366)
* 3 - Current year (0-99)
* 4 - Current second (0-59)
10 PRINT TIM(0)
29
-> TIME$
Returns the local system time
10 PRINT TIME$
07:49:38
-> TIMER
Returns the number of seconds since midnight
10 PRINT TIMER
28210
-> TYP(n)
Returns the type of the next record in a file
Return values:
* 1 - Numeric data (not currently working)
* 2 - String data
* 3 - End of file
10 REM CREATE A FILE FOR TESTING
20 FILENAME$ = "TEST" + STR$(INT(RND(1)*128*2)) + ".TXT"
30 OPEN FILENAME$, AS #1
40 REM POPULATE FILE WITH TEST DATA
50 PRINT# 1, "some text"
60 REM SAVE FILE
70 CLOSE #1
80 REM TEST TYP() COMMAND
90 OPEN FILENAME$, AS #1
100 PRINT TYP(1)
110 REM ADVANCE ONE RECORD
120 INPUT# 1, DUMP$
130 PRINT TYP(1)
140 CLOSE #1
2
3
See also EOF.
-> TROFF
Stops tracing of program statements. Useful for debugging
-> TRON
Starts tracing of program statements. Useful for debugging
-> UPS$(string)
Returns the uppercase value of the given string
10 PRINT UPS$("hello")
HELLO
-> USER$
Returns the current logged in user
10 PRINT USER$
archer
-> VAL(s$)
Returns the numeric value of s$
10 PRINT VAL("12345")
12345
Not to be confused with NUM(s$), which returns the ASCII value of the first
character in the string s$.
-> WIDTH
Returns your terminal width
> 6. FAQ
-> Q: I need a NAND function, but there is none.
A: Create the function with:
DEF FNNAND( A, B ) = NOT ( A AND B )
Now you can call it with:
10 PRINT FNNAND( 0, 0 )
1
-> Q: How do I read from a file?
A: Like this:
10 OPEN "filename.txt", AS #1
20 IF EOF(1) THEN GOTO 60
30 INPUT# 1, A$
40 PRINT A$
50 GOTO 20
60 CLOSE #1
-> Q: How do I write to a file?
A: Like this:
10 OPEN "filename.txt", AS #1
20 PRINT# 1, "Hello World!"
30 CLOSE #1
-> Q: How do I append a file?
A: You have to open the file and put the file-pointer at the end of file,
like this:
10 OPEN "filename.txt", AS #1
20 IF EOF(1) THEN GOTO 50
30 INPUT# 1, DUMP$
40 GOTO 20
50 PRINT# 1, "We are now at the EOF, and appending stuff"
60 CLOSE #1
A2: The solution above (linear search) is somewhat slow for large files.
Exponential search (https://en.wikipedia.org/wiki/Exponential_search) is
more complicated, but finds the end of a 10000-line file in ~0.03 seconds
instead of ~31.6 seconds (1000x faster). Below is an example subroutine:
10 OPEN "filename.txt", AS #1
20 GOSUB 250 : 'probe now points to the last line, but file pointer DOES
NOT NECESSARILY.
30 READ #1, probe; lastline$ : 'advance file pointer to probe
40 PRINT# 1, "We are now at EOF, and appending stuff"
50 PRINT "The previous last line", lastline$
60 CLOSE 1
200 END
250 probe=2 : DIM last(2) : last(0)=0 : last(-1)=2^52-1
255 '(0) is last good line , (-1) is last bad line (EOF), initialized to
max int
260 READ #1, probe
265 ' read record at index (probe) from file #1, but not into any
variables.
266 ' this is slightly faster than input#.
270 last(EOF(1)) = probe
275 'store the probed offset as either good or bad, depending on whether
we hit EOF or not.
280 x = probe*2 : y = last(0) + INT((last(-1)-last(0))/2) : 'Exponential
search for EOF
285 'halfway between last known good and last EOF (binary search)
290 probe = y XOR ((x XOR y) AND -(x < y))
295 ' probe = min(x,y); picks binary search when probe overshoots
300 IF probe > last(0) GOTO 260
305 ' probe>good implies (bad-good)/2>=1 implies EOF may lie beyond good+1;
keep probing.
310 RETURN
-> Q: How do I create a BBS?
A: You can create a BBS by running PPPD.EXE, and pointing it at your BASIC
program file. Your BBS will then appear in bbslist.txt.
Your BBS baud-rate must be 115200 (11.520 kbps) in order for it to appear in
the Telehack netstat. To gain access to faster baud-rates requires you to
upgrade your modem firmware (both SYSADM and BLUEBOX badges are required.)
-> Q: How do I split a string into an array?
A: There are two methods. The Traditional "Pure BASIC" Method, and the
Modern RegEx Method. Both methods are detailed below.
--> Traditional "Pure BASIC" Method
This method involves iterating through your string YOURSTRING$ and looking
for a delimiter DELIMITER$.
For every iteration put the actual character at that position in the string
YOURSTRING$ in a temporary variable TSTR$.
Once you have found the delimiter DELIMITER$, save the result of the
temporary variable TSTR$ into an array. MAXSTACK tells you how many items
are actually in the array.
See the example below:
10 DIM ARRAY$(2)
20 DELIMITER$ = " "
30 YOURSTRING$ = "Hello World"
40 MAXSTACK = 0
45 REM PUT YOUR PROGRAM LOGIC HERE
50 GOSUB 100
55 REM PUT YOUR PROGRAM LOGIC HERE
60 END
100 REM split
110 TSTR$ = ""
120 FOR I = 1 TO LEN(YOURSTRING$)
130 IF MID$(YOURSTRING, I, 1) = DELIMITER$ THEN GOTO 200
140 TSTR$ = TSTR$ + MID$(YOURSTRING$, I, 1)
150 IF I = LEN(YOURSTRING$) THEN GOTO 200
160 NEXT I
170 RETURN
200 REM We have found a delimiter and are pushing it into the array
210 MAXSTACK = MAXSTACK + 1
220 ARRAY$(MAXSTACK) = TSTR$
230 TSTR$ = ""
240 GOTO 160
--> Modern RegEx Method
Let's say, for this example, you have the string NAMES$ which is a list of
names separated by a comma ,. To access this as an array is very
straightforward using Telehack language extentions:
10 NAMES$ = "Tom,Dick,Harry,Bob,Steve,Imhotep"
20 PATTERN$ = "[^\,]+"
30 FOR I = 1 TO TH_RE(NAMES$,PATTERN$,1)
40 PRINT TH_RE$(NAMES$,PATTERN$,I)
50 NEXT I
Tom
Dick
Harry
Bob
Steve
Imhotep
The above example uses both TH_RE (number context), and TH_RE$ (string
context).
-> Q: How can I learn how to write regular expressions?
A: The executable GOLF.EXE contains multiple lessons on regular expressions.
You can also find many RegEx-related challenges in the DOJO.
-> Q: How do I generate a random number?
A: Like this:
10 RANDOMIZE TIMER
20 MAXNR = 10
20 RNR = INT(RND(1)*MAXNR)
30 PRINT RNR
The above example is a pseudorandom number generator, with TIMER being the
seed.
-> Q: I would like to code in BASIC, but all those line numbers are messy!
A: You don't actually have to use line numbers at all in TeleBASIC! They
are only necessary for when using GOTO or GOSUB.
You also don't have to put everything in uppercase, but doing so means your
code will be more compatible with other historical flavours of BASIC.
Here is an example of a modern TeleBASIC program:
1 ' begin
input "What is your name? " n$
print "Hello, " n$ "! There are" len( n$ ) "characters in your name:"
for l = 1 to len( n$ )
? l ": " mid$( n$, l, 1 )
next : ?
input "Again? [y/n] " ; yn$
if yn$ = "y" then goto 1
? "Goodbye!"
end
What is your name? bob
Hello, bob! There are 3 characters in your name:
1 : b
2 : o
3 : b
Again? [y/n] y
What is your name? steve
Hello, steve! There are 5 characters in your name:
1 : s
2 : t
3 : e
4 : v
5 : e
Again? [y/n] n
Goodbye!
Additionally, there is a script written by archer which allows you to use
labels instead of numbers.
Find it on archer's GitHub (https://p85.github.io/renumber/renumber.html).
-> Q: How do I use COMM.EXE via BASIC?
A: Refer to this guide by archer (https://telehack.com/r/pvELT).
-> Q: What's with the fish?
A: That's our mascot, Bassy the dart-mouthed bass.
> 7. ANSI Escape Sequences
-> General Info
An ANSI escape sequence is a sequence of ASCII characters, the first two of
which are the ASCII "escape" character (chr$(27)) and the left-bracket
character [ (chr$(91)).
The character or characters following the escape and left-bracket characters
specify an alphanumeric code that controls a keyboard or display function.
For example, these can be used instead of, or in addition to LOCATE (for
locating the cursor in the window); COLOR (for setting text and background
colours) and getting the user's arrow-key input.
Using escape sequences can give you greater control over how your program
displays its output. Be aware that not all terminal types support some of
these sequences, and your terminal must support 256-bit colours in order to
display such colours.
Standard escape codes are prefixed with Escape, which is represented in the
following ways:
Format |Value
----------------------------------------+-----------------------------------
Ctrl-Key |^[
Octal |\033
Unicode |\u001b
Hexadecimal |\x1b
Decimal |27
This is then followed by the command, somtimes delimited by opening square
bracket [ known as a Control Sequence Introducer (CSI), optionally followed
by arguments and the command itself.
Arguments are delimeted by semi colon (;).
For example boldred$ = chr$(27) + "[1;31m".
-> General ASCII Codes
Name |Decimal |Octal |Hex |C-escape |Ctrl-Key |Description
-------+----------+--------+-------+----------+----------+------------------
BEL |7 |007 |0x07 |\a |^G |Terminal bell
BS |8 |010 |0x08 |\b |^H |Backspace
HT |9 |011 |0x09 |\t |^I |Horizontal TAB
LF |10 |012 |0x0A |\n |^J |Linefeed
VT |11 |013 |0x0B |\v |^K |Vertical TAB
FF |12 |014 |0x0C |\f |^L |Formfeed
CR |13 |015 |0x0D |\r |^M |Carriage return
ESC |27 |033 |0x1B |\e |^[ |Escape character
DEL |127 |177 |0x7F |<none> |<none> |Delete character
Note: Some control escape sequences, like \e for ESC, are not guaranteed to
work in all languages and compilers. It is recommended to use the decimal,
octal or hex representation as escape code.
The Ctrl-Key representation is simply associating the non-printable
characters
from ASCII code 1 with the printable characters from ASCII code 65 ("A").
ASCII code 1 would be ^A (Ctrl-A), while ASCII code 7 (BEL) would be ^G
(Ctrl-
G). This is a common representation (and input method) and historically
comes from one of the VT series of terminals.
-> Cursor Controls
Sequence |Description
----------------------+-----------------------------------------------------
ESC[H |Moves cursor to home position (0, 0)
ESC[{line};{column}H |Moves cursor to line #, column #
ESC[{line};{column}f |Moves cursor to line #, column #
ESC[#A |Moves cursor up # lines
ESC[#B |Moves cursor down # lines
ESC[#C |Moves cursor right # columns
ESC[#D |Moves cursor left # columns
ESC[#E |Moves cursor to start of next line, # lines down
ESC[#F |Moves cursor to start of previous line, # lines up
ESC[#G |Moves cursor to column #
ESC[6n |Request cursor position (reports as ESC[#;#R)
ESC7 |Save cursor position (DEC)
ESC8 |Restores the cursor to the last saved position (DEC)
ESC[s |Save cursor position (SCO)
ESC[u |Restores the cursor to the last saved position (SCO)
ESC[?25h |Show cursor
ESC[?25l |Hide cursor
Note: Some sequences, like saving and restoring cursors, are private
sequences and are not standardized. While some terminal emulators (i.e.
xterm and derived) support both SCO and DEC sequences, they are likely to
have different functionality. It is therefore recommended to use DEC
sequences.
-> Erase Functions
Sequence |Description
---------------------+------------------------------------------------------
ESC[J |Clears the screen
ESC[0J |Clears from cursor until end of screen
ESC[1J |Clears from cursor to beginning of screen
ESC[2J |Clears entire screen
ESC[K |Clears the current line
ESC[0K |Clears from cursor to end of line
ESC[1K |Clears from cursor to start of line
ESC[2K |Clears entire line
-> Colours / Graphics Mode / Character Attributes
Sequence |Reset Sequence |Description
------------------+-----------------+---------------------------------------
ESC[1;34;{...}m | |Set graphics modes for cell
ESC[m | |Reset all modes (styles and colours)
ESC[0m | |Same as above
ESC[1m |ESC[22m |Set bold mode.
ESC[2m |ESC[22m |Set dim/faint mode.
ESC[3m |ESC[23m |Set italic mode.
ESC[4m |ESC[24m |Set underline mode.
ESC[5m |ESC[25m |Set blinking mode
ESC[7m |ESC[27m |Set inverse/reverse mode
ESC[8m |ESC[28m |Set hidden/invisible mode
ESC[9m |ESC[29m |Set strikethrough mode.
Note: Some terminals may not support some of the graphic mode sequences
listed above.
Both dim and bold modes are reset with the ESC[22m sequence. The ESC[21m
sequence is a non-specified sequence for double underline mode and only
works
in some terminals and is reset with ESC[24m.
-> Colour Codes
Most terminals support 8 and 16 colours, as well as 256 (8-bit) colours.
These colours are set by the user, but have commonly defined meanings.
--> 8-16 Colours
Colour |Foreground |Background
-----------------------+--------------------------+-------------------------
Black |30 |40
Red |31 |41
Green |32 |42
Yellow |33 |43
Blue |34 |44
Magenta |35 |45
Cyan |36 |46
White |37 |47
Default |39 |49
Reset |0 |0
Note: the Reset colour is the reset code that resets all colours and text
effects, Use Default colour to reset colours only.
Most terminals, apart from the set of 8 regular colours, also support the
"bright" or "bold" colours. These have their own set of codes, mirroring the
normal colours, but with an additional ;1 in their codes:
e$ = chr$(27)
' Set style to bold, red foreground
hello$ = e$ + "[1;31m" + "Hello"
' Set style to dimmed white foreground with red background
world$ = e$ + "[2;37;41m" + "World"
Terminals that support the aixterm specification provide bright versions of
the ISO colours, without the need to use the bold modifier:
Colour |Foreground |Background
----------------------------+-----------------------+-----------------------
Bright Black |90 |100
Bright Red |91 |101
Bright Green |92 |102
Bright Yellow |93 |103
Bright Blue |94 |104
Bright Magenta |95 |105
Bright Cyan |96 |106
Bright White |97 |107
--> 256 Colours
The following escape codes tells the terminal to use the given colour:
Sequence |Description
----------------------------------+-----------------------------------------
ESC[38;5;{ID}m |Set foreground colour
ESC[48;5;{ID}m |Set background colour
Where ID should be replaced with the colour index from 0 to 255 of the
following colour chart:
Generate this table with the following BASIC code:
10 FOR I = 0 TO 255
20 S$ = TH_SPRINTF$( "%4S", I )
30 ? CHR$(27) "[38;5;" STR$(I) "m" S$ ;
40 IF NOT (I+1) MOD 16 THEN ?
50 NEXT
This table starts with the original 16 colours (0-15).
The proceeding 216 colours (16-231) are formed by a 3bpc RGB value offset by
16, packed into a single value.
The final 24 colours (232-255) are grayscale starting from a shade slighly
lighter than black, ranging up to shade slightly darker than white.
Some emulators interpret these steps as linear increments (256 / 24) on all
three channels, although some emulators may explicitly define these values.
--> RGB Colours
More modern terminals supports Truecolor (24-bit RGB), which allows you to
set foreground and background colours using RGB values.
These escape sequences are usually documented poorly, if at all.
Sequence |Description
----------------------------------+-----------------------------------------
ESC[38;2;{r};{g};{b}m |Set foreground colour as RGB.
ESC[48;2;{r};{g};{b}m |Set background colour as RGB.
Note: ;38 and ;48 corresponds to the 16 colour sequence and is interpreted
by the terminal to set the foreground and background colour respectively,
whereas ;2 and ;5 sets the colour format.
-> Common Private Modes
These are some examples of private modes, which are not defined by the
specification, but are implemented in most terminals.
Sequence |Description
---------------------------+------------------------------------------------
ESC[?25l |Make cursor invisible
ESC[?25h |Make cursor visible
ESC[?47l |Restore screen
ESC[?47h |Save screen
ESC[?1049h |Enables the alternative buffer
ESC[?1049l |Disables the alternative buffer
-> DEC Special Graphics
DEC Special Graphics is a 7-bit character set developed by Digital Equipment
Corporation.
This was used very often to draw boxes on the VT100 video terminal and the
many emulators, and used by bulletin board software.
Sequence |Description
----------------------------+-----------------------------------------------
ESC(0 |Enable DEC special graphics
ESC(B |Disable DEC special graphics
-> Colour Examples (8-bit)
10 PRINT CHR$(27) + "[92mThe foreground is green" CHR$(27) "[m"
20 PRINT CHR$(27) + "[103mThe background is yellow" CHR$(27) "[m"
-> Colour Examples (16-bit)
10 PRINT CHR$(27) + "[38;5;134mThe foreground is purple" CHR$(27) "[m"
20 PRINT CHR$(27) + "[48;5;117mThe background is sky blue" CHR$(27) "[m"
-> Get Arrow Key Input
10 KEY$ = INKEY$
20 IF KEY$ = CHR$(27) THEN KEY$ = INKEY$ : IF KEY$ = "[" THEN GOTO 40
30 GOTO 10
40 KEY$ = INKEY$
50 IF KEY$ = "A" THEN PRINT "UP"
60 IF KEY$ = "B" THEN PRINT "DOWN"
70 IF KEY$ = "C" THEN PRINT "RIGHT"
80 IF KEY$ = "D" THEN PRINT "LEFT"
90 GOTO 10