In the last post we saw some of the history of PIL and how to run it on MTS. We'll now take a closer look at the features of PIL. Examples shown can be entered directly into PIL after starting it with
PIL starts up in direct mode, where statements entered are immediately executed when you press
* is used by PIL as the prompt to enter input. You can use the
TYPE statement and simple arithmetic expressions to make PIL act as a calculator:
* type 22 * 2 22 * 2 = 44.0 * type 2 ** 16 2 ** 16 = 65536.0
On MTS, PIL is case-insensitive for keywords and lines can optionally end with a period. Errors are immediately reported, usually starting with
* TYPE 2+2. 2+2 = 4.0 * TYPE Eh? IMPROPERLY FORMED STATEMENT
If the last character entered on the line is
- then input will continue on the next line before it is executed. The prompt will change to
& to show this continuation.
* at the start of line can be used to make comments.
* type 1 + 2 + 3 +- & 5 + 6 1 + 2 + 3 +5 + 6 = 17.0 * * comment here *
Variables and types
Variables can be introduced by the optional keyword
SET followed by a variable name and an assignment.
* set a = 2 * b = 3 * type a, b, a+b a = 2.0 b = 3.0 a+b = 5.0
PIL understands three types: numerical, which are stored as floating point values, character strings and Boolean values.
* a = 1 / 3 * b = "PIL" * c = The True * type a, b, c a = 0.3333333 b = "PIL" c = The True
Booleans constants are 'The True' or 'The False' - something I've not seen in any other language. Strings can be up to 255 characters long and can be entered with single or double quotes as delimiters. Floats have 7 digits of precision and can be entered with exponential notation. Volume 12 mentions type 9.999999e64 as the maxomum value but on the version I'm running it seems 62 is the maximum exponent.
* type 9.999999e62 9.999999e62 = 9.999999E+62 * type 9.999999e63 Eh? EXPONENT OUT OF RANGE
Variable names are up to 8 characters long, are case sensitive and are distinguished from keywords, as this silly example shows.
* set set = 1 * set SET = 2 * type set, SET set = 1.0 SET = 2.0
Arrays are allowed with any number of dimensions, though once set the number of dimensions cannot be changed.
* x(1, -2) = 3 * x(3, 44.0) = 4 * type x x(1,-2) = 3.0 x(3,44) = 4.0 * x(3,4,5) = 42 Eh? ??-
Arithmetic expressions work mostly as expected. The absolute value can be taken by surrounding an expression with
|; exponentiation is done with
**. Functions for arithmetic operations such as square root, cosine, log etc generally have a short and long form and do not need parentheses unless needed to resolve ambiguities.
* type 1 + |-41| 1 + |-41| = 42.0 * type the square root of 9 the square root of 9 = 3.0 * type sqrt of 16 sqrt of 16 = 4.0 * type sqrt of 25+1 sqrt of 25+1 = 6.0 * type sqrt of (25+1) sqrt of (25+1) = 5.09902
There are functions for min/max, random numbers and extracting parts of a number, as well as special functions to get time (in 300ths of seconds since midnight), date, cpu/elapsed time and storage used.
* type the min of (1,2,3) the min of (1,2,3) = 1.0 * type the time, the date, the elapsed time, the cpu time the time = 1.963908E+07 the date = 17133.0 the elapsed time = 7.819461E+07 the cpu time = 464.0 * type the total size, the size the total size = 188.0 the size = 165.0
Boolean functions are similar to other languages, with
# standing in for logical or.
* type 2 >= 3 2 >= 3 = The False * type 2 $lt 3 2 $lt 3 = The True * type the true # the false the true # the false = The True * type the true & the false the true & the false = The False
Character expressions include length, case conversion, comparison and extraction.
* type the l of "abc" the l of "abc" = 3.0 * type the upper of "abC" the upper of "abC" = "ABC" * type the first 3 characters of "abcde" the first 3 characters of "abcde" = "abc" * type 2 $fc "abcde" + "X" + 1 $lc "abcde" 2 $fc "abcde" + "X" + 1 $lc "abcde" = "abXe" * type "aaa" > "AAA" "aaa" > "AAA" = The False
Finally, the type of an expression can be found and run time evaluation performed.
* type the mode of 42, the mode of the true, the mode of "abc" the mode of 42 = 1.0 the mode of the true = 2.0 the mode of "abc" = 3.0 * type the value of "2*21" the value of "2*21" = 42.0
IF statement with an optional
ELSE clause. The
ELSE can be omitted but the punctuation is required.
* if 1 < 2, then type 'yes'; else type 'no' yes * if 1 > 2, type 'yes'; type 'no' no
For loops have a range or an increment and an optional clause to terminate.
* for i = 1 to 5: type i ** 2 i ** 2 = 1.0 i ** 2 = 4.0 i ** 2 = 9.0 i ** 2 = 16.0 i ** 2 = 25.0 * for i = 1 by 2 to 10: type i ** 2 i ** 2 = 1.0 i ** 2 = 9.0 i ** 2 = 25.0 i ** 2 = 49.0 i ** 2 = 81.0 * for i = 1 by 2 while i < 20: type i i = 1.0 i = 3.0 i = 5.0 i = 7.0 i = 9.0 i = 11.0 i = 13.0 i = 15.0 i = 17.0 i = 19.0
Lines entered that start with a number are treated as stored instructions, broken down by part and step, that can be run later. Here we define a program in part 1 consisting of four steps.
* 1.0 i = 5 * 1.1 type i * 1.2 i = i * i * 1.3 type i
This can then be run with
DO, which will execute all steps in a part.
* do part 1 i = 5.0 i = 25.0
Variables set in a program remain after execution is completed and it is possible to run a single step at a time.
* type i i = 25.0 * do step 1.2 * do step 1.3 i = 625.0
Steps can call other parts with
DO: execution will resume after the part is finished. It's also possible to transfer execution with
TO which will not return.
DONE will return from the current part.
* type part 2, part 3 2.0 i = 3 2.1 do step 3 2.2 i = 5 2.3 do step 3 2.4 i = 7 2.5 to step 3 2.6 type 'not reached' 3.0 type i 3.1 done 3.2 type 'also not reached' * do part 2 i = 3.0 i = 5.0 i = 7.0
The above also shows it is possible to list out programs with
TYPE PART. You can see all entered parts with
TYPE ALL PARTS. With
TYPE ALL STUFF you will see all variables and parts defined.
DELETE can be used to remove a step or a variable definition.
I/O and system access
TYPE used to display variables. You can prompt for a value to be entered with
* delete part 1 * 1.0 demand i * 1.1 i = i * 10 * 1.2 type i * do part 1 i = ?_ 3 i = 30.0
There is also a formatting facility for input and output that is covered in the manual.
Programs can be saved to disk for future list with
SAVE. This takes a file name (which must already exist) and what to save. For example:
save as 'x.pil', all stuff
will save all parts and variables to
x.pil. File format is plain text so it can be edited outside of PIL if needed.
LOAD 'x.pil' will then load the file back into PIL.
The implementation of PIL on MTS includes access to system facilities such as file creation and device access. For example,
CREATE 'x.pil' will create a new file.
In the next post we'll see how to construct a larger PIL program.
MTS volume 12 has a complete reference to PIL as implemented on MTS.
If you can find a copy of the book 'History of Programming Languages', edited by Richard Wexelblat, this has a great section about JOSS talking about its design principles.