Welcome to the Script Interpreter

Overview

My teletext software for RISC OS (!Teletext) and Windows (WinTTX) both incorporate a "script interpreter" which allows you to create 'scripts' permitting you to retrieve and process information from teletext. You may fetch frames, perform various operations on them and then store them back in the cache and/or output them in a variety of formats.

By way of example, several scripts are provided with WinTTX:

These are examples of the sorts of things that can be achieved with the teletext script language.

The script language itself is fairly simple, tailored to exactly what it has been designed for. Thus, it provides a way to pass messages to the user but there is no provision for, say, drawing on the screen. Such a facility would not be useful in processing teletext frames!

 

RISC OS vs Windows

The current RISC OS version of the interpreter (v1.07 from 2003) is a little earlier than the Windows version (v1.08 from 2008), so several newer commands are not provided in !Teletext. There are no plans at present to update !Teletext, though you could add commands yourself as the source code to the RISC OS version has been released.

Perhaps the main problem that you will encounter is differences in file naming and paths between the two systems. For example, "<Teletext$Pages>.MyPage" would be an invalid filename under Windows, and likewise "whatever.txt would be invalid under RISC OS (translating to "whatever\txt." in Win/DOS terms).

It is possible to write scripts that work equally on both systems. To do so, you should take advantage of the differences between !Teletext which offers channel presets, and WinTTX that expects a UHF channel. This, requesting the channel preset number under WinTTX will always return "-1", as this code demonstrates:

set A to status(channel)
if (A ! -1) goto("riscoscode")

; this stuff is Windows code
[...blah blah - WinTTX specific stuff...]
go("continue")

.riscoscode
; this stuff is RISC OS code
[...blah blah - !Teletext specific stuff...]

.continue
; everybody meets back here

Of course, if you only have the one platform or if you don't mind writing slightly different scripts for each, you can dispense of this and just write using the facilities relevant to your version of the teletext software you are using.

Where relevant, differences between RISC OS and Windows script commands will be noted. There is also a look-up chart of all commands and which versions of the interpreter they may be found within.

 

The structure of a script file

Script files are plain text files that contain statements to perform an action. With one specific exception, it is strictly one statement per line. To give you an example, consider:
A = 1 * 2 + 5 / 2

That line would set integer variable 'A' to be the result of the calculation. It is, actually, ambiguous as if we are using the rules of precedence, it is "(1 * 2) + (5 / 2)" so the answer would be 4.5 (rounded to 4); but if we read left to right, the answer is 3.5 (rounded to 3).

Such problems are impossible in the teletext script as it does not support that level of calculation. Instead, you would write:

set A to 1          ; A = 1
mul(A, A, 2)        ;   * 2
add(A, 5)           ;   + 5
div(A, A, 2)        ;   / 2
(note we are using the left-to-right interpretation here)

The script file is executed at the beginning, and continues until it reaches a quit() (normal exit), a terminate() (abandon on problem), an error, or reaching the end of the script file.

The primary difference between quit() and terminate() regards the "call stack" - which is described in just a moment. If there is an active call stack when you quit(), you will be warned. If you instead terminate(), there is no such warning. So you should use terminate() when you have to 'just give up'.

Now, you are asking, "what's a call stack?". Well, no language is useful unless it can take jumps. The example above where we determine if the machine is RISC OS or Windows, you see we used the go() command to jump to a label, that is, a line with a name beginning with a '.' character. This is all described in more detail.
Well, we can crank it up a level by jumping to our label using the command call(), and what that does it is pushes our current 'position' in the script into the 'call stack'. We jump to the label, do whatever, and then we'll use the return() command to take the last-saved position off of the call stack and go back there. In this way, simple procedures can be written. You can see an example of this in the weather script - the code to convert celsius to fahrenheit is called is just such a way. Again, this is described in more detail.

 

Variables

