0% found this document useful (0 votes)
226 views154 pages

Free Pascal Square One Vol 1

This document provides an introduction to a book about learning to program with the FreePascal compiler. It discusses the history of the book, which originally focused on teaching Turbo Pascal but is now being updated to teach FreePascal. The introduction explains that the book is intended to teach programming concepts and the Pascal language to beginners from the very start, without any prerequisites. It will cover installing FreePascal, using its interactive development environment, and writing simple Pascal programs.

Uploaded by

anon_883489826
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
226 views154 pages

Free Pascal Square One Vol 1

This document provides an introduction to a book about learning to program with the FreePascal compiler. It discusses the history of the book, which originally focused on teaching Turbo Pascal but is now being updated to teach FreePascal. The introduction explains that the book is intended to teach programming concepts and the Pascal language to beginners from the very start, without any prerequisites. It will cover installing FreePascal, using its interactive development environment, and writing simple Pascal programs.

Uploaded by

anon_883489826
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 154

FreePascal

From Square One


Volume 1:
The Fundamental Ideas of Programming
Installing and Using FreePascal and Lazarus
The Core of the Pascal Language

by Jeff Duntemann

Revision of 2/1/2010

Repeat...
Until...

Copperwood Press ● Colorado Springs, Colorado USA


FreePascal from Square One
By Jeff Duntemann

This work is licensed under the Creative Commons Attribution-Share alike 3.0
United States License. To view a copy of this license, visit this Web link:
http://creativecommons.org/licenses/by-sa/3.0/us/
or send a letter to:
Creative Commons
171 Second Street, Suite 300
San Francisco CA 94105 USA

So that no one misunderstands the above:


This is a free ebook.
And I really mean that. Like FreePascal itself, you are free to give it to your friends,
post it on your Web or FTP site or Usenet, include it on CDs or DVDs with your
software or your own books, and just get it out there to anybody who needs or
wants it. You are free to print it out at home or on a print services site of some
kind.
I would like to reserve rights to “publisher-style” printed editions sold at retail. If
you’re a publisher and wish to create and sell such an edition, contact me.
I post updated and corrected editions periodically. If you spot errors or see
something that could be improved somehow, please send me an email so that I can
fold those changes into the master copy. Use “jeff” “at” “duntemann” “dot” “com”
and it’ll reach me.
Printed and perfect-bound paper copies of this book (with color covers) may be
ordered at the following URL:

http://www.lulu.com/content/<xxxxxxxx> <fix when uploaded>

Copperwood Media, LLC


Colorado Springs, Colorado
Table of Contents
Introduction: How This Book Came About. . . . . . . . 5
Part 1: The Fundamental Ideas of Programming . . . . 9
Part 2: Installing and Using FreePascal . . . . . . . . 83
Part 3: The Core of the Pascal Language . . . . . . . . xx
4 FreePascal from Square One, Volume 1
Introduction:
How This Book Came to Be,
and
What I’m Trying to Do

Y essir, the book you’re reading has been around the block a few times since
I began writing it in November of 1983—which I boggle to think was over
twenty-five years ago. It’s been through four print editions and on paper sold over
125,000 copies. It’s been translated into five languages.
Now it’s time set it free.
Pascal was not my first programming language. That honor belongs to FORTH,
though I don’t admit it very often. FORTH struck a spark in my imagination, but
it burned like a pile of shredded rubber tires, leaving a stink and a greasy residue
behind that I’m still trying to get rid of. BASIC came next, and burned like dry pine;
with fury and small explosions of insight, but there was more light than heat, and
it burned out quickly. BASIC taught me a lot, but it didn’t take me far enough, and
left me cold halfway into the night.
Pascal, when I found it, caught and burned like well-seasoned ash: Slow, deep,
hot; I learned it with a measured cadence by which one fact built on all those before
it. 1981 is a long time gone, and the fire’s still burning. I’ve learned a lot of other
languages in the meantime, including C, which burns like sticks of dynamite: It
either digs your ditch or blows you to Kingdom Come. Or both. But when something
needs doing, I always come back to Pascal.
When I began writing Pascal From Square One in the fall of 1983, I had no particular
compiler in mind. There were several, and they were all (by today’s standards)
agonizingly bad. The best of the bunch was the long-extinct Pascal/MT+, and I used
that as the host compiler for all of my example code. The book, however, was about
Pascal the language: How to get started using it; how to think in Pascal; how to see
the language from a height and then learn its component parts one by one.
When I turned the book in at the end of summer 1984, my editor at Scott,
Foresman had a radical suggestion: Rewrite the book to focus not on Pascal the
language but on Turbo Pascal the product. The maverick compiler from Scotts
Valley was rapidly plowing all the other Pascals into the soil, and he smelled a new
and ravenous audience. I took the manuscript back, and by January of 1985 I had

5
6 FreePascal from Square One, Volume 1

rewritten it heavily to take into account the numerous extensions and peccadilloes
of Borland’s Turbo Pascal compiler, version 2.0.
The book was delayed getting into print for several months, and as it happened,
Complete Turbo Pascal was not quite the first book on the shelves focusing on Turbo
Pascal. It was certainly the second, however, and it sold over 125,000 copies in the
four print editions that were published between 1985 and 1993. The Second Edition
of Complete Turbo Pascal (“2E”, as we publishing insiders called it) came out in 1986,
and addressed Turbo Pascal V3.0.
By March 1987 I had moved to Scotts Valley, California and was working for
Borland itself, creating a programmer’s magazine that eventually appeared in the
fall of 1987 as Turbo Technix. Doing the magazine was a handful, and I gladly let
others write the books for Turbo Pascal 4.0. I had the insider’s knowledge that V5.0
would come soon enough, and change plenty, so I worked a little bit ahead, and
Complete Turbo Pascal, Third Edition was published in early 1989.
It’s tough to stay ahead in this business. Turbo Pascal 5.5 appeared in May of 1989,
largely as a response to Microsoft’s totally unexpected (but now long-forgotten)
QuickPascal. V5.5 brought with it the new dazzle of object-oriented programming,
and while I did write the V5.5 OOP Guide manual that Borland published with the V5.5
product I chose to pass on updating Complete Turbo Pascal for either V5.5 or V6.0.
The magazine Turbo Technix folded after only a year, and I left Borland at the
end of 1988, wrote documentation for them until the end of 1989, and moved to
Arizona in February of 1990 to start my own publishing company. This included
my own programmers’ magazine, PC Techniques, which became Visual Developer in
1996 and ran until early 2000.
The early 1990s saw some turbulence in the Pascal business. Borland retired
the “Turbo Pascal” brand and renamed their flagship product Borland Pascal.
The computer books division of my publisher, Scott Foresman, was engulfed and
devoured by some other publisher. Complete Turbo Pascal was put out of print, and I
got the rights back. An inquiry from Bantam Books in 1992 led to my expanding
Complete Turbo Pascal into a new book focused on Borland Pascal 7. I was able to re-
title the book Borland Pascal 7 From Square One (the title Complete Turbo Pascal had been
imposed by Scott, Foresman) and bring it up to date. That edition didn’t sell well
because by 1994, Borland had created Delphi, and most of us considered the DOS
era closed. I began writing books about Delphi and never looked back.
And so it was for almost 15 years. I considered just posting the word-processor
files from Borland Pascal from Square One a few years ago, but figured that no one was
using Pascal all by itself anymore. Not so. I first saw FreePascal in 1998 and tried it
from time to time, but it wasn’t until January 2008 that Anthony Henry emailed me
How This Book Came to Be 7

to suggest that FreePascal could use a good tutorial, and it shouldn’t be too hard to
update Borland Pascal 7 from Square One to that role. He was right—and the project
has been a lot of fun.
I mention all this history because I want people to understand where FreePascal
from Square One came from, emphasizing that it’s been a work in progress for 25 years.
Why stop now? I don’t have to cater to publishers, paper costs, print runs, or release
schedules anymore. The book can evolve with the compiler, and every so often you
can download the latest update. My publishing company Copperwood Press offers a
print-on-demand paper edition if you’d like one, but you can print it yourself if you
prefer. That’s how technical publishing ought to be, and someday will be.

What I’m Trying to Do Here


I wrote this book for ordinary people who had the itch to try programming and
(with some dedication) to get good at it over time. You don’t have to know anything
at all about Pascal, or programming generally, to read it. Anyone who lives a
tolerably comfortable life in this frenetic twenty-first century can program. Most of
us (as I’ll show a little later) engage the skills of programming to organize our daily
lives. If you want to program, you can.
It’s that simple.
And this book begins at what I call Square One: The absolute beginning. I will
explain the concepts behind programming, how to install FreePascal, how to run
the text-mode Interactive Development Environment, and how to craft simple
programs in the Pascal language. I will not cover the Lazarus graphical environment,
which is worthy of an entire book—or several—all to itself.
You do need to know your way around your own computer and its operating
system, but that’s for housekeeping more than programming. This first volume will
not get into operating system specific issues except with respect to installation. Part
of FreePascal’s magic is its portability: A simple program written under Windows
can be recompiled without changes under Linux—or, for that matter, under any
operating system to which FreePascal has been ported.
Rather than try to cover all of FreePascal in one book and do justice to none of it,
I’m going to take my time to help you get the basics down cold. It’s tough to build
a fancy house when half the bricks are missing from your foundation. This whole
book is about foundations, and getting familiar with all the skills that you will be
using for the rest of your programming career, even (or especially) once you’ve
forgotten how utterly fundamental they are.
That’s why I call it Square One.
8 FreePascal from Square One, Volume 1
Begin . . . End
Part I:
The Fundamental Ideas
of Programming
1. The Box That Follows a Plan . . . . . . . . . . . . . . . . . 11
2. The Nature of Software Developmement . . . . . . . . 39
3. The Secret Word Is “Structure” . . . . . . . . . . . . . . . 61

If...Then...Else...
9
10 FreePascal from Square One, Volume 1
Chapter 1.
The Box
that Follows a Plan

T here is a rare class of human being with a gift for aphorism, which is the ability
to capture the essence of a thing in only a few words. My old man was one; he
could speak volumes in saying things like, “Kick ass. Just don’t miss.” Lacking the
gene for aphorism, I write books—but I envy the ability all the same.
The patron aphorist of computing is Ted Nelson, the eccentric wizard who
created the perpetually almost-there Xanadu database system, and who wrote the
seminal book Computer Lib/Dream Machines. It’s a scary, wonderful work, in and out
of print for thirty years but worth hunting down if you can find it. In six words, Ted
Nelson defined “computer” better than anyone else probably ever will:
A computer is a box that follows a plan.
We’ll come back to the box. For now, let’s think about plans, where they come
from, and what we do with them.

1.1. Another Colorado Springs Saturday morning


Don’t be fooled. The world is virtually swimming in petroleum. What we need
more of is...Saturdays.
It’s 5:30 AM on the start of a Colorado Springs weekend: The neighborhood
woodpecker hammers on our tin chimney cap, loud enough to wake the dead,
but just long enough to wake the sleeping. QBit stretches and climbs on my chest,
wagging furiously as though to say, Hey, guy, time waits for no man. Shake it!
Over coffee and Corn Chex, I sit down at the kitchen table with a quadrille pad
and try to figure out how to cram thirty hours’ worth of doing into a sixteen-hour
day. The toughest part comes first: Simply remembering what needs to be done.
(This gets harder once you get into your fifties. Trust me.) I brainstorm a list in pure
stream-of-consciousness fashion, jotting things down in no particular order other
than how they occur to me, hoping that when I’m done it’s all there:

11
12 FreePascal from Square One, Volume 1

Read email.
Pay bills.
Put money into checking account if necessary.
Get cash at ATM.
Go to Home Depot.
Get Thompson’s Water Seal.
Get 2 4’ flourescent bulbs.
Get more steel wool if we’re out.
Get more #120 sandpaper if we’re out.
Get birthday present for Brian. Bookman Books? He likes ghost towns.
Put together grocery list. Go to Safeway for groceries.
Sand rough spots on the deck.
Water seal the deck.
See if my back-ordered water filter cartridge is in at Shouse; call first.
Replace refrigerator water filter cartridge if they have it.
Take the empty grill propane tank in and get a full one.
Do what laundry needs doing.
Go to the gym and swim fifty laps.

That’s a lot to ask of one day. If it’s going to be done, it’s going to have to be done
smart, which is to say, in an efficient order so that as little time and energy gets lost
in the process as possible. In other words, to get the most out of a day, you’d better
have a plan.

Time and space priorities


In lining things up for the merciless sprint through a too-short day, you have to be
mindful of both time and space. Time is (as always) crucial. Some things have to
happen before other things. Some things have to happen before a certain time of
the day, or within a time “window”—such as the business hours of a store you need
to get to.
And on any mad dash through a metropolitan area the size of Colorado’s
second-largest city, space becomes an overwhelming consideration. You can’t just
go to one place, come home, then go to the next place, then come home, and go
to another place, then come home again; not if each destination lies ten or twelve
miles or more from home. You have to think about where everything is, and visit all
The Box That Follows a Plan 13

destinations in an order that minimizes needless travel—especially with gas prices


at historical highs. Home Depot is on the way to the Bookman bookstore, so it
makes sense to visit one on the way to the other. Hard decisions sometimes happen:
Shouse Appliances is a long way off, and not along any convenient connect-the-
dots path. Do you need to go there at all? If so, make sure you have to go—call
first—and consider that the water tastes awful, yet you’ve been avoiding the trip for
a couple of months.
Furthermore, there are always hard-to-define necessities that influence how and
in what order you do things. In the summer, you simply must do grocery shopping
dead last, and perferably at a store close to home, if you expect to keep the ice cream
solid and the Tater Tots frozen. The 35ºC days we see now and then in Colorado
Springs are blessed relief; faced with the 45°C summer highs we generally had for
three months in Arizona, most car air conditioners would at best keep you alive.
Finally, when pressed, most of us will admit that we rarely manage to get
everything done on the day we intend to do it. Some things end up squeezed out
of a too-tight day like watermelon seeds from between greasy fingers. Whether we
realize it or not, we often schedule the least necessary things last, so that if we don’t
get to them it’s no disaster. After all, tomorrow is another day, and the undone
items will just head up tomorrow’s (or next Saturday’s) errands list.
One way or another, mostly on instinct but with some rational thought, we put
together a plan. After mulling it for a few minutes, I took my earlier stream-of-
consciousness errands list and drafted my actual plan as shown below:

Pay bills.
Call and add money to checking account if required based on balance.
Check in the garage for steel wool and #120 sandpaper.
Put together grocery list.
Call Shouse Appliance to see if the filters are in.
Check oil in the 4Runner. Add if necessary.
Run errands:
Go up Nevada to hit Home Depot first.
Get Thompson’s Water Seal.
Get 2 4’ flourescent bulbs.
Get more steel wool if we’re out.
Get more #120 sandpaper if we’re out.
Swap out empty propane tank.
14 FreePascal from Square One, Volume 1

Head west out Cimmaron to Bookman.


Buy Colorado ghost-towns book for Brian.
If water filters are in, go across town on Cimmaron to Academy Blvd. then
north to Shouse. Buy water filters.
Go to Safeway for groceries.
Get cash at ATM.
Come home.
Replace water filter cartridge behind refrigerator. (Finally!)
Sand rough spots on the deck.
Water seal the deck.
Do whatever laundry needs doing.
Read EMAIL.
Go to gym and swim fifty laps.
Collapse!

From a height and in detail


The plan (for it is a plan) just outlined was executed pretty much the way I wrote
it. I added a few things I hadn’t thought of the first time, like checking the oil in the
4Runner. The discipline of drafting a plan will often bring out details and issues
that didn’t come through the first time.
Much of the actual detail of the plan acted simply as a memory jogger. In the heat
of the moment (or in the heat of a summer afternoon, desperate to get someplace—
anyplace—air conditioned!) details often get forgotten. I knew, for example, why I
wanted to go to Bookman—to buy a book for my nephew’s birthday. I was unlikely
to forget that. But in bad traffic, or if the 4Runner had acted up, well, forgetfulness
happens...
To be safe, I wrote the plan in more detail than I might have needed. I’ve lived
here for years and know my way around the area pretty well, but there are those 50s
moments sometimes when you forget that it’s a long haul across on Cimmaron to
the East Side and the appliances store.
A plan can exist, however, at various levels of detail. Had I more faith in my
memory (or if I’d been stuck with a smaller piece of paper) I might have condensed
some of the items above into summaries that identify them without actually
describing them in detail. A less verbose but no less complete form of the plan
might look like this:
The Box That Follows a Plan 15

Pay bills.
Replenish checking account from savings.
Put together grocery list.
Put together a Home Depot list.
Call Shouse Appliance to see if the filters are in.
Check in the garage for steel wool and #120 sandpaper.
Check oil in the Magic Van. Add if necessary.
Run errands:
Home Depot.
Bookman Books.
Shouse Appliance
Safeway.
Sand and water seal the deck.
If I get it, replace water filter cartridge behind refrigerator.
Do what laundry needs doing.
Read EMAIL.
Swim fifty laps at gym.
Collapse!

Look carefully at the differences between this list and the previous list. Mostly
I’ve condensed obvious, common-sense things that I was unlikely to forget. I’ve
been to the various stores so often that I could do it asleep, so there’s really little
point in giving myself driving directions. I have an intuitive grasp of where all the
stores are located, and I can plot a minimal course among them all without really
thinking about it. At best, the order in which the stores are written down jogs my
memory in the direction of that optimal course.
I combined items that always go together. Paying bills and adding money back
into my checking account are things I always do together; to do otherwise risks
disorder and insufficient funds.
I pulled details out of the “Home depot” item and instead added an item further
up the plan, reminding me to “Make a Home Depot list.” If I was already going to put
together a grocery list, I figured I might as well flip it over and put a hardware-store
list on the other side. There’s a lesson here: Plan-making is something that gets
better with practice. Every time you draft a plan, you’ll probably see some way of
improving it.
16 FreePascal from Square One, Volume 1

On the other hand, sooner or later you have to stop fooling around and execute
the plan.
I’m saying all this to get you in the habit of looking at a plan as something that
works at different levels. A good plan can be reduced to an “at-a-glance” form that
tells you the general shape of the things you want to do today, without confusing
the issue with reams of details. On the other hand, to be complete, the plan must
at some level contain all necessary details. Suppose I had sprained an ankle out in
the garage and had to have someone else run errands in my place? In that case, the
detailed plan would have been required, down to and perhaps including detailed
driving directions to the various stores.
Had Carol been the one to take over errand-running for me, I might not have
had to add a lot of detail to my list. When you live with a woman for thirty years,
you share a lot of context and assumptions with her. But had my long-lost cousin
Tony from Wisconsin been charged with dashing around Colorado Springs doing
my day’s errands, I would have had to write pages and pages to make sure he had
enough information to do it right.
Or if my very distant relative Heinz Duntemann from Dusseldorf were visiting, I
would have had to do all that, and write the plan in German as well.
Or...if my friend Hkrepats from Tau Ceti V (who neither knows nor cares what a
wood deck is, and might consider Thompson’s Water Seal a species of sports drink)
volunteered to run errands for me, I would have had to explain even the minutest
detail (over and above the English language and alphabet), including what stop
lights mean, how to drive, our decimal currency (Hkrepats has sixteen fingers and
counts in hex) and that cats are pets, not hors d’oerves.
To summarize: The shape of the plan—and the level of detail in the plan—
depends on who’s reading the plan, and who has to follow it. Remember this. We’ll
come back to it a little later.

1.2. Computer Programs as Plans of Action


If you’re coming into this book completely green, the conclusion may not be obvious,
so here it is: A computer program is very much a “do-it” list for a computer, written by you. The
process of creating a computer program, in fact, is very similar conceptually to the
process of creating a do-it list, as we’ll discover over the course of Part 1.
Ted Nelson’s description of a computer as a box that follows a plan is almost
literally true. You load a computer program—the plan—into the computer’s
memory, and the computer will follow that plan, step-by-step, with a tireless
persistance and absolute literal adherence to the letter of the plan.
The Box That Follows a Plan 17

I’m not going to go into a tremendous amount of detail here as to the electrical
internals of computers. If you’re curious about such things, you might pick up my
earlier book Assembly Language From Square One (John Wiley & Sons, 2000; available
on Amazon) and read its first several chapters, which take some pains to explain the
CPU chip and computer memory in plain language.

The notion of an “instruction set”


I had a very hard time catching onto the general concept of computing at first.
Everybody who tried to explain it to me danced all around the issue of what a
computer actually was. Yes, I knew you loaded a program into the computer and the
program ran. I understood that one program could control the execution of other
programs, and a host of other very high-level details. But I hungered to know what
was underneath it all.
What I think was bothering me was the very important question: How does the
computer understand the steps that comprise the plan?
The answer, like a plan, can be understood on several levels. At the highest
level, you can think of it this way: The computer understands a very limited set of
commands. These commands are the instructions that you write down, in order,
when you sit at your desk and ponder the way to get the computer to do the things
you want it to do. Taken together, the commands that the computer understands are
called its instruction set. The instruction set is summarized in a book that describes
the computer in detail. Programmers study the instruction set, and they write a
program as a sequence of instructions chosen from that set.

Emily, the robot with a one-track mind


Let’s consider a very simple thought-experiment describing a gadget that has
actually been built (although many years ago) at a major American university. The
gadget is, in fact, a crude sort of robot. Let’s call the robot Emily. (The name is a
tribute to a robotics project that appeared in Popular Electronics for March, 1962. I
built Emily for my eighth grade science fair, and won an award.)
Picture Emily as a round metal can roughly the size and shape of a low
footstool or a dishpan. Inside Emily are motors and batteries to power them,
plus relays that switch the motors on and off, allowing the motors to run forward
or backward, or to make right and left turns by running one motor or the other
alone. On Emily’s top surface are a slot into which a card can be inserted, and a
button marked “GO.”
18 FreePascal from Square One, Volume 1

Figure 1.1. Emily the Robot

Left to her own devices, Emily does nothing but sit in one place. However, if you
take a card full of instructions and insert the card into the slot on Emily’s lid and
press the “GO” button, Emily zips off on her own, stopping and going and turning
and reversing. She’s following the instructions on the card. Eventually she reaches
and obeys the last instruction on the card, and simply stops where she is, waiting
for another card and another press of the “GO” button.
Figure 1.2 shows one of Emily’s instruction cards. The card contains thirteen
rows of eight holes. In the figure, the black rectangles represent holes punched
through the card, and the white rectangles are places where holes could be punched,
but are not. Underneath the slot in Emily’s lid is a mechanism for detecting holes
by shining eight small beams of light at the card. Where the light goes through
and strikes a photocell on the other side, there is a hole. Where the light is blocked,
there is no hole.
The holes can be punched in numerous patterns. Some of the patterns “mean
something” to Emily, in that they cause her machinery to react in a predictable way.
When Emily’s internal photocells detect the pattern that stands for “Go forward 1
foot” her motors come on and move her forward a distance of one foot, then stop.
Similarly, when Emily detects the pattern that means “Turn right,” she pivots on
one motor, turning to the right. Patterns that don’t correspond to some sort of
action are ignored.
The Box That Follows a Plan 19

Figure 1.2. A program card for Emily the Robot

The card shown in Figure 1.2 describes a plan for Emily. It is literally a list of things
that she must do, arranged in order from top to bottom. The arrow shows which end
of the card must be inserted into Emily’s card slot, with the cut corner on the left.
Once the card is inserted into the slot in her lid, a press on her “GO” button sets her in
motion, following the plan as surely as I followed mine by jumping into the 4Runner
and heading off down Nevada Street to do my Saturday morning errands.
When Emily follows the plan outlined on the card, she moves in the pattern
shown in Figure 1.3. It’s not an especially sophisticated or useful plan—but then
again, there’s only room for thirteen instructions on the card. With a bigger
card—or more slots to put cards into—Emily could execute much longer and more
complex programs.
20 FreePascal from Square One, Volume 1

Figure 1.3. How Emily follows her instructions.

Emily’s instruction set


It’s interesting to look at the plan-card in Figure 1.2 and dope out how many
different instructions are present on the card. The answer may surprise you: four.
It looks more complex than that, somehow. But all that Emily is doing is executing
sequences of the following instructions:

Go forward 1 foot
Go forward 10 feet
Turn left
Turn right
The Box That Follows a Plan 21

There’s no instruction to stop; when Emily runs out of instructions, she stops
automatically.
Now, Emily is a little more sophisticated than this one simple card might
indicate. Over and above the four instructions shown above, Emily “understands”
four more:

Go backward 1 foot
Go backward 10 feet
Rotate 180°
Sound buzzer

I’ve summarized Emily’s full instruction set in Figure 1.4.

Figure 1.4. The Emily Mark I Instruction Set.

When you want to punch up a new card for Emily to follow, you must choose
from among the eight instructions in Emily’s instruction set. That’s all she knows,
and there’s no way to make her do something that isn’t part of the instruction set.
However, it isn’t always completely plain when something is or isn’t part of the
instruction set. Suppose you want Emily to move forward seven feet. There’s
no single instruction in Emily’s instruction set called “Go forward seven feet.”
However, you could put seven of the “Go forward 1 foot” instructions in a row, and
Emily would go forward seven feet.
22 FreePascal from Square One, Volume 1

But that would take seven positions on the card, which only has thirteen
positions altogether. Is there a way to make Emily move forward seven feet without
taking so many instructions?
Consider the full instruction set, and then consider this sequence of
instructions:

Go forward 10 feet
Go backward 1 foot
Go backward 1 foot
Go backward 1 foot

It’s the long way around, in a sense, but the end result is indeed getting Emily to a
position seven feet ahead of her starting point. It takes a little longer, timewise, but
it only uses up four positions on the card.
This is a lot of what the skill of programming involves: Looking at the computer’s
instruction set and choosing sequences of instructions that get the job done. There
is usually more than one way to do any job you could name—and sometimes an
infinite number of ways, each with its own set of pluses and minuses. You will find,
as you develop your skills as a programmer, that it’s relatively easy to get a program
to work—and a whole lot harder to get it to work well.

Different instructions sets


There is something I need to make clear: An instruction set is not the same thing
as a program. A computer’s instruction set is baked into the silicon of its CPU
(Central Processing Unit) chip. (There have been computers—big ones—created
with alterable instruction sets, but they are not the sorts of things we are ever
likely to work on.) Once the chip is designed, the instruction set is almost literally
set in stone.
However, as years pass, computer designers create new CPU chips with new
instruction sets. The new instruction sets are sometimes massively different
from the old ones, but in many cases, a new instruction set comes about simply
by adding new instructions to an existing instruction set while designing a new
CPU chip.
This was done when Intel designed the 80286 CPU chip in the early ‘80s. The
dominent PC-compatible CPU chip up to that time was Intel’s 8088, an 8-bit
version of Intel’s original 16-bit 8086. The 8088 was used by IBM in its original
PC and XT machines. Intel added a lot of computing muscle to the 8088 when it
The Box That Follows a Plan 23

created the 80286, but the remarkable thing was that it only added capabilities—
Intel took nothing away. The 80286’s instruction set is larger than the 8088’s, but it
also contains the 8088’s. That being the case, anything that runs on an 8088 also
runs on an 80286. This has been the case as Intel’s product line has evolved down
the years through the 80386, 80486, and the many varieties of Pentium. All the
instructions available in Intel’s original 8086/8088 instruction set are still there
in the latest Pentium 4. (Whether programs written for the 8088 will run on a
Pentium 4 really depends more on the operating system than the CPU chip.)

Emily Mark II
We can return to Emily for a more concrete example. Once we’ve played with Emily
for a few months, let’s say we dismantle her and rebuild her with more complex
circuitry to do different things. We add more sophisticated motor controls that
allow Emily to make half-turns (45°) instead of just full 90° left and right turns. This
alone allows tremendously more complex paths to be taken.
But the most intriguing addition to Emily is an electrically operated “tail” that
can be raised or lowered under program control. Attached to this tail is a felt-tip
reservoir brush, much like the ones sign painters use for large paper signs. One new
instruction in Emily’s enlarged instruction set lowers the brush so that it contacts
the ground. Another instruction raises it off the ground so that it remains an inch
or so in the air.
If we then put down large sheets of paper in the room where we test Emily, she
can draw things on the paper by lowering the brush, moving around, and then
raising the brush. Emily can draw a 1-foot square by executing the following set of
instructions:

Lower brush
Go forward 1 foot
Turn right
Go forward 1 foot
Turn right
Go forward 1 foot
Turn right
Go forward 1 foot
Raise brush

The full Emily Mark II instruction set is shown in Figure 1.5.


24 FreePascal from Square One, Volume 1

Figure 1.5. The Emily Mark II Instruction Set.

The whole point I’m making here is that a computer program is a plan for action,
and the individual actions must be chosen from a limited set that the computer
understands. If the computer doesn’t understand a particular instruction, that
instruction can’t be used. Sometimes you can emulate a missing instruction by
combining existing instructions to accomplish the same results. We did this earlier
by using several instructions to make Emily act as though she had a “Move forward
seven feet” instruction. Often, however, that is difficult or impossible. How, for
example, might you make Emily perform a half-left turn by combining sequences
of her original eight instructions? Easy. You can’t.
This is one way to understand the limitations of computers. A computer has a
fundamental instruction set. This instruction set is fairly limited, and the individual
instructions are very tiny in their impact. An instruction, for example, might simply
add 1 to a location in memory. Through a great deal of cleverness, this elemental
instruction set can be expanded enormously by combining a multitude of tiny,
limited instructions into larger, more complex instructions. One such mechanism
is the subject of this book: FreePascal, as I’ll come to show in the next chapter.
The Box That Follows a Plan 25

