Marco's Web Center

Menu for Books
Delphi 2007 Handbook
Mastering Delphi 2005
Essential Delphi 8 for .NET
Mastering Delphi 7
Essential Pascal
Essential Delphi
Buy Books Online
Marco's TechBookStore

Site Menu
Object Pascal Handbook
Delphi Handbooks Collection
Mastering Borland Delphi 2005
(Old) White Papers
(Old)Tools
(Old) Conferences

My Other Sites
Italian Site (www.marcocantu.it)
the delphi search

Spirit of delphi

Advertising
Home My Blog Books Object Pascal Marco
Essential Pascal Cover

The cover of the 4th edition of Essential Pascal, the first available in print (and PDF) on Lulu.com.

Marco Cantù's
Essential Pascal

Chapter 2
Coding in Pascal

Before we move on to the subject of writing Pascal language statements, it is important to highlight a couple of elements of Pascal coding style. The question I'm addressing here is this: Besides the syntax rules, how should you write code? There isn't a single answer to this question, since personal taste can dictate different styles. However, there are some principles you need to know regarding comments, uppercase, spaces, and the so-called pretty-printing. In general, the goal of any coding style is clarity. The style and formatting decisions you make are a form of shorthand, indicating the purpose of a given piece of code. An essential tool for clarity is consistency-whatever style you choose, be sure to follow it throughout a project.

Comments

In Pascal, comments are enclosed in either braces or parentheses followed by a star. Delphi also accepts the C++ style comments, which can span to the end of the line:

{this is a comment}
(* this is another comment *)
// this is a comment up to the end of the line

The first form is shorter and more commonly used. The second form was often preferred in Europe because many European keyboards lack the brace symbol. The third form of comments has been borrowed from C++ and is available only in the 32-bit versions of Delphi. Comments up to the end of the line are very helpful for short comments and for commenting out a line of code.

In the listings of the book I'll try to mark comments as italic (and keywords in bold), to be consistent with the default Delphi syntax highlighting.

Having three different forms of comments can be helpful for making nested comments. If you want to comment out several lines of source code to disable them, and these lines contain some real comments, you cannot use the same comment identifier:

{  ... code
{comment, creating problems}
... code }

With a second comment identifier, you can write the following code, which is correct:

{  ... code
//this comment is OK
... code }

Note that if the open brace or parenthesis-star is followed by the dollar sign ($), it becomes a compiler directive, as in {$X+}.

Actually, compiler directives are still comments. For example, {$X+ This is a comment} is legal. It's both a valid directive and a comment, although sane programmers will probably tend to separate directives and comments.

Use of Uppercase

The Pascal compiler (unlike those in other languages) ignores the case (capitalization) of characters. Therefore, the identifiers Myname, MyName, myname, myName, and MYNAME are all exactly equivalent. On the whole, this is definitely a positive, since in case-sensitive languages, many syntax errors are caused by incorrect capitalization.

Note: There is only one exception to the case-insensitive rule of Pascal: the Register procedure of a components' package must start with the uppercase R, because of a C++Builder compatibility issue.

There are a couple of subtle drawbacks, however. First, you must be aware that these identifiers really are the same, so you must avoid using them as different elements. Second, you should try to be consistent in the use of uppercase letters, to improve the readability of the code.

A consistent use of case isn't enforced by the compiler, but it is a good habit to get into. A common approach is to capitalize only the first letter of each identifier. When an identifier is made up of several consecutive words (you cannot insert a space in an identifier), every first letter of a word should be capitalized:

MyLongIdentifier
MyVeryLongAndAlmostStupidIdentifier

Other elements completely ignored by the compiler are the spaces, new lines, and tabs you add to the source code. All these elements are collectively known as white space. White space is used only to improve code readability; it does not affect the compilation.

Unlike BASIC, Pascal allows you to write a statement on several lines of code, splitting a long instruction on two or more lines. The drawback (at least for many BASIC programmers) of allowing statements on more than one line is that you have to remember to add a semicolon to indicate the end of a statement, or more precisely, to separate a statement from the next one. Notice that the only restriction in splitting programming statements on different lines is that a string literal may not span several lines.

Again, there are no fixed rules on the use of spaces and multiple-line statements, just some rules of thumb:

  • The Delphi editor has a vertical line you can place after 60 or 70 characters. If you use this line and try to avoid surpassing this limit, your source code will look better when you print it on paper. Otherwise long lines may get broken at any position, even in the middle of a word, when you print them.
  • When a function or procedure has several parameters, it is common practice to place the parameters on different lines.
  • You can leave a line completely white (blank) before a comment or to divide a long piece of code in smaller portions. Even this simple idea can improve the readability of the code, both on screen and when you print it.
  • Use spaces to separate the parameters of a function call, and maybe even a space before the initial open parenthesis. Also keep operands of an expression separated. I know that some programmers will disagree with these ideas, but I insist: Spaces are free; you don't pay for them. (OK, I know that they use up disk space and modem connection time when you upload or download a file, but this is less and less relevant, nowadays.)

