HOME - - - - - - - - - Other material for programmers - - - - - - - - - Pascalite Tutorial Table of Contents

Pascalite Programming: Generalised Program Structrure: Second on topic


If you haven't read the first tutorial on this subject, you might want to do so now, but that isn't essential. Skim this, even if you elect not to plow through the first tutorial.

Think of the effect of standing between two large mirrors which are parallel to each other, the effect which creates the "hall of mirrors" down which you see you in a mirror, in a mirror, in a mirror....

Pascal programs can be structured like that. You can (just about) have a program within a program within a program.... Maybe the following will show you what I mean. I've used slightly odd indenting to help emphasise the point. The program doesn't do anything profound. Don't try to compile the it.
program Example;
var bTmp:byte;

   procedure SecondLevel;
   var boIsIt:boolean;

       procedure ThirdLevel;
       var bAnotherOne:byte;
       begin
       bTmp:=5;
       boIsIt:=true;
       end;

   begin {SecondLevel's main begin}
   ThirdLevel;{This is a call of the procedure "ThirdLevel"}
   boIsIt:=false;
   end;

begin {Top level's main begin}
bTmp:=4;
SecondLevel;{This is a call of the procedure "SecondLevelLevel"}
if boIsIt then
  begin {here's an example of a begin that isn't a "main" begin}
  write(lcd,'hi');
  end; {to finish block started with "begin{here's...}
end.{of program "Example"}
The beauty of the nesting shown above is that in a real programming example, it allows you to divide and conquer. The details of anything can be set apart in their own procedure declaration, and after the procedure or function has been created, you can simply use it without having the details underfoot to confuse. In a big project, you will have several levels. A wordprocessor, for instance, might have a procedure for saving a user-created document. That procedure would have various parts, one, for instance, to show what files already exist on part of your hard disc. THAT procedure might need to call upon an even more deeply buried procedure that was responsible for tinkering with the name and details of one file so that the name and details appear as the user requires.

Pascalite doesn't enable you to use nesting to the degree that bigger Pascals or Delphi allow. But don't complain! Pascalite DOES allow one degree of nesting, and that is sufficient for many things. The price of unlimited nesting would be a more expensive, more error susceptible, bigger Pascalite.

With the idea of nesting comes the idea of "local" and "global" variables and procedures.

In the example program, bTmp is a "global" variable. You can use it anywhere within the program. We say that it's scope is global. On the other hand, bAnotherOne is "local to the procedure "ThirdLevel". If, near the end of the program, you said write(lcd,bAnotherOne) instead of write(lcd,'hi'), the compiler would complain "Unknown variable". This, believe it or not, is good! It helps keep one part of your program from having unintended effects on other parts of your program. Deep within the example program, within the procedure ThirdLevel, we see boIsIt:=true. This would be acceptable to a compiler.... anything declared in a higher level is available to lower levels contained within that higher level.

Pascalite is a little eccentric in it's respect of scope. You can declare variables within a procedure, which makes them invisible to parts of the program outside the procedure. In most Pascals, but not in Pascalite, the same variable name can be used in several places... without the contents of one variable called, say, bTmp, destroying what is stored in some other bTmp elsewhere in the program. It does work, and is beneficial, strange as that may seem.

In Pascalite, even if a variable is local to a procedure, the name you are using must not be re-used elsewhere. The following wouldn't work in Pascalite, but might be of interest anyway, as it will work in other Pascals.....
program Example2;
var bNum,bOther:byte;

    procedure Nested;
    var bNum:byte;
      bNum:=5;
      bOther:=50
      write(lcd,bNum);
      write(lcd,Other);
      end;
begin
  bNum:=2;
  bOther:=20;
  write(lcd,bNum);
  write(lcd,bOther);
  Nested;
  write(lcd,bNum);
  write(lcd,bOther);
end.
That program would write 2, 20, 5, 50, 2, 50 on the LCD, which should seem strange to you at first. It should be easy to see where the first 2 and the 20 came from. Even seeing where the 5 and the 50 comes from shouldn't be too hard. However, until you grasp the scope issues, you might expect the last two numbers to be 5 and 50. The last write(lcd,bNum) produced another 2 because of the rules of scope. The program has two bNums. The one within the procedure Nested is separate from the one existing as a global variable. If the var bNum:byte had not been in the declaration of Nested, then Nested would have used the global bNum, just as it uses the global bOther.

Even though Pascalite doesn't allow local variables to have the same name as any existing global variables, and even though Pascalite local variables do not save memory, it is still worth using them as a help towards organising your program.
To search THIS site.... (Go to the site's above, and use their search buttons if you want to search them.)... Way to search this site without using forms
   Search this site or the web        powered by FreeFind

  Site search Web search

Ad from page's editor: Yes.. I do enjoy compiling these things for you... hope they are helpful. However.. this doesn't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows pc) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated!
Click here to visit editor's freeware, shareware page.

Link to editor's (Arunet) homepage
How to email or write this page's editor, Tom Boyd