1.3. Changing course inside the plan


Back in the DOS era (basically 1981-1995) if you used a PC for any amount of time,
you probably wrote small “batch” files to execute sequences of DOS commands
or utility programs. Virtually everyone back then periodically tinkered with
AUTOEXEC.BAT, which was the batch file in charge of setting up your machine
at boot-time by loading resident programs, changing video modes, checking
remaining hard disk space, and things like that.
A DOS batch file was very much what we’ve been talking about: a “do-it” list for
your computer. I had a whole lot of them, most created to take the three or four
small steps necessary to invoke some application. When I wanted to work with
my address book file using the Paradox database application, I used to use this little
batch file:

D:
CD \PARADOX3\PERSONAL
VHR MDS /N
PARADOX3

It’s not much, but it saved me having to type these four lines every time I wanted
to update someone’s phone number in my address book database. (We forget
sometimes what tremendous time savers Windows and Mac OS have been by
handling things like that for us, and retaining applications in memory for quick use
at any time.) The first command shown above moves me to the D: hard disk drive.
The second command moves me into the subdirectory containing my address
book database. The third command invokes a special utility program that resets
and clears the unusual monitor and video board that I used for years in the DOS era.
The fourth and last line invokes the Paradox 3.0 database program.
Yes, DOS batch files are ancient and little-used these days, but they perfectly
illustrate my point: Like most people’s “do-it” lists, DOS batch files run straight
through from top to bottom, in one path only.

Departing from the straight and narrow


Well, how else would it run? Well, a batch program (for they truly were computer
programs) might contain a loop or a branch, which alters the course of the plan
based on what happens while the plan is underway. (Branching was possible with
DOS batch, but only deep geeks ever did much of it.)
You do that sort of thing all the time in daily life, mostly without thinking.
Suppose, for example, you go grocery shopping with the item “poppy-seed rolls”
26 FreePascal from Square One, Volume 1

on your grocery list. Now when you get to Safeway, suppose it’s late in the day and
the poppy-seed rolls are long gone. You’re faced with a decision: What to buy? If
you’re having hamburgers for supper, you need something to put them on. So you
buy Mother Ersatz’ Genuine Bread-Flavored Imitation Hamburger Buns. You didn’t
write it down this way and may not even think of it this way, but your “do-it” list
contains this assumed entry:

If the bakery poppy-seed rolls are gone,


buy Mother Ersatz’ Buns.

Then again, if Mother Ersatz’ products make your tummy breakdance all night
after supper, you might change your whole supper strategy, leave the frozen
hamburg in the freezer, and gather materials for stir-fry chicken instead:

If the bakery poppy-seed rolls are gone, then do this:


Buy package of boneless chicken breasts;
Buy bottle of teriyaki sauce
Buy fresh mushrooms
Buy can of water chestnuts

Most of the time we perform such last-minute decision-making “on the fly,”
hence we rarely write such detailed decisions down in our original and carefully
crafted “do-it” lists. Most of the time, Safeway will have the poppy-seed rolls and we
operate under the assumption that they will always be there. We think of “Plan B”
decisions as things that happens only when the world goes ballistic on us and acts
in an unexpected fashion.
In computer programming, such decisions happen all the time, and programming
would be impossible without them. In a computer program, little or nothing can
be assumed. There’s no “usual situation” to rely on. Everything has to be explained
in full. It’s rather like the situation that would occur if I sent Hkrepats the alien out
shopping for me. I’d have to spell the full decision out in great detail:

If the store bakery poppy-seed rolls are still available,


then buy one package,
otherwise buy one package of Mother Ersatz’ Buns.
The Box That Follows a Plan 27

This is an absolutely fundamental programming concept that we call the


IF..THEN..ELSE branch statement. (The word “otherwise” stands in well for the
Pascal term ELSE.) It’s a fork in the plan; a choice of two paths based on the state of
things as they exist at that point in the plan. You can’t know when you head out the
door on your way to Safeway whether everything you want will be there...so you go
in prepared to make decisions based on what you find when you get to the bakery
department. In Pascal programming you’ll come to use branches like this so often it
will almost be done without thinking.

Doing part of the plan more than once


Changing the course of a plan doesn’t necessarily mean branching off on a whole
new trajectory. It can also mean going back a few steps and repeating something
that may need to be done more than once.
A simple example of a loop to get a job done comes up often in something as
simple as a recipe. When you’re making a cake from scratch and the recipe book
calls for four cups of flour, what do you do? You take the 1-cup measuring cup, dip
it into the flour canister, fill it brim-full, and then dump the flour it contains into the
big glass bowl.
Then you do exactly the same thing a second time...
...and a third time...
...and a fourth time.
The plan (here, a cake recipe) calls for flour. Measuring flour is done in one-
cup increments, because you don’t have a four-cup measuring cup. It’s a little like
the situation with Emily the Robot, when she has to move three feet forward. The
instruction set doesn’t allow you to measure out four cups of flour in one swoop, so
you have to fake it by measuring out one cup four times.
In the larger view, you’ve entered a loop in the plan. You go through the
component motions of measuring out a cup of flour. Then, you ratchet back just far
enough in the plan to go through the same motions again. You do this as often as
you must to correctly accomplish the recipe.

Counting passes through the loop


You’ve probably been in the situation where you begin daydreaming after the
second cup, and by the time you shake the clutter out of your head, you can’t
remember how many times you’ve already run through the loop, and either go
one too many or one too few. Counting helps, and being as how I’m a champion
daydreamer, I’m not afraid to admit that when the count goes more than three or
28 FreePascal from Square One, Volume 1

four, I start making tick marks on a piece of scratch paper for each however much
of whatever I throw into the bowl. This makes for much better cakes. (Or at least
more predictable ones.)
You might write out (for cousin Heinz or perhaps Hkrepats the alien) this part of
the plan like so:

Do this exactly four times (and count them!):


Dip the measuring cup into the flour canister;
Fill the cup to the line with flour;
Dump the flour into the mixing bowl.

This is another element that you’ll see very frequently in Pascal programming.
It’s called a FOR..DO loop, and we’ll return to it later in this book.

Doing part of the plan until it’s finished


There are other circumstances when you need to repeat a portion of a plan
until...well, until what must be done is done. You do it as often as necessary.
It’s something like the way Mary Jo Mankiewicz measures out jelly beans at
Candy’N’Stuff. You ask her for a quarter-pound of the broccoli-flavored ones. She
takes the big scoop, holds her nose, and plunges it deep into that rich green bin.
With a scoop full of jelly beans, she stands over the scale, and repeatedly shakes a
dribble of jelly beans into the scale’s measuring bowl until the digital display reads
a little more than .25.
Written out for Hkrepats the Alien, the plan might read this way:

Dig the scoop into the jelly beans and fill it.
Take the full scoop over to the digital scale.
Repeat the following:
Shake a few jelly beans from the scoop into the scale’s bowl;
Until the scale’s digital readout reads 0.25 pounds.

Exactly how many times Mary Jo has to shake the scoop over the scale depends
on what kind of a shaker she is. If she’s new on the job and cautious because she
doesn’t want to go too far, she’ll just shake one or two jelly beans at a time onto the
scale. Once she wises up, she’ll realize that going over the requested weight doesn’t
matter so much, and she’ll shake a little harder so that more jelly beans drop out of
The Box That Follows a Plan 29

the scoop with each shake. This way, she’ll shake a lot fewer times, and when she
ends up handing you half a pound of jelly beans, that’s OK—since one can’t ever
have enough broccoli-flavored jelly beans, now, can one?
Computers, of course, do mind when they go over the established weight limit,
and they don’t mind making small shakes if that’s what it takes to get the final
weight bang-on. A computer, in fact, is a tireless creature, and would probably
shake out only one bean at a time, testing the total weight after each bean falls
into the bowl.
This sort of loop is called a REPEAT..UNTIL loop, and it’s also common in
Pascal programming, as I’ll demonstrate later on in this book.

The shape of the plan


The whole point I’m trying to make in this section is that a plan doesn’t have to
be shaped like one straight line. It can fork, once or many times. Portions of the
plan can be repeated, either a set number of times, or as many times as it takes
to get the job done. This is nothing new to any of us—we do this sort of thing
every day in muddling through our somewhat overstuffed lives. In fact, if you’ve
taken any effort at all to live an organized life, you’ll probably make a dynamite
programmer, since success in life or in programming cooks down to creating a
reasonable plan and then seeing it through from start to finish without making
any (serious) mistakes.

1.4 Information and Action


Actually, we’ve only talked about half of what a plan (in computer terms) actually is.
The other half, which some people say is by far the more important half, has been
waiting in the wings for its place in this discussion.
That other half is the stuff that is acted upon when the computer works through
the plan you devise for it. When we spoke of Mary Jo Mankeiwicz measuring out
jelly beans, we focused on the way she ladled them out. Just as important to the
process are the jelly beans themselves. And so it is, whether you characterize
the plan as shopping for groceries, measuring out flour for a recipe, or building a
birdhouse. The shopping, the measuring, and the building are crucial—but they
mean nothing without the groceries, the flour, and those little pieces of plywood
that always split when you try to get a nail through them.
In computer terms, the stuff that a program acts on is information, by which I
mean symbols that have some meaning in a human context.
30 FreePascal from Square One, Volume 1

Code vs. data


When you create a computer program, the plan portion of the program is a series
of steps, written in a programming language of some sort. In this book, that’s
going to mean FreePascal, but there are plenty of programming languages in the
world (too many by half—or maybe three quarters, I think) and they all work pretty
much the same way. Taken together, these steps are called program code, or simply
code. Collectively, the information acted on by the program code is called data. The
program as a whole contains both code and data.
My friend Tom Swan (who has written some terrific books on the Pascal
programming language himself) says that code is what a computer program
does, and data is what a computer program knows. This is a very elegant way of
characterizing the difference between program code and data, and I hesitate in
using it mostly because too many people have swallowed the Hollywood notion
of mysteriously intelligent computers a little too fully. A program doesn’t “know”
anything—it’s not alive, and a consensus is beginning to form that computers can
never truly be made to think in the sense that human beings think. Roger Penrose
has written a truly excellent book on the subject, The Emperor’s New Mind, which is
difficult reading in places but really nails the whole notion of “artificial intelligence”
to the wall. The subject is a big one, and an important one, and I recommend the
book powerfully.

Figure 1.6. Computer, Code, and Data.


The Box That Follows a Plan 31

But there’s another reason: Thinking of code and data as “doing” and “knowing”
leaves out an essential component: The gizmo that does the doing and the knowing;
that is, the computer itself. I recommend that you always keep the computer in the
picture, and think of the computer, code, and data as an unbreakable love triangle.
No single corner is worth a damn without both of the other two. Between any two
corners you’ll read what those two corners, working together, create. See Figure
1.6.
In summary: The program code is a series of steps. The computer takes these
steps, and in doing so manipulates the program’s data.
Let’s talk a little about the nature of data.

Let X be...
A lot of people shy away from computer programming due to math anxiety. Drop
an “X” in front of them and they panic. In truth, there’s very little math involved
in most programming, and what math there is very rarely goes beyond the high-
school level. In virtually all programs you’re likely to write for data processing
purposes (as opposed to scientific or engineering work) you’ll be doing nothing
more complex than adding, subtracting, multiplying, or (maybe) dividing—and very
rarely taking square roots.
What programming does involve is symbolic thinking. A program is a series
of steps that acts upon a group of symbols. These symbols represent some reality
existing apart from the computer program itself. It’s a little like explaining a point
in astronomy by saying, “Let this tennis ball represent the Earth, and this marble
represent the Moon...” Using the tennis ball and the marble as symbols, you can
show someone how the moon moves around the earth. Add a third symbol (a
soccer ball, perhaps) to represent the Sun, and you can explain solar eclipses and
the phases of the Moon. The tennis ball, marble, and soccer ball are placeholders
for their real-life rock-and-hot-gas counterparts. They allow us to think about
the Earth, Sun, and Moon without getting boggled by the massiveness of scale on
which the solar system operates. They’re symbols.

A bucket, a label, and a mask


Using a couple of balls to represent bodies in the solar system is a good example
of an interesting process called modeling, which is a common thing to do with
computer programs, and we’ll come back to it at intervals throughout this book.
But data is simpler even than that. A good conceptual start for thinking about data
is to imagine a bucket.
32 FreePascal from Square One, Volume 1

Actually, imagine a group of buckets. (Your programs won’t be especially useful


if they only contain one item of data.) Since the buckets all look pretty much alike,
you’d better also imagine that you can slap a label on each bucket and write a name
on each label.
The buckets start out empty. You can, at will, put things in the buckets, or
take things out again. You might place ten marbles in a bucket labeled “Ralph,” or
removed five marbles from a bucket labeled “George.” You can look at the buckets
and compare them: Bucket Ralph now contains the same number of marbles as
bucket George—but bucket Sara contains more marbles than either of them. This
is pretty simple, and maps perfectly onto the programming notion of defining a
variable—which is nothing more than a bucket for data—and giving that variable
a name. The variable has a value, meaning only that it contains something. The
subtlety comes in when you build a set of assumptions about what data in a variable
means.
You might, for example, create a system of assumptions by which you’ll indicate
truth or falsehood. You make the following assumption: A bucket with one marble
in it represents the logical value True, whereas an empty bucket (that is, one with
no marbles in it) represents the logical value False. Note that this does not mean you
write the word “True” on one bucket’s label or “False” on another’s. You’re simply
treating the buckets as symbols of a pair of more abstract ideas.
With the above assumptions in mind, suppose you take a bucket and write
“Mike Is At Home” on its label. Then you call Mike on the phone. If Mike picks
up the phone, you drop one marble into the labeled bucket. If Mike’s phone simply
rings (or if his answering machine message greets you) you leave the labeled bucket
empty.
With the bucket labeled “Mike Is At Home” you’ve stored a little bit of
information. If you or someone else understands the fact that one marble in a
bucket indicates True, and an empty bucket indicates False, then the bucket labeled
“Mike Is At Home” can tell you something useful: That it is true that Mike is at home.
Just look in the bucket—and save yourself a phone call.
What’s important here is that we’ve put a sort of mask on that bucket. It’s not
simply a bucket for holding marbles anymore. It’s a way of representing a simple
fact in the real world that may have nothing whatsoever to do with either marbles
or buckets.
Much of the real “thinking” work of programming consists of devising these sets
of assumptions that govern the use of a group of symbols. You’ll be thinking things
like this:
The Box That Follows a Plan 33

Let’s create a variable called BeanCount. It will represent the


number of jelly beans left in the jelly bean jar. Let’s also create a
variable called ScoopCapacity, which will represent the number
of jelly beans that the standard scoop contains when filled.

In both instances, the variable itself is simply a place somewhere inside the
computer where you can store a number. What’s important is the mask of meaning
that you place in front of that variable. The variable contains a number—and that
number represents something.
This is the fundamental idea that underlies all computer data items. They’re all
buckets with names—for which you provide a meaning.

1.5. The Craftsman, His Pockets, His Workbench, and His


Shelves
Let’s turn our attention again to Ted Nelson’s aphorism that a computer is a box that
follows a plan. So far I’ve spoken about the plan itself—how it runs from top to
bottom, perhaps branching or looping along the way. I’ve talked a little bit about
data—the stuff that the program works on when it does its work. However, only
half of the essence of computing is the plan and its data, and the other half is the
nature of the box that follows the plan.
It’s time to talk about the box.

Divided into three parts


Your PC (and virtually all other kinds of computers that have ever been designed) is
divided into three general areas: The Central Processing Unit (CPU), storage, and input/
output (I/O).
The CPU is the boss of the machine. It’s the part of the machine that contains
the instruction set we spoke of earlier. The instruction set, if you recall, is that
fundamental list of abilities that the computer has. All programs, no matter how
big or how small, and regardless of how simple or how complex, are composed of
some sequence of those fundamental instructions.
Storage is another term for memory, although it actually includes what we call
Random Access Memory (RAM) and disk storage as well. Storage is where program
code and data lives most of the time. RAM is storage that exists right next to and
around the CPU, on silicon chips. The CPU can get into RAM very quickly. The
disadvantage to RAM is that it’s expensive, and, (worse) it goes blank when you turn
power to the computer off. Disk storage, by contrast, is “farther away” from the
34 FreePascal from Square One, Volume 1

CPU and is much slower to read from and write to. Balancing that disadvantage is
the fact that disk storage is cheap and (better still) once something is written onto a
disk, it stays there until you erase it or write something over it.
Input and output are similar, and differ mainly in the direction that information
moves. Your keyboard is an input device, in that it sends data to the CPU when you
press a key. Your screen is an output device, in that it puts up on display information
sent to it by the CPU. The parallel port to which you connect your printer is another
output device, and your Ethernet network port swings both ways: It both sends and
receives data, and thus is both and input and an output device at once.

What happens when a program runs


Programs are stored on disk for the long haul. When you execute a program, the
CPU brings the program from disk storage into RAM. That done, the CPU begins at
the top of the program in RAM and begins “fetching” instructions from the program
in RAM into itself. One by one, it fetches instructions from RAM and then executes
them. It’s a process much like reading a step from a receipe and then performing
that step. You first need to know (by reading the receipe) that you must throw four
cups of flour into the bowl, and then you have to go ahead and actually measure out
the flour and put it into the bowl.
During a program’s execution, the CPU may display information on the screen
or ask for information from the keyboard. There’s nothing special about input or
output like this; there are instructions in the CPU’s instruction set that take care of
moving numbers and characters in from the keyboard or out to the screen.
What is more intriguing is the notion that the plan—that is, the sequence of
instructions being executed by the CPU—may change based on data that you type
at the keyboard. There are forks in the road (usually a multitude of them) and which
road the CPU actually follows depends on what you type into data entry fields or
answer to questions the CPU asks you.
You may see a question displayed on the screen something like this:

Do you want to exit the program now? (Y/N:)

If you press the “Y” key, one road at the fork will be taken, and that fork leads to
the end of the program. If you press the “N” key, the other road at the fork will be
taken, back into the program to do some more work.
Programs like this are said to be interactive, since there’s a constant conversation
going on between the program and you, the user. Inside the computer, the program
The Box That Follows a Plan 35

is threading its way among a great many possible paths, choosing a path at each
fork in the road depending on questions it asks you, or else depending on the results
of the work it is doing.
Sooner or later, the program either finishes its work or is told by you to pack
up for the day, and it “exits,” which means that it returns control to the operating
system, whatever the operating system might be.

Inside the box


That’s how things appear to you, outside the box, sitting at the keyboard supervising.
Understanding in detail what happens inside the box is the labor of a lifetime (or at
least often seems to be) and is the subject of this entire book—and hundreds of
others, including all the other books that I’ve ever written.
But a good place to start is with a simple metaphor. The CPU is a craftsman,
trained in a set of skills that involves the manipulation of data. Just as a skilled
machinist manipulates metal, and a carpenter manipulates wood, the CPU
manipulates numbers, characters, and symbols. We can think of the CPU’s skills as
those instructions in its instruction set. The carpenter knows how to plane a board
smooth—and the CPU knows how to add two numbers together to produce a sum.
The carpenter knows how to nail two boards together—and the CPU knows how to
compare two numbers to see if they are equal.
The CPU has a workbench in our metaphor: The computer’s RAM. RAM is
memory inside the computer, close to the CPU and easily accessible to the CPU.
The CPU can reach anywhere into RAM it needs to at any time. It can choose a
place in RAM “at random,” and this is why we call it Random Access Memory. As
the CPU stands in front of its workbench, it can reach anywhere on the workbench
and grab anything there. It can move things around on the workbench. It can pick
up two parts, put them together, and then place the joined parts back down on the
workbench before picking up something else.
But before beginning an entirely different project, the CPU, being a good
craftsman, will tidy up its workbench, put its tools away, and sweep the shavings
into the trashbin, leaving a clean workbench for the next project.
Disk storage is a little different. In our metaphor, you should think of disk storage
as the set of shelves in the far corner of the workshop, where the craftsman keeps
tools, raw materials, and incomplete projects-in-progress. It takes a few steps to go
over to the shelves, and the craftsman may have to get up on a stepstool to reach
something on the highest shelves. To avoid running itself ragged (and wasting a lot
of time) going back and forth to the shelves constantly, the CPU tries to take as much
as it can from the shelves to its workbench, and stay and work at the workbench.
36 FreePascal from Square One, Volume 1

It would be like buying a birdhouse kit, opening the package, leaving the opened
package on the shelves, and then traipsing over the to shelves to pull each piece out
of the birdhouse kit as you need it while assembling the birdhouse.
That’s dumb. The CPU would instead take the entire kit to the workbench and
assemble it there, only going back to the shelves for something too big to fit on the
workbench, or to find something it hadn’t anticipated needing.
One final note on our metaphor: The CPU has a number of storage locations that
are actually inside itself, closer even than RAM. These are called registers, and they
are like the pockets in a crasftman’s apron. Rather than placing something back on
the workbench, the craftsman can tuck a small tool or part conveniently in a pocket
for very quick retrieval a moment later. The CPU has a few such pockets, and can
use them to tuck away a number or a character for a moment.
So there are actually three different types of storage in a computer: Disk storage,
RAM, and registers. Disk storage is very large (these days, hundreds of billions of
bytes is not uncommon in hard drives) and quite cheap—but the CPU has to spend
considerable time and effort getting at it. RAM is much closer to the CPU, but it is
a lot more expensive and rarely anything near as large. Few computers have more
than 2 or 4 gigabytes of RAM these days. Finally, registers are the closest storage
to the CPU, and are in fact inside the CPU—but there are only a half dozen or so of
them, and you can’t just buy more and plug them in.

Summary: Truth or metaphor?


The electrical reality of a computer is complicated in the extreme, and getting
moreso all the time. I’ve discussed it to a much greater depth in my book Assembly
Language Step By Step than I can possible discuss it here, and if you’re curious about
what RAM “really” is, that would be a good book to read.
I’m not going to that depth in this book because FreePascal shields you from
having to know as much about the computer’s electrical structure and deepest
darkest corners. I’m sticking with metaphor because a computer program is a
metaphor. A program is a symbolic metaphor for a frighteningly obscure torrent
of electrical switching activity ultimately occurring in something about the size of
your thumbnail.
When we declare a variable in FreePascal (as I’ll be explaining shortly) we’re
doing nothing different from saying, “Let’s say that these eight transistor storage
cells represent a letter of the alphabet, and we’ll give it the name DiskUnit.”
FreePascal, in fact, is a tool entirely devoted to the creation and perfection of
such metaphors. You could create a simple program that modeled a shopping trip
taken by Hkrepats the alien to Safeway, just as I described earlier in this chapter.
The Box That Follows a Plan 37

There was, in fact, an intriguing software product available years ago called “Karel
the Robot” which was in fact a simulation of a robot on the computer screen. Karel
could be given commands and would follow them obediently, and the net effect was
a very good education on the nature of computers.
This chapter has been groundwork, basically, for people who have had absolutely
no experience in programming. All I’ve wanted to do is present some of the
fundamental ideas of both computing and programming, so that we can now dive
in and get on with the process of creating our program metaphors in earnest.
38 FreePascal from Square One, Volume 1
Chapter 2.
The Nature of
Software development

A s I hinted in the last chapter, a computer program is a plan, written by you, that
the computer follows in order to get something done. The plan consists of a
series of steps that must be taken, and some number of decisions to be made along
the way when a fork in the road turns up.
That’s programming in the abstract, as simply put as possible. There are a lot of
ways of actually writing a program, each way focusing on a different programming
language. In this book, I’ll be talking about only one programming language, the
one called Pascal. Furthermore, I’ll be focusing on only one single “dialect” of that
language, FreePascal. FreePascal is itself very similar to the venerable Turbo Pascal
from Borland, which has been with us since 1983. Nearly all program code written
for Turbo Pascal (including Turbo Pascal’s big brother Borland Pascal) will compile
and run correctly under FreePascal.
This is not a limitation. Borland’s Pascal implementations pretty much plowed
all other Pascal dialects under the soil. If you’re going to learn Pascal programming
at all, you might as well learn the dialect comprising probably 95% of all Pascal
compilers ever sold.
Look no further. You won’t find anything better.

2.1. Languages and dialects


In the “Save the Whales” episode of the Star Trek movie series, the crew of the
Enterprise travel back in time to 1987 San Francisco. When Engineer Scottie needs
to use a computer, he is shown a Macintosh and immediately picks up the mouse as
though it were a microphone and begins addressing the poor machine directly:
“Computer: We’re going to design a molecular structure for transparent
aluminum!”
The Mac had very little to say in reply. Computers didn’t understand the English
language very well back in 1987, and they don’t understand it much better today. So
what do computers understand? What is their native language?

39
40 FreePascal from Square One, Volume 1

Assembly language
The fast answer is that computers understand something called “assembly language,”
in which each step in the plan is one of those fundamental machine instructions I
described conceptually in Chapter 1. Machine instructions are incredibly minute in
what they do; for example, a single instruction may do nothing more than fetch a
byte of data from a location in RAM and store it in a location inside the CPU called
register AX. It takes an enormous number of such instructions to do anything useful;
hundreds or thousands for small programs, and many hundreds of thousands or
even millions for major application programs like Microsoft Excel or AutoCAD.
The instructions themselves are terse, cryptic, and look more like something
copied out of a mad scientist’s notebook than anything you or I would call a
language:

MOV EAX,[EBX]
SUB EAX,EDX
AND EAX,0FF0DH
DEC ECX
LOOPNZ MSK13

Actually, the frightening truth is that even these cryptic statements are
themselves “masks” for the true machine instructions, which are nothing more than
sequences of 0’s and 1’s:

0110101000110010
0000000101110011
1110111110011011
0110110110001010

It’s possible to program computers by writing down sequences of 0’s and 1’s
and somehow cramming them into a computer through toggle switches, with an
“up” switch for a “1” and a “down” switch for a “0”. I used to do this in 1976 (for my
home-made computer called the COSMAC ELF) and thought it was great good fun,
because back then it was the best that my machine and I could do.
Is it really fun?
Mmmmm...no. In truth, it gets old in a big hurry. Doing something as simple as
making the PC’s speaker beep requires fifteen or twenty machine instructions, all
laid out precisely the right way. Even writing assembly language in almost-words like
MOV EAX,[EBX] is tiresome and done today only by the most curious and the most
dedicated among us. But the computer only understands machine instructions.
What to do?
The Nature of Software Development 41

High-level computer languages


The answer dates back almost to the dawn of computing. (As I said, writing and
debugging machine instructions gets old in a big, big hurry...) Early on, people
defined what we call high-level computer languages to do much of that meticulous
machine-instruction arranging automatically.
In a high-level language, we define words and phrases that mean something to
us and perform some simple task on the computer. A good example is beeping the
PC’s speaker. We might decide that the word BEEP will be used to indicate that the
computer’s speaker is to be sounded. That done, we write down the sequence of
machine instructions that actually causes sound to be generated on the speaker,
and we associate those machine instructions with the recognizable term BEEP.
This sequence of instructions remains consistent and never changes. So we create
a program for ourselves that, when it sees the word BEEP, substitutes the sequence
of twenty machine instructions that actually does the speaker-beeping. We only
need to remember that the word BEEP does the beeping. Our clever program,
called a compiler, remembers the twenty-instruction sequence that accomplishes
the beep, so that we don’t have to. (Perhaps our program isn’t especially clever. But
it remembers things very well...)
We go on from there and define other easily-readable words and phrases that
stand for sequences of dozens or even hundreds of machine instructions. This
allows us to write down easily readable commands like the following in only a few
seconds:

Remainder := Remainder - 1;
IF Remainder = 0 THEN
BEGIN
BEEP;
Write(‘Warning! Your time has run out!’);
END;

Once you have a feeling for the high-level language, you can look at sequences
like this and know exactly what they’ll do without stretching your brain too much.
The reality is that it may take hundreds of machine instructions for the CPU to do
the work involved in what we have written, but for our eyes, it’s only a few short
lines.

Programs that write other programs


This clever compiler program understands a great many English-like words and
phrases. We create a disk file, like a word processor file, containing sequences of
English-like words and phrases. The compiler program reads in the file of English-
42 FreePascal from Square One, Volume 1

like words and phrases, and writes out an equivalent file of machine instructions.
This file of machine instructions can be loaded and executed by the CPU. But even
though this program file consists of thousands or tens of thousands of machine
instructions, we never had to know even a single machine instruction to write it. All we had
to do was understand how the English-like commands of the high-level language
affect the machine. The compiler takes care of the “ugly” stuff like remembering
which sequence of twenty machine instructions beeps the speaker. All we have to
remember is what BEEP does.
Much better!
A compiler program is thus a program that writes other programs, with some
direction from us. It does its job so well that we can actually forget all about what
happens with the machine instructions (most of the time, anyway) and concentrate
on the logic of how the English-like words and phrases go together.

