<!--
  canonical-url: https://www.avonture.be/blog/docker-pascal
  published:     2023-12-01
  This is a static plain-Markdown mirror generated at build time.
  Visit the canonical URL above for the fully rendered page, with images and interactive components.
-->

# Play with Docker and Pascal

> Can you run 30-year-old Pascal code today? Yes! This guide shows you how to use Docker and the Free Pascal Compiler (FPC) to compile and execute your legacy Turbo Pascal programs.

---
![Play with Docker and Pascal](/img/v2/experiments.webp)

**TL;DR**

This article revives 30-year-old Turbo Pascal source code (pulled from the old SWAG archive) using the `signumtemporis/fpc` Docker image to compile `.pas` files into Windows executables with zero local install, running both a "Hello World" and an old school byte-to-binary conversion function written back in 1992.

Good old memories... During my studies (in 1991-1993), I was a huge fan of Turbo Pascal 7.0. It was the first language that I really learned, and I loved it so much. I used to spend dozens of hours behind my computer writing anything and everything.

If you still remember that time, Turbo Pascal 7.0 was used to create executables for MS-DOS.

The idea for this article came after the one written on [assembly language](/blog/docker-assembly): is it possible in 2023 to run Pascal code written 30 years earlier?

![Turbo Pascal](./images/turbo_pascal.webp)

The first thing to do was to find some old source code and to do that, I went back to the **S**ource**w**are **A**rchive **G**roup; known as **SWAG**.

The following parametrized query will retrieve some code I've published 30 years ago: <https://www.google.com/search?q=avonture+site%3Ahttp%3A%2F%2Fwww.retroarchive.org>. Out of nostalgia, I've also copied these sources here: <https://github.com/cavo789/swag>.

## Hello world

Please run `mkdir C:\tmp\pascal && cd C:\tmp\pascal` in a MS-DOS console to create a folder called `pascal` and jump in it.

Please create a new file called `Hello.pas` with this content:

**Hello.pas**

```pas
begin
    writeln('Hello world! I''m a Turbo Pascal source code');
end.
```

As you know, Pascal is a compiled language and should then be compiled into an `.exe`. The command below will do this:

```bash
$ docker run -it --rm -v %CD%:/app -w /app signumtemporis/fpc:cross.x86_64-win64.slim Hello.pas
Free Pascal Compiler version 3.2.2 [2021/12/10] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Win64 for x64
Compiling Hello.pas
Linking Hello.exe
2 lines compiled, 0.1 sec, 32432 bytes code, 1508 bytes data
```

Our executable has been created. Time to start it by running `Hello.exe`:

```bash
$ Hello.exe
Hello world! I'm a Turbo Pascal source code
```

Voilà, we've successfully created our first Pascal code in 2023.

*This blog has a small collection of such "run language X without installing it" articles: [Java](/blog/docker-java), [Python](/blog/docker-python) and [PHP](/blog/docker-php-run-script-or-website).*

> **Docker CLI reminder:**
>
> As a reminder, the used Docker run commands are (almost always the same):
>
> * `-it` to start Docker interactively, this will allow the script running in the container to ask you for some prompts f.i.,
> * `--rm` to ask Docker to kill and remove the container as soon as the script has been executed (otherwise you'll have a lot of exited but not removed Docker containers; you can check this by not using the `--rm` flag then running `docker container list` on the console),
> * `-v %CD%:/app` to share your current folder with a folder called `/app` in the Docker container,
> * `-w /app` to tell Docker that the current directory, in the container, will be the `/app` folder
> * then `signumtemporis/fpc:cross.x86_64-win64.slim` which is the name of the Docker image to use and, finally,
> * `Hello.pas` i.e. our source file (the fpc image seems to not request to specify the `fpc` executable; just the source file).

## Convert a number to a byte

Let's try something a *little more complex* than just *Hello world*; a conversion function to determine the byte representation of a positive number *(please be comprehensive; it was a school assignment 😄)*.

I wrote this function in 1992 (published in the *SWAG* in 1997): <https://github.com/cavo789/swag/blob/master/Byte2Bin/files/source.pas>

Create the `Byte2Bin.pas` file on your disk with this content:

**Byte2Bin.pas**

```pas
Function Byte2Bin (Chiffre : Byte) : String;

Var I, Temp : Byte;
    St      : String;

Begin

   St := '';

   For I := 7 Downto 0 do Begin
       Temp := (Chiffre and (1 shl I));
       If (Temp = 0) then St := St + '0' Else St := St + '1';
   End;

   Byte2Bin := St;

End;

begin
    WriteLn( Byte2Bin(197) );
end.
```

> **SHL for Shift left one position:**
>
> The `shl` instruction will shift the number from one byte left.

And compiled it:

```bash
$ docker run -it --rm -v %CD%:/workspace signumtemporis/fpc:cross.x86_64-win64.slim Byte2Bin.pas

Free Pascal Compiler version 3.2.2 [2021/12/10] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Win64 for x64
Compiling Byte2Bin.pas
Linking Byte2Bin.exe
20 lines compiled, 0.1 sec, 32656 bytes code, 1508 bytes data
```

As you can see in the source code, the idea was to show the binary representation of `197` and, yes!, it's indeed `11000101`. Still in 2023.

```bash
$ Byte2Bin.exe
11000101
```

OK, so the point of running TP7 code in 2023 is minimal and useless, but it is well fun to see it still works.

Same idea, different language: I've also played with [Python](/blog/docker-python) and [Java](/blog/docker-java) using the exact same "zero local install" Docker approach.