Pretty-Printing

The last suggestion on the use of white spaces relates to the typical Pascal language-formatting style, known as pretty-printing. This rule is simple: Each time you need to write a compound statement, indent it two spaces to the right of the rest of the current statement. A compound statement inside another compound statement is indented four spaces, and so on:

if ... then
  statement;

if ... then
begin
  statement1;
  statement2;
end;

if ... then
begin
  if ... then
    statement1;
  statement2;
end;

The above formatting is based on pretty-printing, but programmers have different interpretations of this general rule. Some programmers indent the begin and end statements to the level of the inner code, some of them indent begin and end and then indent the internal code once more, other programmers put the begin in the line of the if condition. This is mostly a matter of personal taste.

A similar indented format is often used for lists of variables or data types, and to continue a statement from the previous line:

type
  Letters = set of Char;
var
  Name: string;
begin
   { long comment and long statement, going on in the
     following line and indented two spaces }
   MessageDlg ('This is a message',
     mtInformation, [mbOk], 0);

Of course, any such convention is just a suggestion to make the code more readable to other programmers, and it is completely ignored by the compiler. I've tried to use this rule consistently in all of the samples and code fragments in this book. Delphi source code, manuals, and Help examples use a similar formatting style.

Syntax Highlighting

To make it easier to read and write Pascal code, the Delphi editor has a feature called color syntax highlighting. Depending on the meaning in Pascal of the words you type in the editor, they are displayed using different colors. By default, keywords are in bold, strings and comments are in color (and often in italic), and so on.

Reserved words, comments, and strings are probably the three elements that benefit most from this feature. You can see at a glance a misspelled keyword, a string not properly terminated, and the length of a multiple-line comment.

You can easily customize the syntax highlight settings using the Editor Colors page of the Environment Options dialog box (see Figure 2.1). If you work by yourself, choose the colors you like. If you work closely with other programmers, you should all agree on a standard color scheme. I find that working on a computer with a different syntax coloring than the one I am used to is really difficult.

FIGURE 2.1: The dialog box used to set the color syntax highlighting.

Note: In this book I've tried to apply a sort of syntax highlighting to the source code listings. I hope this actually makes them more readable.

Using Code Templates

Delphi 3 introduced a new feature related to source code editing. Because when writing Pascal language statements you often repeat the same sequence of keywords, Borland has provided a new feature called Code Templates. A code template is simply a piece of code related with a shorthand. You type the shorthand, then press Ctrl+J, and the full piece of code appears. For example, if you type arrayd, and then press Ctrl+J, the Delphi editor will expand your text into:

array [0..] of ;

Since the predefined code templates usually include several versions of the same construct, the shortcut generally terminates with a letter indicating which of the versions you are interested in. However, you can also type only the initial part of the shortcut. For example, if you type ar and then press Ctrl+J, the editor will display a local menu with a list of the available choices with a short description, as you can see in Figure 2.2.

Figure 2.2: Code Templates selection

You can fully customize the code templates by modifying the existing ones or adding your own common code pieces. If you do this, keep in mind that the text of a code template generally includes the '|' character to indicate where the cursor should jump to after the operation, that is, where you start typing to complete the template with custom code.

Language Statements

Once you have defined some identifiers, you can use them in statements and in the expressions that are part of some statements. Pascal offers several statements and expressions. Let's look at keywords, expressions, and operators first.

Keywords

Keywords are all the Object Pascal reserved identifiers, which have a role in the language. Delphi's help distinguishes between reserved words and directives: Reserved words cannot be used as identifiers, while directives should not be used as such, even if the compiler will accept them. In practice, you should not use any keywords as an identifier.

In Table 2.1 you can see a complete list of the identifiers having a specific role in the Object Pascal language (in Delphi 4), including keywords and other reserved words.

Table 2.1: Keywords and other reserved words in the Object Pascal language