Different languages
A whole host of high-level languages exists for the PC. Pascal, C, C++, C#, and BASIC
are the most common, but there are hundreds of others with obscure or puckish
names like COBOL, Perl, Python, Java, Forth, APL, Smalltalk, Eiffel, PHP, PL/1, Rexx,
FORTRAN, Lisp, Scheme, and on and on and on. As different as they may seem on
the surface, they all do the same thing underneath: Arrange machine instructions to
accomplish the work that we encode in English-like words and phrases.
Pascal, for example, uses the word Write to display information on the screen.
BASIC, by contrast, uses the word PRINT. The C and C++ languages use the word
printf. Forth uses the word TYPE. Others use words like SAY, OUTPUT, or
Show. Those words were chosen by the people who designed each language for
reasons they considered good ones. However, what those different words do is all
pretty much the same.
A high-level language is defined as a set of commands, plus a set of rules as to
how these commands are used alone and combined. These rules are called the syntax
of the language, and they correspond roughly to the syntax and grammar of spoken
human languages like English and German. Computer languages are not as rich in
expression as human languages, but they are much more precise—and needless to
say, they “speak” only of things that a computer can actually accomplish.

Dialects of a single language


Having a mob of hundreds of dissimilar languages to choose from might seem
confusing enough. Unfortunately, even within a single language, there are variations
on a theme called dialects. Each person or company who creates a compiler that
The Nature of Software Development 43

understands a given computer language might construct the compiler to understand


things a little differently from other compilers written earlier for the same language.
Thus not all Pascal compilers agree on what certain program commands mean.
Nor do all BASIC compilers agree on the syntax and command set of BASIC. If you
write a program in Drs. Kemeny & Kurtz’s TrueBasic it won’t necessarily compile
correctly if you hand that same program to Microsoft’s Visual BASIC.
Dialects usually happen when companies who write compilers add new features
and abilities to languages, in order to produce a more powerful language or (at least)
one perceived as different from the compilers already on the market.
FreePascal is a dialect of the Pascal language. Pascal has been around for about
thirty five years now (since 1971) and it’s done some serious growing in the process.
Pascal predates PCs; in fact, it predates all microcomputers of any design and was
originally created to run on massive mainframe computers, those famous for
being kept behind locked doors in air-conditioned rooms with raised floors. The
man who designed Pascal, Niklaus Wirth, was trying to prove a point in computer
science when he designed Pascal, and really didn’t intend to write an exhaustive
and generally useful language. Other companies added features to Pascal over the
years, and little by little the language broke into mutually-exclusive dialects that
were about 90% common. Alas, in computer languages as in horseshoes, “almost”
just doesn’t count.
For example, Wirth’s original Pascal wrote information to disk files with
the Put command. Borland’s Turbo Pascal broke with this concept in the early
1980s by using the Write command to write data to disk, and omitted the Put
command completely. FreePascal does things the Turbo/Borland Pascal way. If
you take a program written in the original version of Pascal and try to compile it
using FreePascal, the compiler will display an error message if it encounters a Put
command, since it doesn’t know what sequence of machine instructions Put is
supposed to represent.
This problem of dialects is worse in most languages other than Pascal, because
FreePascal’s progenitor Turbo Pascal has dominated the Pascal world for so long
that most of the earlier dialects have simply disappeared. If you ever attempt to
program in different versions of BASIC, on the other hand, the dialects problem
will appear in spades, and you will have a great deal of work to do making programs
written for one BASIC compile correctly using another BASIC.
In general, this book will be speaking of the FreePascal dialect of Pascal. Here and
there, I’ll be pointing out differences between FreePascal and other Pascals, but as I’ve
said before, the differences are becoming less and less important as time goes on.
44 FreePascal from Square One, Volume 1

2.2. Operating Systems and User Interfaces


When I wrote the first version of this book, way back toward the end of 1983,
computing was a much, much simpler field. Most people who had personal
computers had IBM PCs. Fewer people (but still a lot of them) had Apple IIs. Some
further number had an odd assortment of machines from many manufacturers that
had little in common but an operating system called CP/M. The Macintosh did not
yet exist, nor did Microsoft Windows.
Things are different now, heh.
The operating system called DOS was not an “operating system” as the industry
defined it in the 1980s. At best it was a sophisticated file manager, and most of what
it did was write files to disk drives (generally floppies until the midlate 1980s) and
read files from disk drives. “Running a program” was just another file operation:
DOS read a program file from a disk drive and stored it in RAM, and then stepped
back and gave control of the CPU to the program that it had recently placed in RAM.
When the user exited the program, DOS would regain control of the machine—
with some luck. My 1979 CP/M machine would literally reboot itself each time a
program exited, so that CP/M could again regain control. (“Rebooting” was a far
simpler process with those ancient machines, and took only a second or two.)
What was true of DOS was also true of CP/M and the Apple II operating system.
Only one program could run at a time. There was no networking without a great
deal of added complication. The user interface was a “command line” on a text-only
screen that could at best display 80 characters wide by 24 characters high. To run
a program you had to type a command at the command prompt and then press
Enter. “Graphics mode,” where it existed at all, was a slow and limited special case.
There were no windows, no task bar, no mouse, nor any drop-down menus except
as provided by the occasional forward-looking program.
The text-mode command-line user interface was the default until the late 1980s,
when personal computers finally became fast enough to manage images on a
graphical screen. The Macintosh was the first successful graphical user interface
(GUI) machine, but I remember sitting in front of Bruce Schneier’s brand-new
Macintosh in late 1984 and feeling like the poor little thing was struggling terribly.
Microsoft Windows was virtually unusable—and generally ignored—until 1990.
Although I adopted Windows NT when it was released in 1993, Windows itself
did not become generally accepted until Windows 95 appeared in 1995. The DOS
command-line interface was widely used until Windows 98. It wasn’t until 2000 or
so that most people had come to depend on graphical user interfaces, and about
that time the whole idea of a command line and text screens was mostly forgotten,
except by mainframe programmers and Unix users.
The Nature of Software Development 45

A fifth grader once wrote on an exam: “Now that dinosaurs are safely dead, we
can call them clumsy and stupid.” It’s easy to dismiss the DOS-style command-
line interface as clumsy, awkward, and time consuming, but it has the virtue of
simplicity. (We also forget that dinosaurs ruled the Earth for 100 million years. They
must have done something right.) It’s also far from extinct.

Text mode and console windows


Command-line interfaces are still used, as are text-mode displays. Although non-
technical people rarely use it, Windows contains something called the “Command
Prompt,” (look in the Accessories group) which is basically a DOS prompt in a black
window that displays only text characters. Much ancient DOS software will still run
if executed from the Windows command prompt. More to the point, some crucial
Windows utilities only run from the command prompt, and only accept textual
commands and output only text lines.
The window in which the command prompt appears is generally called a console
window. Figure 2.1 is a typical console window as displayed by Windows 2000 and
Windows XP. The desktop versions of Linux and Unix also have console windows.
Mac OS/X has a console window called Terminal. All console windows on whatever
operating systems work and look pretty much the same. (The group of commands
that each understands is different, of course.)

Figure 2.1. A console window under Windows 2000


46 FreePascal from Square One, Volume 1

The existence of console windows make certain things easier for people creating
computer language compilers like FreePascal. If a compiler only communicates
with its users through simple text screens, it can work pretty much the same way
no matter what operating system is in control of the computer. So it was done with
FreePascal: By default, it works in a console window. This means that you can open
a console window and type textual commands to FreePascal, which responds by
displaying textual information in the same window on the next line or lines. Figure
2.2 is a console window “conversation” with FreePascal, as it would occur during
the compilation of a very simple pascal program.

Figure 2.2. A FreePascal compilation operation in a console window

All the major FreePascal implementations look pretty much the same when run
in console windows, whether you’re using Windows, Linux, OS/X, or anything else.
Of course, once you begin writing programs that work specifically with a graphical
user interface belonging to a particular operating system, the explanations begin to
diverge. I won’t, however, be going that far in this introductory volume.

Text-mode user interfaces


Output in a console window is generally line-by-line: A program displays a line of
text and then moves the cursor down to the next line below it. However, that’s not all
that can be done. With a little bit of additional software behind it, a console window
can be treated as a grid of character locations, and addressed by X,Y coordinates.
Text can be displayed anywhere on a console window, at random, under program
control, by specifying an X,Y location at which to begin text display. Text can
The Nature of Software Development 47

be displayed in different colors. Boxes and frames may be created using special
characters. (IBM pioneered text-mode “graphics” this way with their original 1981
IBM PC.) Furthermore, the console window text cursor may be directed around the
window by the computer’s mouse.
Abilities like these allow us to create simple editing and compiling environment
sentirely in text mode, to run in a console window. Many of the concepts we’re
used to in graphical operating environments like Gnome, KDE, and Windows
can be emulated, albeit on a character basis and with far less resolution. Such an
environment (whether implemented in text-mode or graphics mode) is called an
Interactive Development Environment (IDE), and one is included with and installed
with FreePascal on most operating systems for which the compiler is available.
The FreePascal console window IDE is shown in Figure 2.3, with a simple Pascal
program loaded and displayed, ready to be compiled and run.

Figure 2.3. The FreePascal Text-Mode IDE in a Console Window

Graphical IDEs for FreePascal programming


FreePascal’s text-mode IDE is simple and can be very handy, but it’s a little fluky
and doesn’t always work correctly on all operating systems. Fortunately, you aren’t
limited to the text-mode IDE that comes with the compiler. Graphical IDEs exist for
FreePascal, and there’s no reason not to use one if one is available for your OS .
The best of these is Lazarus, which at this writing (2010) is available for
Windows, Linux, FreeBSD, and Mac OS/X. Lazarus is an ambitious Rapid
Application Development (RAD) system very much in the mold of Borland’s (now
Embarcadero’s) Delphi. Figure 2.4 shows the Lazarus RAD environment in its full
glory, ready to create windowed GUI applications.
48 FreePascal from Square One, Volume 1

Figure 2.4. The Full Lazarus RAD Environment in Action

Lazarus is a complicated system and was created specifically to develop fully


event-driven windowed GUI applications like the one shown above, but it’s
perfectly at home managing very simple Pascal programs that communicate
through console windows. It may seem like overkill for the sort of teaching
programs I’ll be presenting in this book, but when you’ve learned enough Pascal to
move up to object-oriented programming and the creation of windowed graphical
applications, you’ll find that Lazarus makes the process hugely easier. That’s why
I want to use Lazarus as the teaching IDE from the very beginning. The skills you
develop now by using Lazarus to write simple programs will make learning the rest
of it a snap later on when you need it.
The Nature of Software Development 49

Lazarus is itself a multi-window application, and the good news is that we can
make Lazarus a lot simpler to understand by closing the windows that you don’t
need for the time being. Figure 2.5 shows Lazarus as it appears while you’re writing
a simple Pascal program. The program code is edited from a GUI window (here,
under Windows XP) but the program’s output is displayed in a console window.

Figure 2.5. Lazarus Used to Edit and Run a Simple Pascal Program

There are three Lazarus windows shown: The control window is the narrow
one at the top. It’s the “boss” window that controls all the rest of the Lazarus
system. The larger window in the center is the editor window, where you write your
Pascal code and fix your inevitable errors. The slim window at the bottom is the
messages window, which tells you what the system is doing and points out your
errors. The black window is a console window, and is not itself a part of Lazarus.
Lazarus launches a console window when your program runs, to provide a separate
“blackboard” (literally!) on which your program can write its output, and display
the input that you enter through the keyboard.
50 FreePascal from Square One, Volume 1

2.3. The FreePascal Process


FreePascal is itself a program, and needs to be installed on your hard disk
before you can begin to learn how to use it. Later on, I’ve devoted an entire
chapter to the installation of FreePascal and Lazarus so as not to get bogged
down in installation details right here. Later in this chapter I’m going to run
through the compilation of a short, simple program. You don’t necessarily
have to run FreePascal to benefit from that run-through. Reading it carefully
will be sufficient. I’m simply trying to get you familiar with the shape of the
process of creating programs with FreePascal. However, if you’re a practical,
hands-on kind of person, you might want to stop here, jump to Chaper 4, and
install FreePascal and Lazarus on your machine if you haven’t already. That
way, you can come back to this section and follow along with a real program
while I’m explaining what’s going on. You don’t need to go through the rest of
this chapter to install the software. Now or later: It’s your choice.
Note well that I’m going to go into the mechanics of using the FreePascal
compiler and the Lazarus Environment in much more detail later on in this book.
The overview in this section will be very brief.

Source files, object files, resource files, and project files


Two words you may have heard before and will certainly hear in the future are source
code and object code. Source code files are the “human readable” form of a program.
A source code file is an ordinary text file that you create by typing into a text editor
like the one built into Lazarus. (You can edit source code files in any text editor;
people have used Windows Notepad, Wordpad, or even Microsoft Word; and there
are a multitude of text editors available for Linux.) Object code files, on the other
hand, contain the individual machine instructions that the CPU knows how to
execute. These are those endless runs of 0’s and 1’s that I described in the previous
section. The whole purpose of the FreePascal compiler is to take source code files
that you write, and use them to generate object code files that may be executed on
a computer.
Source code files for FreePascal usually have a file extension of .PAS. Object code
files come in several types. Unit files contain bits and pieces of programs that can
be used again and again, but are not in themselves complete programs. They’re
basically libraries of precompiled code. Executable files are real programs that you
can run from your operating system.
For decades, programming was simple enough so that source code files and
object code files were all there were. Today, the demands of GUI programming have
given birth to yet another class of files: Resource files contain things like icons and
The Nature of Software Development 51

images that must be “baked into” an executable program file. Finally, there are files
associated with a programming project that summarize the details of the project
for the benefit of the programming environment itself. In our case, that would be
Lazarus, but all of the ambitious RAD environments used today generate project files
to manage the mountain of details inherent in advanced programming projects.
You may not have to pay details attention to resource and project files while writing
simple programs in FreePascal, but at least understand that they’re necessary. For
the most part they are generated and maintained by the RAD environment, and
while they must be understood, you don’t often have to explicitly edit them.
In your early explorations of FreePascal, you’ll be creating simple, standalone
.PAS files and compiling them to executable files. (I’ll explain about creating unit
files for maintaining reusable code libraries later on.) You’ll then run the executable
files in a console window to see how well they work. The executable files may be run
from a console window prompt without any help from the FreePascal compiler or
the Lazarus IDE. However, for the example programs in this book you’ll generally
be able to test your executable files from inside console windows created by the
Lazarus IDE itself.

Cross-platform programming
This is a slightly advanced topic, but it’s worth noting as part of the big picture:
FreePascal can handle cross-platform programming. What this means is that you
create a program on one operating system running on one type of computer
hardware, but generate programs that can run on other, different operating systems
or hardware. For example, if your main machine is Microsoft Windows running on
Intel x86 hardware (a very common combo that we often call the “Wintel” platform)
you can still write programs that will run under Linux, Unix, Mac OS/X, and a long
list of other operating systems that you may not have even heard of.
There are often limitations on what such programs can do. For example, there
are whole classes of operating systems that don’t have a graphical user interface.
Everything that they do is done in a purely textual environment much like a console
window. If you load a graphical windowed program intended for the Linux GNOME
windowing environment on such a system, the machine will throw up its hands
in despair because it won’t know how to deal with requests to create windows or
accept mouse clicks to buttons.
The issues that come into play suring cross-platform programming are many
and they are subtle. You need to become fluent in FreePascal long before you should
attempt to create code on one platform to run on another.
52 FreePascal from Square One, Volume 1

The program development cycle


Creating programs with FreePascal works like this: You begin by conceptualizing a
design of some sort for your program. This might involve some study, some notes,
and some drawn diagrams indicating how the program is to work. With your design
(that is, your notes and diagrams) close at hand, you bring up a text editor window
and begin writing program code based on your design into the code editor window.
For the tutorials in this book, that editor window will be part of the Lazarus IDE.
(You can use other text editors if you want to, and many people do.) Every so often
during this process, you must save your program source code file or files to disk. For
the Lazarus IDE that’s as easy as pressing the Ctrl-S key combination.
Once you’ve completely typed your program’s source code file into the text
editor window, you invoke the FreePascal compiler. This, like most of the commonly
used commands, can be done by pulling down a menu option or by pressing a key
combination. (In this case, it’s just a single key, F9.) The compiler reads the source
code that you’ve typed into the text editor window and generates the appropriate
object code files., plus a single executable file.
Once the compiler begins running, one of two things happens: The compiler
either finds an error, or it doesn’t. If the compiler does not find an error, you have
what is called a correct compilation. This doesn’t mean you have a bug-free program
yet by any means—but we’ll get to that little matter in a moment.
Most of the time (especially while you’re still a Pascal newcomer) the compiler will
“complain” about something in your source code. You may have typed something
incorrectly, or else misunderstood some element of Pascal and written something
incomplete or nonsensical. No object code files will be created in this case. You’ll
have to stare at your code a little more, read the online help (or this book!), correct
what’s wrong, and try the compilation again.
Sooner or later, your program will compile correctly. At that point, you’ll have
object code, including an executable file, and you can try running it from within the
Lazarus IDE.
As with compilation, when you try running your program, one of two things
happens: Either it works perfectly, or else it doesn’t. And when it doesn’t work
perfectly, that’s when we say that your program has those legendary bugs.
Getting rid of bugs is a lot tougher than just getting rid of compiler errors. The
compiler will usually give you strong hints about where a compiler error lies and
what’s causing it. Bugs, by contrast, range from some simple, innocuous action that
you didn’t ask for (or one you asked for that didn’t occur) all the way to provoking
the operating system to abort execution of your program and throw it out of
memory. The compiler doesn’t spot bugs. You do.
The Nature of Software Development 53

FreePascal and Lazarus contain a number of built-in tools to help you flush out
the inevitable bugs you’ll find in your programs. Using these tools and your own
good sense, you gradually find and fix the causes of whatever bugs come to light.
This process can take awhile. Getting rid of disastrous and obvious bugs happens
early in the cycle, because you’re pretty motivated to find them and fix them. Getting
rid of minor or subtler bugs that don’t necessarily make your program worthless
could be a long process—and for programs of a useful size may be an endless one.
People say that there’s always one more bug, and you can devote as much time and
energy as you care to rooting that last bug out.
But even when you root the “last” bug out, there’s always one more bug. Trust me.

The process, summarized


At this point, let’s run down a list of the major steps in the FreePascal program
development process:
1. You design the program on paper. This does not mean simply writing out
program statements with a pencil. It usually means charts, diagrams, and
high-level notes we call specifications.
2. Working from your design, you type program source code into a text
editor window. (This will generally be within the Lazarus IDE.) Save your
code early and often!
3. Once you consider the source code complete, try to compile it.
4. Fix any compiler errors that come up in the text editor window, saved the
edited file, and then recompile to see if you’ve fixed any errors. Repeat the
process until there are no more compiler errors.
5. Once the program compiles correctly, try running it. Take note of any
bugs that appear, where a bug is anything a program does that it isn’t
supposed to, or something it doesn’t do that it should.
6. Fix all identified bugs, and run the program some more, to see if you can
identify any further bugs. This stage is called testing. It takes a long time.
7.When you can’t find any more bugs, the program can be considered
finished. This doesn’t mean that the program doesn’t contain any more
bugs. It generally means that you’ve simply run out of patience with
bug-chasing, and will be content with what you have. Days, weeks, or
months later, you may become sufficiently irritated by one bug or another
to begin the debugging process all over again, starting with Step 5.
I’ve summarized this process in Figure 2.6.
54 FreePascal from Square One, Volume 1

Figure 2.6. The FreePascal Programming Process

2.4. Let’s try it!


With all that under your belt, it’s time to see the actual compilation process in action.
I’d like you to type in a simple program, save it, compile it, debug it, and run it. I’m
skipping the design phase for the time being, since I’ve found it’s difficult to explain
the design process to a person who isn’t yet comfortable with the programming
language itself. This doesn’t mean that you should skip the design phase later on, or
dive into writing code before giving your design the attention it deserves. It’s just
that for the purpose of learning the software development process, you need to
know a little about coding first.
To actually follow along with me, you’ll obviously have to install FreePascal and
the Lazarus RAD environment first. I describe the installation process in detail in
Chapter 4. I encourage you to turn to Chapter 4, find the installer files, download
them, and install them on your system.
The Nature of Software Development 55

Before you launch Lazarus, create a working directory somewhere on your


machine. How this is done varies by operating system, but it doesn’t matter where it
is as long as your filesystem allows you to create and change files there. The directory
you create here will be used to store the programs that you enter and compile.
Now run Lazarus itself, however that’s done on your particular machine. For
Windows this means you double-click on the Lazarus icon, assuming that the
installer created a desktop icon. You can also run Lazarus by navigating to it in the
Start menu. How software is launched under the Linux shells depends on the shell
and how you’ve set up launchers and panels and so on.
Once Lazarus is running, create a new project by selecting Project | New Project
from the Lazarus main menu. Assuming that you’ve configured it as I describe in
Chapter 4, what you’ll see will look a great deal like the screen shown in Figure 2.7.
(Much of that configuration involves hiding the parts of Lazarus that you don’t yet
need.) The label “project1.lpr” is the default name for a new project that you have
not yet given a name to. We’ll give it a proper name shortly.

Figure 2.7. The initial Lazarus IDE screen


56 FreePascal from Square One, Volume 1

Entering a program to an edit window


An edit window is already open and ready to go—it’s the mostly-white window
labeled “Source Editor.” However, something’s already there. In creating a brand-
new project, Lazarus has created a sort of skeleton program for you. The program is
technically “empty” in that it contains no Pascal statements that do anything useful
or even visible. It is, however, a complete framework for a Pascal program, and
includes some instructions to the compiler. These are things like:

{$mode objfpc}{$H+}

Don’t worry about exactly what this means; I’ll explain it later on. Lazarus knows
how the FreePascal compiler needs to do its job in most circumstances, and the red
text (which is not program code!) contains instructions to the compiler telling it
how to compile your project and prepare the executable file. All the text in red can
be safely ignored for the time being. Don’t change it, however, or bad things could
happen!
The test program is shown below in its entirety. Some of it was already “typed
in” by Lazarus when it created the new skeleton program. The words PROGRAM,
USES, BEGIN, and END are all there in black (albeit in lower case), along with
some necessary commas and semicolons. Your job right now is to enter all of the
text in the test program that is not already present in the editor window.

1 PROGRAM EatAtJoes;

2 USES Crt;

3 BEGIN
4 ClrScr;
5 GotoXY(10,5);
6 Writeln(‘Eat at Joe’’s!’);
7 GotoXY(10,7);
8 Writeln(‘Ten Million Flies Can’’t ALL Be Wrong!’);
9 Readln;
10 END.

Important: The numbers in the left margin are not to be entered! Those are line
numbers, and I added them to the printed program so that I can refer unambiguously
to a specific line in a program while talking about the program in the book. For a
program this short that may seem unnecessary, but for the larger and more complex
programs I’ll present later on it will be essential. Lazarus always shows line numbers
in the left margin of its editor windows without any orders from you.
The Nature of Software Development 57

Here’s how to proceed:


1. Highlight the default project name after “program” and replace it with
“EatAtJoes”.
2. Place the text cursor after “Classes” and type a comma. Press Enter. Add
the word “Crt”. The USES clause is a list of code libraries, and Crt is one
of them. You’re adding Crt to the list. (Why the other libraries are already
named is a question that will have to wait for the time being.)
3. Enter the text I show between the words BEGIN and END into the editor
window, between begin and end.

The character case issue


Without spending too much time on it right now, I must emphasize that, in Pascal,
character case does not matter to the compiler. In other words, FreePascal sees BEGIN,
Begin, and begin as precisely the same thing. Unfortunately, Lazarus and I differ on
a key formatting issue: I feel very strongly that reserved words in Pascal like BEGIN
and END should be in uppercase. This should be a configuration option in Lazarus
but it is not. So in any code that Lazarus generates automatically (like the skeleton
program) reserved words will be in lower case. This is a bad idea, and although you
can do it whichever way you like, keep this in mind: Reserved words are different. They
have “super powers” and must be treated specially. It pays to set them off somehow
from ordinary program identifiers like constants and variables, to make your
program code more readable and less vulnerable to certain types of completely
avoidable errors.
Certain people will try to tell you in a weirdly excitable tone: “But...but...uppercase
letters mean that you’re...shouting!”
Maybe somewhere in the world they do, somewhere ancient and obsolete but
alas, not yet dead. In Pascal, reserved words are the framing members of your
programs. They must stand out. If you put them in lowercase, you will miss them
now and then and make stupid mistakes, and spend more time and energy fixing
things than you otherwise would.
That said, there is one (small) advantage in Lazarus’ habit of generating reserved
words in lowercase: You’ll be able to tell immediately what code Lazarus wrote, and
what code you wrote. In very small programs this won’t be an issue. In large, complex
programs, it can become difficult to tell at a glance what code was automatically
generated. If you place your reserved words in uppercase, you will always know,
and knowing is always important.
58 FreePascal from Square One, Volume 1

Giving a name to your new project


At this point, you’ve entered the text for the test program, but you’re still using the
default name that Lazarus gave to the project on its creation. Giving a descriptive
name to the project is our next step.
To name the new project, select Project | Save Project As. (There’s no hotkey.)
A dialog will appear allowing you to enter a new name for the project. Leave the
default file extension as it is. In this case, call the project EatAtJoes and click Save.
Correctly entered and properly renamed, your project will look like what’s
shown in Figure 2.8.

Figure 2.8. The project entered and renamed.

Saving your work to disk


It’s hard to overemphasize the importance of saving your work to disk frequently.
For a certain period of time, what you’ve just typed into the open edit window
exists only in RAM memory and nowhere else. If your machine failed for some reason
right now, or if lightning hit a power pig and knocked out the electricity to your
neighborhood, what you just typed would be gone for good. Such irritations are
never necessary. Get it down on disk regularly by saving the project.
The Nature of Software Development 59

In Lazarus, this is almost trivial. Just click the Save icon (which looks like a
diskette) in the main menu bar (third icon from the left) or press Ctrl-S. Lazarus
will save your project into your working directory. If you haven’t already given your
project a name, Lazarus will pop up the Save Project As... dialog, and allow you to
specify a directory and a name for the project. Thereafter, saving the project will be
done without a dialog, and it will be saved to the directory and name specifed via
Save Project As...
There’s more to a project than just one file. If you look at your working directory
after naming and saving your project, you’ll see a fair number of files with your
project name and different extensions; for example, EatAtJoes.exe, EatAtJoes.ico,
EatAtJoes.manifest, EatAtJoes.lpr, and so on. For simple programs not all of these
files might be strictly necessary, but Lazarus treats a little 10-line example program
the same way it treats a million-line windowed application. I’ll have more to say
about the various files that make up a project in Chapter 5.

Compiling and building your program


You’ve now got a new program typed in and saved on disk as a Lazarus project. It’s
time to turn the FreePascal compiler loose on it. This step will discover any errors
you might have made while typing, and if the program is correct, it will create
(among others) an eexecutable code file that can be run and observed.
At this point I have to refine the jargon a little: Compiling a source code file, as I
explained earlier, generates an object code file from the source code file. However,
creating an executable file that you can actually run isn’t generally done as part of
the compile step. In years past, when computing was simpler, Pascal compilers
did generate an executable file when compiling a program. Today, however, things
have gotten complicated enough that executable files are not generated in one
pass. Even fairly simple programs may consist of more than one Pascal source file.
Each of these files must be compiled, and then the several object code files then
linked into a single executable file. The whole process taken together—compiling
all the various Pascal source code files that are part of the project and then linking
them into a single executable file—is called building. We use the term even for the
simplest projects that have only one single Pascal source code file. We can compile
a single Pascal file, but we build a Lazarus project.
Building your project is done from the Run menu. Pull down the Run menu and
select the Build option. Lazarus will launch the FreePascal compiler behind the scenes,
and do whatever else needs to be done (which varies among different computing
platforms) to generate an executable file. On such a small program fle as this frst
exammple, FreePascal does its work almost instantaneously. You’ll perceive very little
60 FreePascal from Square One, Volume 1

delay at all. And you’ll have to forgive me, but I slipped a minor error into the Pascal
file as I printed it on page 56. If you typed the code in exactly as shown, FreePascal will
post an error message in the Lazarus Messages window. (This is the slender window
below the Source Editor window.) Your screen will then look like Figure 2.9.

Figure 2.9. A FreePascal compiler error message.

Spotting and fixing compile-time errors


This is what we call a compile-time error, because it turns up during the compilation
process. (Runtime errors appear when you actually run your program.) It’s a very
common one, not only for newcomers to Pascal but for us old-timers as well.
Missing semicolons, like the poor, always seem to be with us. There’s a science to
semicolon placement, which I’ll take up in detail later on in Section X.X. Trust me
this time: I should have placed a semicolon at the end of the line GotoXY(10,5).
Notice from the error message that the compiler is giving you a hint, but also that
it’s not telling you exactly where the semicolon is supposed to go. The compiler is
smart, but it has limitations. One of these is that it will point out an error not where
the error actually is, but where the compiler frst noticed that there was an error.
The Nature of Software Development 61

