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
- 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
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
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
% Your first PLANC module.
- MODULE ml
- % The following INTEGER ARRAY will contain the
- % of the program. It will be initialized as such
- % main program. A program may have any number
- % stacks, although you rarely need more than
- INTEGER ARRAY : StackSpace (0:255)
- % Main %
- % %
- % The keyword PROGRAM tells the compiler that
- % follows is a routine in which program execution
will start. %
- PROGRAM :
- % These are declarations of a couple of variables;
- % is an integer which will occupy two bytes of
- % the next is a real number.
- INTEGER2 :
- REAL :
- % Before the program can run, it needs a stack
- % storing stackframes, parameters and intermediate
- % results during execution. The StackSpace array
- % prepared for that use in the next declaration.
- INISTACK StackSpace
- % This is the first executable statement in the
- % In PLANC, the operator =: is used to store
- % into data elements during evaluation of an
- % The store operator works from left to right:
- % result of the expression on the left is stored
- % the variable on the right.
- % In the following statement, the value 7 is
- % into the variable i.
- 7 =: i
- % There is type checking In PLANC. For Instance,
- % values that are INTEGER can be stored into
- % declared as INTEGER. If It is necessary to
- % INTEGER value Into a REAL variable, it must
- % verted to REAL before It can be stored, as
- (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
- % where program execution will begin. Both PROGRAMs
- % all other routine declarations end with the
- % statement. Just to make it clear which routine
- % where, you can write the name of the routine
- % ENDROUTINE statement.
- ENDROUTINE Main
- % Just like ENDROUTINE ends routines, ENDMODULE
- % modules.
- % The next line contains a compiler command that
- % the end of the current file. This command is
- % necessary, only useful. If it were not used,
- % have to type EXIT to the compiler to leave
it, but the
- % next line stops the compiler for you. (If this
- % included as part of another file, the compiler
- % resume compilation of the other file instead
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
- % on routines and records this time. The code
- % shows how vector arithmetic can be implemented.
- % are records consisting of real numbers that
are handy in
- % three-dimensional mathematics, in case you
- % the term before.)
- MODULE m2
- INTEGER ARRAY : Stack (0:1027)
- % S q r t
- % PLANC does not have built-in mathematical functions,
- % an iterative algorithm for computing square
- % reals is implemented as a PLANC routine.
- % All routines except the main PROGRAMs are defined
- % the keyword ROUTINE. PLANC has a couple of
- % the in-value and the out-value. In Sqrt, the
- % not used, as indicated with the keyword VOID,
- % routine has an out-value that is REAL. That
is the value
- % that the routine will return to where it was
- % Next comes parentheses, inside which the parameters
- % the ROUTINE are declared. There is one parameter
- % namely the real number for which the square
root is to
- % be computed. Following the parameters comes
- % 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.
- % variables are only known locally, i.e. between
- % the enclosing ROUTINE ... ENDROUTINE statements.
- REAL :
- % We cannot compute the square root of a negative
r >= 0.0 THEN
- % Giving initial values to the local variables.
- r =: xn
- 0.0 =: xp
- % The DO ... ENDDO construction makes an endless
- % One or more WHILE statements are needed inside
- % to exit from it.
- % 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
- % execution continues at the first statement
- % the keyword ENDDO.
- xn =: xp
- % Now, the value of xn is good enough to be returned
- % as the out-value of the routine.
- xn RETURN
- % If r is negative, return to the calling routine
- % with an ERRETURN statement which signals that
- % is wrong. If a routine exits through ERRETURN,
- % exception handler in the calling program (see
- % can be invoked to take appropriate action.
- 0 ERRETURN
- ENDROUTINE Sqrt
- % OldSqrt
- % In PLANC versions up to H, another ROUTINE
- % layout was used. In it, the parameter types
- % red before the :, while the parameter names
- % red after the routine name. Sqrt uses a new
- % is easier to read, but the old layout can still
- % and this is how an old style Sqrt declaration
- ROUTINE VOID, REAL (REAL) : OldSqrt (r)
- REAL :
- % ... et cetera.
- xn RETURN
- % V e c t o r
- % This is a record describing a vector as a record
- % three components. This vector definition also
- % routine that computes a real number that is
- % length of the vector.
Vector = RECORD
- % The vector's three real components:
- REAL :
x, y, z
- % L e n g t h returns a real out-value computed
- % applying the Sqrt routine to the sum of the
- % of the real components of the vector.
- ROUTINE VOID, REAL : Length
- % ON ... ENDON is an exception handler for use
- % exits via its ERRETURN statement. When an exception
- % occurs and handlers for it exist, the closest
- % before the offending statement is activated.
- % exception handler statements have been executed,
- % program will continue on the statement immediately
- % after the offending statement - unless the
- % handler changes the flow of control.
- ON ROUTINEERROR DO
- % & is the line continuation sign. It makes
- % current statement continue on the next line.
- Output(1, 'a', &
- 'You cannot get the square root of a negative number!$')
- Sqrt(x*x + y*y + z*z) RETURN
- ENDROUTINE Length
- % +
- % You are probably not used to routines having
- % as the next routine, which is called +. It
- % in-value, an out-value and a parameter which
- % Vectors.
- % The in-value to a routine represents a dataelement
- % can be written to the left of the routine when
- % called, and used inside the routine together
- % parameters.
- % Furthermore, if a routine has only one parameter,
- % parameter can be written without an enclosing
- % theses when the routine is called.
- % To uniquely identify a routine, the type of
- % in-value and the number and types of the parameter(s)
- % are used together with the name of the routine.
- % the compiler sees a Vector followed by a +
- % another Vector, it knows that + is the name
of a routine
- % that takes a Vector on each side of it - i.e.
- % works like a binary operator. This + also has
- % 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
- % Here, the x-component of the in-value is added
- % x-component of the parameter, the result being
- % 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
- % and Result can be returned as the routine's
- Result RETURN
- ENDROUTINE +
- % All variables declared on the outermost level
- % module are called global, while variables declared
- % inside routines (Including PROGRAMs) are called
- % Global variables (and local variables with
- % only, see later) can be given Initial values.
- % variable of type Vector has three real numbers
- % components, and the three initial values for
- % nents must be grouped together as a list of
- % enclosed by parentheses. Statement continuation
- % signs are not needed if you insert a CrLf in
- % 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),
- % The following global variable is also initialized.
- % single initial value need not be enclosed in
- REAL :
l := 0.0
- PROGRAM :
- % ... Important: always remember to initialize
- % 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
- % stored.
- zAxis + YAxis =: Composite
- % All records of the type Vector contain a Length
- % which has a real number representing its length
- % out-value. This routine is accessed via the
- % notation for record component access. Let us
- % the length of the Vector called Composite and
- % into 1.
- Composite.Length =: l
- ENDROUTINE Main
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.
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 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).
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
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.