PLANC User Guide
About this chapter
This chapter will teach you to read and make PLANC code.
The first two sections
The first subsection will introduce you to the language features that
make PLANC programs look unfamiliar at first sight.
The rest builds on these basics and your previous knowledge
When you have a grasp of these basics, you will be shown how the cornmon
ingredients in block-structured languages have been implemented in PLANC.
There will be sections about:
- Control structures
- Declaration of simple and composite variables
- Statements
- Routines
- Pointers and indirect routine calls
- Object-oriented programming
Learn by examples
The manual contains extensive and complete code examples that can be
compiled into executable programs. Much information is given as cornments
inside the examples. There are three reasons for this approach:
- It is desirable that the examples should answer as many questions as
possible about how and where to use the PLANC features that are demonstrated.
- Much of your work will consist in reading PLANC code - you may as well
get used to it early.
- We hope the manual will promote good and uniform programming habits
among PLANC users, thus making it easier for you to read other people's
code.
Use tools while learning PLANC
It is common practice in textbook examples of code to include numerous
1/0 statements which print results during execution of the prograrns. These
I/0 statements do not contribute to the readability of the examples, and
can be made superfluous if the you use a good debugger (such as the ND Symbolic
Debugger) to observe the state of the programs during execution. It is also
a good idea to use LED, as it is designed with features that facilitate
development of programs in PLANC (indentation, pretty-print, compilations
to locate errors and so on).
Getting used to reading PLANC
For the most part. PLANC is a conventional block-structured language.
However, it has a few features that set it a apart from other languages
such as C and Pascal and which will obscure the more familiar features of
the language until you know more about them. This section contains a couple
of profusely commented programs that demonstrate those features.
M1 - Your first PLANC program
Introduction
This subsection contains a simple program. It shows how all statements
are contained in a block delimited by the keywords MODULE and ENDMODULE.
You will also notice PLANC's explicit stack initiation, how to use the PROGRAM
declaration, how PLANC assignments are written, and a little
about type checking.
Before you start reading the example
What you need to know before you read the following code is that end-ofline
also denotes end-of-statement, and that the percent sign, (%), marks the
beginning of a comment that ends at the end of the line. To give emphasis
to the comments to important module and routine declarations, they have
been placed inside LED header frames. When using LED, you make such frames
by pressing the F4 key on the TDV keyboard. There are percentage signs at
the end of some comments too, but they are there for cosmetic purposes only.
The points demonstrated by the example are summarized immediately after
it.
- %=============================================================%
% m1
% Your first PLANC module.
%=============================================================%
- MODULE ml
- % The following INTEGER ARRAY will contain the
stack space
- % of the program. It will be initialized as such
in the
- % main program. A program may have any number
of
- % stacks, although you rarely need more than
one.
- INTEGER ARRAY : StackSpace (0:255)
- %=============================================================%
- % Main %
- % %
- % The keyword PROGRAM tells the compiler that
what %
- % follows is a routine in which program execution
will start. %
- %=============================================================%
- PROGRAM :
Main
- % These are declarations of a couple of variables;
one
- % is an integer which will occupy two bytes of
memory,
- % the next is a real number.
- INTEGER2 :
i
- REAL :
r
- % Before the program can run, it needs a stack
for
- % storing stackframes, parameters and intermediate
- % results during execution. The StackSpace array
is
- % prepared for that use in the next declaration.
- INISTACK StackSpace
- % This is the first executable statement in the
program.
- %
- % In PLANC, the operator =: is used to store
values
- % into data elements during evaluation of an
expression.
- % The store operator works from left to right:
The
- % result of the expression on the left is stored
into
- % the variable on the right.
- % In the following statement, the value 7 is
stored
- % into the variable i.
- 7 =: i
- % There is type checking In PLANC. For Instance,
only
- % values that are INTEGER can be stored into
variables
- % declared as INTEGER. If It is necessary to
store an
- % INTEGER value Into a REAL variable, it must
be con
- % verted to REAL before It can be stored, as
follows:
- (i * i) CONVERT REAL =: r
- % The keyword ENDROUTINE ends the PROGRAM.
- % In the comment to the PROGRAM declaration,
we said that
- % the keyword PROGRAM designates the start of
the routine
- % where program execution will begin. Both PROGRAMs
and
- % all other routine declarations end with the
ENDROUTINE
- % statement. Just to make it clear which routine
ends
- % where, you can write the name of the routine
after its
- % ENDROUTINE statement.
- ENDROUTINE Main
- % Just like ENDROUTINE ends routines, ENDMODULE
ends
- % modules.
- ENDMODULE
- % The next line contains a compiler command that
signals
- % the end of the current file. This command is
not strictly
- % necessary, only useful. If it were not used,
you would
- % have to type EXIT to the compiler to leave
it, but the
- % next line stops the compiler for you. (If this
file were
- % included as part of another file, the compiler
would
- % resume compilation of the other file instead
of stopping.)
- $EOF
Comments
Most PLANC code comes in modules. (Only CONSTANT,
TYPE and macro declarations plus compiler commands
are allowed outside modules, as we shall see later.)
Variables (and routines) are declared by first writing their type followed
by a colon (:), followed by the name of the variable(s). In the example,
INTEGER ARRAY, INTEGER2
and REAL were used to declare the StackSpace,
i and r variables.
All keywords that mark the beginning of a block of code are matched with
a similar keyword marking the end of the block. In this example, MODULE
was matched with ENDMODULE, while PROGRAM
was matched with ENDPROGRAM.
A program must contain one, and only one, PROGRAM
declaration to indicate where execution will start.
The stack is handled explicitly. The programmer must declare a suitable
INTEGER ARRAY for it,
and initialize the stack before the first executable statement in the PROGRAM.
M2 - Presenting PLANC
The first example contained only one routine, which happened to be the
simplest of routine declarations, the PROGRAM.
Now meet some more complex routines: a record with a routine inside it and
an exceptionhandler .
- %=============================================================
- % M 2
- %
- % This module shows more PLANC features, with
emphasis
- % on routines and records this time. The code
here
- % shows how vector arithmetic can be implemented.
(Vectors
- % are records consisting of real numbers that
are handy in
- % three-dimensional mathematics, in case you
haven't met
- % the term before.)
- %=============================================================
- MODULE m2
- INTEGER ARRAY : Stack (0:1027)
- %=============================================================
- % S q r t
- %
- % PLANC does not have built-in mathematical functions,
so
- % an iterative algorithm for computing square
roots of
- % reals is implemented as a PLANC routine.
- %
- % All routines except the main PROGRAMs are defined
using
- % the keyword ROUTINE. PLANC has a couple of
specialties:
- % the in-value and the out-value. In Sqrt, the
in-value is
- % not used, as indicated with the keyword VOID,
while the
- % routine has an out-value that is REAL. That
is the value
- % that the routine will return to where it was
called.
- % Next comes parentheses, inside which the parameters
to
- % the ROUTINE are declared. There is one parameter
here,
- % namely the real number for which the square
root is to
- % be computed. Following the parameters comes
a colon
- % and the name that the routine will be known
by in the
- % program.
- %=============================================================
- ROUTINE VOID, REAL (REAL : r) : Sqrt
- % Declaring a couple of variables to work with.
These
- % variables are only known locally, i.e. between
- % the enclosing ROUTINE ... ENDROUTINE statements.
- REAL :
xn, xp
- % We cannot compute the square root of a negative
number.
- IF
r >= 0.0 THEN
- % Giving initial values to the local variables.
- r =: xn
- 0.0 =: xp
- % The DO ... ENDDO construction makes an endless
loop.
- % One or more WHILE statements are needed inside
the loop
- % to exit from it.
- DO
- % This is the iterative formula.
- (xn + r/xn) / 2.0 =: xn
- % Iterations are to continue until there is no
- % significant improvement relative to the previous
- % value.
- WHILE ABS(xn
- xp) > 1.OE-6
- % This statement is executed as long as the above
- % condition holds. If the condition does not
hold,
- % execution continues at the first statement
after
- % the keyword ENDDO.
- xn =: xp
- ENDDO
- % Now, the value of xn is good enough to be returned
- % as the out-value of the routine.
- xn RETURN
- ELSE
- % If r is negative, return to the calling routine
- % with an ERRETURN statement which signals that
something
- % is wrong. If a routine exits through ERRETURN,
an
- % exception handler in the calling program (see
below)
- % can be invoked to take appropriate action.
- 0 ERRETURN
- ENDIF
- ENDROUTINE Sqrt
- %=============================================================
- % OldSqrt
- %
- % In PLANC versions up to H, another ROUTINE
declaration
- % layout was used. In it, the parameter types
were decla-
- % red before the :, while the parameter names
were decla-
- % red after the routine name. Sqrt uses a new
layout which
- % is easier to read, but the old layout can still
be used,
- % and this is how an old style Sqrt declaration
looks:
- %=============================================================
- ROUTINE VOID, REAL (REAL) : OldSqrt (r)
- REAL :
xn, xp
- % ... et cetera.
- xn RETURN
- ENDROUTINE
- %=============================================================
- % V e c t o r
- %
- % This is a record describing a vector as a record
with
- % three components. This vector definition also
contains a
- % routine that computes a real number that is
called the
- % length of the vector.
- %=============================================================
- TYPE
Vector = RECORD
- % The vector's three real components:
- REAL :
x, y, z
- % L e n g t h returns a real out-value computed
by
- % applying the Sqrt routine to the sum of the
square
- % of the real components of the vector.
- ROUTINE VOID, REAL : Length
- % ON ... ENDON is an exception handler for use
if Sgrt
- % exits via its ERRETURN statement. When an exception
- % occurs and handlers for it exist, the closest
handler
- % before the offending statement is activated.
When the
- % exception handler statements have been executed,
the
- % program will continue on the statement immediately
- % after the offending statement - unless the
exception
- % handler changes the flow of control.
- ON ROUTINEERROR DO
- % & is the line continuation sign. It makes
the
- % current statement continue on the next line.
- Output(1, 'a', &
- 'You cannot get the square root of a negative number!$')
- ENDON
- Sqrt(x*x + y*y + z*z) RETURN
- ENDROUTINE Length
- ENDRECORD
- %=============================================================
- % +
- %
- % You are probably not used to routines having
names such
- % as the next routine, which is called +. It
has an
- % in-value, an out-value and a parameter which
are all
- % Vectors.
- %
- % The in-value to a routine represents a dataelement
that
- % can be written to the left of the routine when
it is
- % called, and used inside the routine together
with the
- % parameters.
- %
- % Furthermore, if a routine has only one parameter,
the
- % parameter can be written without an enclosing
paren-
- % theses when the routine is called.
- %
- % To uniquely identify a routine, the type of
the
- % in-value and the number and types of the parameter(s)
- % are used together with the name of the routine.
So when
- % the compiler sees a Vector followed by a +
followed by
- % another Vector, it knows that + is the name
of a routine
- % that takes a Vector on each side of it - i.e.
the +
- % works like a binary operator. This + also has
the same
- % priority as the operator + when used in expressions.
- %=============================================================
- ROUTINE Vector,
Vector (Vector : b) : +
- % A local Vector dataelement to put the desired
- % out-value in.
- Vector : Result
- % The in-value is accessed using the special
character
- % Here, the x-component of the in-value is added
to the
- % x-component of the parameter, the result being
stored
- % into the x-component of the local Vector.
- @.x + b.x =: Result.x
- @.y + b.y =: Result.y
- @.z + b.z =: Result.z
- % ... Result's components contain the desired
values,
- % and Result can be returned as the routine's
out-value.
- Result RETURN
- ENDROUTINE +
- % All variables declared on the outermost level
of the
- % module are called global, while variables declared
- % inside routines (Including PROGRAMs) are called
local.
- % Global variables (and local variables with
READ access
- % only, see later) can be given Initial values.
Each
- % variable of type Vector has three real numbers
as
- % components, and the three initial values for
the compo-
- % nents must be grouped together as a list of
reals
- % enclosed by parentheses. Statement continuation
- % signs are not needed if you insert a CrLf in
the middle
- % of a list, like this:
- Vector : xAxis := (1.0, 0.0, 0.0),
- yAxis := (0.0, 1.0, 0.0),
- zAxis := (0.0, 0.0, 1.0),
- Composite
- % The following global variable is also initialized.
Its
- % single initial value need not be enclosed in
parentheses.
- REAL :
l := 0.0
- PROGRAM :
Main
- % ... Important: always remember to initialize
the stack
- % in your PROGRAM!
- INISTACK Stack
- % In the next statement,
- % zAxis is a Vector used as in-value,
- % + is a routine name,
- % yAxis is a Vector used as parameter,
- % Composite is a Vector into which the out-value
is
- % stored.
- zAxis + YAxis =: Composite
- % All records of the type Vector contain a Length
routine
- % which has a real number representing its length
as
- % out-value. This routine is accessed via the
usual dot
- % notation for record component access. Let us
compute
- % the length of the Vector called Composite and
store it
- % into 1.
- Composite.Length =: l
- ENDROUTINE Main
- ENDMODULE
- $EOF
Comments
This program demonstrated how routines and records are made and used.
Routines can be used like operators because of the in-/out-value mechanism
and naming convention, while records can have routines as components.
Routines
The keyword ROUTINE is used for defining all
routines except the main PROGRAM.
ROUTINEs always have an in-value
and an out-value.
The in-value and the out-value can be declared as being of any valid
type, or of the special type VOID if you do not
want to use one or both of them. The keyword VOID can
only be used in routine declaration.
When routines with non-void in-values are called, the name of the variable/constant/expres-
sion you want to use as in-value is written to the left of the
routine name, and can subsequently be accessed (but not changed) using the
special variable name @ inside the routine.
If the out-value is not declared as VOID, the
routine returns to the calling statement with a value that can be stored
in a variable or used in further calculations. If the out-value is void,
then no value is returned.
Routines can have zero or more parameters, and the parameters can be
of any type. The parameter names can either be declared together with their
type declarations to the left of the : (new style), or separately after
the routine name (old style).
When the routine is called, the parameters are written as a list enclosed
in parentheses to the right of the routine name, with one exception: if
the routine has one parameter, the parameter can optionally be
written without enclosing parentheses.
To identify the routine declaration used in a routine call when the routine
name is overloaded, the compiler uses the type of the in-value,
the number and the types of the parameters, and the name of the routine.
The out-value is not used for routine identification when overloading.
This is because the out-value is not necessarily used. The routine name
may be written as a statement all by itself, if necessary preceded
by an in-value only. On the other hand, the routine name may be
written as invalue to other routines. The latter routines have the same
name, but have different types of in-value. The compiler, which uses the
routine declarations to identify overloaded routines, will not get enough
information about the out-value of the first routine from the context of
the call to decide which of the latter is to be used.
Records
Records can contain routines as components.
Routines that are part of records are called using the customary dot
notation for record component access.
Such routines can access the components of the record they are declared
in directly (without the use of dot notation).
Exception handlers
If specific error conditions occur in the program, execution of exception
handler code tailored to the condition can be invoked. Such specific conditions
can be errors in the routines called, attempts to divide by zero, stack
overflows, and when evaluation of conditional expressions in ASSERT
statements yields the value FALSE.
Exception handler code is enclosed between the keywords ON
and ENDON.
When an exception condition arises, the statements in the first relevant
exception handler before the offending statement are executed.
If the exception handler does not contain statements that affect flow
of control, the first statement after the offending statement will be executed
after the exception-handler statements.