It’s a little like the situation you find yourself in when you go out after supper to
fill your gas tank and forget your wallet. You made a mistake when you failed to put
your wallet back in your pocket when you changed pants after work. But you only
notice the mistake when you’ve pumped a tank full of gas and reach for your credit
cards. Whoops...
I make the point here because a lot of people assume that FreePascal not only
discovers errors but points out where those errors are. Not true—it can only tell
you where it frst noticed that something was wrong. Keep that in mind as you
struggle through your first few error-rich sessions with FreePascal!
Repairing this particular error is easy. Place the text cursor atthe end of the
GotoXY(10,5) line, and type a semicolon there. Click the Save icon (the diskette)
to save the change. Then select Run | Build again.
Or, if you think there may be still more compile-time errors lurking in your
Pascal code, select Run | Quick Compile. This option is different from Build in that
it only compiles the source code file currently loaded in the Source Editor window.
When you’re working on a large, multi-file project, Build will take more time. If
you’re simply checking the current source code file for errors, Quick Compile will
do the job faster. (For small files like this you won’t see much difference.)
Lazarus doesn’t blow a trumpet or pop up a special window when a build
completes successfully. All you’ll see is the following message in the Messages
window, in very small type:

Project “EatAtJoes” successfully built. :)

Running your program


When you see the message above, the compile pass was correct, the build was
accomplished, and you’ve now got an executable code file out there somewhere,
waiting to be run. You don’t technically have to know where it is, or even what its
name is. The name is easy, though: EatAtJoes.exe. The executable version of a Pascal
program created with Lazarus and FreePascal is the same as the project name, but
with .exe as the file extension rather than .lpr.
Executing your programs is also simple: Click the right-pointing green
arrowhead in the second row of icons in the main Lazarus menu bar. (For most
platforms, hover the mouse pointer over the arrowhead icon and you’ll see “Run”
in flyover help .) Your program will be executed, and our backhanded advertising
slogan will be displayed in a console window. The slogan will remain on the screen
as long as you choose to leave it there. To end program execution and return to
Lazarus, press the Enter key.
62 FreePascal from Square One, Volume 1

The arrowhead icon in the main menu bar isn’t the only way to execute your
program. You can also select Run | Run, or simply press the F9 shortcut key. Note
also that to run, your program does not require Lazarus or FreePascal at all. In your
working directory (or wherever you saved the EatAtJoes project) you’ll find a file
called EatAtJoes.exe. This is a complete and independent executable file, and you
can run it by naming it on a console window command line, or by double-clicking
on it in Windows Explorer. (Other graphical environments may have their own
ways of executing standalone .exe files.)
An interesting point to be made here is that FreePascal, Lazarus, and the
EatAtJoes program you’ve just successfully run are all native code programs,
conceptually identical and pretty much equal in the eyes of the computer itself. The
programs you’re writing are not “toy” programs by nature nor are they crippled in
any way. (They’re just small—for now.) You could theoretically write something as
complex as—or even more complex than—FreePascal itself. This is definitely big-
time programming. Don’t let anyone tell you otherwise.
When the program that you ran finishes its execution, it immediately hands the
baton back to the Lazarus environment. You can then continue the development
cycle of write code, save, build, and run.

2.5. Recapping development basics


As you might imagine, what you’ve just seen barely scratches the surface of what
FreePascal and Lazarus can do. But for the frst few small programs you’ll write with
FreePascal, that’s just about all you really need to know about it. The mechanics of
elementary FreePascal development come down to this:
1. Create a new project. Enter your source code into the Source Editor
window, expanding the skeleton file that Lazarus creates when it creates a
new project.
2. Save your project (which saves your source code) under a new,
meaningful name by selecting the Project | Save Project As... menu option.
It’s a good idea to save a new project before you’ve typed more than a
screen full of source code—and save it often (by using the Ctrl-S shortcut
key or clicking the Save icon) after you’ve saved it that frst time.
3. Build the project using the Run | Build menu option. The build process
identifes any compile-time errors in your source code files. If no errors
appear during a compile, your program is compilable and correct. (This
doesn’t mean it has no bugs!) You can also build the project using the Ctrl-
F9 shortcut key.
The Nature of Software Development 63

4. Test your new program by clicking on the green arrowhead Run icon, or
by selecting the Run | Run menu option. You can also run your program
using shortcut key F9.
Here are a few other points worth remembering:
• As much as you might be tempted to do otherwise, spend some time
designing your program before you begin to write actual program code in
the FreePascal IDE editor. We’ll talk more about program design later on.
• Character case does not matter. BEGIN and begin are exactly the same!
• Text shown in bright red in the Source Editor window are instructions
to the compiler, not Pascal code! Lazarus generates some of these
instructions automatically, and as you become more of an expert and
write more complicated programs, you may find it necessary to add some
to the project yourself.
• When a problem comes up during compilation, it’s called an error. When
a problem comes up during your actual testing of a program that has
compiled correctly, it’s called a bug. The compiler will give you some
hints when it discovers an error. But you’re pretty much on your own to
identify and correct bugs.
Finally, this would be a good time to go back and take one more look at
EatAtJoes.pas. It’s a series of steps bracketed between the two words BEGIN and
END. In this simple program, these steps should be close to self-explanatory, even
thought you may never have looked at a single line of Pascal code before.
The line USES Crt simply tells FreePascal to use a library named Crt. We’ll
talk about using code libraries later on in this book.The only other line that might
have you (as a beginner) squinting hard is the last program step: Readln. That’s the
step that waits for you to press the Enter key so that the program can terminate its
execution and give control of the console window back to FreePascal. As with all of
the fundamental elements of FreePascal code, we’ll return to Readln in more detail
later in this book.

Closing in on Pascal the language


The main purpose of this chapter has been to get you comfortable with the idea
of creating real, runnable programs in the FreePascal fashion. EatAtJoes is a pretty
pointless program, but it’s also obvious what it does and how it works. You’ve
begun your (long) journey into programmer country, but it is a long journey. Our
next step is to look at the map of the territory from a height.
64 FreePascal from Square One, Volume 1
Chapter 3.
The Secret Word
Is “Structure”

O K. Do you want to build a shed? Or do you want to build a cathedral? With


FreePascal (or with most any programming language, actually), the choice is
yours. And the difference (far more than simply scale, since there can be mighty big
shacks and mighty small cathedrals) is solely a matter of structure.
You may have heard this before. It’s been said many times, and (far too often)
said badly. People very often lose track of the difference between small-scale
knowledge and big-picture knowledge, and the corollary difference between
small-scale quality and big-time mess. You can perfectly memorize the usage
of every single reserved word, operator, and predefined identifier in FreePascal,
and still not have the least clue as to how to write a program with any hint of
quality. Smearing individual statements around on the screen can be fun, and
such smearings can actually compile and (sometimes) run, but hey, how much
fingerpainting hangs in the Louvre?
In this chapter, I’m going to provide a sort of “view from a height” of FreePascal
program structure. Along the way, you’ll pick up some of the fundamentals of
defining and using variables, as well as some of the simpler operators and standard
functions. It’s tough to explain structure when you haven’t yet explained the
boards, bolts and girders from which the structure is made!
Note also that almost everything I explain in this chapter is true of almost any
dialect of Pascal you’ll ever see. What we’re exploring is the fundamental nature of
the language itself, quite apart from any individual implementation. Pascal is about
organizing complexity into comprehensible form. Keep that in mind. If you don’t, you
might as well work in mud-pie languages like C and C++.

3.1. Taking it subsystem by subsystem


Way, way, way back in 1974, I walked out of university into the thick of a recession,
having a degree in English, a 1968 Chevelle, and precious little else. English majors
rarely get any respect (you have to be an English lieutenant colonel for that to

65
66 FreePascal from Square One, Volume 1

happen, I’ve heard) so to keep the blood pumping and the gas tank full I got a job as
a Xerox machine repairman.
And I’ll never forget the horrible sinking feeling in my guts the first time I saw
a Xerox copier with its panels off, merrily making copies. There were gears and
drums turning, cams flipping, relays clicking, little claws grabbing a document and
dragging it through a maze of harsh green fluorescent lights, past crackling high-
voltage corotron wires, under a grimy, grinding developer housing, and ultimtely
dropping it into a stainless-steel paper chute.
The instructor must have seen the expression on my face. He snorted through
his bushy mustache and said, “Hey, Jeff, don’t panic! It’s only a copier. Just take it
subsystem by subsystem.”
He was right, of course.
It’s easy to fall into despair the first time you try to make sense of a programming
language. There’s five times the complexity of that gross little Model 660
electromechanical copier, and each and every detail must be exactly right, or nothing
is accomplished but the wholesale tearing of hair.
So do what I did, and take it subsystem by subsystem.

The way to wrestle with complexity


I learned how to fix Xerox machines in record time, and spent the next couple of
years wandering around downtown Chicago, keeping the paper pumping. But in
learning how to fix Xerox machines, I learned something far more important: How
to deal with complexity.
Inside almost any complicated concept (assuming that the concept makes any
sense at all) there is something vitally important: Structure. The way to understand
anything complicated is to develop an eye that sees the structure in complexity, and
then to develop a set of selective blinders that allows you to focus in on one element
of that structure at a time.
Structure exists in layers, like an onion, and beneath one layer of structure may
exist several more, each (in its turn) composed of still more layers.
Start at the very top. Examine one layer at a time. Understand the “big picture”
of that one layer only, looking neither higher, to the larger principles, nor smaller, to
the component details. Only when you have that layer under your belt do you delve
into its component layers, and so on.
You’ll find that the Pascal language is wonderfully structured, which makes it
relatively easy to grasp once you have your “structure eyes.”
The Secret Word Is "Structure" 67

Pascal (like Gaul) is divided into three parts


Every Pascal program can be seen as having no more than three separate parts (I
won’t call them subsystems; parts is parts!) that can be studied separately:
• Constant and data definitions;
• Procedure and function definitions; and
• The main block
Very tiny programs may get away without any procedures or functions
(EatAtJoes.PAS from the last chapter had none) and totally trivial programs may not
define any data. All programs, however, must have a main block, and all genuinely
useful programs will have all three parts.
Let’s take a look at them, one by one.

3.2. The main block


The little demo program EatAtJoes.PAS we compiled in the last chapter has a main
block. It’s all main block, in fact. The main block is the portion of the program
delimited between the words BEGIN and END. Here’s the main block from
EatAtJoes.PAS:

BEGIN
ClrScr;
GotoXY(15,11);
Writeln(‘Eat at Joe’’s!’);
GotoXY(15,12);
Writeln(‘Ten Million Flies Can’’t ALL Be Wrong!’);
Readln;
END.

BEGIN and END are what we call reserved words. They have special meanings to
the FreePascal compiler and you can’t use them for anything else. I’ll have more
to say about reserved words a little later, when we get into the detailed view of the
Pascal language. They are the “framing members” of a Pascal program—the logical
2 X 4s that give a program its structure. They define its shape, and control the way
execution flows within a program.
In this book, reserved words will always be printed entirely in upper-case
characters, as BEGIN, END, WHILE, RECORD, and so on. (Additionally, all
program identifiers of any kind will be printed in bold in the body text of the book.)
In Pascal, character case is not significant for reserved words and other identifiers
like the names of variables, so some people write them in lower case. That’s fine;
68 FreePascal from Square One, Volume 1

FreePascal considers BEGIN and begin to be precisely the same. I like to place
reserved words in capital letters so that they stand out—it helps you take in the
overall structure of a program quickly and easily. Reserved words and variables
are not the same thing—not even close, in fact—so making them look different is
actually a very good thing.

Statements
Between BEGIN and END are six lines, each of which is a step in the program’s
execution. When a program begins running, the first step in the main block
executes, (here, ClrScr) and then the second, and then the third, and so on, until the
last step in the main block is executed. Program execution is then finished, and the
program stops running.
Each one of those steps is called a statement. The single word ClrScr is a statement,
as is the more complicated line Writeln('Eat at Joe''s!').
Note carefully here that statements and lines are very different things. (Beginners often
confuse them, with predictably bad results.) A statement may exist all by itself on a
single line. A statement may occupy more than one line. More than one statement
may exist on a single line. The key is that statements are separated by semicolons.
Semicolons don’t end lines. They separate statements. This means that you can
have a perfectly legal line like the following:

ClrScr; GotoXY(15,11);

Here there are two statements on one line, with a semicolon after the first to act
as a separator. There is a semicolon after the second as well, but that semicolon
separates the statement GotoXY(15,11) from whatever statement begins the next
line. More on this a little later.
The statements in EatAtJoes.PAS are simple and easy to dope out by reading
them and by watching what the program does. ClrScr clears the screen. GotoXY
moves the cursor to an X,Y position on the screen. Think of your CRT screen as a
Cartesian grid like the ones you worked with in high school math. The X (across)
value comes first, followed by the Y (down) value. The upper left corner of the
screen is the origin, 1,1. Saying GotoXY(15,11) moves the cursor 15 positions
across, and 11 positions down. Writeln writes a line of text to the screen, starting
at the cursor position.
There is always a period after the END of the main block of a Pascal program.
The period indicates that the fat lady has indeed sung, and that the program is over.
Control leaves the Pascal program and returns to the operating system.
The Secret Word Is "Structure" 69

Compound statements
I’ll have a great deal more to say about statements later on in this book. It’s
important to note that, in a Pascal sense, the whole main block of the program is
itself a compound statement. In most cases, a compound statement is some number of
statements delimited by a BEGIN and END reserved word. There are a couple of
instances where a compound statement may be framed by other reserved words,
like REPEAT and UNTIL rather than BEGIN and END. We’ll deal with these
special cases later on.
It might help to characterize the main block by considering it to be a collective
statement that indicates the larger, single purpose that the program as a whole was
designed to accomplish. Just as a sentence in the English language is a statement
made of words followed by a period, so the main block in Pascal is a compound
statement made of statements followed by a period. This compound statement
summarizes the program’s larger purpose, and by reading the main block of a Pascal
program first, you should be able to garner the big picture of what the program is
supposed to do.
Compound statements appear in many other parts of the Pascal language.
You’ll be tripping over them wherever you go. When you see one in a program,
ask yourself what the unifying purpose of the compound statement is. It’ll help
you refine your “structure vision” and help you focus on just that one part of the
program as a whole.

3.3. Variable definitions


EatAtJoes.PAS has no data at all. It’s a dumb billboard, and not especially interesting
as a program. Real programs do significant work for us by storing and manipulating
data. Another major component of any program, therefore, is a set of definitions
that dictate how much data we’re using in a program and how we can use it.
Since EatAtJoes.PAS lacks data, we’re going to have to come up with a new
program to demonstrate some data-bashing. One begins on the following page.
Read it over, and see if you can work out the general sense of what it does based on
what you’ve already learned about the Pascal language. Pascal, for the most part,
“talks straight” and tries not to be cryptic. That said, comments—explanatory text
enclosed in curly brackets—are essential and something that you as a programmer
should use to clarify what each individual line of code means.
70 FreePascal from Square One, Volume 1

1 {--------------------------------------------------------------}
2 { Aliens }
3 { }
4 { by Jeff Duntemann }
5 { FreePascal V2.2.0 }
6 { Last update 2/8/2008 }
7 { }
8 { From: FREEPASCAL FROM SQUARE ONE by Jeff Duntemann }
9 {--------------------------------------------------------------}
10
11 PROGRAM Aliens;
12
13 USES Crt; { For ClrScr, Random, and Randomize }
14
15 CONST
16 MaxLength = 9; { The longest name we’ll try to generate }
17 MinLength = 2; { The shortest name we’ll try to generate }
18 LastLetter = 122; { Lower-case ‘z’ in the ASCII symbol set }
19
20 TYPE
21 NameString = STRING[MaxLength]; { Waste no space in our strings! }
22
23 VAR
24 Printables : SET OF Char; { Holds the set of printable letters }
25 I,J : Integer; { General-purpose counter variables }
26 NameLength : Integer; { Holds the length of each name }
27 NameChar : Char; { Holds a randomly-selected character }
28 NamesWanted : Integer; { Holds the number of names we want }
29 CurrentName : NameString; { Holds the name we’re working on }
30
31 BEGIN
32 Randomize; { Seed the random number generator }
33 Printables := [‘A’..’Z’,’a’..’z’]; { Only printable letters! }
34 ClrScr;
35 Write(‘How many alien names do you want? (1-10): ‘);
36 Readln(NamesWanted); { Answer the question }
37
38 FOR I := 1 TO NamesWanted DO
39 BEGIN
40 CurrentName := ‘’; { Start with an empty name }
41
42 REPEAT
43 NameLength := Random(MaxLength); { Pick length for this name }
44 UNTIL NameLength > MinLength;
45
46 FOR J := 1 TO NameLength DO { Pick a letter: }
47 BEGIN
48 REPEAT { Keep picking letters until one is printable: }
49 NameChar := Chr(Random(LastLetter));
50 UNTIL NameChar IN Printables;
The Secret Word Is "Structure" 71

51 CurrentName := CurrentName + NameChar; { Add to the name }


52 END;
53 Writeln(CurrentName); { Finally, display the completed name }
54 END;
55 Readln; { Pause until Enter hit so you can see the names }
56 END.

Don’t panic!
I mean that. You’re not going to be tested on the full details of how the Aliens
program works at this point, so don’t worry about digesting it whole and in every
last little detail. It’s a complete Pascal program that even does something interesting,
and I’ll be talking about it for a while in this chapter, explaining most of its workings
as I do. So follow along as we go, and don’t fret not knowing the details of character
sets or the REPEAT..UNTIL statement right now. All in good time. Remember,
we’re going for the big picture here. The details will crystallize out in the chapters
to come.

Solving an SF writer’s problem


The Aliens program does a job for SF writers like myself who are too lazy to come
up with imaginative names for the seventeen-eyed wonders who haunt the starlanes
in bad space wars novels. It’s a very simple program; if you have the listing typed in
already or have obtained the listings archive for this book, I’d suggest that you load,
compile, and run Aliens.PAS right now.
Aliens asks you a question: How many alien names do you want? It then waits
for you to type in a number from 1 to 10 and then press Enter. At that point, it will
produce the exact number of names you asked for by almost literally pulling letters
out of a hat and stringing them together. As each name is completed, Aliens will
display that name on the screen. This happens so quickly that all the names will
seem to appear instantly.

Zeroing in on data definitions


That’s what Aliens does. Now let’s take a look at some of its machinery. We’re
currently focusing on the data definitions part of a Pascal program. Although there
is some flexibility about where the data definition part of a program goes, most of
the time you’ll have to place your definitions at the very beginning of a program.
The data definitions in Aliens.PAS are shown by themselves on the next page:
72 FreePascal from Square One, Volume 1

CONST
MaxLength = 9; { The longest name we’ll try to generate }
MinLength = 2; { The shortest name we’ll try to generate }
LastLetter = 122; { Lower-case ‘z’ in the ASCII symbol set }

TYPE
NameString = STRING[MaxLength]; { Waste no space in our strings! }
CharSet = SET OF Char; { To weed out odd symbols }

VAR
Printables : SET OF Char; { Holds the set of printable letters }
I,J : Integer; { General-purpose counter variables }
NameLength : Integer; { Holds the length of each name }
NameChar : Char; { Holds a randomly-selected character }
NamesWanted : Integer; { Holds the number of names we want }
CurrentName : NameString; { Holds the name we’re working on }

The data definition part of a Pascal program is almost literally a set of blueprints
for the data that the program will be using during its execution. The Pascal compiler
reads the definitions and sets up a little reference table for itself that it uses while it
converts your source code file to a unit file or an executable program file. This
reference table allows the Turbo Pascal compiler to tell you when something you’re
trying to write as part of a program is bad practice or nonsensical.

Variables as buckets
Variables are defined after the VAR reserved word. Think of variables as buckets
into which data values may be placed. In variable definitions, you declare the name
of a variable followed by its type. The name and the type are separated by a colon.
Variables—like buckets—come in a great many shapes and sizes. The type of a
variable indicates how large the bucket is and what sorts of stuff you can safely put in
it. A plastic water bucket will carry water handily—but don’t try to lug molten lead
in it. A colander can be thought of as a bucket suitable for carrying meatballs—but
don’t expect to use it to hold flour or tomato juice without making a mess.
The notion of types in Pascal exists precisely to keep you from making certain
kinds of messes.
In Aliens, there’s a variable called NameLength. Its type is Integer, which is
a signed whole number from -32,678 to 32,767. NameLength is thus a bucket
for carrying numeric values falling in that range that don’t have a decimal part.
Similarly, NameChar is a Char variable, meaning it is intended to hold character
values like ‘A’ or ‘*’.
The Secret Word Is "Structure" 73

Types as blueprints for buckets


So what happens if you try to place a number like 17,234 in a Char variable? You
can’t—the FreePascal compiler won’t let you. The two types aren’t compatible, so
you’ll get an error at compile time if you try to load an Integer value into a Char
variable, or vise versa.
Where do types come from? Some of them are built right into FreePascal and
are always available. Integer and Char are two such types, and there are numerous
others. On the other hand, Pascal allows you define your own types, and then create
variables with those new, programmer-defined types.
Aliens.PAS contains an example. Notice the statement immediately after the
TYPE reserved word:

NameString = STRING[MaxLength]; { Waste no space in our strings! }

This is a type definition. It defines a type called NameString. This type is a string
type—meaning that it’s designed to contain data in alphanumeric strings of
characters like ‘I am an American, Chicago-born’ or ‘THX1138’. FreePascal strings
come in all sizes from 1 character to 255 characters and you can create a string type
in any size within that range. That’s what the type definition statement in Aliens
does: It creates a string type with a length given by a constant named MaxLength.
(We’ll get back to MaxLength and what it is shortly. For now, just assume it’s a
number—or look a few lines back to see how it’s defined!)
NameString is a very simple type. You can create much, much more complex
types in FreePascal, as I’ll explain later in this book. It’s easy to see how a type is in
fact a blueprint for making buckets, in that it defines what sort of data some new
kind of bucket is meant to contain.
Then, when you actually need a bucket of this new type, you can make one in the
VAR section:

CurrentName : NameString; { Holds the name we’re working on }

This statement gives you a variable in memory that contains string data. The name
of the variable is CurrentName. The length of the string is given by the MaxLength
constant.
Remember: A type is not a variable and holds no data. It’s simply a spec or
template that allows you to create variables with a specified size and set of attributes
and uses. Use the TYPE reserved word to create blueprints for buckets—and then
use VAR to create the buckets themselves.
74 FreePascal from Square One, Volume 1

Constants as names for data values


So what, then, is MaxLength? It’s a constant, which in Pascal is simply a way of
giving a name to a data value. Long before you ever knew what programming was,
you were using constants. You learned that the number 3.14159 (approximately) is
called “Pi.” If you took a little more math, you learned that a constant named “e”
(the base of the natural logarithms) was equal to about 2.71828.
The actual values of constants are hard to remember unless you use them all day,
every day. I had to look up the value of e just now, even though I know what it is and
have used it many times in my life. I just haven’t used it often enough to remember
it.
Constants serve a very similar purpose in programming: They allow you to give
a descriptive name to a data value that might otherwise be hard to recall accurately.
Constants have an even more important job, however: They allow you to specify
a value once, at the top of your program, and then use that value any number of
times anywhere else in the program. Later on, if you want to change that value for
some reason, you change it in one place only—in the statement where you defined
it—rather than having to hunt down dozens or hundreds of uses of the literal value
in what might be a very big source code file.
MaxLength is defined in ALIENS as being 9, which is a nice maximum length
for an unpronounceable name. (Hkrepats has no trouble pronouncing his name,
but we both might stumble on jhuuTDplb.) We could have defined MaxLength as
20, and gotten much longer alien names, or 5, and gotten much shorter ones.
Because we only use MaxLength once in ALIENS, it’s not as obvious how useful
constants are as centrally-located definitions for widely-used values. But there is a
predefined constant in FreePascal called Pi, which you can use anywhere you want
instead of the literal value 3.14159. Later on, you can pretend to be the Tennessee
Legislature and declare Pi equal to 3.0. None of your math will work out, but it’s a
great insight into the minds (if one could call them that) of politicians.
Be careful not to confuse constants and variables. A variable is a bucket; that is,
a container for values. A constant is a value with a name. You can call the numeric
value 42 “Ralph” and then put “Ralph” in a bucket. But what the bucket then
contains is the number 42. The name “Ralph” is used only to drop the value 42 into
the bucket. This will become more clear once you do it a few times.

Loading up your buckets


A variable, once defined, is an empty bucket. It contains no value until you give it
one—though it may acquire a value by accident, as I’ll explain later on. Accidental
The Secret Word Is "Structure" 75

values are not predictable, and can cause many kinds of trouble. Better by far to give
every variable a value early on, before it finds one on its own!
You can give a variable a value in several ways, but the most straightforward way
is through an assignment statement. An assignment statement takes a value and assigns
that value to a variable. In effect, it takes the value and “loads it into” that variable, as
though dropping something into a bucket. Here’s a simple assignment statement:

Repetitions := 141;

What we’ve done here is taken the numeric value 141 and dropped it into
the variable Repetitions. The two character sequence := is called the assignment
operator. When FreePascal sees the assignment operator, it takes whatever is on the
right side of the operator and drops it into whatever is on the left side.
Here’s an assignment statement from Aliens.PAS:

CurrentName := '';

What it does is drop an empty string (that is, a string containing no characters) into
the variable CurrentName. (A string with something in it would look like this:
‘Jeff’) It may seem odd to think of dropping an empty value into a bucket, so you
might consider this a way of emptying the bucket of anything else that might have
already been there.

3.4. Procedures and functions


Compared to EatAtJoes.PAS, Aliens.PAS is a considerably larger program. The main
block in ALIENS.PAS is 26 lines long. Still manageable—but what happens when
you want to write a program that does something genuinely useful? It might take
hundreds of lines to write even a fairly simple utility, or easily thousands or tens of
thousands of lines to write something like a custom database program to handle
sales leads or invoice mail-order sales.
The secret, again, is structure. And without question, the most powerful tools
for structuring your programs are procedures and the slightly special-purpose
procedures called functions.
The whole idea in creating a procedure or a function is to gather together a
sequence of related statements, and give them a new, descriptive name. Then later,
when you need to execute that sequence of statements, you need only execute the
name of the procedure, as though it were a single statement that did everything you
wanted done by the group of statements hiding “inside” the procedure.
76 FreePascal from Square One, Volume 1

As easy as brushing your teeth


This sounds hairier than it is. Consider this business of brushing your teeth. You get
up in the morning, and as you shake the cobwebs out of one ear or the other, you
remind yourself that you can’t go to work this time without brushing your teeth.
So brushing your teeth is one single activity. Or is it? Watch yourself as you do it,
and take note of the steps involved:

Pick up the toothpaste tube.


Twist off the cap.
Pick up your toothbrush in your other hand.
Squeeze some toothpaste onto your toothbrush.
Sprinkle a little water on the toothbrush.
Put the toothbrush into your mouth.
Repeat:
Work the toothbrush up and down
...until your mind starts to wander.
Rinse off your toothbrush.
Pick up your Flintstones cup.
Fill it with water.
Take a mouthful of water.
Swill it around.
Spit it out.

Taken as the sum of its individual steps, brushing your teeth is a real mouthful.
When you actually get down and do it, you run faithfully through each of those
steps, and if you ever had to tell somebody how to do it, you could. But when you’re
trying to impose some order on your morning, the whole shebang shows up in
your mind under the single descriptive term, “brushing your teeth.”

Statements inside statements inside compound statements


Inside the term “brushing your teeth” are thus some number of other terms, in a
certain order. You think of the single term “brushing you teeth” to avoid cluttering
your mind with a multitude of piddly little details.
A procedure is the same thing, for the same reasons, and works much the same
way. You gather together some number of Pascal statements, and then hide them
The Secret Word Is "Structure" 77

behind a single identifier of your own choosing. You can execute the new identifier
as though it were a single statement, masking the complexity represented by the
original sequence of Pascal statements.
Suppose you have these three statements in a Pascal program:

DoThis;
DoThat;
DoTOther;

Taken together, these three statements accomplish something. Let’s call that
something “grobbling.” (It’s a made-up word. Don’t read anything into it.) We could
say that the following compound statement represents what must be done in order
to grobble:

BEGIN
DoThis;
DoThat;
DoTOther;
END;

We can hide this compound statement behind a single statement, which we’ll
call Grobble—so that any time we need to execute those three statements together,
we only have to execute this single statement:

Grobble;

Doing it is fairly easy. We mostly need to provide a name to the compound


statement shown above:

PROCEDURE Grobble;

BEGIN
DoThis;
DoThat;
DoTOther;
END;

What we have here are statements within a compound statement, within a


procedure—which itself may be used as a kind of statement.

An adventure in structuring
To make it all click, let’s do it, right now, to Aliens.pas. This is a slightly advanced
exercise, and if you’ve never written a line of program code before some of it may
78 FreePascal from Square One, Volume 1

puzzle you. Bear with me—and have faith that all will be explained in good time.
One of the things that Aliens has to do is choose a length for any given alien
name. It does this by “pulling” random numbers repeatedly until it pulls a random
number within a specified range. This range is the range from MinLength to
MaxLength, both of which are defined as constants, and in this case are equivalent
to the range 2 through 9.
The code that pulls a random length within those two boundaries is this:

REPEAT
NameLength := Random(MaxLength); { Pick a length for this name }
UNTIL NameLength > MinLength;