Keyword Role
absolute directive (variables)
abstract directive (method)
and operator (boolean)
array type
as operator (RTTI)
asm statement
assembler backward compatibility (asm)
at statement (exceptions)
automated access specifier (class)
begin block marker
case statement
cdecl function calling convention
class type
const declaration or directive (parameters)
constructor special method
contains operator (set)
default directive (property)
destructor special method
dispid dispinterface specifier
dispinterfacetype
div operator
do statement
downto statement (for)
dynamic directive (method)
else statement (if or case)
end block marker
except statement (exceptions)
export backward compatibility (class)
exports declaration
external directive (functions)
far backward compatibility (class)
file type
finalizationunit structure
finally statement (exceptions)
for statement
forward function directive
function declaration
goto statement
if statement
implementationunit structure
implements directive (property)
in operator (set) - project structure
index directive (dipinterface)
inherited statement
initializationunit structure
inline backward compatibility (see asm)
interface type
is operator (RTTI)
label declaration
library program structure
message directive (method)
mod operator (math)
name directive (function)
near backward compatibility (class)
nil value
nodefault directive (property)
not operator (boolean)
object backward compatibility (class)
of statement (case)
on statement (exceptions)
or operator (boolean)
out directive (parameters)
overload function directive
override function directive
package program structure (package)
packed directive (record)
pascal function calling convention
private access specifier (class)
procedure declaration
program program structure
property declaration
protected access specifier (class)
public access specifier (class)
published access specifier (class)
raise statement (exceptions)
read property specifier
readonly dispatch interface specifier
record type
register function calling convention
reintroduce function directive
repeat statement
requires program structure (package)
resident directive (functions)
resourcestringtype
safecall function calling convention
set type
shl operator (math)
shr operator (math)
stdcall function calling convention
stored directive (property)
string type
then statement (if)
threadvar declaration
to statement (for)
try statement (exceptions)
type declaration
unit unit structure
until statement
uses unit structure
var declaration
virtual directive (method)
while statement
with statement
write property specifier
writeonly dispatch interface specifier
xor operator (boolean)

Expressions and Operators

There isn't a general rule for building expressions, since they mainly depend on the operators being used, and Pascal has a number of operators. There are logical, arithmetic, Boolean, relational, and set operators, plus some others. Expressions can be used to determine the value to assign to a variable, to compute the parameter of a function or procedure, or to test for a condition. Expressions can include function calls, too. Every time you are performing an operation on the value of an identifier, rather than using an identifier by itself, that is an expression.

Expressions are common to most programming languages. An expression is any valid combination of constants, variables, literal values, operators, and function results. Expressions can also be passed to value parameters of procedures and functions, but not always to reference parameters (which require a value you can assign to).

Operators and Precedence

If you have ever written a program in your life, you already know what an expression is. Here, I'll highlight specific elements of Pascal operators. You can see a list of the operators of the language, grouped by precedence, in Table 2.1.

Contrary to most other programming languages, the and and or operators have precedence compared to the relational one. So if you write a < b and c < d, the compiler will try to do the and operation first, resulting in a compiler error. For this reason you should enclose each of the < expression in parentheses: (a < b) and (c < d).

Some of the common operators have different meanings with different data types. For example, the + operator can be used to add two numbers, concatenate two strings, make the union of two sets, and even add an offset to a PChar pointer. However, you cannot add two characters, as is possible in C.

Another strange operator is div. In Pascal, you can divide any two numbers (real or integers) with the / operator, and you'll invariably get a real-number result. If you need to divide two integers and want an integer result, use the div operator instead.

Table 2.2: Pascal Language Operators, Grouped by Precedence

Unary Operators (Highest Precedence)
@ Address of the variable or function (returns a pointer)
not Boolean or bitwise not
Multiplicative and Bitwise Operators
* Arithmetic multiplication or set intersection
/ Floating-point division
div Integer division
mod Modulus (the remainder of integer division)
as Allows a type-checked type conversion among at runtime (part of the RTTI support)
and Boolean or bitwise and
shl Bitwise left shift
shr Bitwise right shift
Additive Operators
+ Arithmetic addition, set union, string concatenation, pointer offset addition
- Arithmetic subtraction, set difference, pointer offset subtraction
or Boolean or bitwise or
xor Boolean or bitwise exclusive or
Relational and Comparison Operators (Lowest Precedence)
= Test whether equal
<> Test whether not equal
< Test whether less than
> Test whether greater than
<= Test whether less than or equal to, or a subset of a set
>= Test whether greater than or equal to, or a superset of a set
in Test whether the item is a member of the set
is Test whether object is type-compatible (another RTTI operator)

Set Operators

The set operators include union (+), difference (-), intersection (*),membership test (in), plus some relational operators. To add an element to a set, you can make the union of the set with another one that has only the element you need. Here's a Delphi example related to font styles:

Style := Style + [fsBold];
Style := Style + [fsBold, fsItalic] - [fsUnderline];

As an alternative, you can use the standard Include and Exclude procedures, which are much more efficient (but cannot be used with component properties of the set type, because they require an l-value parameter):

Include (Style, fsBold);

Conclusion

Now that we know the basic layout of a Pascal program we are ready to start understanding its meaning in detail. We'll start by exploring the definition of predefined and user defined data types, then we'll move along to the use of the keywords to form programming statements.

Next Chapter: Types, Variables, and Constants