Learning Structured Programming

Self-taught programmers tend to sit at the keyboard and just type their program without having put much thought into the design.  Structured programming is a very simple concept.  Basically, you are required to think about the program you are about to write and design it based on a group of smaller logical functions.
Another trap that self -taught programmers fall into is producing 'spaghetti code'.  That's code that is riddled with GOTOs and trying to follow the logic flow is a headache.
RULE #1 - You can't use GOTOs.  In fact, in POW!, there isn't a GOTO statement in the language!
 
RULE #2 - All VARiables must be declared before they can be referenced in your code.  Variables are declared by:

VAR
  a: INTEGER;
  b,c,d: LONGINT;
etc.
The following variable types are available:
BOOLEAN
CHAR
INTEGER
LONGINT
REAL
LONGREAL
SET

You may also have ARRAYs of a specific type:

VAR
   numbers:  ARRAY 100 OF INTEGER;
There will be 100 elements in this array.  The first element is referenced as:  number[0] and last: number[99].
(Note the use of []  - (square brackets) for specifying a subscript to an array.

In the TYPEs that are available, you may have noticed that there is no type for strings.  That's OK - you can create your own types:

TYPE
  ShortString =  ARRAY 16 OF CHAR;
  String =   ARRAY 256 OF CHAR;
  LongString =  ARRAY 32000 OF CHAR;
VAR
  KeyWord:  ShortString;
  FileName:   String;
  Text:    LongString;
BEGIN
  FileName := "c:\pow\examples\hellow.mod";
.........

You can also have Records (or in BASIC terms - STRUCTures):

TYPE
  Point = RECORD
    x:          INTEGER;
    y:         INTEGER;
  END;
VAR
  StartPoint:      Point;

RULE #3 - All PROCEDURES (and Functions) must be defined before they can be used.
This means that they must be positioned in the code BEFORE the point they are used - or - the must exist in another MODULE that is IMPORTed.  Example:

MODULE Box;

TYPE
  Rect = RECORD
   x1,
   y1,
   x2,
   y2:      INTEGER;
  END;

PROCEDURE Swap(VAR i1, i2: INTEGER);
VAR
  temp:    INTEGER;
BEGIN
  temp := i1;
  i1 := i2;
  i2 := temp;
END Swap;

PROCEDURE DrawBox(r: Rect);
BEGIN
  IF r.x1 > r.x2 THEN Swap(r.x1, r.x2); END;
  IF r.y1 > r.y2 THEN Swap(r.y1, r.y2); END;

.......
END DrawBox;

Notice the declaration for the PROCEDURE Swap:
PROCEDURE Swap(VAR i1, i2: INTEGER);
The VAR command here ensures that values are changed in the calling procedure.  Without the VAR command - this procedure is just passed a COPY of the parameters - and so just the copy would be swapped - not the original parameters.
DID THAT MAKE SENSE?
Sometimes when we call another Procedure it is to take some kind of action without disturbing the values of the parameters passed to it.  For example - the DrawBox routine probably should not be able to alter the values of the Record 'r'.  But to be able to draw the box - it needs to ensure that the coordinates are specified in a particular way - so in DrawBox the VAR command is NOT used with the parameter - but we do use it in the Swap procedure.

SCOPE OF TYPEs and VARiables.
In the above example there is a variable called 'temp' declared within the Swap procedure.  This variable is ONLY know within the Swap procedure and cannot be referenced anywhere else in the program.  (You can declare a variable called 'temp' elsewhere in your program - but that is a different variable).  The RECORD TYPE called Rect is know throughout the whole program - but it is not known to other modules.  To make it available to other modules you must EXPORT it by putting an * after its name:
TYPE
  Rect* = RECORD
   x1,
   y1,
   x2,
   y2:      INTEGER;
  END;

RULE #4 - There are no CALL or GOSUB commands.
Did you notice that in the DrawBox procedure we accessed the Swap procedure just by using its name - just as if Swap was now part of the POW! language.  Similarly the Type called Rect has become part of the POW! language for this Module.  This is why POW! is called an extensible language.  When you write a new procedure - it becomes part of the language for the rest of the module.

Functions and Procedures.

POW! has both Functions and Procedures - but they are both identified with the keyword PROCEDURE.  The difference between them is that Functions are PROCEDURES that RETURN a value:

PROCEDURE Minimum(a,b: INTEGER): INTEGER;
BEGIN
  IF a < THEN
    RETURN a
  ELSE
    RETURN b;
  END;
END Minimum;

A Function MUST be exitted with a RETURN statement - failing to do so with cause your program to Halt with a runtime error.

 

Home
Email Brosco