FreePascal contains a built-in library function called Random that returns a


random number less than the number contained in the parameter that you pass to
it. The parameter is the literal value or variable enclosed in parentheses immediately
after the name Random. That is, calling the function Random(9) will return a
random number value between 0 and 9. This value can then be assigned to some
other variable (in our case, NameLength) for safekeeping. (A function, in case you’re
not yet familiar with the term, is a procedure that returns a value, which may then
be assigned to a variable or used in other ways. More on this very shortly.)
The three lines shown above repeatedly get a random number and test it, to
make sure it’s greater than MinLength. The Random function itself guarantees
that the value it returns will be no larger than its parameter; that is, the constant
MaxLength that the Random function holds within its parentheses.

Creating a function
Random numbers are useful things, and it’s even more useful to be able to specify
a range of values within which a random number is to be pulled. It would be nice
to have a procedure of some sort that would pull a random number for us without
our having to remember all the precise details of how it was done. We could call the
procedure Pull, and it would be a sort of number-generating machine. We would
pass it a minimum value and a maximum value, and Pull would somehow return a
value for us that fell within those two bounds.
As I said a little earlier, in Pascal, a function is a procedure that returns a value.
I’ll have much more to say about functions and how they’re used later in this book,
but it cooks down to that. To illustrate, suppose we had a numeric variable called
NumberBucket. We could define a function called Pull, and it would be Pull’s job
to generate a random number. To fill NumberBucket with a brand-new random
number, we would use this statement:
The Secret Word Is "Structure" 79

NumberBucket := Pull;

Although it may look like one, Pull is neither a constant nor a variable. It’s actually a
compound statement masquerading as a single value. The value is computed within
the compound statement, and then returned “through” the name of the function.
With that in mind, let’s create the Pull function from the three lines in Aliens
that pull a random length for alien names:

FUNCTION Pull(MinValue,MaxValue : Integer) : Integer;

VAR I : Integer;

BEGIN
REPEAT
I := Random(MaxValue); { Pick a length for this name }
UNTIL I >= MinValue;
Pull := I;
END;

Things have changed a little—but for a reason, as I’ll explain. The central portion of
Pull does the same thing that the three lines we lifted from the Aliens program did.
What we’ve mostly added is framework; a body for the lines to exist in.
But we’ve also added a strong measure of generality. The lines that pull a random
name length within Aliens can be used only to pull a random name length. The new
Pull function can be used to pull random numbers within a specified range for any
reason. We could use it just as easily in a dice game as in an alien name generator—
and that’s a big, big advantage.
We can use Pull in Aliens.pas. Just insert the definition for Pull in the program
file just before the beginning of the main block, and then replace the three lines that
pull a random name length with the following single line:

NameLength := Pull(MinLength,MaxLength);

The two items named MinLength and MaxLength are called parameters. They’re
special-purpose variables belonging to the function that work as pipelines,
allowing you to drop values into the function. Drop a “7” value into MaxLength,
and the Pull function’s internal machinery will receive the value 7 as the maximum
allowable value for the random number it’s been told to generate.
The altered copy of Aliens.pas(let’s call it Aliens2.pas) is shown on the next page,
with the Pull function replacing the three lines used to pull random numbers in the
original Aliens.pas.
80 FreePascal from Square One, Volume 1

1 {--------------------------------------------------------------}
2 { Aliens2 }
3 { }
4 { by Jeff Duntemann }
5 { FreePascal V2.2.0 }
6 { Last update 2/8/2008 }
7 { }
8 { From: FREEPASCAL FROM SQUARE ONE by Jeff Duntemann }
9 {--------------------------------------------------------------}
10
11
12 PROGRAM Aliens2;
13
14 USES Crt; { For ClrScr, Random, and Randomize }
15
16 CONST
17 MaxLength = 9; { The longest name we’ll try to generate }
18 MinLength = 2; { The shortest name we’ll try to generate }
19 LastLetter = 122; { Lower-case ‘z’ in the ASCII symbol set }
20
21 TYPE
22 NameString = STRING[MaxLength]; { Waste no space in our strings! }
23
24 VAR
25 Printables : SET OF Char; { Holds the set of printable letters }
26 I,J : Integer; { General-purpose counter variables }
27 NameLength : Integer; { Holds the length of each name }
28 NameChar : Char; { Holds a randomly-selected character }
29 NamesWanted : Integer; { Holds the number of names we want }
30 CurrentName : NameString; { Holds the name we’re working on }
31
32 FUNCTION Pull(MinValue,MaxValue : Integer) : Integer;
33
34 VAR I : Integer;
35
36 BEGIN
37 REPEAT
38 I := Random(MaxValue); { Pick a length for this name }
39 UNTIL I >= MinValue;
40 Pull := I;
41 END;
42
43
44 BEGIN
45 Printables := [‘A’..’Z’,’a’..’z’];
46 Randomize; { Seed the random number generator }
47 ClrScr;
48
49 Write(‘How many alien names do you want? (1-10): ‘);
The Secret Word Is "Structure" 81

50 Readln(NamesWanted); { Answer the question }


51
52 FOR I := 1 TO NamesWanted DO
53 BEGIN
54 CurrentName := ‘’; { Start with an empty name }
55
56 NameLength := Pull(MinLength,MaxLength); { Pull random length }
57
58 FOR J := 1 TO NameLength DO { Pick a letter: }
59 BEGIN
60 REPEAT { Keep picking letters until one is printable: }
61 NameChar := Chr(Random(LastLetter));
62 UNTIL NameChar IN Printables;
63 CurrentName := CurrentName + NameChar; { Add to the name }
64 END;
65
66 Writeln(CurrentName); { Finally, print the completed name }
67 END;
68 Readln; { Pause until Enter hit so you can see the names }
69 END.

Hiding complexity
The details of having to pull a number again and again until one appears that falls
within a specified range are masked now. We only see the “front door” of the
random number factory. The machinery that actually builds the random numbers
is hidden away behind the door somewhere. And that’s good—because most of the
time we really don’t care how random numbers are made; we only care that they do
get made according to our specifications.
It’s true that creating the Pull function added a few lines to the program. Later
on, we’ll see how we can remove Pull from Aliens2.pas and place it in a library
of functions and procedures called a unit. This library is available to any of your
programs that need it. If ten of your programs need a random-number puller,
you can give a random number puller to all ten of them—and yet have only one
copy of Pull’s ten little lines. If you yank enough general-purpose procedures and
functions out of your programs into libraries, you can actually cut the source code
bulk of your programs considerably.

Organizing programs with procedures


Hiding details is the fundamental purpose of procedures and functions. The little
example given here is not an especially good one, since there aren’t a lot of details
to be hidden in a random-number puller.
82 FreePascal from Square One, Volume 1

But consider a simple accounting program. A good one (even a simple one,
as accounting programs go) might have 10,000 lines of code. You could write all
10,000 lines of code in one enormous main block. But how would you read and
understand those 10,000 lines of code? You’d probably have to do what was done
in the ancient days of programming, and literally cut a long program listing up into
chunks with a scissors, and only look at the chunk you needed to concentrate on at
the moment.
Even War and Peace is divided into chapters—and procedures are often used as
“chapters” in a larger program. In our accounting program example, you would have
several accounting tasks like Payroll, Accounts Payable, Accounts Receivable, General
Ledger, and so on. It’s possible to make each of these accounting tasks a procedure:

PROCEDURE AccountsPayable;

BEGIN
<about 2000 lines>
END;

PROCEDURE AccountsReceivable;

BEGIN
<about 3000 lines>
END;

PROCEDURE Payroll;

BEGIN
<about 2000 lines>
END;

PROCEDURE GeneralLedger;

BEGIN
<about 2200 lines>
END;

Now at least you have a fighting chance. When you need to work on the payroll
portion of your accounting program, you can print out the Payroll procedure and
ignore the rest. All the “payroll-ness” of the accounting program is concentrated
right there in one procedure, so you don’t have to go searching for payroll details
across the entire program. Better still, details that you don’t have to pay attention to
right now remain hidden, inside their respective procedures.
The Secret Word Is "Structure" 83

With your payroll blinders on, you’ll have a much easier time focusing on the
payroll part of the program. The main block becomes quite small then, and is
mostly a little menu manager that lets you choose which of the four big procedures
you want to run.

Procedures within procedures


If you’re perceptive, you may have noticed something else about procedures (and
functions too): They look like little programs. They are little programs, in fact, and
procedures and functions share the same general structure with the “big” Pascal
programs that contain them. This resemblance between Pascal programs and
procedures and functions is reflected in a generic term that encompasses both
procedures and functions: subprograms.
If Pascal programs are divided into three parts, then so are procedures and
functions: They too have constant and data definitions, procedure and function
definitions, and a main block. You may have noticed that the Pull function had a
variable definition in it, for an integer variable named I. The variable I is what we call
a local variable, by which we mean one that belongs inside Pull and never ventures
outside Pull’s “city limits.” Only Pull can see or use the variable I. Procedures and
functions can define any number of local variables and constants for their use, just
as programs can.
But most interestingly, procedures and functions can define and contain their
own local procedures and functions. Just as Pull was inside and thus local to
Aliens2.PAS, you could place a procedure or a function (or several of them) inside
Pull as well. These local procedures and functions would be for Pull’s private use
only; no subprogram outside of Pull could make use of them.
This nesting can go on and on almost without limit: You can place subprograms
within subprograms within subprograms, like those little barrel-shaped Chinese
dolls that fit one inside the other.

3.5. Program structure recap


This chapter has been an overview of program structure, to get you started on
your road to Pascal mastery in the right frame of mind, and with a general method
for finding your way. I’ve touched on a great many topics without going into any
of them especially deeply. In the rest of this book, I’ll begin describing the Pascal
language in detail.
But before getting into a hurricane of details, I wanted to lay the big picture out
in front of you. Let’s recap the big picture.
84 FreePascal from Square One, Volume 1

Pascal programs are divided into three parts


These three parts are data definitions, procedure and function (subprogram)
definitions, and the main block.
Data definitions include constant definitions, type definitions, and variable
definitions. Constant definitions give descriptive names to unchanging values.
The value 3.14159, for example, is often made a constant with the name Pi. Type
definitions define a particular kind of data, and act as blueprints for creating
variables of that kind of data. A type definition defines how large a data type is, and
what sorts of ways it can be used. A variable definition creates a little storage bucket
somewhere for a particular type of data. Think of type definitions as blueprints
for data buckets, and variable definitions as the way the buckets themselves (the
variables) are actually made. Constants, in turn, are one (but only one) method by
which those buckets are filled with data.
The main block is a compound statement, which is a sequence of Pascal
statements between the reserved words BEGIN and END.
Procedures and functions allow groups of Pascal statements to be grouped
together and “hidden” behind a single descriptive name. Using that single name
has the same effect as using each of the individual statements within the procedure
or function. Functions are specialized procedures that return values that may be
assigned to variables in assignment statements. Apart from that, they are identical
to procedures.
Procedures and functions are the primary means of masking complexity in a Pascal
program. The details of a larger program task may be hidden within a procedure
or function, so that your attention to that larger function will not be distracted by
the details. When you need to be concerned with the details, you can examine the
definition of the procedure or function to see how it operates internally.
When you need to see the details, you can. When you don’t, you won’t. Much of
structuring a program is the artful hiding of details.

Procedures and functions (subprograms) are miniature programs


The essential structure of a Pascal program is echoed in the structure of subprograms,
which is in fact why procedures and functions are called subprograms.
Procedures and functions have data definitions and a main block, and
furthermore, they can contain their own local (that is, private) procedures and
functions. This nesting of procedures within procedures has no explicit limits, and
may continue as far as needed. (There is a “too far,” and moderation is a virtue in
Pascal programming as anywhere else.)
The Secret Word Is "Structure" 85

Programs are organized by dividing them up into subprograms


A single monstrous program can be made conceptually manageable by dividing it
up into subprograms. Large subprograms can themselves be made manageable by
dividing them internally into separate, smaller subprograms. By creating a program
in layers in this way, you can focus your attention only on the layer that you need to
see, without distraction either from the big picture at a higher level, or from details
at a lower level.

Take it one subsystem at a time!


Most of all, I want you to remember the lesson of the trainer-man at Xerox: Take it one
subsystem at a time. Being boggled gets you nowhere. Develop your structure-eyes,
and learn to look selectively at a program to see the structure in it, and then either
work to understand that structure (if the program was written by someone else) or
to create that structure (if the program doesn’t exist yet) using the structuring tools
available in FreePascal.
86 FreePascal from Square One, Volume 1
Begin . . . End
Part II:
Installing, Learning,
and Using FreePascal
and Lazarus
4. Installing FreePascal and Lazarus . . . . . . . . . . . . . 89
5. Configuring and Using the Lazarus Environment . . XX

If...Then...Else...
87
88 FreePascal from Square One, Volume 1
d
e
h
is
n
fi
n
U
Is
Chapter 4.
r
te
Installing FreePascal
p
a

and Lazarus
h
C
is
h

O ne of the (few) downsides to free and open-source software is that you can’t
T

cover installation by saying, “Order the product, open the box, and follow the
manufacturer’s instructions.” It’s a little more complex than that, especially when
the product (like FreePascal) can be run on a number of different operating systems
and CPU types. So in this chapter, I’ll explain how to find the downloadable install
suites for FreePascal, how to be sure you have the right one, and then how to install
it for Windows and Linux.

4.1. Platforms and targets


Most of us are used to either buying a software product in a box at a local store, or
else ordering a product (or at least a product install CD) online. FreePascal is different
from a lot of software products in that it exists for a number of different platforms.
A platform is an operating system running on a particular type of hardware. For
example, Microsoft Windows running on 32-bit Intel hardware like the Pentium
is a platform. (It’s probably the commonest platform in the world, and often called
“Wintel.”) But even though the underlying hardware is the same, Ubuntu Linux
running on a 32-bit Intel Pentium CPU is considered a separate platform. Similarly,
the PowerPC CPU is the hardware in many older Apple Mac machines. The OS X
operating system running on a PowerPC CPU is considered still another platform.
And OS X running on an Intel CPU is considered yet another platform.
This is all made trickier by the fact that some operating systems run on multiple
hardware types, and most CPUs can run multiple operating system. So you must be
aware of both the CPU type in your machine, and the operating system you intend
to install FreePascal under.
At this writing (February 2010) installable binary files are available for all the
platforms shown in Table 4.1. They are listed by CPU type, with supported operating
systems listed beneath each CPU type. The name of the downloadable file for each
platform is given in the rightmost column.

89
90 FreePascal from Square One, Volume 1

CPU/Operating System Filename


ARM CPUs
Game Boy Advance arm-gba-fpc-2.4.0.i386-win32-zip
Linux *
Nintendo DS arm-nds-fpc-2.4.0.i386-win32.zip
Windows CE fpc-2.4.0.arm-wince.exe
iPhone fpc-2.4.0.arm-iphone.dmg
Intel i386
DOS (with Go32v2 extender) dos240full.zip
FreeBSD
Linux *
Mac OS X fpc2.4.0.intel-macosx.dmg
Netware
OS/2 os2240full.zip
Windows 32-bit (Win32) fpc-2.4.0.i386-win32.exe
PowerPC
Linux *
Mac OS X fpc-2.4.0.powerpc-macosx.dmg
PowerPC 64-bit
Linux *
Mac OS X
x86-64 (both AMD and Intel)
Linux *
Windows 64-bit fpc2.4.0.x86_64-win64.exe
* Linux file naming is complex; see the
FreePascal Web site.
Table 4.1. Installable binary files for available releases of FreePascal.

Binaries only!
One important point to note is that the installable files listed in Table 5.1 include
only the binary files for the FreePascal compiler, its libraries, and its text-mode IDE.
The source code for FreePascal is available as a separate archive. Using the source
code files, you can recompile FreePascal in itself (which sounds impossible to
newcomers, but it’s true!) and tweak it to run on other operating systems and CPUs.
That, however, is a very advanced topic that I won’t be going into in this book.
Installing FreePascal and Lazarus 91

4.2. The Relationship Between FreePascal and Lazarus


As I explained earlier in this book, FreePascal is a compiler, and Lazarus is an
interactive development environment (IDE). It’s true that Lazarus is more than just
an IDE—it contains a world-class “GUI builder,” as I’ll explain in the next chapter—
but while you’re frst learning FreePascal the IDE features of Lazarus are all you’re
going to need.
Just keep this in mind: FreePascal and Lazarus are two are separate software
projects with separate teams of programmers writing, testing, and debugging them.
FreePascal and Lazarus “cooperate” in many ways, at several levels, so it makes
sense to use them together. The relationship between the two can be summed up
this way:
• Lazarus is a program written in FreePascal.
• Lazarus executes the FreePascal compiler “behind the scenes” to generate
executable code from source code managed from within Lazarus.
Basically, FreePascal can function without Lazarus, but Lazarus cannot function
without FreePascal. You can edit and manage FreePascal source code from other
editors if you want, but none have quite the power of Lazarus, simply because
Lazarus “knows” the Pascal language, and knows it better than any other free
program I’ve yet tested. However, you cannot use other compilers from within
Lazarus. (Yet; it’s been discussed and may happen someday.)

Stable versions vs. development versions


Because FreePascal and Lazarus are two separate software projects, they each have a
separate and independent version number. At this writing (August 2010) FreePascal
is at version 2.4.0. Lazarus is at version 0.9.28.2. These are the “stable” releases; that
is, releases that have been tested extensively and are known to be mostly functional
and largely bug-free. (No software is ever entirely bug-free!)
Both products are open-source, and are maintained by volunteers scattered all
over the world. Because FreePascal and Lazarus are not developed in secret at a
single large software house, intermediate releases are publicly available to anyone
who wants them. These are “development” releases, issued by the programming
teams for testing and debugging purposes, and are really intended for installation
by programmers interested in working on the FreePascal and Lazarus programs
themselves. Development releases are not guaranteed to be stable. They may
contain partially completed features and outright bugs, but that’s what they’re
out there for: to broaden the base of testers who can bring bugs to light and fix
them.
92 FreePascal from Square One, Volume 1

Development releases happen regularly and quite frequently. However,


unless you’re an experienced programmer and interested in compiler internals, I
recommend that you not install development releases of either product. Finding
bugs in your own code is hard enough, especially when you’re a beginner!
The stable versions of both products may be obtained from the FreePascal and
Lazarus Web sites. It’s a good idea to check the sites now and then to see what’s
current. I generally install each new stable version as it appears, because both
products (especially Lazarus) are evolving quickly.

What comes with what


Because Lazarus requires FreePascal to do its work, the downloadable installers
for Lazarus also contain the FreePascal compiler, and when you install Lazarus
you install both. However, the release schedules for FreePascal and Lazarus are not
synchronized. The downloadable installer for the newest stable release of Lazarus
does not necessarily contain the newest stable release of FreePascal. As I write this,
the current Lazarus installer installs FreePascal v2.2.4, rather than the newest stable
release 2.4.0.
This is almost never a problem, especially while you’re still learning the Pascal
language. The features of Pascal that I’ll be teaching in this book haven’t changed much
in a while. Later on, if you’d like to have a development version of Lazarus that installs
the newest stable release of FreePascal, you can get it from the Lazarus Web site.

The text-mode IDE


By default, the FreePascal install wizard will install a program called fp.exe, which
is the text-mode IDE that runs in a console window. You can see what it looks like
by turning back to Figure 2.3. There’s a quirk here: The Lazarus installer installs
FreePascal, but it does not install fp.exe. The logic there is that if you’re going to
install Lazarus, you’re probably not going to use the text-mode IDE.
I deliberately chose not to use the text-mode IDE for the examples in this book because
I’ve had a some bad experience with it, especially when run in a console window under
Windows. Other platforms have worked well for me; e.g., DOS, GNOME, KDE, and
Linux/Unix versions run fp.exe without problems from the console. However, if fp.exe
crashes or comes up with weird display quirks, I don’t have a great deal of advice other
than to use another standalone editor and invoke the compiler from the command line.
Lazarus is a great deal more stable, especially under Windows, and if you’re just learning
the language and are working in Windows or Linux under GNOME or KDE, it’s probably
the easiest way to proceed. Furthermore, if you intend to do full-bore object-oriented
GUI app programming later on, you might as well start learning Lazarus now.
Installing FreePascal and Lazarus 93

FreePascal’s Documentation
When you install FreePascal (all versions, for all platforms) you get a substantial
set of manuals in PDF file format. The files reside in the DOC directory under FPC,
if you installed using the default directory locations. Interestingly the PDF files are
available online, but at this writing, the files installed with the compiler itself are
newer than the ones you can download from the Web.
The available manuals are these:
• The FreePascal User Guide (user.pdf) explains how to install and configure
the compiler and how to invoke it. This includes compiler modes,
compiler error messages, debugging using gdb, and a list of the standard
units installed with the compiler. (The units are not described in detail; for
that see the Runtime Library Reference Guide.) A large part of the file explains
how to use the text-mode IDE, which I won’t be discussing in detail in this
book.
• The FreePascal Programmer’s Guide (prog.pdf) explains programming issues
that go beyond the fundamentals of Standard Pascal. This includes
language extensions, compiler directives, low-level issues like assembly
language interface and external calling conventions.
• The FreePascal Reference Guide (ref.pdf) is a concise description of the Pascal
language as implemented by the FreePascal compiler, including “railroad”
syntax diagrams. The descriptions are terse and should not be considered
tutorial in any sense.
• The Runtime Library Reference Guide (rtl.pdf) describes all of FreePascal’s
standard units in detail, procedure by procedure. If you want to know how
to call the GotoXY procedure, this is where to look, keeping mind that
the descriptions of individual procedures and functions are necessarily
brief and technical. The file is 1,450 pages long.
• The Compiler Switch Summary Chart (chart.pdf) is a two-page document with
a summary of global compiler switches on one page, and local compiler
switches on the other. This can be handy, and the best way to use it is to
print it on both sides of a single sheet of paper and keep it close by while
you program.
• The Free Component Library Reference Guide (fcl.pdf) is a reference for the
FCL object-oriented library that is used for writing component-based
programs, particularly for GUI platforms like Windows and Linux under
one of the graphical shells. The FCL is an advanced topic that I won’t be
covering in this book, so this file won’t be of much use to you in your first
steps as a Pascal programmer.
94 FreePascal from Square One, Volume 1

All the documentation files are PDF files, and if you’ve got a printer capable of
duplexing, it can be useful to print the files and place them in 3-ring or duo-tang
binders. The page size is A4, but the pages will print well if scaled to fit American
Letter-size sheets. The Runtime Library Reference Guide is an immense file, but you
don’t need to print all of it. (Some of the libraries are relatively arcane.) For your
initial learning exercises, print the sections covering the following units: crt and
sysutils.
I did something interesting but very useful: I uploaded the PDF files to the
Lulu.com self-publishing site and ordered printed books for my own use. As a
courtesy to Michaël Van Canneyt and the other authors, I uploaded the files as
provate projects and they are not available to the public. You’ll have to upload
them yourself! It was, however, worthwhile: I ordered the books made with a spiral
binding that lies flat on the desktop or propped on a copy frame.

4.3 Installing FreePascal and Lazarus for Windows


How you install FreePascal depends heavily on what you intend to use for your
working IDE. FreePascal’s text-mode IDE fp.exe is installed by default when you
install FreePascal by itself. As I mentioned earlier, fp.exe is problematic under
Windows, though it has worked very well for me under Linux. When you install
Lazarus you will in the process install FreePascal automatically, because Lazarus
uses FreePascal to compile all of its code in the background. However, when you
install Lazarus, you will not get fp.exe as part of the install.

Installing FreePascal by itself


If for whatever reason you’re not interested in using Lazarus for your IDE, install the
FreePascal compiler package by itself. Begin by downloading the FreePascal installer
file from SourceForge. The main SourceForge page for FreePascal is this:

http://www.freepascal.org/
Once you’re there, definitely poke around! The page will show you news on the
latest releases. If you’re reading this book a long time after I published it (mid-2010)
the latest stable version of FreePascal may not be the one I call out here. To find
the current version, click on the Downloads link, and look for the list of available
binary installers. For 32-bit Windows, click on the Win32 link.
Once the FreePascal Web site hands you off to SourceForge, look frst for a big
green button saying Download Now! Click the button, and the installer fle for 32-bit
Windows will begin coming down. If for some reason the download doesn’t begin
Installing FreePascal and Lazarus 95

Figure 4.1. The Lazarus downloads page on SourceForge.


96 FreePascal from Square One, Volume 1

immediately, click on the direct link just under the title reading, “Your FreePascal
Compiler download will start shortly...”
And just in case you’re a better typist than a hotlink navigator, here’s a shortcut
that goes directly to the installer fle for version 2.4.0:

http://sourceforge.net/projects/freepascal/fles/Win32/2.4.0/fpc-2.4.0.i386-
win32.exe/download
The installer is an ordinary Windows executable file. Close all open Windows
applications and run it, either from the Run window or by navigating to the installer
fle and double-clicking on it. The installer will open a conventional Windows
install wizard. All of the wizard’s felds provide useful default values, so you can
accept all the default values in each one of the wizard’s dialogs. When the wizard
has completed its series of dialogs and terminated, you’ll see a new icon on your
desktop, for the FreePascal IDE.

Watch out for spaces in pathnames!


By default, the FPC wizard installs FreePascal at C:\FPC. This may seem strange at first.
Most people are used to installing Windows apps in the Program Files directory tree,
but remember that even though FreePascal can be run from Windows, FreePascal is
not a Windows GUI app. It’s a console app. I’d recommend leaving FreePascal at C:
\FPC, or perhaps D:\FPC. The reason for this is a little odd: FreePascal may not deal
perfectly with spaces in pathnames. The safest way is to install FreePascal in the
root directory of one of your fxed (not removable) hard drives.
This caution against spaces in pathnames applies more generally, to any
circumstance where FreePascal has to deal with a directory path; say, when you save
projects to a directory. Use dashes or internal capitalization if you must, but don’t
create paths containing space characters if the path will have to be used by FreePascal. There
may be technical reasons why this is the case, but it’s something I consider a bug
and hope will be fixed someday.

Downloading Lazarus for Windows


If you install the Lazarus RAD environment, FreePascal comes in right along
with it. You do not need to install FreePascal before you install Lazarus. As with
FreePascal, there is a Windows installer fle for Lazarus. In short, you download the
installer and run it, accepting or tweaking the values presented by the install wizard
as appropriate.
The Lazarus Web site is actually part of the FreePascal Web site:
Installing FreePascal and Lazarus 97

http://www.lazarus.freepascal.org/
This is the Lazarus “home page” and a good starting point when looking for the
latest on Lazarus. There’s a link to the Downloads section in the left column, which
will take you to the Lazarus download page on SourceForge. Click Downloads,
and (as with FreePascal) locate the big green button once the page loads. (See
Figure 4.1.) If you hover the mouse over the green button, Windows will show
you the full filename that you’re about to download. The string “win32” should be
there somewhere for the 32-bit Windows version. If you’re looking for the 32-bit
Windows installer, just click the green button and the download will begin.
If you want the 64-bit Windows version instead, click the link labeled “View
All Files” to the right of the big green button. This expands the folders list below
the button, and if you scan down the list you will eventually find a folder labeled
“Lazarus Windows 64 bits”. Click the link to expand it. Inside the folder will be
two additional folders. The first contains the current release of Lazarus, and the
second contains all the older releases gathered into a single (very large) archive.
People who have old code originally written for an older version of Lazarus may
need to download past versions of Lazarus, but if you’re just learning FreePascal
and Lazarus, click the folder for the current version. The folder will open to reveal a
link in blue. Click the blue link to begin the download.
While you’re there, it might be a good idea to download the Lazarus documentation.
The documentation folder is right beneath the folder for the 32-bit Windows version,
labeled “Lazarus Documentation.” The documentation fle is available in HTML or as
a Windows .chm help fle. The two files are otherwise identical.

Installing Lazarus and (along with it) FreePascal


As I mentioned earlier, installing Lazarus under Windows is easy. You run the .exe
installer, and answer the wizard’s questions. You can specify the language used by
the product and where it is to be installed. The caution I mentioned earlier about
spaces in pathnames applies to Lazarus as well as Freepascal, so I recommend
letting it install at the default location, which is C:\lazarus. You’re allowed to specify
the file associations recorded by Windows for Lazarus, and unless you have another
compiler or IDE associated with the .pas extension, accept all the defaults.
When the wizard runs its course and exits, you’ll have a new directory, C:\lazarus
by default, and (if you checked the box specifying the creation of a desktop icon) the
blue Lazarus icon on your Windows desktop. FreePascal will be present in its own
directory under C:\lazarus, but it will not get a separate desktop icon, because it is
not a Windows GUI app.
98 FreePascal from Square One, Volume 1

To run Lazarus, just double-click the desktop icon, as with any Windows app.
Note that when you install FreePascal as part of the Lazarus installation, the text-
mode IDE fp.exe will not be installed. If you want to experiment with fp.exe after
installing Lazarus, I suggest installing FreePascal separately. There’s nothing wrong
or hazardous about having two copies of FreePascal installed on a single hard drive,
though the second copy will cost you about 150 MB in disk space.
Installing FreePascal separately under Windows will create a desktop icon for
the text-mode IDE, and you run the IDE by double-clicking on the icon. Keep in
mind that the operation of the IDE can be erratic under Windows, so if it crashes or
looks peculiar, there may not be much you can do about it.
Again, there is much more to Lazarus than you need in order to learn the
fundamentals of the Pascal language, and much more than I’ll be covering in this
first book. I recommend confguring Lazarus to hide the IDE windows that you
won’t need, to keep the clutter down and make the product easier to grasp. I’ll
explain how to do this in Chapter 5.

