Go to the first, previous, next, last section, table of contents.

# From Borland Pascal to GNU Pascal

This chapter is intended to be a QuickStart guide for programmers who are familiar with Borland Pascal, version 7 for DOS protected mode. Other versions don't differ too much but this one is the very last DOS version Borland has published.

- Borland compatibility
- There is no IDE!
- Comments and compiler directives
- Units; GPI files and AutoMake
- Optimization
- Debugging
- GPC inline assembler
- Objects
- Strings
- Typed constants
- Bit; byte and memory manipulation
- User-defined operators
- Data types
- Files
- Built-in constants
- Built-in operators
- Built-in Procedures and Functions
- Parameters
- Miscellaneous

## Borland compatibility

Unlike other FreeWare compilers, GNU Pascal is *not* intended to be 100% Borland compatible. GNU Pascal is part of the GNU project, so portability is one of its primary goals. For this reason, non-portable features of Borland Pascal will probably not be included into GNU Pascal. Some other differences are so minimal that we have more important things to do than to implement them.

However if you want to contribute to GNU Pascal by eliminating holes in GPC's Borland compatibility, be welcome in the GNU Pascal development team! See See section How you can contribute to GNU Pascal for details.

## There is no IDE!

It is one of the most annoying points about GPC that there is no Integrated Development Environment like BP.EXE at the moment. We are working on it, but this will take some time, especially because GNU Pascal is a portable compiler intended to run under a large variety of operating systems in the same manner. Please be patient--or offer your help! (For the moment, you can try to use Borland's IDE for GNU Pascal--see below.)

The GNU Pascal Compiler, GPC, is called about like the command-line version of the Borland Pascal Compiler, BPC. Edit your source file(s) with your favorite ASCII editor (e.g. the Borland IDE), then call GNU Pascal with a command line like

      C:\GNU-PAS> gpc hello.pas -o hello.exe

on your DOS or OS/2 box (with EMX you may omit the ``-o ...'`) or

      myhost/home/joe/gnu-pascal> gpc hello.pas -o hello

on your UNIX (e.g. Linux) box. Don't omit the suffix ``.pas'`: GPC is a common interface for a Pascal compiler, a C, ObjC and C++ compiler, an assembler, a linker, and perhaps a Modula and FORTRAN compiler. From the extension of your source file GPC figures out which processor to run.

The `-o` is a command line option which tells GPC how the executable has to be named. This is not necessary for DOS and OS/2, so we omit it in this file from now on.

Note that GPC is case-sensitive concerning file names, so it will not work if you type

      C:\GNU-PAS> GPC HELLO.PAS -O HELLO.EXE

GPC is a very quiet compiler and doesn't print anything on the screen unless you request it or there is an error. If you want to see what is going on, invoke GPC with additional options:

      -Q            "don't be quiet"  (or: Quassel-Modus in German)

(with capital ``Q'`!) means that GPC prints out the names of procedures and functions it processes, and

      --verbose

means that GPC informs you about the stages of compilation, i.e. preprocessing, compiling, assembling, and linking.

One example (this time for OS/2):

      [C:\GNU-Pascal] gpc --verbose -Q hello.pas

Throughout this chapter, we will tell you about a lot of command-line switches. They are all invoked this way.

After compilation, there will be an executable `hello` file in the current directory. (`hello.exe` with DOS and OS/2.) Just run it and enjoy. If there are errors, GNU Pascal will not stop compilation after the first one--as Borland Pascal does--but try to catch them all in one compilation. If you get more error messages than your screen can hold, you can catch them in a file (e.g. `gpc.out`) in the following way:

      gpc hello.pas 2>gpc.out

This works with OS/2 and any bash-like shell under UNIX; for DOS you must get a replacement for `command.com` which supports this kind of redirection (see also the DJGPP FAQ).

You can also use Borland's IDE for GNU Pascal on the DOS platform: Install the GNU Pascal Compiler in the Tools menu (via Options/Tools).

      Name:       GNU Pascal
      Path:       gpc
      Arguments:  $SAVE ALL --verbose -Q $NAME($EDNAME).pas
      HotKey:     Shift+F9

Note once more that GPC is case-sensitive, so it is important to specify `.pas` instead of the `.PAS` Borland Pascal would append otherwise!

You can include more command-line arguments to GNU Pascal (e.g. ``--automake'`; see below) as you will learn more about them.

Since Borland Pascal will try to recompile your program if you use its `run` menu function, you will need another "tool" to run your program:

      Name:       run program
      Path:       command.com
      Arguments:  /c $NAME($EDNAME)
      HotKey:     Shift+F10

## Comments and compiler directives

According to ISO 7185 and ISO 10206 standard, GNU Pascal recognizes by default comments opened with `(*` and closed with `}`. With Borland Pascal, both types of comments can be nested, so you will probably have sources where passages containing comments are "commented out".

To use this with GPC, you have to "switch on" nested comments either by a command-line option, or by a compiler directive:

      --nested-comments            {$N+}    (*$N+*)

The $N directive also exists in BP but has another meaning. The same holds for most of GPC's other compiler directives (also corresponding to command-line options in most cases):

      --short-circuit     $B+ $B-  like in Borland Pascal:
                                   $B- means short-circuit Boolean
                                   operators; $B+ complete evaluation

      --c-numbers         $C+ $C-  enable/disable C-style octal 0177
                                   and hexadecial 0xFF numbers

      --char-escapes      $E+ $E-  enable/disable C-style character
                                   escape sequences in strings

      --nested-comments   $N+ $N-  see above

      --pedantic          $P+ $P-  give/don't give warnings about
                                   violations of ISO 7185
                                   Standard Pascal

                          $W+ $W-  enable/disable warnings

                          $X+ $X-  enable/disable extended syntax
                                   (function return value ignore,
                                   operator definitions)

      {$I FileName }               include filename.pas or
                                   filename.p (make it lowercase)

      {$include "filename.pas"}    include (case-sensitive)

      {$include <filename.pas>}    the same, but don't search in
                                   current directory

      {$M Hello!}                  write message "Hello!" to error
                                   device during compilation

      {$D GNU}                     define GNU (for conditional
      {$define GNU}                compilation)

      -D GNU                       the same in command line

      {$D loop while true do}      define "loop" to be "while
                                   true do" as a macro like in C.
                                   It is case-sensitive.

      {$ifdef GNU}                 conditional compilation
        ...                        (like in Borland Pascal).
      {$else}                      GPC predefines the symbol
        ...                        __GPC__ (with two leading
      {$endif}                     and trailing underscores).

You also can use C-style preprocessor directives, e.g. #include.

As in Borland Pascal, `{$...}` and `(*$...*)` are equivalent.

## Units, GPI files and AutoMake

You can use Units in the same way as in Borland Pascal. However, there are some differences, problems and new features. (Please report the bug if something doesn't work.)

Concerning the syntax of a Unit, you can, if you want, use Extended Pascal syntax to specify a Unit initializer, i.e. instead of writing

      begin
        ...
      end.

at the end of the Unit, you can get the same result with

      to begin do
        begin
          ...
        end (* to begin *);

and there also exists

      to end do
        begin
          ...
        end (* to end *);

which specifies a finalization routine. Use this instead of Borland Pascal's exit procedures. You also can specify an order in which initializers are run--see See section GNU Pascal extensions and See section About Pascal and Extended Pascal languages for more about this. There you can also find information about Extended Pascal Modules, an alternative to Units.

At the moment, there are no qualified identifiers, so take care about name clashes between different Units.

When GPC compiles a Unit, it produces two files: an `.o` object file (compatible with other GNU compilers such as GNU C) plus a precompiled Interface which resides in a `.gpi` file. (See See section GPI files -- GNU Pascal Interfaces for GPI file internals.)

GPC does not automatically recognize that something is a Unit and cannot be linked; you have to tell this by a command line switch:

      -c            only compile, don't link.

For example, to compile two units, use:

      gpc -c myunit1.pas myunit2.pas

Of course, one of the purposes of writing Units is to compile them separately. However, GNU Pascal allows you to have one or more Units in the same source file (producing only one `.o` file but separate `.gpi` files). You even can have a Program and Units in one and the same source file; in this case, no `.o` file is produced at all.

You can use the above as a workaround (*$include the Unit *) in case something goes wrong with the .gpi mechanism. (It is a new feature in GPC 2.0 and may be unstable.)

When you have all Units compiled and want to compile the Program, specify the `.o` files in the command line:

      gpc hallo.pas myunit1.o myunit2.o

You also can specify the program and the units in one command line:

      gpc hallo.pas myunit1.pas myunit2.pas

As an alternative to manually compiling and specifying object files, you can use GPC's AutoMake feature. (WARNING: This is a new feature in GPC 2.0 and may be unstable!) With an additional command-line argument

      gpc --automake hallo.pas

GPC tries to behave like Borland Pascal's `make` facility and automatically recompiles Units the source of which has been changed. It also works if an included file has been changed.

To pass arguments to the compilation of Units, specify them in a string surrounded by quotation marks after `--automake=`. For example, if you want to give the `--verbose` argument not only at top level but also for (re)compilation of Units, use:

      gpc --verbose --automake="--verbose" hallo.pas

For more information about the AutoMake mechanism, see See section GNU Pascal's AutoMake facility.

## Optimization

GNU Pascal is a 32 bit compiler with excellent optimization algorithms (which are identically the same as those of GNU C). There are three optimization levels, specified by the command line options ``-O'`, ``-O2'`, and ``-O3'`. (Levels up to ``-O6'` are worked on.)

One example:

      Program Test;

      Var
        A, B: Integer;

      begin
        A:= 3;
        B:= 4;
        writeln ( A + B );
      end.

When GNU Pascal compiles this program with optimization, it recognizes that the argument of writeln is the constant 7--and optimizes away the variables `A` and `B`.

For more about optimization, see the GNU C documentation.

## Debugging

The command line option ``-g'` specifies generation of debugging information for GDB, the GNU debugger. GDB is not as comfortable as the Turbo Debugger, but it has the same abilities but one: The program being debugged is slowed down. For more information about GDB, call it (with ``gdb'`) and type in the `help` command.

GDB has one very nice feature which might even make up for the slowing-down problematic: When a GNU-compiled program crashes, it puts out a `core` file. When you say "target core core" to the GNU debugger, it reads the core file and can tell you the address of the crash, the contents of variables and of the stack, and so on.

Sometimes it is nice to have a look at the assembler output of the compiler. When you specify the `-S` command line option, GPC produces an `.s` file instead of an `.o` file which contains assembler source for your program. More about this in the next section.

## GPC inline assembler

GNU Pascal has an inline assembler, but it is quite different from Borland's one. I have not yet found reasonable documentation about the use of this assembler, but I found out the following:

The syntax is

      asm ( 'movl $12345678, %eax' );
      asm ( 'movl %eax, %edx' );

to move the (hex) value ``$12345678'` to the EAX register and then to the EDX register. The String argument of the asm "procedure" is passed as a string to the assembler stage of the compilation. The assembler follows the AT&T, not the Intel syntax. Note that the order of operands is reversed with respect to the order you know from Intel assemblers and that the size of the arguments is appended to the mnemonic as a suffix b (byte), w (word = 2 bytes), or l (long = 4 bytes).

You can learn about the GNU assembler syntax when compiling your program with ``-S'` (see above) and looking into the resulting assembler source.

To access Pascal symbols from the assembler, do something like

      asm ( 'movl %%eax, %0' : : 'rm' ( MyVariable ) );

Here, the % signs in front of the register names are doubled because % gets some special meaning. The 'rm' means that the operand may be in a register or in memory.

(If somebody knows more about the GNU assembler syntax, please, please, please explain it to me or point me to some reasonable documentation about it! <peter.gerwinski@uni-essen.de>)

## Objects

Objects in the Borland Pascal 7.0 notation are implemented into GNU Pascal with the following differences:

- the "private" directive does not work,
- data fields and methods may be mixed:

        MyObj = object
          x: Integer;
          Procedure Foo; virtual;
          y: Real;
          Function Bar: Char;
        end (* MyObj *);

## Strings

Strings are "Schema types" in GNU Pascal which is something more complicated than Borland-style strings. For variables, you cannot specify just `String` as a type (always specify the maximum length); for parameters you can. There is no 255 length limit. According to Extended Pascal, the maximum string length must be in (parantheses); GNU Pascal accepts [brackets], however.

For more about Strings and Schema types see See section GNU Pascal extensions and See section About Pascal and Extended Pascal languages.

String-handling functions (see See section GNU Pascal extensions) are different in both dialects but can approximately be mapped on each other:

      Borland Pascal          GNU Pascal

      length                  length
      Pos                     Index
      Str                     WriteStr
      Val                     ReadStr
      Copy                    SubStr, MyStr [ 2..7 ]
      MyStr [ 0 ]:= #7;       Trim
        -                     EQ, NE, LT, LE, GT, GE
      Insert                    -
      Delete                    -

It should not be difficult to write a compatibility Unit--if you do so, please send it to us!

## Typed constants

GNU Pascal supports Borland Pascal's "typed constants" but also Extended Pascal's initialized variables:

      Var
        x: Integer value 7;

When a typed constant is misused as an initialized variable, a warning is given.

Initialization of structured variables (typed constants) is not yet stable.

When you want a local variable to preserve its value, define it as ``__static__'` instead of using a typed constant:

      Procedure Foo;

      Var
        x: __static__ Real;

      begin (* Foo *)
        (* x keeps its value between two calls to this Procedure *)
      end (* Foo *);

Remark: If you don't like underscores, you can use the (*$define *) mechanism to get rid of them:

      (*$define static __static__ *)

## Bit, byte and memory manipulation

The (non-standard) bitwise operators ``shl'`, ``shr'`, ``and'`, ``or'`, ``xor'` work in GNU Pascal like in Borland Pascal. As an extension, you can use them as "procedures", for examples

      and ( x, $0000FFFF );

as an alternative to

      x:= x and $0000FFFF;

Instead of the Borland-specific notation ``$ABCD'` for hexadecimal numbers you also can use Extended Pascal notation:

       2#11111111   for a binary,
       8#177        for an octal,
      16#FF         for a hexadecimal number,

and so on up to a basis of 36.

Inc and dec are implemented like in Borland Pascal; pred and succ are generalized according to Extended Pascal:

      a:= succ ( a, 5 );

Absolute variables work only in the context of overloading with other variables, not in the context of specifying an absolute address. The Mem and Port arrays don't exist in GNU Pascal.

Borland Pascal's procedures `FillChar` and `move` are not built-in into GNU Pascal. However, you can write them by yourself using untyped Var parameters (see Sec. `Data types`).

## User-defined operators

GNU Pascal allows the user to define operators according to the Pascal-SC syntax:

      (*$X+*)

      Type
        Point = record
          x, y: Real;
        end (* Point *);

      Operator + ( a, b: Point ) c: Point;

      begin (* Point + Point *)
        c.x:= a.x + b.x;
        c.y:= a.y + b.y;
      end (* Point + Point *);

It is necessary to enable "extended syntax" ``(*$X+*)'` when defining operators.

The Pascal-SC operators ``+>'`, ``+<'`, etc. for exact numerical calculations are not implemented, but you can define them. If you write a module which really implements these operators, please send it to us, so we can include it into the next distribution.

(And if you know more about modules in Pascal-SC than just their existence, please contact us either! We could probably easily implement them if we knew how they look like. Something quite close to Pascal-SC modules already *is* implemented as "GNU specific modules".)

## Data types

- Generic Pointer: There is no built-in untyped Pointer in GNU Pascal. Use ``^Void'` to define it.
- Integer types: There is no built-in Byte, Word, etc. in GNU Pascal. Use the modifiers ``__byte__'`, ``__short__'`, ``__long__'` and ``__unsigned__'` (described in See section GNU Pascal extensions) to define them.

        Borland Pascal          GNU Pascal

        shortint                __byte__ Integer
        Integer                 __short__ Integer
        LongInt                 Integer = __long__ Integer
        Comp                    __longlong__ Integer
        Byte                    __unsigned__ __byte__ Integer
        Word                    __unsigned__ __short__ Integer
          -                     __unsigned__ __long__ Integer
          -                     __unsigned__ __longlong__ Integer

  Real types: There is no built-in ``Single'`, ``Double'`, ``Extended'` in GNU Pascal; Real has 8 bytes on an Intel-x86 machine. Use ``__short__ Real'` to define ``Single'`, ``__long__ Real'` to define ``Extended'`.

        Borland Pascal          GNU Pascal

        Single                  __short__ Real
        Real                      -
        Double                  Real
        Extended                __long__ Real
        Comp                    __longlong__ Integer

  A KNOWN BUG: You cannot `writeln` variables of a type with a `__` modifier. To work around, cast them to their basis type (Integer or Real) when `writeln`ing them:

        Var
          x: __long__ Real;

        writeln ( Real ( x ) );

- Complex numbers: According to Extended Pascal, GNU Pascal has built-in complex numbers.
- Record types: GNU Pascal alignes 32-bit fields on 4-byte addresses. Thus the record

        Type
          myRec = record
            f, o, oo: Boolean;
            Bar: Integer;
          end (* myRec *);

  has 8 bytes, not 7.
- Instead of procedural types, GNU Pascal has pointers to procedures:

          Type
            FuncPtr = ^Function ( Real ): Real;

  Furthermore, GNU Pascal supports Standard Pascal's procedural parameters--see below.

## Files

- GNU Pascal no built-in `Assign` procedure for files, but you can write it by yourself using the "Bind" mechanism of Extended Pascal:

        Procedure Assign ( Var T: Text; Name: String );

        Var
          B: BindingType;

        begin (* Assign *)
          unbind ( T );
          B:= binding ( T );
          B.Name:= Name;
          bind ( T, B );
          B:= binding ( T );
        end (* Assign *);

- GNU Pascal has no untyped files, "BlockRead", or "BlockWrite".

## Built-in constants

- Pi constant: not built-in. Use Pi = 3.14159265358979323846.
- Other built-in constants: GNU Pascal has ``MaxInt'`, ``MaxChar'`, ``MaxReal'`, and ``MinReal'`, but no ``MaxLongInt'`.

## Built-in operators

- Exponentiation: According to Extended Pascal, GNU Pascal supports exponentiation operators `pow` and `**` which do not exist in Borland Pascal. You can use `x pow y` for integer and `x ** y` for real or complex exponents; the basis may be integer, real or complex in both cases.
- Address operator: GNU Pascal accepts Borland's `@`, but also `&` as an address operator.
- GNU Pascal has a symmetric set difference operator `set1 >< set2`. See See section GNU Pascal extensions for more about this.

## Built-in Procedures and Functions

- ``Write'` and ``writeln'` default behaviour: The numeric default format of "write" and "writeln" differs between both Pascal dialects. The standard format of GNU Pascal is a field of length 14 for real, and a field of length 10 for integer values, while Borland Pascal begins just left by default. An explicit fieldlength of zero causes GNU Pascal to omit the output; in Borland Pascal it yields the default.
- ``GetMem'` and ``FreeMem'`: ``GetMem'` can also act as a function in GNU Pascal:

        p:= GetMem ( 1024 );

  The second parameter to FreeMem is ignored by GNU Pascal and may be omitted. Memory blocks are always freed with the same size they were allocated with. Remark: Extended Pascal Schema types will provide a cleaner approach to most of the applications of ``GetMem'` and ``FreeMem'` in the future.
- ``Min'` and ``max'`: GNU Pascal has built-in ``min'` and ``max'` functions (two arguments) which work for all ordinal types (``Integer'`, ``Char'`, ...) plus ``Real'`.
- ``UpCase'` function: not built-in.
- ``Lo'`, ``Hi'`, ``Swap'` functions: not built-in.

## Parameters

- Untyped Var parameters can be denoted by

        Procedure Foo ( Var x );

  like in Borland Pascal. In GNU Pascal, you can also use

        Procedure Foo ( Var x: Void );

- GNU Pascal defines "ellipsis" parameters vor variable argument lists,

        Procedure Foo ( a: Integer; ... );

  but does not (yet) provide a portable mechanism to access the additional arguments.
- Structured function return values: According to Extended Pascal, GNU Pascal allows structured function return values.
- Open array parameters

        Procedure Foo ( a: array of Integer );

  are implemented. However, Standard Pascal conformant array parameters (only partially implemented) are a "cleaner" mechanism to pass arrays of variable size.
- GNU Pascal supports Standard Pascal's procedural parameters:

        Procedure DrawGraph ( f: Function ( Real ): Real );

## Miscellaneous

- Headlines: According to Extended Pascal, a Program headline must contain the program's parameters:

          Program Foo ( Input, Output );

  In GNU Pascal, headline parameters are optional. If the headline is omitted, a warning is given.
- Case statements: In a case statement, GNU Pascal has `otherwise` as an alternative to `else` (according to Extended Pascal):

        case x of
          1: writeln ( 'one' );
          2: writeln ( 'two' );
          otherwise: writeln ( 'many' );
        end (* case *);

  If there are two ore more statements following `otherwise`, they must be grouped with `begin` and `end`.
- Char constants: Chars like ``#13'` or ``^M'` are not implemented into GNU Pascal.
- Sets: GNU Pascal has a `card ( myset )` function for sets which counts their elements.
- Inline: GNU Pasccal allows "inline" Procedures and Functions, while Borland Pascal only allows machine code to be inline: Borland Pascal:

        Function Max ( x, y: Integer ): Integer;
        Inline ( $58 / $59 / $3B / $C1 / $7F / $01 / $91 );

  GNU Pascal:

        Inline Function Max ( x, y: Integer ): Integer;

        begin (* Max *)
          if x > y then
            Max:= x
          else
            Max:= y;
        end (* Max *);

  (Actually, a more general Max is already built-in.) This feature is not so important as it might seem because in optimization level 3 (see above), GNU Pascal automatically "inlines" short Procedures and Functions.

Go to the first, previous, next, last section, table of contents.