There are 26 variables, from A to Z.
This is divided so the first 16 variables (A to P) are integers that can hold whole numbers like 1, 2, 3... while the final 10 variables (Q to Z) are floats which can hold fractional numbers like 1.23, 7.4367, etc.

INTEGERFLOAT
AQ
BR
CS
DT
EU
FV
GW
HX
IY
JZ
K
L
M
N
O
P
The integer variables are intended to be used for status, page numbers, loop counters... while the floats are intended for calculations such as temperature conversions, currency, and anything where fractional accuracy is desired.

Speaking of accuracy, all floats are constrained to nine decimal places, so that WinTTX and !Teletext running on standard BBC BASIC V (not the FP version) should give the same results; however if you are making comparisons with floating point values, it is always best to flatten() down to the level of accuracy that is actually required.

 

Strings

There are no string variables or operators. If you need to read strings out of the teletext file, these should be copied byte by byte, using code such as:
set A to 30
.reportloop
  set B to char(A, 17)
  filewritebyte(B)
  A++
  if (A [ 40) go("reportloop")
(this copies the characters from position 30,17 to 40,17.

Where strings are required as input, such as to the userchoice() command, you can:

For example:
message("Please set satellite receiver to \"arte\" (channel FAV:29)")

Note that the use of "\n" and "\"" are suppressed in places where filenames are expected.

Note that the RISC OS script interpreter does not support "\n" and "\"".

 

The view of a teletext frame

The top-left corner of a teletext frame is 1,1, leading to the lower right corner which is 40,25; hence there are 40 character cells across the display, in 25 rows.

One you have retrieved data using getframe() or getframes(), you can use selectframe() or selectframes() to make a cached frame 'current'. Only one frame can be current, but you can switch which is current as you wish, even to the extent of copying from one frame to another byte by byte.

When a frame is 'current', you can read bytes from the frame using set <var> to char(<x>, <y>); and you can write bytes to the frame using setchar().
You can also blank entire lines using omitline() (which has special significance for file output).
When you have made the necessary alterations, you can either write the frame to a file using writeframe() or writeframes(), or you can push the frame back into the cache (replacing the current cached one) using storeframe().

 

Page numbering

Within the script, page numbering is in 'simple' form. That is, page 101 is specified as page 101.
You should not convert page numbers into their hexadecimal forms...
Some calls exist to read various items in hex, however this is mostly facultative.
Obviously, there is no way for a script to retrieve extended pages (i.e. p3FF).

 

Script errors

Pretty much everything that causes an error will cause the script to be aborted. Sometimes it can be difficult trying to work out what the error means, so in WinTTX there is an option to perform an automatic LVar upon script error. This creates a status file showing what the script is up to which can be a useful debugging aid.
Under RISC OS, create a RAMdisc (at least 128K) and !Teletext will write a logfile.

 

Interpretation speed

The script interpreter does not execute quickly. This is because the majority of time is likely to be spent waiting for information to arrive off-air. Under RISC OS, conducting tests with the current arrangement (with polls frequently) and a system where the script was given more priority showed only seconds difference in a script taking nearly ten minutes to run. For those seconds, the system loading was deemed unacceptable - for example the rolling header does not need to be read anywhere like as often as when the viewer is active, either the page has arrived or it hasn't...

Under RISC OS, on a 40MHz ARM710 processor, the teletext software, when in use, loads the system between 15% and 60% (depending on what it is doing), with an average loading of around twenty-thirty percent. When the script is running, this may go up to around forty percent (again depending on what is happening). Some scripts may take in the order of ten minutes to execute.
The system is designed to be used multitasking, where you start a script and then forget about it for a while.
Please note that the timings were taken on my RiscPC700 with Ran Mokady's !Usage, and is subjective to the other tasks running on your system, and the system itself.

There are currently no timings for system loading under Windows; and such assessment is not terribly relevant for I am using a 450MHz machine running XP. It 'feels' comfortable, doesn't drag the machine down. The Windows process scheduling system means that it often seems to me as if other things are holding up WinTTX, rather than the other way around!