4.4 Installing FreePascal and Lazarus Under Linux


I’ll have to be honest here: Installing Lazarus under some distributions of Linux
is not as easy as it is under Windows. FreePascal and Lazarus are available from
Open Source software repositories, and most Linux desktop distributions have
mechanisms built into their graphical user interfaces to download and install all
necessary files pretty much automatically. (For example, the Ubuntu Software
Store.)
This sounds great, but there can be problems. There are several different package
formats in common use for Linux, and the Lazarus package for each one is different,
with each maintained by a different team. So if you download and install Lazarus
and FreePascal through a distro package manager, you may not get the same
versions from all repositories in all formats.
At this writing, packages are available in the RPM and Debian formats. Linux
distributions that don’t support either of these formats (and I can’t think of any off
the top of my head) will need to have build Lazarus and FreePascal from source.
Explaining that it beyond the scope of this book, and may change from version
to version as the software evolves. Long-time Linux programmers will probably
know how to do it, and Linux newcomers who want to learn should sniff around
the online forums, particularly the Lazarus forum on the FreePascal Website:

http://www.lazarus.freepascal.org/index.php?action=forum
Installing FreePascal and Lazarus 99

Installing under Fedora 13


Obtaining and installing Lazarus and FreePascal under Fedora 13 is about as easy
as it gets. Fedora uses the RPM package format, and the FreePascal/Lazarus RPM is
well maintained. Installing it is best done with the YUM package manager. If you’re
logged in as root, open a console window and enter this command:

yum install lazarus


If you don’t work as root (and that’s generally a wise policy) you’ll need to use su
to launch yum:

su -c ‘yum install lazarus’


You’ll be asked for your root password. After that, yum takes off and begins
downloading packages and checking dependencies. Once it determines what it
needs to download, it’ll check with you:

Total download size: 85 M


Is this ok [y/n]:
Type “y” to continue. The number of bytes to download will vary based on the
version and what you already have installed. 80-100 MB is typical. How long it takes
to come down will vary depending on the quality of your broadband connection.
On my cable modem system, the whole yum process took about 25 minutes.

Installing under OpenSuse


The OpenSuSE Web site has a marvelous technology called the OpenSuSE Build
Service (OBS), which makes installing Lazarus on OpenSuSE extremely easy. The
search/install page can be found at this URL:

http://software.opensuse.org/search
The OBS is a platform for distribution and installation of open source software.
It uses the YaST installation/configuration manager, and provides “1-click install”
buttons on the search page. Calling it “1-click” is a bit of an exaggeration, but the
big win is that you don’t have to type in the names of any packages or repositories,
enter any scripts, or do any manual unpacking or building. One click kicks off the
process, which launches an installation wizard. Run through the wizard, answer its
questions (which does require a few additional clicks) and YaST will begin installing
the selected package.
Here’s a step-by-step:
100 FreePascal from Square One, Volume 1

Figure 4.2. The OpenSuSE Build Service search page.


1. Go to the OBS search page. (See Figure 4.2.)
2. Type “lazarus” into the search field.
3. Select your distribution from the drop-down list box.
4. Click the Search button.
5. Several search hits will appear. Any of them should work (I haven’t
tried them all) but in my view the best is likely to come from the devel:
languages repository. The repository is shown in the upper right corner of
each search hit summary. (See Figure 4.3.)
6. Find the one from devel:languages. Click on the “1-Click Install” button.
7. An installation wizard will appear. Run through the wizard, changing
anything that needs changing. I was able to keep all the default options.
8. When you’ve reached the last pane of the wizard, click Finish. YaST will
then begin downloading files, checking dependencies, and doing whatever
might be necessary to install Lazarus and FreePascal on your OpenSuSE
system. This will take a while (perhaps 20-25 minutes at most, assuming a
broadband Internet connection) but when it’s done, you’ve got it!

Installing under Ubuntu


As easy as it is to use, Ubuntu’s Software Store (in place since Karmic Koala 9.10) has
some issues with respect to Lazarus. Ubuntu and most other Debian-based distros
use the Debian Package Manager format for software installation. Debian Packages
for a given product install easily through the Store, but they have to be correctly
built and maintained as new releases of the product appoear. The Debian package
for Lazarus has not been well-maintained over the last two years or so. The version
Installing FreePascal and Lazarus 101

Figure 4.2. The Lazarus OBS entry from devel:languages.

of Lazarus and FPC installed are not the latest, and (peculiarly) the FreePascal source
is not included in the package, even though Lazarus requires it. So if you install
Lazarus from one of the Debian packages downloadable at this writing (mid-2010),
Lazarus will complain when you launch it that the FreePascal source code is not
available, and that some of its features (not stated) will not work completely.
This is not the fault of the people who wrote and maintain FreePascal and
Lazarus, because they do not have complete control over how the Debian package
for the product is maintained, which is a separate issue from maintaining the
product itself.
The RPM package, by contrast, is far better maintained and works very well, but
does not install under Debian-based distributions. One solution that I have not yet
tried is to convert the RPM package to a Debian package with a utility called Alien.
This tutorial may be useful:

http://www.howtoforge.com/converting_rpm_to_deb_with_alien
If you expect to be using Lazarus and FreePascal over the long term, you might
be better off using OpenSuSE, because updating Lazarus on Ubuntu as new releases
have been issued has been a bumpy business for me, and far more work than it
needs to be.
102 FreePascal from Square One, Volume 1

4.5. The Virtual Machine Approach to Programming


There’s another way to approach development with FreePascal and Lazarus that
makes a lot of sense if you want to produce and test code for more than one platform:
install them in virtual machines. There’s nothing truly new about virtual machines
(I was using them six or seven years ago) but in case you’re not familiar with them,
the basic idea is this: An installable utility called a virtual machine manager (VMM)
creates a framework called a virtual machine (VM), within which an entire operating
system can be installed. The OS “thinks” that it’s running on an ordinary computer.
But it’s not: The VMM uses various arcane tricks baked into the silicon of modern
Intel-compatible CPUs to establish virtual hard disks (which are actually large files
on your real hard disk) and a virtual memory system, with virtual peripherals like
video adapters, and even a virtual BIOS for the operating system to call into as
needed.

Programming for multiple operating systems on one PC


There are a lot of uses for virtual machines, and this isn’t the place to discuss the
topic in depth. For our purposes in programming Pascal code, here’s the payoff:
You can install multiple operating systems as virtual machines on a Windows PC.
You can have Fedora Linux running in a Windows window, right beside another
window running Ubuntu Linux, and a third running OpenSuSE Linux, or whatever
other Linux distro that interests you. When you don’t need them, you can minimize
them to the taskbar, or “power them down” at the end of the day, just as though they
were physical computers.

Sandboxing software under test


Virtual machines are even useful for installing a virtual copy of Windows on a
Windows machine, for this reason: While you’re testing an ambitious piece of
software that you’re writing, you don’t want your bugs to damage your “real”
Windows installation. If an unfinished Windows app running in a Windows VM
goes berserk and nukes the Registry, your main Windows machine isn’t affected at
all. Only the virtual machine is affected. If you took a “snapshot” of the VM before
you launched your unpredictable app (a feature most VMMs support) you can
“revert” to that snapshot if the app damages something. It’s as though the damage
never happened.
This use of virtual machines is sometimes called “sandboxing” an app under
test. Software running inside a virtual machine is almost completely isolated from
the physical PC, and from software running in any other VMs that you may have
created. Your app under test can treat the VM as a sandbox to play in, and it can’t get
Installing FreePascal and Lazarus 103

out of the sandbox. If it damages the sandbox, you can revert and have a brand-new
sandbox in almost no time at all, ready to try again.

Popular virtual machine managers


There are quite a few virtual machine manager products out there, and I have
not used them all. Below is a quick summary of what I know and what I’ve used.
Note well that VMM software is more closely tied to CPU architecture than most
software. A VMM package written for 32-bit Intel CPUs will not work well or at all
on 64-bit CPUs. When you buy or download a VMM package, make sure that what
you get matches your “host” machine; that is, the “real” physical CPU on which the
VMM pckage is to be installed. “Guest” operating systems, on the other hand, can
generally be either 32-bit or 64-bit in nature. Check with the documentation of any
particular VMM package to see what its limitations may be.

VMWare Workstation 7
I learned virtual machine techology on VMWare’s Workstation product, and
although at about $200 is moderately expensive (especially compared to free
alternatives) it works extremely well and I’ve continued to pay for upgrades and use
it daily. Shortcomings: Older versions do not support 4-core CPUs, and no version
supports FireWire peripherals. It really does pay to keep the product current.
There is an add-on package for installation in supported “guest” operating
systems (those installed in VMs) called VMWare Tools, allowing better graphics and
better mouse integration. Not all operating systems and versions are compatible
with VMWare Tools, but if you’re installing a compatible OS in a VM, definitely
install VMWare Tools for it.
Here’s the vendor’s product page:

http://www.vmware.com/products/workstation/

Microsoft Virtual PC
Microsoft’s Virtual PC product has been around since 1997, and was a paid product
for years, until it was made a free (but not open-source) product in 2006. The 2007
version is the last version of the product to support Linux in its VMs. More recent
versions are called Windows Virtual PC, and do not allow the creation of VMs for
use with Linux or other non-Microsoft operating systems. Note well that each copy
of Windows installed in a VM must be separately licensed, and Microsoft’s VMMs
enforce this to the best of their abilities. Linux support is better in both VMWare
Workstation and VirtualBox.
104 FreePascal from Square One, Volume 1

For these reasons, I don’t recommend Virtual PC, even though it is technically
robust and reasonably easy to use. If you do want to try it, you can download the
most recent Linux-compatible version here:

http://www.microsoft.com/downloads/details.aspx?FamilyId=28C97D22-
6EB8-4A09-A7F7-F6C7A1F000B5&displaylang=en

Oracle VM VirtualBox
This was called Sun VirtualBox until Oracle acquired Sun in early 2010 and
rebranded the product. VirtualBox is available in both closed-source and open-
source versions. The open-source version lacks some of the server-associated
features of the “full” version and is intended for desktop use only.
Licensing is complex. Oracle offers the closed-source “full” version without
charge for personal (non-commercial) use. If you’re part of a corporation that may
be an issue; if you’re just learning Pascal at home it will not be. You can download
the closed-source version here:

http://www.sun.com/software/products/virtualbox/get.jsp
There is a weirdness in VirtualBox involving USB support. In the open-source
version USB peripherals cannot be accessed from within a VirtualBox VM. I don’t
completely understand the technical issues, but a detailed tutorial explaining how
to enable USB support is here:

http://news.softpedia.com/news/How-to-Fix-VirtualBox-USB-Support-
111715.shtml
The free and open source version of VirtualBox may be downloaded here:

http://www.virtualbox.org/wiki/Downloads
I’ve used both, and prefer the closed-source version, since I have no interest in
modifying and re-compiling the product in any way.

Parallels
I am not a Mac user and don’t have any Apple expertise, but the Parallels VMM
product is highly regarded by my Mac-user friends. There are two versions of the
Parallels product:
• Parallels Desktop for Mac is for Intel-based Mac machines running OS X
Tiger or later. The host OS must be Mac OS X. Guest OSes include Mac OS
X, Linux, BSD Unix, OS/2, Solaris, and Windows. eSATA, Firewire, and
Installing FreePascal and Lazarus 105

Bluetooth are major peripheral technologies not supported. $80; no free


version. Guest OSes must be 32-bit.
• Parallels Workstation Extreme is a high-performance desktop VMM. Its
big downside is that it’s a little hardware-specific, and may not run on
any arbitrary Intel architecture CPU. See the Parallels Web site for details.
$400; no free version.
I have never used either version, but both are highly regarded in the Mac
community.

What I do
My main development machine runs Windows XP. I have VMWare Workstation
installed, and keep “clean” snapshots of VMs containing major Linux distros on
disk. These snapshots include FreePascal and Lazarus, installed and configured as I
like them. My project directory tree is shared with the several VMWare VMs.
I do most of my programming on Windows, but when I need to test a build
on Linux I open one of the Linux VMs and load the project into Lazarus from the
shared project directory. Because all project source code is kept in a single location,
there’s no danger of the Windows and Linux source code getting “out of sync.”
That said, once I move beyond simple Pascal console apps to GUI apps (which
I won’t be covering in this book) I tend to keep the source code suites separated by
platform. Portability is an ideal to shoot for, but depending on what your app needs
to do, it may not be possible to target both Windows and Linux from the same
source code suite. Fortunately, you won’t have to worry about this until such time
as you learn enough FreePascal to move ahead to Lazarus and GUI apps.

4.6. Miscellaneous Install Notes


Software installation is an untidy business, because both software and the
machinery that installs it change over time. As recently as 18 months ago, we did
not have either the Ubuntu Software Store nor the OpenSuSE Build Service, and the
descriptions in this chapter would have been different had this book appeared back
then. So in the last section of this chapter, I’ll include whatever odd notes I have on
installing Lazarus and Freepascal that didn’t fit any of the earlier sections.

Obtaining the text-mode IDE for Ubuntu with apt-get


As with Windows, when you install Lazarus for Linux, the FreePascal text mode
IDE is not installed with it . Nor does the IDE have a record in the Ubuntu Software
Store. To install the IDE, you have to open a terminal window and manually request
106 FreePascal from Square One, Volume 1

the IDE program through apt-get, using this command:

sudo apt-get fp-ide


After you enter your account admin password, the apt-get mechanism will
download, unpack, and install the IDE for you. Once installed, you run the IDE by
opening a terminal window and typing the command fp. The IDE that appears runs
in text mode, but it uses color.
Now, depending on what version of FreePascal and Linux you’re using (and
recognizing that bugs are fixed regularly in the Open Source world) you may see a
peculiar error message when you run FreePascal’s text-mode IDE, warning against
(possible) problems with Debian bug # 412927. (See Figure X.X.) This bug involves
mouse and mouse-wheel support under Debian-based distros, but in my own work
in Ubuntu I have had no trouble at all. By the time you read this, that bug may have
been addressed and you may not see the message, but if you do, there’s no reason to
panic. Try the IDE and see if mouse support works. If not, you also have the option
of creating FreePascal text-mode programs in the Lazarus IDE.
d
e
h
is
n
fi
n
U
Chapter 5.

Is
Using the Lazarus
r
te
Environment
p
a
h
C
is
h
T

“G ive me a lever long enough, and a place to stand, and I will move the Earth.”
In perhaps his best-known statement, Archimedes was speaking literally
about the power of mechanical levers, but behind his words there is a larger truth
about work in general: To get something done, you need a place to work, with
access to tools. My radio bench down in my workshop is set up that way: A large,
flat space to lay ailing transmitters down, and a shelf above where my oscilloscope,
VTVM, frequency counter, signal generator, and dip meter are within easy reach.
Much of the initial success of Turbo Pascal 25-odd years ago was grounded in that
simple but compelling truth. For the first time, a compiler vendor had assembled
the most important tools of software development and put them together in an
intuitive fashion so that the various tasks involved in creating software flowed
easily and quickly from one step to the next.

6.1. Meet Lazarus, FreePascal’s RAD Environment


Turbo Pascal versions 1 through 3 were pretty effective in this way. Later versions
were even moreso, reaching a sort of optimum for text-mode DOS programming
with Borland Pascal 7 in 1991. Back in early 1995, Borland shook the development
world with the first release of Delphi. Delphi was more than just an IDE for
Pascal, and certainly more than the Borland Pascal 7 IDE rewritten to run under
Windows. Three major things set Delphi apart from earlier versions of Turbo/
Borland Pascal:
• Delphi contained a whole new mechanism for creating user interfaces
by dragging and dropping components like buttons and scroll bars from
a component pallette onto initially blank windows. We now call such
mechanisms “GUI builders” in the generic.
• Delphi became object-oriented from top to bottom. Precisely what this
means is hard to explain before explaining the fundamentals of the

107
108 FreePascal from Square One, Volume 1

Pascal language, and it will have to wait until later in this book. Think of
object-orientation as a new, higher level of program structure that defines
relationships between code and data in a hierarchical way.
• Delphi actually wrote parts of the code for new applications, especially
applications crafted with the help of the GUI builder. Delphi basically
generated a sort of generic program skeleton that programmers would
“flesh out” to make it perform specific tasks. Object-orientation was
essential to this code-generation mechanism.
Delphi was a roaring success for many reasons, primarily that it made the process
of writing programs to run under Windows easier to understand and hugely faster.
The improvement in programmer productivity was such that Delphi became
known as a rapid application development (RAD) environment.
Delphi is still being actively developed and is widely used by corporate developers,
especially outside the US. It is, however, very expensive compared to the original $50
Turbo Pascal. Even the entry-level version of Delphi 2010 costs over $1000. This
puts it beyond the means of newcomers and hobby programmers who don’t have a
corporation with an IT budget behind them.
Back when Delphi was released, a company called SpeedSoft offered a product
called SpeedPascal, written to run under IBM’s ill-fated OS/2 operating system.
Speedsoft created a RAD environment for OS/2, using SpeedPascal as the “back
end” compiler. The RAD environment was called Sibyl. Sibyl was very compatible
with Delphi, and allowed programmers to port Delphi apps to OS/2 without
rewriting all their code from scratch. OS/2’s success began to wane in the shadow of
Windows 95’s success, and Sibyl’s fate was tied to OS/2. In 1998, SpeedSoft released
the source code for Sibyl and made it an open-source product before the company
finally closed its doors.
With the Sibyl source code as a model, a group of Israeli programmers began a
project in 1998 that they called Megido. The idea behind Megido was to create an
open-source Windows-based RAD environment like Borland’s Delphi. The project
vanished after about a year for reasons that never became fully known. Later in
1999 several programmers resurrected the idea of Megido as the Lazarus Project.
(Lazarus, some of you may recall from Sunday School, was the man whom Jesus
brought back from the dead.)
The Sibyl source code was less useful than originally thought, largely because
so much of it was in 32-bit x86 assembly and thus not easily portable to platforms
based on other CPUs. So over the past ten years, Lazarus has been written entirely
in FreePascal, thus making it at least potentially portable to any platform where
FreePascal exists.
Using the Lazarus Environment 109

Ten years on, Lazarus is still very actively in development, and is definitely
mature enough to develop commercial applications with.

Lazarus’ major elements


Lazarus consists of a number of interdependent subsystems. Not all of these will
come into play in this book, but you should be aware that they exist:
• A windowed source code editor.
• The FreePascal compiler.
• An interface to the Gdb debugger.
• The Lazarus Component Library, a code library roughly equivalent to the
Delphi VCL.
• Interfaces to major GUI toolits and widget sets, including the Win32
and Win64 GDI, Gtk+ 1.2 and 2.6, and Max OS X Carbon. Others are in
development, including Qt4.2 and Cocoa.
• A code explorer, which lets you quickly view the names of things in
your programs, without having to look at all the code. It creates a sort of
“structure summary” of a program, allowing you to “take in” many details
at once.
• An object inspector, which is a window providing a view of the sometimes
subtle relationships among fields and methods within FreePascal objects.
• A restriction browser, which provides quick access to the restrictions
implemented in the objects used in a program.

One thing to be aware of is that a lot of the way Lazarus is designed caters to
the needs of object-oriented programming, and it will take most of a book before
we can discuss objects at any length at all. The object inspector and the restriction
browser, in particular, make little sense until you “get” the object-oriented idea. The
Lazarus Component Library is completely object-oriented and is not something
that may be called from within very simple Pascal programs.

A project-oriented IDE
Through most of the history of Pascal programming, a “project” in Pascal was
simply a Pascal program, or perhaps a program and a number of Pascal library files
named within the program and linked with the program to create the executable
program file. As Pascal programming has gotten more complex, and especially
with the advent of object orientation and GUI apps for Windows and the Linux
110 FreePascal from Square One, Volume 1

graphical shells, Pascal projects include more than simple Pascal code. You need
icon files, form files, and many other things in the general category called resources.
For this reason, when you want to write a program in FreePascal using Lazarus, you
don’t simply create a new Pascal source code file. You create a project.
A Lazarus project includes the main program’s source code file, obviously. It also
includes code libraries and other resources. Giving a project a single name (which
does not have to be the name of any source code file) gives you a sort of umbrella
beneath which you can tinker the various elements of an ambitious Pascal project
without losing track of what parts belong to what project.
Once you’ve created a project, you can add new files to the project whenever you
need to, and being able to treat the collection of files as a named entity helps a great
deal in managing the complexity of a sophisticated project.
This will become a lot clearer once we create an example project later in this
chapter.

Software conversations “beneath the surface”


Beginners sometimes wonder, after installing and looking at Lazarus and its
many windows, where the window for the FreePascal compiler is. The truth is, the
compiler does not need a window, and does not have one.
The Lazarus environment can be thought of as a sophisticated “remote control”
system for FreePascal. You type source code into the source code window, and select
options in several of the other windows. When you have your project set up the way
you want it (or at least the way you think you want it) you basically tell Lazarus to
turn the FreePascal compiler loose on the project.
Lazarus runs the FreePascal compiler invisibly, passing to the compiler the
necessary names of pertinent files in your project, along with certain terse
instructions as to how the project should be compiled. The compiler does what it’s
told, and it passes back to Lazarus various messages indicating success or (failing
complete success) error conditions. Lazarus digests these messages, and relays
some of them up to you through the Messages window.
This process happens down where you can’t watch it, and that’s OK. Whatever
messages coming back from FreePascal that you might find remotely useful will
appear in the Messages window.
Using the Lazarus Environment 111

5.2. Configuring Lazarus for Pascal Programming


Lazarus was designed to help you write GUI apps for Windows and other graphical
user interface shells like GNOME and KDE. It can certainly help you write relatively
simple Pascal programs, even though for beginning Pascal work Lazarus is overkill.
It’s possibly to simplify Lazarus somewhat, to make it easier to grasp while you’re
learning it, and to keep unneeded portions of the system from distracting you while
you’re working.

Closing unneeded windows


The first step in simplifying Lazarus is to close the windows that you won’t need. To
open, compile, and run the example programs presented in this book, you need the
following windows to be open:
• The main window. (This cannot be closed without closing Lazarus as a
whole.)
• The Source Code window.
• The Messages window.
Later on, I’ll explain how to use the Code Explorer, but for your first steps in Pascal
you might as well close it, as it won’t be of much use.
Bringing one of Lazarus’ windows into visibility is done from the menu bar in
the main window. Pull down the View menu, and you’ll see a list of items. Each item
in the first group is a separate window. You make a window visible by selecting its
item in the View menu.
Items in the View menu are not toggles. That is, you don’t select an item once to
show and then select it a second time to hide. To “put a window away” so that it’s
no longer visible, you click on the small “x” in the upper right corner of the window.
Closing a window in that fashion changes nothing in the window itself; the window
can be made visible again simply be selecting it from the View menu.

Configuring line numbering


Oddly, by default Lazarus does not display line numbers on every source window
line. It can be confgured to display numbers every n lines, where n can be any
number from 1 to 100. When reading enormous source code files, having line
numbers only once in ten might be useful, but when you’re just learning, having a
number on each line is better, especially since I will be referring to individual listing
lines by number in this book.
112 FreePascal from Square One, Volume 1

Compiling vs. linking vs. building


Begin . . . End
Part III:
The Core of the
Pascal Language
6. Pascal Atoms . . . . . . . . . . . . . . . . . . . . . . . . . XX
7. Data and Data Types. . . . . . . . . . . . . . . . . . . . . XX
8. Controlling the Flow of Program Execution . . . . . . XX

If...Then...Else...
113
114 FreePascal from Square One, Volume 1

H aving gotten a feeling for both programming and the “big picture” of Pascal
itself, it’s now time to after the details of both the Pascal language and the
programming process. And therein lies a snag for me.
I’d like to be able to say, “Read this book from cover to cover and you’ll learn
Pascal.” That’s how I think books of this kind work best. The problem with teaching
Pascal in a strictly linear fashion is that it’s a continuous, linear narrative that weaves
all of Pascal’s ideas together in a single stream. There would be no “chapter” on
simple data types, because you have to introduce simple data types right alongside
reserved words, identifiers, operators, and so on. This reads well in the fashion of a
novel, but it doesn’t re-read very well. By that I mean that once you’ve read it, you may
feel that your understanding of derived types is fuzzy, and you may want to go back
and reread a discussion of derived types. But in a strictly linear exposition of Pascal,
derived types are discussed in no one place, but here, there, and in several other
places. Like all the other topics, they weave in now and again in the one big story.
Once I’ve laid the groundwork it’ll be a lot easier. But in laying the groundwork
I’ve had to make a number of seemingly arbitrary decisions: Do I explain first what
reserved words and identifiers are, and then explain what data is? Or do I explain data
types first, so that I can explain how reserved words and identifiers come together
to make statements? Maybe it’s a silly thing to worry about. But I’m trying hard to
make this book accessible to the total newcomer to the idea of programming, and
putting across the foundations of any idea is absolutely critical.
So you’ll have to cut me a little slack here. I’ve chosen to begin with Pascal’s
fundamental atoms like letters and symbols. In keeping with Pascal’s idea of
structure, I’ll go from there to reserved words and identifiers, and from there to
data types. After data types I’ll cover operators, expressions, and statements. That’s
mostly a linear, bottom-up approach, and it will help things come back to mind
when you return to these early chapters for review. Some might prefer that I cover
operators before the apparently more complex topic of data types, but trust me:
Data types without operators make more sense than operators without data types.
It will help a great deal if you’ve already read Chapter 3, which presents an
overview of most of the fundamental ideas of Pascal. If you haven’t, you ought to go
back and read Chapter 3 now. The overview material will definitely help bridge the
occasional chicken-and-egg dependencies you’ll find in the next several chapters.
And once you’ve got the core of the language under your belt, the problem goes
away.
Really!
d
e
h
is
n
fi
n
U
Is
Chapter 6.
r
te
Pascal Atoms
p
a
h
C
is
h

P
T

ascal, by design, is a structured language. Unlike certain “freeform” languages


like APL and Perl, as well as older versions of BASIC and FORTRAN, it imposes
a very clear structure on its programs. Pascal will not let you string statements
together haphazardly, even if every statement, taken alone, is syntactically correct.
There is a detailed master plan that every Pascal program must follow and the
compiler is pretty strict about enforcing the rules. A program must be coded in
certain parts. Some parts must go here, and others must go there. Everything must
be in a certain order. Some things cannot work together. Other things must work
together.
Aside from some concessions to compiler designers (the Pascal language
specification makes their task easier in some respects) Pascal’s structure exists solely
to reinforce a certain way of thinking about programming. This way of thinking
language creator represents Niklaus Wirth’s emphasis on developing programs that
are understandable without scores of pages of flowcharts and thousands of lines of
explication. As I described in Part I, this way of thinking championed by Wirth and
others is called “structured programming.” Although structured programming can
be accomplished in any computer language (even BASIC, though I have my doubts
about APL) Pascal is one of a growing family of computer languages that absolutely
requires it.
A structure must be made of something. A crystal is a structure of atoms in a
particular orderly arrangement. A Pascal program is made of “atoms” that are formed
from the ASCII character set, and “molecules” formed from ASCII characters. These
program atoms and molecules fall into several categories. There are numbers and
symbols. There is a fairly small group of reserved words, an even smaller number of
modifiers, and then the unlimited multitude of ordinary identifiers created by you,
the programmer, as names for your data items, procedures, and functions. In this
chapter we’ll discuss the different kinds of Pascal atoms and how they’re used to
create structured programs.

115
116 FreePascal from Square One, Volume 1

6.1. Symbols, Digits, and ASCII Characters


The most “atomic” of Pascal’s atoms (and perhaps “subatomic”) are the individual
members of the ASCII character set. The American Standard Code for Information
Interchange (ASCII) is a set of 128 values based on the English character set. Of the
128 ASCII characters, 94 are visible when displayed. 33 are not visible.
Of those 33 “invisible” characters, several are called whitespace characters, which
do not have associated glyphs (symbols) but which give structure to visible text on
the page or screen by dividing text into lines and aligning text within lines vertically
into structures. Whitespace characters include the space character, the tab character,
the carriage return character, and the line feed character. Whitespace characters do
divide your Pascal programs into words and lines, but they are mostly there for
your benefit: Without them, your programs would be one long line of symbols
and words spanning many pages, and would be virtually impossible to read. The
FreePascal compiler strips all whitespace out except for the space characters that
separate the visible elements of the program from one another.
When you write program code, it looks like this on your screen and on your
printouts:

FOR I := 1 TO 17 DO
BEGIN
SHR(J);
INC(J)
END;

However, after it removes excess whitespace, the compiler “sees” a continuous and
unformattted stream like this:
FOR I := 1 TO 17 DO BEGIN SHR(J); INC(J) END;

