code Text=12;
Text(0, "Hello World!")
"Text" is a built-in routine that displays text strings enclosed in quote
marks. The zero (0) tells where to send the message. In this case it's
sent to the display screen, but it could just as easily be sent to the
printer or out the serial port by using a different number.
begin
MakeNumber;
repeat InputGuess;
TestGuess
until Guess = Number
end
Note that the program is almost word for word the same as the description
of the task. First we "make a number" then we repeatedly "input a guess"
and "test the guess" until it's the number. There needs to be more to this program since it does not tell how to make a number, input a guess, or test the guess. Each of these operations is a subroutine to the main program. In XPL0 these subroutines are called procedures. Here's how to write each of these procedures.
procedure MakeNumber;
begin
Number:= Ran(100) + 1
end
This procedure generates a random number between 1 and 100 (inclusive)
and puts that number into the variable called "Number".
procedure InputGuess;
begin
Text(0, "Input guess: ");
Guess:= IntIn(0)
end
This procedure displays the message: "Input guess: " on the monitor
(output device 0) and gets a number (INTeger IN) from the keyboard (input
device 0). In XPL0 nine different input and output devices can be called
from the program. This allows direct access to the monitor, keyboard,
printer, disk files, and so forth.
procedure TestGuess;
begin
if Guess = Number then Text(0, "Correct!")
else
if Guess > Number then Text(0, "Too high")
else Text(0, "Too low");
CrLf(0)
end
This procedure is more complicated but still easy to understand. If the
computer's number is equal to the guess then we execute one statement; if
it's not equal then we execute another statement. If the numbers are
equal, we tell the user that the guess is correct; if they are not equal,
we test if the guess is high or low and tell the user. CrLf(0) starts a
new line on the monitor (Carriage Return and Line Feed). Here is the complete program:
code Ran=1, CrLf=9, IntIn=10, Text=12;
integer Guess, Number;
procedure MakeNumber;
begin
Number:= Ran(100) + 1
end;
procedure InputGuess;
begin
Text(0, "Input guess: ");
Guess:= IntIn(0)
end;
procedure TestGuess;
begin
if Guess = Number then Text(0, "Correct!")
else
if Guess > Number then Text(0, "Too high")
else Text(0, "Too low");
CrLf(0)
end;
begin
MakeNumber;
repeat InputGuess;
TestGuess
until Guess = Number
end
Two new items are shown. The command word "code" is used to give names to
intrinsics. Intrinsics are built-in subroutines that do common
operations. For example, "Ran" is the name of the random-number
intrinsic, and "Ran" is used to call this random-number generator as a
subroutine. The second item is the command word "integer". This declares
a name and allocates memory space for each variable that follows it. Note that the main procedure is the last block in the program. An XPL0 program is read starting at the bottom to get the main flow and working upward to get the details in the procedures.
Here is an example of what this program does when it runs:
Input guess: 50
Too high
Input guess: 25
Too high
Input guess: 9
Too low
Input guess: 18
Correct!
It's generally a good practice to break a program up into subroutines,
but something this simple would probably be written more like this:
include c:\cxpl\codesi;
integer Guess, Number;
begin
Number:= Ran(100)+1;
repeat Text(0, "Input guess: ");
Guess:= IntIn(0);
Text(0, if Guess = Number then "Correct!"
else if Guess > Number then "Too high"
else "Too low");
CrLf(0);
until Guess = Number;
end;
\Weed.xpl 15-Jan-2006 \Plots the "Weed" function include c:\cxpl\codesi; \intrinsic routine declarations define S = 100., \size of plotted image (scale factor) N = 32000., \number of points plotted Pi2 = 3.14159265*2.; integer X, Y; \graphic coordinates (pixels) real A, D; \angle and distance (polar coordinates) begin SetVid($12); \640x480 graphics in 16 colors A:= 0.; \for A:= 0 to Pi2 do... repeat D:= (1.+Sin(A)) * (1.+.9*Cos(8.*A)) * (1.+.1*Cos(24.*A)) * (.9+.05*Cos(200.*A)); X:= Fix(D*Cos(A)*S); \convert polar to rectangular coordinates Y:= Fix(D*Sin(A)*S); Point(X+320, 400-Y, 2\green\); A:= A + Pi2/N; until A >= Pi2; X:= ChIn(1); \wait for keystroke SetVid($03); \restore normal text mode end;
Ignore the hairy math for a moment and notice the intrinsic routine
called SetVid. This sets the video mode to hex 12, which is a graphic
display mode. The intrinsics Sin and Cos convert angles to their sine and cosine values. Real numbers (also called floating-point numbers) are used along with integers. The intrinsic Fix converts a real number to its closest integer.
The Point intrinsic plots the resulting coordinates.
SetVid is also used to restore the display to its normal text mode after ChIn receives a character from the keyboard.
\Clock.xpl 15-Jan-2006 \Display the current time of day inc c:\cxpl\codesi; \include intrinsic code declarations proc NumOut(N); \Output a 2-digit number, including leading zero int N; begin if N <= 9 then ChOut(0, ^0); IntOut(0, N); end; \NumOut proc ShowTime; \Display current time (e.g: 12:03:45) int Reg; begin Reg:= GetReg; \address of array that has copy of CPU registers Reg(0):= $2C00; \call DOS function 2C (hex) SoftInt($21); \DOS calls are interrupt 21 (hex) NumOut(Reg(2) >> 8); \the high byte of register CX contains the hours ChOut(0, ^:); NumOut(Reg(2) & $00FF); \the low byte of CX contains the minutes ChOut(0, ^:); NumOut(Reg(3) >> 8); \the high byte of DX contains the seconds end; \ShowTime begin \Main repeat ChOut(0, $0D); \carriage return moves to the start of the line ShowTime; \call routine to show the current time until ChkKey; \keep repeating until a key is struck end; \MainThe intrinsics GetReg and SoftInt are used to access DOS and BIOS routines. GetReg returns the address of an array where a copy of the processor's hardware registers are stored. Values (such as $2C00 in the example) may be stored into this array. When SoftInt is called, the values in the array are loaded into the processor's registers and the specified interrupt ($21 in the example) is called.
ChOut outputs a character (such as ":") to the display, and IntOut outputs an integer's value to the display. ChkKey checks the keyboard for a keystroke.
The AND operator "&" and the SHIFT operator ">>" manipulate the individual bits in an integer.
Command words such as "integer" and "include" can be abbreviated to their first three letters.
include c:\cxpl\codes; \standard library 'code' definitions repeat Cursor(Ran(80), Ran(25)); \randomly select location on screen Attrib(if Ran(2) then 10 else 2); \randomly select light or dark green ChOut(6, Ran(2)+^0); \randomly output an ASCII 0 or 1 until ChkKey; \run until a key is struckThe intrinsic Cursor specifies the column and row on the screen where characters will appear. The upper-left corner is 0,0.
The Attrib intrinsic specifies the attributes (usually the foreground and background colors) used for displaying characters on device 6. The argument "if Ran(2) then 10 else 2" is an example of an 'if' expression, which is different than the more common 'if' statement. It's equivalent to the C expression: "rand()%2 ? 10 : 2". If Ran(2) returns a zero value, it's interpreted as being 'false', while any non-zero value (such as 1) is treated as being 'true'. Thus the argument evaluates to either 2 (for false) or 10 (for true). These are the values of the two shades of green for EGA (and newer) video modes.

Last updated: 14-Jun-2007