The point here is that how you arrange the lines of code in your program is
not important to the FreePascal compiler. You can indent lines by two spaces per
level (as is my custom) or six or eight spaces. You can place two lines in between
procedures and functions, or three, or whatever you prefer. You can, if you like,
place short compound statements (that is, code falling between BEGIN and END
reserved words) on a single line. Pascal reserved words and identifiers must be
separated from one another by spaces. Beyond that, well, it’s up to you.
Some of the invisible 33 ASCII characters are “control characters” that were originally
designed to control the operation of mechanical teletype printers and later on, CRT
terminals. These are almost all obsolete nowadays and rarely used. Interestingly, one
such control character, the BEL character, was originally used to ring a small mechanical
bell in teletype machines, and later on caused CRT terminals to beep.
Pascal Atoms 117

Numeric Digits
Individually and together, the digits 0-9 are used by Pascal as you would expect: to
express literal numeric values:

8
71
29784

Pascal does not separate large values into groups of thousands with commas, as we
often do when writing ordinary text; for example, 29,784. Placing a comma within
a number will trigger a compiler error.
In addition to expressing literal numeric values, the digits 0-9 can also be part of
the identifiers you create as variable and procedure names; for example, Area51.
More on this a little later.

Alphabetic characters
The alphabetic characters A-Z and a-z are used individually and in combination
to create the names of compiler commands, reserved words, constants, variables,
procedures, and functions. Note well that unlike in some other programming
languages (the C familiar, particularly) character case is not significant. For example,
the FreePascal compiler considers A and a to be the same character except when
present in quoted string literals. As I’ll explain later, within a string literal, case is
significant; ‘Jeff’ and ‘JEFF’ are considered different by the compiler.

Symbols
The ASCII character set includes a number of visible symbols that are neither
numeric digits nor letters of the English alphabet. These include punctuation marks
like ! and ?, arithmetic symbols like + and -, straight and curly brackets { } [ ], slashes,
and a few others. Most such symbols have very specific meanings to the FreePascal
compiler. Some symbols can mean more than one thing; for example, the period
character, which expresses decimal parts of numeric literals, and also references to
fields within records. Sometimes two symbols are combined into a single symbol.
For example, the two symbols <> together mean “not equal to” and the symbols (*
begin a comment.
For the most part, symbols are not allowed within identifiers. That is, you cannot
create a variable named Ham&Cheese. The exception is the underscore character;
Ham_and_Cheese is perfectly legal. More on this later.
118 FreePascal from Square One, Volume 1

6.2: Reserved Words: Pascal’s Framing Members


Reserved words are words that have special meanings within the Pascal language. They
cannot be used by the programmer except to stand for those particular meanings.
The compiler will immediately error-flag any use of a reserved word that is not
rigidly in line with that word’s meaning. Examples would include BEGIN, END,
PROCEDURE, FUNCTION, ARRAY, and that old devil GOTO.
Which words the FreePascal compiler considers reserved words depends on
what mode you have the compiler operating in. As I explained a little earlier
in Chapter 5, FreePascal can work in several modes. In each mode, FreePascal
“works like” a different Pascal compiler. Those modes are controlled by the
$MODE switch. The two modes you’re likely to use as a beginning programmer
are Turbo Pascal mode and FreePascal mode. If you begin using the Lazarus GUI
Builder to create graphical apps (which I will not be covering in this book) you
will then operating in Delphi mode. FreePascal mode is the default. To work in
Turbo Pascal mode you must set the $MODE TP switch. Table 6.1. lists all the
reserved words defined in Turbo Pascal mode.

Table 6.1. Reserved Words enforced in Turbo Pascal 7.0 mode

ABSOLUTE ELSE NIL SET


AND END NOT SHL
ARRAY FILE OBJECT SHR
ASM FOR OF STRING
BEGIN FUNCTION ON THEN
BREAK GOTO OPERATOR TO
CASE IF OR TYPE
CONST IMPLEMENTATION PACKED UNIT
CONSTRUCTOR IN PROCEDURE UNTIL
CONTINUE INHERITED PROGRAM USES
DESTRUCTOR INLINE RECORD VAR
DIV INTERFACE REINTRODUCE WHILE
DO LABEL REPEAT WITH
DOWNTO MOD SELF XOR

Table 6.2 lists the additional reserved words recognized by FreePascal when
operating in Delphi mode, using the $MODE DELPHI switch. Note well that these
are additional to the reserved words in Table 6.1. When operating in Delphi mode,
FreePascal recognizes all of the reserved words in Table 6.1 as well as all the reserved
words in Table 6.2.
Pascal Atoms 119

Table 6.2. Additional reserved words enforced in Delphi mode.


AS FINALIZATION LIBRARY RAISE
CLASS FINALLY ON THREADVAR
EXCEPT INITIALIZATION OUT TRY
EXPORTS IS PROPERTY

When FreePascal is operating in its default FreePascal mode (or has been set to
FreePascal mode using the $MODE FPC switch) it enforces a few more reserved
words in addition to all of those enforced in Turbo Pascal 7 mode and Delphi mode.
These are listed in Table 7.3. Again, keep in mind that when operating in FreePascal
mode, the compiler enforces all reserved words listed in Tables 7.1 through 7.3.

Table 6.3. Additional reserved words enforced in FreePascal mode.


DISPOSE FALSE TRUE
EXIT NEW

In addition to the reserved words shown in Tables 6.1-6.3, there is another list of
predefined words that you should be aware of. These are called modifiers, and they
work in conjunction with certain reserved words to modify what those reserved
words mean to the compiler, hence their name. For the most part, you will have no
call to use them while you’re just learning FreePascal. However, it is important that
you not use them for anything else in your own programs.

Table 6.4. Modifiers understood by FreePascal


ABSOLUTE EXTERNAL NOSTACKFRAME READ
ABSTRACT FAR OLDFPCCALL REGISTER
ALIAS FAR16 OVERRIDE SAFECALL
ASSEMBLER FORWARD PASCAL SOFTFLOAT
CDECL INDEX PRIVATE STDCALL
CPPDECL LOCAL PROTECTED VIRTUAL
DEFAULT NAME PUBLIC WRITE
EXPORT NEAR PUBLISHED

The compiler has its own somewhat arcane uses for them, but it will also allow
you to use them if you choose to, as the names of variables, constants, procedures,
or functions. That, however, is a bad idea. I recommend treating the list of modifiers
in Table 6.4 as though they were reserved words. To avoid confusion, especially as
you advance in your skills, use them only where and how they were designed to be
120 FreePascal from Square One, Volume 1

used by FreePascal’s authors. All of them are considered advanced to very advanced
topics, and I will be discussing few if any of them in this first book. For now, treat
them as a list of words to be avoided as you define named elements in your own
programs.

Put your reserved words in uppercase!


In the Ancient Days of Pascal, standard practice was always to place reserved words
in upper case, and I’ll do so throughout this book. Pascal is not case-sensitive, so
you can place reserved words in lower or mixed case if you wish. BEGIN is treated
the same way by the compiler as begin or Begin or (for that matter) BeGIn. In
recent years, a strange aversion to upper case characters has appeared among
programmers, and in most other books about Pascal and Delphi you will see
reserved words and nearly everything else in lower case.
That’s a mistake. Uppercase helps reserved words stand out like beacons when
you read your own code listings or those of others. Because reserved words are
the framing members of your Pascal programs and govern the very shape that
your programs take, I think it pays to be able to see them clearly, at a glance. This
is important, and although I’m considered “old-school” (and a bit of a crank) for
insisting on it, I make no apologies and will no longer discuss the issue. Putting
everything in your program in lower case makes it hard to read, and from my
perspective, readability is the #1 feature of correct Pascal code. Basically, even if
your Pascal code is bug-free, if it’s hard to read, it’s worthless.

6.3. Identifiers
Your computer creates programs for your use. Programs are collections of things
(data) and steps to be taken in storing, changing, and displaying those things
(statements). The computer knows such things by their addresses in its memory.
The readable, English-language names of data, of programs, of functions and
procedures, are for your benefit. We call such names, taken as a group, identifiers.
They exist in the source code only. Identifiers do not exist in the final executable code file.
Any name that you invent and apply to an entity in a program is an identifier. The
names of variables, of data types, of named constants, of procedures and functions,
and of the program itself are identifiers. An identifier you create can mean whatever
you want it to mean (within Pascal’s own rules and limits) as long as it is unique
within its scope.
The notion of scope is a subtle and important concept that I will explain at length
later on, but broadly put, it indicates what portion of your program the compiler
Pascal Atoms 121

can “see” at any given point in your code. The compiler will complain if it can “see”
more than one item with the same identifier. That is, if you have a variable named
Counter you cannot have a procedure named Counter within the same scope. Nor
can you have another variable (or anything else) named Counter within that scope.
Understanding scope requires that you understand more about program structure
than I’ve explained so far; hold on until we get there.
FreePascal identifiers are sequences of characters of any length up to 255
characters that obey these few rules:
• Legal characters include letters, digits, and underscores. Spaces and
symbols like &,!,*, or % (or any symbol not a letter or digit) are not
allowed.
• Digits (0-9) may not be used as the first character in an identifier. All
identifiers must begin with a letter from A-Z (or lowercase a-z) or an
underscore.
• Identifiers may not identical to any reserved word.
• Case differences are ignored. The letter A is the same as a to the compiler.
• Underscores are legal and significant. Note that this differs from most
older, non-Borland derived Pascal compilers, in which underscores
are legal but ignored. You may use underscores to “spread out” a long
identifier and make it more readable: SORT_ON_ZIP_CODE rather
than SORTONZIPCODE. (A better method that has become the custom
in the Pascal community is to use mixed case to accomplish the same
thing: SortOnZIPCode.)
• All characters are significant in a FreePascal identifier, up to 255
characters. Some ancient Pascal compilers allowed longer identifiers but
ignored any character after the eighth character.

The following are all invalid identifiers that will generate errors:

Fox&Hound Contains an invalid character, “&”, that may not be in an identifier


FOO BAR Contains a space
7Eleven Begins with a number
RECORD RECORD is a reserved word and can’t be used as an identifier

Here’s a point that Pascal beginners sometimes misunderstand: There is no


penalty at all for using a long identifier over a short identifier. In other words,
the identifier I and the identifier StatusOfPrimaryKeyUpdateOperation take
up precisely the same amount of space in the compiled program that FreePascal
generates. And that amount of space is…none! Identifiers do not exist in your executable
122 FreePascal from Square One, Volume 1

binary program. They are used by FreePascal to build a “symbol table” of memory
addresses that allow it to generate the executable code file, but they are left behind
when the work is done.
With that in mind, create identifiers that help you read your source code. That’s what
they’re for. An identifier can be too long, of course, but that’s rarely the problem.

A quick look ahead by looking back: Variable definition


I’m going to do something here that in programming is called a “forward reference”:
I’m going to briefly explain how identifiers become variables. There’s a chicken-
and-egg problem in describing Pascal fundamentals, in that you need variables
to demonstrate operators, and you need operators to define variables. I’ll explain
in a great more detail how data items are defined in the next chapter, but for now,
think back to what you learned in Section 3.3. In fact, re-reading that section now
wouldn’t be a bad idea.
To recap: In Pascal, variables must be defined before they’re used. Defining a variable in
Pascal is done using the VAR reserved word, up toward the top of your program.
The VAR reserved word associates an identifier with a data type. Here’s a common
example:
VAR
I : Integer;

This is a complete Pascal statement. It creates a variable by associating a valid


identifier (here, the letter “I”) with a standard Pascal data type, Integer. Your
program will now treat variable I as an integer, and allow I to be used in certain
kinds of numeric operations expressed in Pascal statements. If you attempt to use
I in ways outside the powers of the Integer type, FreePascal will call foul, and you’ll
get a type conflict error at compile time. Variable definition in Pascal is an important
and subtle business, I’ll have much more to say on it in Chapter 7.

6.4. Operator Basics


In Pascal, an operator is a symbol or short group of symbols that specifies either a
relationship between two data items, or else some kind of operation to be done on
one or more values, hence the name. Some Pascal operators are single characters,
like “=”, but because there are only so many characters in the ASCII character set,
most operators are short groups of two or three characters, like “>=” and “NOT”.
An operator operates on one or more variables or constants. These variables and
constants are called the operator’s operands.
Pascal Atoms 123

A good place to start is the with assignment operator. A variable is a container in


memory laid out by the compiler. It has a particular size and shape defined by its
type. Into a variable you load an item of data that conforms to the size and shape of
the variable. This data is the variable’s value.
You’re probably already familiar with the assignment operator, which is perhaps
the most fundamental operator in Pascal: “:=” The assignment operator is (usually)
how values are placed into variables. Consider this simple assignment statement:
I := 17;

A value on the right side of the assignment operator is assigned to the variable on
the left side of the assignment operator. In an assignment statement, there is always
a variable on the left side of the assignment operator. On the right side may be a
constant, a variable, or an expression.

Expressions
An expression in Pascal is a combination of data items and operators that eventually
“cook down” to a single value. Data items are constants and variables. The best way
to understand expressions is to think back to your grade-school arithmetic, and
how you used arithmetic operations to combine two or more values into a single
result. This is an expression, both in basic arithmetic and in Pascal:
17 + 3

The addition operator + performs an add operation on its two operands, 17 and 3.
The value of the expression is 20.
An expression like “17 + 3”, while valid in Pascal, would not be used in a real
program, where the literal value “20” would suffice. It’s a lot more useful to create
expressions that involve variables. For example:
3.14159 * Radius * Radius

This expression’s value is recognizable as the area of the circle defined by whatever
value is contained in the variable Radius. Note here that a Pascal expression is not
the same thing as a Pascal statement, and expressions do not stand alone. To pass
the compiler’s picky standards, expression must always be part of a statement.
Standard Pascal includes a good many different operators for building
expressions, and FreePascal enhances ISO Pascal with a few additional operators.
They fall into a number of related groups depending on what sort of result they
return: Relational, arithmetic, set, and logical (also called “bitwise”) operators.
124 FreePascal from Square One, Volume 1

6.5. Relational operators


The relational operators are used to build Boolean expressions, that is, expressions
that evaluate down to a Boolean value of True or False. Boolean expressions are
the most widely used of all expressions in Pascal. All of the looping and branching
statements in Pascal depend on Boolean expressions. More on this in Chapter 7.
A relational operator causes the compiler to compare its two operands for some
sort of relationship. The Boolean value that results is calculated according to a set
of well-defined rules as to how data items of various sorts relate to one another.
Table 6.5 summarizes the relational operators implemented in FreePascal. All
return Boolean results:

Table 6.5. Relational Operators


Operator Symbol Operand types Precedence
Equality = scalar, set, string, 5
pointer, record, object
Inequality <> scalar, set, string, 5
pointer, record, object
Less than < scalar, string 5
Greater than > scalar, string 5
Less than or equal <= scalar, string 5
Greater than or equal >= scalar, string 5
Set membership IN set, set members 5
Set inclusion, left in right <= set 5
Set inclusion, right in left >= set 5
Negation NOT Boolean 2
Conjunction AND Boolean 3
Disjunction OR Boolean 4
Exclusive OR XOR Boolean 4

The column labeled “Precedence” has to do with order of evaluation, which I’ll
return to later on in this book.
The set operators fall into two separate worlds; they’re set operators, obviously,
but they also express certain relationships between sets and set members that return
Boolean values. (I’ll come back to sets later on.) The convention is that any operator
that returns a Boolean value is relational, since Boolean values express the “truth
or falsehood” of some stated relation. The three relational operators that involve
sets, set membership and the two set inclusion operators, will be discussed along
Pascal Atoms 125

with the operators that return set values, in Section X.X. Note that the set inclusion
operators share symbols with the greater than or equal to/less than or equal to
operators, but the sense of these two types of operations are radically different.
Some of the types mentioned briefly in this section are types I haven’t yet
explained in detail. Most of these will be covered in the next chapter except for
pointers, which will have to wait until considerably later on. The mentions are here
not so much for you to read on your first linear pass through this book, but on those
occasions when you return to this section for a brushup.

Equality
If two values compared for equality are the same, the expression will evaluate as
True. In general, for two values to be considered equal by Turbo Pascal’s runtime
code, they must be identical on a bit-by-bit basis. This is true for comparisons
between like types. Most comparisons must be done between values of the same
type.
The exceptions are comparisons done between numeric values expressed as
different types. Turbo Pascal allows comparisons rather freely among integer types
and real number types, but this sort of type-crossing must be done with great care.
In particular, do not compare calculated reals (real number results of a real number
arithmetic operation) for equality, either to other reals or to numeric values of other
types. Rounding effects may cause real numbers to appear unequal to compiled
code even though the mathematical sense of the calculation would seem to make
them equal.
Integer types Byte, ShortInt, Word, Integer, and LongInt may be freely
compared among themselves.
Two sets are considered equal if they both contain exactly the same members.
(The two sets must, of course, be of the same base type to be compared at all.) Two
pointers are considered equal if they both point to the same dynamic variable. Two
pointers are also considered equal if they both point to NIL.
Two records are considered equal if they are of the same type (you cannot
compare ecords of different types) and each field in one record is bit-by-bit identical
to its corresponding field in the other record. Remember that you cannot compare
records, even of the same type, using the greater than/less than operators >, <, >=,
or <=.
Two strings are considered equal if they both have the same logical length (See
Section X.X) and contain the same characters. This makes them bit-by-bit identical
out as far as the logical length, which is the touchstone for all like-type equality
comparisons under Turbo Pascal. Remember that this makes leading and trailing
126 FreePascal from Square One, Volume 1

blanks significant:

‘ Eriador’ <> ‘Eriador’ { True! }


‘Eriador ‘ <> ‘Eriador’ { True! }

Inequality
The rules for testing for inequality are exactly the same as the rules for equality. The
only difference is that the Boolean state of the result is reversed:

17 = 17 { True }
17 <> 17 { False }
42 = 17 { False }
42 <> 16 { True }

In general, you can use the inequality operator anywhere you can use the
equality operator.
Pointers are considered unequal when they point to different dynamic variables,
or when one points to NIL and the other does not. The bit-by-bit rule is again
applied: Even one bit’s difference found during a like-type comparison means the
two compared operands are unequal. The warning/ applied to rounding errors
produced in calculated reals applies to inequality comparisons as well.

Greater Than/Less Than


The four operators greater than, less than, greater than or equal to, and less than or
equal to, add a new dimension to the notion of comparison. They assume that their
operands always exist in some well-defined order by which the comparison can be
made.
This immediately disqualifies pointers, sets, and records. Saying one pointer is
greater than another simply makes no sense, given the way pointers are defined.
You could argue that since pointers are physical addresses, one pointer will always
be greater or less than another non-equal pointer. This may be true, but in the spirit
of the Pascal language, details about how pointers are implemented are hidden
from the programmer at the purely Pascal level. (And going to the next level down
and messing with pointer internals can get you into several different kinds of
trouble, especially once you begin using Borland Pascal 7.0 to create applications
that run in protected mode. Protected mode is very fussy about what you do with
your pointers!)
The same applies to sets and records. Ordering them makes no logical sense, so
Pascal Atoms 127

operators involving an implied order cannot be used with them.


With scalar types (see Section 7.X) a definite order is part of the type definition.
For integer types (ShortInt, Byte, Integer, Word, and LongInt) the order is
obvious from our experience with arithmetic; integers model whole numbers
between specific bounds.
The Char and Byte types are both limited to 256 possible values, and both
have an order implied by the sequence of binary numbers from 0 to 255. The Char
type is ordered by the ASCII character set, which makes the following expressions
evaluate to True:

‘A’ < ‘B’


‘a’ > ‘A’
‘@’ < ‘[‘

The higher 128 values assignable to Char variables have no truly standard characters
outside of the PC world, but they still exist in fixed order and are numbered from
128 to 255.
Enumerated types are limited to no more than 255 different values, and usually
have fewer than ten or twelve. Their fixed order is the order the values were given in
the definition of the enumerated type:

TYPE
Colors = (Red,Orange,Yellow,Green,Blue,Indigo,Violet);

This order makes the following expressions evaluate to True:

Red < Green


Blue > Yellow
Indigo < Violet

The ordering of string values involves two components: The length of the string
and the ASCII values of the characters present in the string. Essentially, Turbo
Pascal begins by comparing the first characters in the two strings being compared.
If those two characters are different, the test stops there, and the ordering of the two
strings is based upon the relation of those two first characters. If the two characters
are the same, the second characters in each string are compared. If they turn out to
be the same, then the third characters in both strings are compared.
This process continues until the code finds two characters that differ, or until
one string runs out of characters. In that case, the longer of the two is considered to
be greater than the shorter. All of the following expressions evaluate to True:
128 FreePascal from Square One, Volume 1

‘AAAAA’ > ‘AAA’


‘B’ > ‘AAAAAAAAAAAAA’
‘AAAAB’ > ‘AAAAAAAAAA’

NOT, AND, OR, and XOR


There are four operators that operate on Boolean operands: NOT, AND, OR and
XOR. These operators are sometimes set apart as a separate group called Boolean
operators. In some ways, they have more in common with the arithmetic operators
than with the relational operators. They do not test a relationship which already
exists between two operands. Rather, they combine their operands according to
the rules of Boolean algebra to produce a new value that becomes the value of the
expression.
The simplest of the four is NOT, which takes only one Boolean operand. The
operand must be placed after the NOT reserved word. NOT negates the Boolean
value of its operand:

NOT False { Expression is True }


NOT True { Expression is False }

Some slightly less simplistic examples:

NOT (6 > I) { True for I < 6 }


NOT (J = K) { True for J <> K }

The parentheses indicate that the expression within the parentheses is evaluated
first, and only then is the resultant value acted upon by NOT. This expression is an
instance where “order of evaluation” becomes important. I’ll discuss this in detail
in Section X.X.
AND (also known as “conjunction”) requires two operands, and follows this
rule: If both operands are True, the expression returns True; else the expression returns False.
If either operand or both operands have the value False, the value of the expression
as a whole will be False. Some examples:

True AND True { Expression is True }


True AND False { Expression is False }
False AND True { Expression is False }
False AND False { Expression is False }

(7 > 4) AND (5 <> 3) { Expression is True }


(16 = (4 * 4)) AND (2 <> 2) { Expression is False }

All of these example expressions use constants, and thus are not realistic uses of
Pascal Atoms 129

AND within a program. We present them this way so the logic of the statement is
obvious without having to remember what value is currently in a variable present
in an expression. We’ll be presenting some real-life coding examples of the use of
NOT, AND, and OR in connection with the discussion of order of evaluation in
Section X.X.
OR (also known as “disjunction”) requires two operands, and follows this rule:
If either (or both) operands is True, the expression returns True; only if both operands are False
will the expression return False.
Some examples, again using constants:

True OR True { Expression is True }


True OR False { Expression is True }
False OR True { Expression is True }
False OR False { Expression is False }

(7 > 4) OR (5 = 3) { Expression is True }


(2 < 1) OR (6 <> 6) { Expression is False }

Finally, there is XOR, which also requires two operands, and follows this rule: If
both operands are the same Boolean value, XOR returns False; only if the operands have unlike
Boolean values will XOR return True. Some examples:

True XOR True { Expression is False }


True XOR False { Expression is True }
False XOR True { Expression is True }
False XOR False { Expression is False }

Greater Than or Equal To/Less Than or Equal To


These two operators are each combinations of two operators. These combinations
are so convenient and so frequently used that they were welded together to form
two single operators with unique symbols: >= (read, “greater than or equal to”,) and
<= (read, “less than or equal to.”)
When you wish to say:

X >= Y

you are in fact saying

(X > Y) OR (X = Y)

and when you wish to say


130 FreePascal from Square One, Volume 1

X <= Y

you are in fact saying

(X < Y) OR (X = Y)

The rules for applying >= and <= are exactly the same as those for < and >. They
may take only scalars or strings as operands.

6.5: Arithmetic operators


Manipulating numbers is done with arithmetic operators, which along with
numeric variables, form arithmetic expressions. About the only common
arithmetic operator not found in Pascal is the exponentiation operator, that is, the
raising of one number to a given power. (We will, however, build a function which
raises one number to the ower of another in Section X.X.) Table 6.6 summarizes the
arithmetic operators implemented in FreePascal.

Table 6.6. Arithmetic Operators


Operator Symbol Operand Types Result Type Precedence
Addition + Integer, real, cardinal same 4
Sign Inversion - Integer, real same 1
Subtraction - Integer, real, cardinal same 4
Multiplication * Integer, real cardinal same 3
Integer Division DIV Integer, cardinal same 3
Real Division / Integer, real, cardinal real 3
Modulus MOD Integer, cardinal same 3

Note that for the purposes of the table, “Integer” types include Integer, LongInt,
ShortInt, and SmallInt. “Cardinal” types include Word, Byte, LongWord,
Cardinal. “Real” types include Real, Single, Double, Extended, and Currency.
The old Comp type inherited from Borland Pascal is also considered a real type, but
it is not implemented on all platforms and I recommend that you not use it.
There are a lot of numeric types, and there are “gotchas” connected with some of
them, like Comp. I’ll explain numeric types in a great deal more detail in the next
chapter.
The Table 6.6 “operands” column lists those data types that a given operator
may take as operands. The compiler is fairly free about allowing you to mix types
Pascal Atoms 131

of numeric variables within an expression. In other words, you may multiply bytes
by integers, add reals to bytes, multiply integers by bytes, and so on. For example,
these are all legal expressions in FreePascal:

VAR
I,J,K : Integer;
R,S,T : Real;
A,B,C : Byte;
U,V : Single;
W,X : Double;
Q : ShortInt;
L : LongInt;

I * B { Integer multiplied by byte }


R + J { Integer added to real }
L * Q { LongInt multiplied by ShortInt }
C + (R * I) { Etc. }
J * (A / S)

The “result type” column in the table indicates the data type that the value
of an expression incorporating that operator may take on. Pascal is ordinarily
very picky about the assignment of different types to one another in assigment
statements. This “strict type checking” is relaxed to some extent in simple arithmetic
expressions. Numeric types may, in fact, be mixed fairly freely within expressions
as long as a few rules are obeyed:
1. Any expression including a floating point value may only be assigned
to a floating point variable.
2. Expressions containing floating point division (/) may only be assigned
to a floating point variable even if the operands are integer types.
Failure to follow these rules will generate the following error message:
Error 26: Type mismatch.

However, outside of the two mentioned restrictions, a numeric expression may


be assigned to any numeric variable, assuming the variable has sufficient range
to contain the value of the expression. (More on range in the next chapter.) For
example, if an expression evaluates to 14,000, you should not assign the expression
to a variable of type Byte, which can only contain values from 0 to 255. Program
behavior in cases like that is unpredictable. If range checking is on, such an
assignment will generate a range error.
Addition, subtraction, and multiplication are handled the same way ordinary
arithmetic is handled with pencil or calculator. Division is a little tricky.
132 FreePascal from Square One, Volume 1

Division
There are three distinct division operators in Pascal. One supports floating point
division, and the other two support division for integer and cardinal types. Floating
point division (/) may take operands of any numeric type, but it always produces a
floating point value, complete with decimal part. Attempting to assign a floating
point division expression to an integer type will generate error #26, even if all numeric
variables involved are integers:

VAR
I,J,K : Integer;

I := J / K; { Won’t compile!!! }

Division for numbers that cannot hold decimal parts is handled much the same
way division is first taught to grade schoolers: When one number is divided by
another, two numbers result. One is a whole number quotient; the other a whole
number remainder.
In Pascal, integer division is actually two separate operations that do not depend
upon one another. One operator, DIV, produces the quotient of its operands:

J := 17;
K := 3;
I := J DIV K; { I is assigned the value 5 }

No remainder is generated at all by DIV, and the operation should not be considered
incomplete. If you wish to compute the remainder, the modulus operator (MOD)
is used:
I := J MOD K; { I is assigned the value 2 }

Assuming the same values given above for J and K, the remainder of dividing J by K
is computed as 2. The quotient is not calculated at all (or calculated internally and
thrown away); only the remainder is returned.

Sign inversion
Sign inversion is a “unary” operator; that is, it takes only a single operand. What it
does is reverse the sign of its operand. It will make a positive quantity negative, or a
negative quantity positive. It does not affect the absolute value (distance from zero)
of the operand. Note that sign inversion cannot be used with cardinal types like
Cardinal, Byte, Word, or LongWord. Cardinal types are “unsigned”; that is, they
are never considered negative, and so changing the sign of the value is impossible.
Pascal Atoms 133

Recap: Pascal atoms and Pascal molecules


As with everything in Pascal, there’s structure going on here: Digits, letters, and
symbols might be thought of as Pascal’s “subatomic particles.” Combined according
to Pascal’s rules, you get reserved words, modifiers, identifiers, and operators, which
might be considered Pascal’s atoms.
Combining reserved words, operators, and identifiers gives you statements. If
you like the metaphor, statements might be considered Pascal’s molecules. For
example, IF and THEN and are reserved words. The equal sign = is a symbol, and
in nearly all cases in Pascal also acts as an operator. (I’ll describe operators in detail
in Chapter 8.) GotoXY is the identifier of a library function. Counter, Limit, and
NextProg are programmer-defined (that is, defined by you) identifiers.
This little snippet of code is a statement:
IF Counter = Limit THEN GotoXY(5,7);

Statements intuitively come across as “molecules of action,” much as English-


language sentences are. The statement above is almost sentence-like: “If Counter
equals Limit, then GotoXY at position 5,7.” Combining statements in a fashion
that respects Pascal’s structure gives you a program, which can be thought of
(stretching the metaphor perhaps a little beyond usefulness) as Pascal “machines”
or even “organisms.” The idea you need to take away from the metaphor is that in
Pascal, big things are made from smaller things, which in turn may be made from
even smaller things, according to rules that the compiler enforces. The atoms, for
the most part, are givens, but you make up the molecules, and from the molecules
create even larger and more complex things. Obviously, we’ll be talking about this
in more detail throughout the book. But for our next step, we need to talk about
data, and how Pascal defines data and structures it into data types.
134 FreePascal from Square One, Volume 1
Pascal Atoms 135
136 FreePascal from Square One, Volume 1
d
e
h
is
n
fi
n
U
Is
Chapter 7.
r
te
Data and Data Types
p
a
h
C
is
h
T

D ata is the raw material of computing. We sometimes seem obsessed by the


coding details of the programs that manipulates our data, but the data itself
is what we buy or sell and ultimately live by. The machinery of programming lies
empty without it. Good programs coalesce around a solid, detailed vision of what
data should be, both coming into a process and leaving it. So let’s look at the idea of
data, and the way that Pascal defines and manipulates it.

8.1. The notion of types and type conflicts


Data are chunks of information that your program manipulates. There are different
types of data, depending on what the data is intended to represent. How your
program handles your variables depends completely on what type you decide they
are. Every variable used in a Pascal program must be declared to be of some type,
with a notation like this:
CreditHours : Integer;

The variable’s identifier comes first, followed by a colon and then the name of the
type that you choose to define that variable by. The definition shown above allows
you to manipulate integer values in a variable called CreditHours, subject to
Pascal’s explicit limitations on what can be done with Integer data types.
I didn’t show it explicitly in the above definition, but variable definitions must
reside in the variable definition section of a Pascal program. The reserved word
VAR begins the variable definition section, and it runs until another program
section (say, a procedure or a function, or the main program) begins. The variable
definition section of a program (and there may be more than one in Turbo Pascal) is
where you give names to variables and assign them types. We’ll speak more of the
several sections of a Pascal program when we get into program structure later on.
In the meantime, you can refer back to a complete Pascal program with a variable
definition section on Page 80.

137
138 FreePascal from Square One, Volume 1

The nature of types


At the lowest level, all data of any type in a Pascal program (or in any program, really)
is stored as one or more binary numbers somewhere in your computer’s memory.
The data type of a data item to some extent dictates the way those binary numbers
are arranged in memory, and to a greater extent dictates how you as a human being
will use that data. The type of a data item is actually a set of rules governing the
storage and use of that data item. Data takes up space in memory. The type of a
data item dictates how much space is needed and how the data is represented in
that space. A signed integer, for example, occupies two bytes of memory. The most
significant bit of an integer carries the sign (that is, whether the integer value is
positive or negative) of the number that the integer represents.
The data type also governs how a data item may be used. The simplest example:
What is the letter “A” plus 17? That’s a meaningless question, since a letter is not
the same sort of a thing as a number. They’re used in different ways and “mean” in
different ways when we think about them. In Pascal, a letter is of type Char (short for
“character,” obviously) and 17 is type Integer, from the technical term for a number
(either positive or negative) with no decimal part. Pascal’s rules of typing prevent
you from adding two incompatible types like Char and Integer. The compiler will
not compile any such attempt, and will give you a type conflict error for trying.
Char and Integer are of different sizes in memory, so there is a sort of natural
incompatibility between them. However, the size of a type has very little to do with
the rules that govern it. Type Char and type Byte are both stored as single bytes in
memory, but you can add or multiply two variables of type Byte. Attempting to use
variables of type Char in an arithmetic expression will generate an error at compile
time.
The Pascal language incorporates strong typing, which means that there are strict
limitations on how individual types may be used, and especially on how variables of
one type may be assigned to variables of another type. In most cases, a variable of
one type may not be assigned to a variable of a different type. (The major exception
is with numeric types, which have a broad compatibility with one another. We’ll
discuss that issue in more detail a little later.) Transferring information between
variables across type boundaries is usually done with “transfer functions” that
depend upon well-defined relationships between types. Transfer functions will be
described in Chapter X.
Simple types (which include all the types described in this chapter) are
“unstructured;” that is, they are data atoms that cannot be broken down into
simpler data types.
Pascal Atoms 139

Pascal’s fundamental data types


All Pascal compilers implementing the standard Pascal language share certain
fundamental data types. These types express some of the most basic concepts of
computing: text, numbers, and logical truth and falsehood. From these fundamental
types you can build data structures to model practucally any data “idea” you can think
of, as I’ll discuss in more detail in Chapter X. Here are those fundamental types:
• Integers are numbers (including negative numbers) that cannot have
decimal points, like 1, -17, and 4529.
• Characters (indicated by predefined identifier Char) consist of the ASCII
character codes from 0 to 127. These include all the common letters,
numbers, and symbols used by all modern computers. FreePascal extends
the definition of type Char to include those first 128 ASCII characters
plus an additional 128 characters containing foreign language characters,
mathematical symbols, and those very useful “line-draw” characters used
to make boxes on the screen. Don’t be confused by the fact that the ASCII
character codes are numbered. Char is not a numeric type; just because
Box #3 has a number doesn’t make it a number rather than a box!
• Boolean types have only two possible values, True and False. They
represent the notion of truth and falsehood in logic, and are sometimes
called “flags”. Pascal uses them in conditional statements like IF/THEN/
ELSE and REPEAT/UNTIL to determine whether to take some action or
not. Boolean types will become very important in Chapter X, where I’ll
explain how you can use Boolean values and Pascal’s control statements
to produce structured programs.
• Real type variables are used to express “real numbers”; that is, numbers
that may include a decimal part. 1.16, -3240, 6.338 and -74.0457 are all
real numbers.

FreePascal’s simple data types


In addition to these elementary data types understood by all Pascal compilers,
FreePascal adds several of its own.
• Byte is a numeric type that can contain values from 0 to 255. Byte is an
example of an unsigned or cardinal numeric type, meaning that it cannot
take on a negative value. (That is, it can have neither a positive nor a
negative sign in front of it, as can most of the standard numeric types.
Byte types are always assumed to be positive.) Byte gets its name from the
fact that it occupies one single byte in memory. (The Word type occupies
two bytes, and some of the more esoteric numeric types occupy as many
as ten.)
140 FreePascal from Square One, Volume 1

• Word is like Byte in that it is unsigned and cannot hold negative values.
Like Integer it occupies two bytes of memory. Word types are sometimes
referred to, in fact, as “unsigned integers.” They may contain values from
0 to 65,535. Word variables are handy at times because they can hold
positive numbers twice as large as type Integer can.
• LongInt is what its name implies: A “long integer.” It occupies four bytes
in memory rather than two, as Integer types do. Their range is hugely
greater than Integer, however, and can express values from -2147483648
to 2147483647. Note again that you cannot use commas to break up the
expression of large numbers in Pascal, as we often do in ordinary day-
to-day correspondence. So while spitting out a number like 214748647
seems awkward without the commas, do get used to it: it’s simply the way
we do things in programming.
• ShortInt is another numeric type related to Integer, in that it holds
signed numeric values. Its range, however, is limited to -128 to 127, and it
occupies only one byte in memory. It is, in fact, a “signed byte.”

There are a number of additional numeric values defined in FreePascal. These are
the real number types modeled on the CPU’s “in silicon” real-number support, and
I’ll address them in detail later, in Section X.X.

8.2. Simple Constants


Constants are data values that are “baked into” your source code and do not change
during the execution of a program. There are two kinds of simple constants in
Standard Pascal: literal and named. FreePascal adds a third kind of constant that is
not really a constant: typed constants, that is, constants that have a specified type and
can be data structures like arrays and records. I’ll discuss typed constants after I’ve
had a chance to explain data structures, in Section X.X.

Literal versus named constants


A literal constant is a value of some sort that is stated as a value where it is used in your
code. For example:
SphereVolume := (4/3)*PI*(Radius*Radius*Radius);

In this line of code, “4” and “3” are literal constants, representing the numeric values
of 4 and 3.
There is another constant in that statement: The identifier PI was previously
declared a constant in the constant declaration part of the program. The constant
Pascal Atoms 141

declaration part begins with the reserved word CONST and runs until some other
part of the program begins. The constant declaration part is typically very early in a
program, and is often the very first part of a program after the program name:

PROGRAM AreaCalc;

CONST
PI = 3.14159;

Here, PI is a named constant. We could as well have used the literal constant
3.14159 in the statement, but “PI” is shorter and makes the expression less cluttered
and more readable. Especially where numbers are concerned, named constants
almost always make a program more readable.
Another use for constants is in the setting of program parameters that need
changing only very rarely. They still might be changed someday, and if you use a
named constant, changing the constant anywhere in the program is only a matter of
changing the constant’s declaration once in the constant declaration part of the
program and then recompiling.
The alternative is to hunt through hundreds or thousands of lines of source code
to find every instance of a literal constant to change it. You will almost certainly
miss at least one, and the resultant bug explosion may cost you dearly in time and
torn hair.
In short, don’t use literal constants anywhere you will ever anticipate needing
changes. In mathematical formulae literal constants are usually OK; but keep in
mind that using a named constant in place of a literal constant allows you to control
the precision of the constant everywhere in the program, from one constant
definition. You may want to use pi to eight decimal places initially, but later on, to
improve program performance, you may decide that five decimal places is plenty.
If you define the mathematical constant pi in a named constant at the front of your
program, you can change the precision instantly just by changing the definition—
and not have to worry about forgetting one or two places where you had hard-
coded a specific value of pi into an expression.

Constants and their types


In Standard Pascal, constants may be simple types, strings, and sets only. (I’ll be
covering sets in detail in Chapter X.) That group includes real numbers, integers,
characters, strings, sets, and Booleans. Individual enumerated types may also be
considered constants, although they are not declared the same way other constants
are. (Like sets, enumerated types are derived types that I’ll cover in Section X.X.)
142 FreePascal from Square One, Volume 1

Structured types like records, pointers and arrays may not be constants in Standard
Pascal. FreePascal supports data structure constants, (see Section X.X) but I must
explain data structures first before going into those.
Here are some example named constants of various types:
CONST
PI = 3.14159; { Floating point real }
Threshold = -71.47; { Negative FP real }
PenIOAddress = $06; { Hexadecimal value }
Using8087 = True; { Boolean }
DriveUnit = ‘A’; { Character }
Revision = ‘V2.61B’; { String }
Answer = 42; { Integer }
NotAnswer = -42; { Negative integer }
YesSet = [‘Y’,’y’]; { Set }
NullString = ‘’; { Null (empty) string }
BigNumber = 6117834 { Long integer or real }

I haven’t said much about strings yet (and will cover them in detail in Chapter
X) but string literals are easy to understand: You enclose some sequence of ASCII
characters between single-quote marks:
‘Call me Ishmael. In fact, call me anything but late for dinner.’

Literal string constants like this may be assigned to string variables later on in
the program.

Constants versus variables


How is a constant different from a variable? The obvious difference is that the value
of a constant is set at compile time. You cannot assign a value to a simple constant
in an assignment statement. Given the list of example constants shown above, you
could not legally code:
Answer := 47;

because Answer has been defined as a constant that already has a value of 42.
There is an important difference between constants and variables. In FreePascal,
simple constants are written into the code by the compiler as what we call immediate
data. This is difficult to explain if you don’t have some grasp of how computers
work down at the silicon level, but think of it this way: The value represented by a
simple constant is written into your program every place you use it. If you were to
define the Answer constant as shown above and reference it twelve times in your
program, the compiler would store Answer’s equivalent binary value (here, 42)
twelve times in your program code.
Pascal Atoms 143

Variables, by contrast, are kept separate from the code portion of a program, and
each variable is stored in only one place. Your program has a data segment in memory
where it stores its variables, and a named variable is present in the data segment
only once. To access the value stored in a variable, your program must use a memory
reference into the data segment to the place where the variable’s value is stored.
This isn’t something you need to know a lot about, and (especially while you’re a
beginner) where a variable is stored in memory and how the variable is represented
in memory aren’t terribly important. The important thing to remember is this:
• A constant is defined at compile time and cannot be changed whiel your
program is running.
• A variable is not given a value until your program gives it one at runtime,
and that value may be changed by your program at any point while the
program runs.
The type of a constant depends, to some extent, on its context. Consider:

PROGRAM AllTheAnswers;

CONST
Answer = 42;

VAR
Tiny : Byte; { One byte }
Little : ShortInt { A short integer (1 byte) }
Small : Integer; { An integer (2 bytes) }
Big : LongInt { A long integer (4 bytes) }
Huge : Real; { A real number (8 bytes) }

BEGIN
Tiny := Answer;
Little := Answer;
Small := Answer;
Big := Answer;
Huge := Answer;
END.

In the code snippet given above, Answer’s value is defined as 42. But it is perfectly
legal to assign the value of Answer to type Byte, type Integer, type ShortInt, type
LongInt, or type Real. The code the compiler generates to do the assignment in
each case is a little different, and that code is smart enough to translate the numeric
value “42” into a binary number that will be properly expressed as type Byte,
Integer, ShortInt, LongInt, or Real, or any other numeric type supported by the
compiler. (There are a few others that I’ll explain later on. FreePascal really does
have a numeric type for every occasion.) But the end result is that all five variables
of five different types will each express a numeric value of 42 in its own fashion.
144 FreePascal from Square One, Volume 1

Notes on literal constants


A dollar sign ($) in front of a numeric literal means that the compiler will interpret
the literal as a hexadecimal number—that is, a number written in base 16. The
numeric literal may not have a decimal point if it is to be considered hexadecimal.
Hexadecimal digits, in case you’re not familiar with the concept, run from 0
through 15, but the values 10 through 15 are expressed as the letters A (10) B (11)
C (12) D (13) E (14) and F (15.) So a hexadecimal number may include both letters
and digits:
$47
$5A
$B62F
$ECF6AA

I cover the hexadecimal system and hex numbers in great detail in my print book,
Assembly Language Step By Step, Third Edition (John Wiley & Sons, 2009).
Inside string literals, lower case and upper case characters are distinct. If you
wish to include a single quote mark as a character inside a string literal, you must
use two single quotes together:
Writeln(‘>>You haven’’t gotten it right yet...’);

This line of code will display the following line:


>>You haven’t gotten it right yet...

8.3: Constant expressions


Turbo Pascal 5.0 introduced the concept of constant expressions to the Pascal language,
and FreePascal inherited that idea. Prior to Turbo Pascal 5, a named constant could
be defined in only one way: By stating its name and equating it to a single literal
value with the “=” symbol. For example:
FudgeFactor = 17; { Simple named constant definition}

A constant expression allows you to give a value to a named constant in terms


of an expression that is evaluated at compile time. I haven’t covered expressions in
detail yet, but you may look ahead to Chapter X if you’d like to understand constant
expressions fully at this point; otherwise, return to this section once you’ve had a
chance to get acquainted with them.
Note that only simple constants may be given values from constant expressions.
Typed constants may not by assigned values from constant expressions. Typed constants are
a slightly odd concept, and I’ll discuss them in Chapter X.
Pascal Atoms 145

An expression, briefly, is a combination of identifiers, values, and operators that


“cooks down” to a single value. Expressions resemble portions of equations from
physics, into which you plug necessary values and finally evaluate to a single value:

Kinetic energy = Mass * Velocity2


Here, “Mass * Velocity2” is an expression, albeit not one written in Pascal. Once you
know the mass and velocity in the current context, you can plug theose values into
the equation and “do the math” to come up with a value for the kinetic energy.
It’s much the same way with constant expressions. In a constant expression,
a constant is given a value in terms of a combination of operators, values, and
constants that were defined earlier in the program:
DropletDiameterInMM = 3;
DropletRadiusInMM = DropletDiameterInMM / 2;
DropletAreaInSqMM = 4 * PI * DropletRadiusInMM * DropletRadiusInMM;

Here, DropletDiameterInMM is a simple named constant. Both of the constants


that follow it are defined by constant expressions. When the compiler encounters
a constant expression during its compilation of the program, it “does the math”
and assigns the resulting value to the constant itself. A constant expression may
make use of constants defined by earlier constant expressions. In the example
above, DropletRadiusInMM is calculated from DropletDiameterInMM. On the
next line, DropletAreaInSqMM is calculated from DropletRadiusInMM. The
identifier PI here is a named constant that is predefined by FreePascal and is always
available to your programs.
As with simple constants, a value is calculated for a constant expression at
compile time, and the constant may not be given a different value at runtime.

Limitations of constant expressions


If you’re familiar with expressions as they occur in normal Pascal statements, you
may be wondering if any legal expression may be assigned to a constant. The answer
is emphatically no; the permissible expressions used in constant expressions are
much more limited. Legal elements of a constant expression are these:
• Literal constants. These include numeric literals like 42 and 17.00576, the
Boolean literals True and False, and quoted string and character literals
like ‘Z’ and ‘Snark’.
• Previously defined constants. In other words, a constant expression may
make use of named constants defined earlier in the program, like
DropletDiameterInMM in the example above.
146 FreePascal from Square One, Volume 1

• Pascal operators. These are the basic arithmetic operators like addition
and subtraction, the logical operators like AND and OR, and the
bitwise operators like AND, OR, SHR, SHL, and so on. For a complete
discussion of FreePascal’s operators, see Chapter X.
• Certain built-in functions. A very few of FreePascal’s built-in functions may
take part in constant expressions. These include Ord, Chr, Odd, Hi,
Lo, Length, Abs, Pred, Succ, and Swap. All other functions, including
those you write yourself and those built into the compiler (including Sqr
and Cos) are illegal. For those of you who can appreciate the differences
at this point in your understanding of Pascal, FreePascal generates code
for “functions” like Abs in-line (in the fashion of an assembly language
macro) while other functions like Sqrt and Cos are true Pascal functions
that must be called like any other functions from the FreePascal runtime
library. Abs and its kin are more properly macros than functions, and can
be evaluated in-line by the compiler during compilation.
Although it might be obvious to veteran Pascal programmers, it’s worth stating
clearly that variables cannot be part of constant expressions. FreePascal allows constants
to be defined after variables are declared (as Standard Pascal does not) but not after
variables are assigned values. This means that a variable would introduce an undefined
quantity into a constant expression, which can cause a lot of trouble at runtime.

Some examples of constant expressions


The best way to show what’s possible with constant expressions is to put a few in
front of you. The following are all legal, if not necessarily useful in every case.
CONST
Platter = 1;
FirstSide = Odd(Platter); { Boolean }
FlipSide = NOT FirstSide; { Boolean}

Yesses = [‘Y’,’y’]; { Character set }


Noes = [‘N’,’n’]; { Character set }
Answers = Yesses + Noes; { Union of 2 sets }

USHoller = ‘ATTENTION!! ‘; { String }


USGasMsg = ‘Fuel level is low!’; { String }
USGasWarn = USHoller + USGasMsg; { String concatenation }
USWarnSiz = Length(USGasWarn); { String length }

LongSide = 17;
ShortSide = 6;
TankDepth = 8;
Volume = LongSide * ShortSide * TankDepth; { Constant expression }
Pascal Atoms 147

Why use constant expressions?


There are two excellent reasons to use constant expressions: Reconfiguration and
documentation. Both relate to the use of what I call “magic numbers” in program
development.
Many programs use values that may be defined once in a program and are
never modified. These include mathematical constants, and I/O port numbers and
bit numbers for low-level control of embedded systems hardware. These “magic
numbers” aren’t expected to change, but to be safe, they should always be defined
as constants rather written out separately as dozens or hundreds of numeric literals
shotgunned throughout what may be a very large program.
An excellent example of reconfiguration through constant expressions involves
directly programming the communications port on the PC. This used to be fairly
common in the DOS era, when direct control of PC hardware was easy and virtually
unrestricted. Windows and Linux now forbid such application-level tinkering, but
direct access to hardware like serial ports is still done in embedded systems work.
FreePascal is sometimes used to develop embedded systems code, but I won’t be
covering that use in this book.
Whether or not you ever get a chance to work on serial port driver code, as an
example it’s still instructive: Two serial ports, COM1: and COM2:, are supported
by the PC hardware. They are accessed through different sets of I/O ports, and the
differences in the port addresses follows an unchanging relationship. By defining a
single constant specifying either COM1: or COM2:, the control port addresses may
be recalculated in constant expressions based on that single port number definition.
This is what the following code does:
CONST
COMPORT = 1; { 1 = COM1: 2 = COM2: }
COMBASE = $2F8; { Build on this “magic number” }

{ Base I/O port is $3F8 for COM1: and $2F8 for COM2: }
PORTBASE = COMBASE OR (COMPORT SHL 8);

{ Transmit Holding Register is write-only at the base port: }


THR = PORTBASE;

{ Receive Buffer Register is read-only at the base port: }


RBR = PORTBASE;

IER = PORTBASE + 1; { Interrupt Enable register }


IIR = PORTBASE + 2; { Interrupt identification register }
LCR = PORTBASE + 3; { Line control register }
MCR = PORTBASE + 4; { Modem control register }
LSR = PORTBASE + 5; { Line status register }
148 FreePascal from Square One, Volume 1

Don’t panic if most of this doesn’t make immediate sense to you! What matters
here is knowing how each of the identifiers in the example above is given a value.
Every one of the constants defined in the example code fragment has a different
value depending on whether the COM1: or COM2: serial ports is to be used. By
changing the value of the constant COMPORT from 1 to 2, all the other constants
change accordingly to the values that apply to serial port COM2:. The program
does not need to be peppered with magic numbers like $2FC and $3FA. Also,
your program does not need to spend time initializing all these port numbers as
variables, because the compiler does all the calculation at compile time, and the
resulting values are inserted as immediate data into the code generated from your
source file.
The other use for constant expressions helps your programs document
themselves. You may need some sort of mathematical “fudge factor” in a complicated
program. You can define it as a simple named real-number constant:
FudgeFactor = 8.8059;

No one, looking at the literal numeric value, would have any idea of its derivation.
If the value is in fact the result of an established formula, it can help readability to
make the formula part of a constant expression:
ZincOxideDensity = 5.606;
FudgeFactor = ZincOxideDensity * (PI / 2);

This will help others (or maybe even you) keep in mind that you had to fudge things
by multiplying the density of zinc oxide by Pi over 2. (That is, assuming you want
the world to know...)
The idea should never be far from your mind that Pascal programs are meant
to be read. If you can’t read them, you can’t change them (or fix them) and then you
might as well throw them away and start from scratch. Do whatever you can to
make your programs readable. You (or whoever will someday inherit and have to
work with your code) will be glad you did.

8.4. FreePascal’s Non-Numeric Ordinal Types


Many of Pascal’s most useful types fall into a category we call ordinal types. An ordinal
type has a limited number of discrete values that exist in one completely-defined
and ordered series. There is a “first” value and a “last” value, and there are Pascal
functions to allow you to move from one value in an ordinal type to the next value,
or to the previous value. Pascal’s ordinal types include Char and Boolean. Integer
types like Integer, Byte, ShortInt, and LongInt are ordinal types, but I’ll describe
Pascal Atoms 149

them in the next section, as there are complications unique to numeric types that
will take some time to explain. Enumerated types are also considered ordinal, but
I’ll treat them separately in Chapter X.

Characters
The best way to explain Pascal’s ordinal types is through a close look at the most
common such type: Char.Type Char (character) is an ISO Standard Pascal type,
present in all implementations of Pascal. Type Char includes the familiar ASCII
character set: Letters, numbers, common symbols, and the control characters
like carriage return, backspace, tab, etc. There are 128 characters in the ASCII
character set. But type Char actually includes 256 different values, since a character
is expressed as an eight-bit byte. (Eight bits may encode 256 different values.)
The “other” 128 characters have no standard names or meanings in the ASCII
character set. When displayed on a device that supports their glyphs, the “high” 128
characters show up as foreign language characters, fractions, segments of boxes, or
mathematical and other miscellaneous symbols.
How, then, to represent such characters in your program? The key lies in the
concept of ordinality. There are 256 different characters included in type Char.
These characters exist in a specific ordered sequence numbered 0,1,2,3 and onward
up to 255. The 65th character (counting from 0, remember) is always capital A. The
32rd character is always a space, and so on.
An ordinal number is a number indicating a position in an ordered series. A
character’s position in the sequence of type Char is its ordinality. The ordinality
of capital A is 65. The ordinality of capital B is 66, and so on. Any character in
type Char can be unambiguously expressed by its ordinality, using the standard
“transfer function” Chr. A capital A may be expressed as the character literal ‘A’. It
may also be expressed as Chr(65). The expression Chr(65) may be used anywhere
you would use the character literal ‘A’.
Beyond the limits of the displayable ASCII character set, the Chr function is the
only reasonable way to express a character. The character expressed as Chr(234)
will display on the PC-compatible screena as the Greek capital letter omega (Ω) but
may be displayed as something else on another computer that is not PC-compatible.
It is best to express such characters using the function Chr.
What will Pascal allow you to do with variables of type Char?
1. You can write them to the screen or printer using Write and Writeln:
Writeln(‘A’);
Write(Chr(234));
Write(UnitChar); { UnitChar is a variable of type Char }
150 FreePascal from Square One, Volume 1

2. You can concatenate them with string variables using the string
concatenation operator (+) or the Concat built-in function: (See Section
X.X)
ErrorString := Concat(‘Disk error on drive ‘,UnitChar);
DriveSpec := UnitChar + ‘:’ + FileName;

3. You can derive the ordinality of characters with the Ord transfer
function:
BounceValue := 31+Ord(UnitChar);

Ord returns a numeric value giving the ordinality of the character


parameter. Ord allows you to perform arithmetic operations on the
ordinality of a character. I’ll discuss this in more detail in connection with
transfer functions in Section X.X.
4. You can compare characters to one another with relational operators like
=, >, <, >=, <=, and <>. (See Chapter 6.) This is due to the way characters
are ordered in a series. What you are actually comparing is the ordinality
of the two characters in their series when you use relational operators.
For example, when you see this expression:
‘a’ > ‘A’

(which evaluates to a boolean value of TRUE) the computer is actually


performing a comparison of the ordinalities of ‘a’ and ‘A’:
97 > 65

Since lower-case ‘a’ is positioned after upper-case ‘A’ in the series of


characters, its ordinality is larger, and therefore ‘a’ is in fact “greater than”
‘A’.

8.5. Booleans
Type Boolean is part of ISO Standard Pascal. A Boolean variable has only two
possible values, TRUE and FALSE. Like type Char, type Boolean is an ordinal
type, which means it has a fixed number of possible values that exist in a definite
order. In this order, FALSE comes before TRUE. By using the transfer function
Ord you would find that:
Ord(FALSE) returns the value 0.
Ord(TRUE) returns the value 1.
Pascal Atoms 151

The status of the words TRUEand FALSEis a little tricky. In older versions
of Pascal, including both the Borland Pascals and Delphi, TRUEand FALSE are
predefined identifiers with no special status beyond that. The compiler predefines
them as constants of type Boolean. This means that if you really want to, you
can give TRUE and FALSE some other definition in your programs, as constants
or variables. (This is a very bad idea and I don’t recommend it.) When FreePascal
is operating in Turbo mode ($MODE TP) or Delphi mode ($MODE DELPHI) this
remains the case. However, in FreePascal’s native mode ($MODE FPC) TRUE and
FALSE are reserved words and may not be redefined. Unless you explicitly specify
one of the other modes, FreePascal operates in FreePascal mode, so by default
TRUE and FALSE are reserved words. I think this is a good idea, and the upper-
case expression of TRUE and FALSE in the rest of this book reflects it.
A Boolean variable occupies only a single byte in memory. The actual words
True and False are not physically present in a Boolean variable. When a Boolean
variable contains the value TRUE, it actually contains the binary number 01.
When a Boolean variable contains the value FALSE, it actually contains the binary
number 00. If you write a Boolean variable to a disk file, the binary values 00 or 01
will be physically written to the disk. However, when you print or display a Boolean
variable using Write or Writeln, the binary values are recognized by program
code and the words “TRUE” or “FALSE” (in uppercase ASCII characters) will be
substituted for the binary values 00 and 01.
Boolean variables are used to store the results of expressions using the relational
operators =, >, <, <>, >=, and <=, and the set operators +, *, -. Operators and
expressions will be discussed more fully in Section X.) An expression such as “2
< 3” is easy enough to evaluate; logically you would say that the statement “two is
less than three” is “true.” If this were put as an expression in Pascal, the expression
would return a Boolean value of True, which could be assigned to a Boolean
variable and saved for later processing:
OK := 2 < 3;

This assignment statement stores a Boolean value of TRUE into the Boolean variable
OK. The value of OK can later be tested with an IF..THEN..ELSE statement, with
different actions taken by the code depending on the value assigned to OK:

OK := 2 < 3;
IF OK THEN
Writeln(‘>>Two comes before three, not after!’)
ELSE
Writeln(‘>>We are all in very serious trouble...’);
152 FreePascal from Square One, Volume 1

Boolean variables are also used to alter the flow of program control in the
WHILE..DO statement and the REPEAT..UNTIL statement. (See Sections X.X
and X.X.)
Pascal Atoms 153

You might also like