🔷 Introduction to the Pascal Programming Language

Andrew J. Pounds, Ph.D.

🎯 Learning Objectives

After completing this exercise, you will be able to:

1 What is Pascal?

Pascal is a procedural programming language designed by Niklaus Wirth and first published in 1970. It was created as a small, efficient language intended to encourage good programming practices through structured programming and data structuring. Pascal was named in honor of the French mathematician and philosopher Blaise Pascal.

Pascal was originally developed for teaching programming as a systematic discipline, but it quickly became popular for professional software development due to its clarity and strong typing. Key features include:

Pascal source files typically use the .pas or .pp extension. We will use the Free Pascal Compiler (FPC), which is a mature, open-source compiler supporting multiple platforms.

2 Your First Pascal Program

Create a file called hello.pas with the following content:

program Hello;

begin
    writeln('Hello, World!');
end.

Compiling and Running

Open a terminal and navigate to the directory containing your file. Compile and run with:

fpc hello.pas
./hello

You should see Hello, World! printed to the console.

By default, FPC creates an executable with the same name as your source file (minus the extension). You can specify a different output name with fpc -ohello hello.pas.

Understanding the Code

Code Element Explanation
program Hello; Declares the program name (optional in FPC, but good practice)
begin Marks the start of the main program block
writeln(...) Writes output to the console followed by a newline
end. Marks the end of the program (note the period, not semicolon)
Pascal is case-insensitive. You can write BEGIN, Begin, or begin — they all mean the same thing. However, consistent capitalization improves readability.

3 Variable Types

Pascal is a statically typed language, meaning you must declare all variables and their types before using them. Variables are declared in a var section before the begin keyword.

Integer Types

Type Size Range
shortint 8 bits -128 to 127
smallint 16 bits -32,768 to 32,767
integer 16 or 32 bits Platform dependent (usually 32-bit)
longint 32 bits -2,147,483,648 to 2,147,483,647
int64 64 bits -9.2×1018 to 9.2×1018

Unsigned types are also available: byte, word, longword, qword.

Floating-Point Types

Type Size Description
single 32 bits Single precision (~7 significant digits)
double 64 bits Double precision (~15 significant digits)
real Platform dependent Usually equivalent to double in FPC
extended 80 bits Extended precision (platform dependent)

Other Fundamental Types

Type Description Example
boolean Boolean (true or false) var flag: boolean = true;
char Single character var letter: char = 'A';
string Sequence of characters var name: string = 'Alice';

Variable Declaration Example

program Variables;

var
    { Each variable must be declared with its type }
    age: integer;
    gpa: real;
    name: string;
    enrolled: boolean;
    grade: char;

begin
    { Assign values to variables }
    age := 25;
    gpa := 3.85;
    name := 'Alice';
    enrolled := true;
    grade := 'A';

    { Output the values }
    writeln('Name: ', name);
    writeln('Age: ', age);
    writeln('GPA: ', gpa:0:2);
    writeln('Enrolled: ', enrolled);
    writeln('Grade: ', grade);
end.
In Pascal, the assignment operator is := (colon-equals), not =. The single equals sign = is used only for comparison.

4 Console Output

Pascal provides two primary output procedures:

Procedure Description
write() Outputs without adding a newline
writeln() Outputs and adds a newline at the end
program OutputDemo;

var
    x: integer;
    price: real;
    item: string;

begin
    x := 42;
    price := 19.99;
    item := 'widget';

    { Basic output }
    writeln('The answer is ', x);

    { Multiple values }
    writeln('Item: ', item, ', Price: , price:0:2);

    { Using write (no newline) }
    write('Processing');
    write('...');
    writeln(' Done!');

    { Formatted numeric output }
    writeln('The ', item, ' costs , price:0:2);
    writeln('Padded integer: ', x:8);
    writeln('Padded real: ', price:10:2);
end.

Formatting Output

Pascal uses field width specifiers to format output:

Syntax Description Example
value:width Right-justify in field of specified width x:5 → 42
value:width:decimals For reals: width and decimal places 3.14159:8:2 → 3.14
value:0:decimals Minimum width with specified decimals 3.14159:0:2 → 3.14
Use :0:2 for real numbers when you want exactly 2 decimal places without extra padding.

5 Console Input

Pascal provides two primary input procedures:

Procedure Description
read() Reads input without consuming the newline
readln() Reads input and consumes the newline
program InputDemo;

var
    name: string;
    age: integer;
    gpa: real;

begin
    { Reading a string }
    write('Enter your name: ');
    readln(name);

    { Reading an integer }
    write('Enter your age: ');
    readln(age);

    { Reading a real number }
    write('Enter your GPA: ');
    readln(gpa);

    { Display the results }
    writeln;
    writeln('Hello, ', name, '!');
    writeln('Age: ', age);
    writeln('GPA: ', gpa:0:2);
end.
Always use readln() instead of read() when reading from the console, especially when mixing numeric and string input. Using read() leaves the newline character in the input buffer, which can cause problems with subsequent reads.

Reading Multiple Values

You can read multiple values on a single line:

program MultipleInputs;

var
    x, y, z: integer;

begin
    write('Enter three integers separated by spaces: ');
    readln(x, y, z);
    writeln('Sum: ', x + y + z);
end.

6 Assignment Statements and Operators

Basic Assignment

The assignment operator := stores a value in a variable:

var
    x, y: integer;
    
begin
    x := 10;      { assign 10 to x }
    x := 20;      { assign new value }
    y := x;       { copy value from x to y }
end.

Arithmetic Operators

Operator Description Example Result (if a=10, b=3)
+ Addition a + b 13
- Subtraction a - b 7
* Multiplication a * b 30
/ Real division a / b 3.333...
div Integer division a div b 3
mod Modulus (remainder) a mod b 1
Pascal has separate operators for integer and real division. The / operator always returns a real number, while div performs integer division and returns an integer.

Increment and Decrement

Free Pascal provides Inc and Dec procedures:

var
    count: integer;

begin
    count := 5;
    Inc(count);      { count is now 6 }
    Inc(count, 3);   { count is now 9 (add 3) }
    Dec(count);      { count is now 8 }
    Dec(count, 2);   { count is now 6 (subtract 2) }
end.

Integer vs. Real Division

program DivisionDemo;

var
    a, b: integer;

begin
    a := 7;
    b := 2;

    writeln('7 / 2   = ', 7 / 2:0:4);     { prints 3.5000 (real division) }
    writeln('7 div 2 = ', 7 div 2);        { prints 3 (integer division) }
    writeln('7 mod 2 = ', 7 mod 2);        { prints 1 (remainder) }
    writeln('a / b   = ', a / b:0:4);     { prints 3.5000 }
    writeln('a div b = ', a div b);        { prints 3 }
end.
Use div when you need integer division (discarding the remainder) and mod when you need only the remainder.

7 Control Structures

The if Statement

Execute code conditionally based on a boolean expression:

program GradeCalculator;

var
    score: integer;

begin
    write('Enter your score (0-100): ');
    readln(score);

    if score >= 90 then
        writeln('Grade: A')
    else if score >= 80 then
        writeln('Grade: B')
    else if score >= 70 then
        writeln('Grade: C')
    else if score >= 60 then
        writeln('Grade: D')
    else
        writeln('Grade: F');
end.
In Pascal, there is no semicolon before else. A semicolon terminates a statement, and else is a continuation of the if statement.

Using begin-end for Multiple Statements

if score >= 90 then
begin
    writeln('Grade: A');
    writeln('Excellent work!');
end
else
begin
    writeln('Grade: Below A');
    writeln('Keep studying!');
end;

Comparison Operators

Operator Meaning Example
= Equal to x = 5
<> Not equal to x <> 5
< Less than x < 5
> Greater than x > 5
<= Less than or equal to x <= 5
>= Greater than or equal to x >= 5

Logical Operators

Operator Meaning Example
and Logical AND (x > 0) and (x < 100)
or Logical OR (x < 0) or (x > 100)
not Logical NOT not found
In Pascal, you must use parentheses around comparisons when combining them with logical operators. For example: (x > 0) and (x < 100) — not x > 0 and x < 100.
program DrivingCheck;

var
    age: integer;
    response: string;
    hasLicense: boolean;

begin
    write('Enter your age: ');
    readln(age);

    write('Do you have a license? (yes/no): ');
    readln(response);

    hasLicense := (response = 'yes');

    if (age >= 16) and hasLicense then
        writeln('You can drive.')
    else if (age >= 16) and (not hasLicense) then
        writeln('You''re old enough but need a license.')
    else
        writeln('You''re too young to drive.');
end.
To include an apostrophe within a string, use two apostrophes: 'You''re' produces You're.

The case Statement

Use case when comparing a single value against multiple options:

program DayOfWeek;

var
    day: integer;

begin
    write('Enter a day number (1-7): ');
    readln(day);

    case day of
        1: writeln('Monday');
        2: writeln('Tuesday');
        3: writeln('Wednesday');
        4: writeln('Thursday');
        5: writeln('Friday');
        6, 7: writeln('Weekend!');
    else
        writeln('Invalid day number');
    end;
end.
Pascal's case statement doesn't require break statements — each case automatically ends without falling through to the next. You can also use ranges: 1..5: writeln('Weekday');

8 Looping Structures

The while Loop

Repeats a block of code as long as a condition is true. The condition is checked before each iteration:

program WhileDemo;

var
    i: integer;

begin
    { Count from 1 to 5 }
    i := 1;
    while i <= 5 do
    begin
        writeln('Count: ', i);
        Inc(i);
    end;
end.

The repeat-until Loop

Similar to while, but the condition is checked after each iteration. The loop body always executes at least once:

program GuessingGame;

var
    guess: integer;
    secretNumber: integer;

begin
    secretNumber := 7;

    repeat
        write('Guess a number (1-10): ');
        readln(guess);

        if guess < secretNumber then
            writeln('Too low!')
        else if guess > secretNumber then
            writeln('Too high!');

    until guess = secretNumber;

    writeln('Correct!');
end.
The repeat-until loop does not require begin/end even for multiple statements — the repeat and until keywords serve as the block delimiters.

The for Loop

Best for counting a specific number of iterations:

program ForDemo;

var
    i: integer;

begin
    { Basic counting up }
    for i := 1 to 5 do
        writeln('Iteration ', i);

    writeln;

    { Counting down }
    writeln('Countdown:');
    for i := 10 downto 0 do
        writeln(i);
end.
Pascal's for loop only increments or decrements by 1. Use to to count up and downto to count down. For other step values, use a while loop.

Nested Loops

program MultiplicationTable;

var
    row, col: integer;

begin
    writeln('Multiplication Table (1-5):');
    writeln;

    { Print header row }
    write('     ');
    for col := 1 to 5 do
        write(col:4);
    writeln;
    writeln('   --------------------');

    { Print table rows }
    for row := 1 to 5 do
    begin
        write(row:2, ' |');
        for col := 1 to 5 do
            write((row * col):4);
        writeln;
    end;
end.

Loop Control: break and continue

program LoopControl;

var
    i: integer;

begin
    { break - exit the loop early }
    writeln('Finding first multiple of 7:');
    for i := 1 to 100 do
    begin
        if i mod 7 = 0 then
        begin
            writeln('Found: ', i);
            break;  { exit loop immediately }
        end;
    end;

    writeln;

    { continue - skip to next iteration }
    writeln('Numbers 1-10, skipping multiples of 3:');
    for i := 1 to 10 do
    begin
        if i mod 3 = 0 then
            continue;  { skip this iteration }
        writeln(i);
    end;
end.

9 Complete Example: Temperature Converter

This program demonstrates input, output, control structures, and loops working together:

program TemperatureConverter;

var
    choice: integer;
    celsius, fahrenheit: real;
    running: boolean;

begin
    writeln('=== Temperature Converter ===');
    writeln('1. Celsius to Fahrenheit');
    writeln('2. Fahrenheit to Celsius');
    writeln('3. Quit');

    running := true;

    while running do
    begin
        writeln;
        write('Enter choice (1-3): ');
        readln(choice);

        case choice of
            1:
            begin
                write('Enter temperature in Celsius: ');
                readln(celsius);
                fahrenheit := (celsius * 9.0 / 5.0) + 32.0;
                writeln(celsius:0:2, '°C = ', fahrenheit:0:2, '°F');
            end;

            2:
            begin
                write('Enter temperature in Fahrenheit: ');
                readln(fahrenheit);
                celsius := (fahrenheit - 32.0) * 5.0 / 9.0;
                writeln(fahrenheit:0:2, '°F = ', celsius:0:2, '°C');
            end;

            3:
            begin
                writeln('Goodbye!');
                running := false;
            end;
        else
            writeln('Invalid choice. Please enter 1, 2, or 3.');
        end;
    end;
end.

10 Quick Reference

Task Pascal Syntax
Print with newline writeln('text', variable);
Print without newline write('text');
Formatted real output writeln('Value: ', x:0:2);
Read string readln(s);
Read integer readln(n);
Read real readln(d);
Assignment x := 10;
Integer division a div b
Modulus (remainder) a mod b
Not equal a <> b
Logical AND (cond1) and (cond2)
Logical OR (cond1) or (cond2)
Compile fpc filename.pas
Run ./filename

📝 Programming Exercise: Prime Number Analyzer

Write a Pascal program that analyzes prime numbers. Your program should:

  1. Prompt the user to enter a positive integer n (must be ≥ 2)
  2. Validate the input: If the user enters a number less than 2, display an error message and ask again (use a loop)
  3. Determine if n is prime: A prime number is only divisible by 1 and itself
  4. If n is prime: Display "n is a prime number!"
  5. If n is not prime: Display "n is not prime. Its smallest factor is f." (where f is the smallest factor other than 1)
  6. Count and display how many prime numbers exist from 2 up to and including n
  7. Ask the user if they want to check another number (y/n). If yes, repeat; if no, exit with a goodbye message

Sample Output

=== Prime Number Analyzer === Enter a positive integer (>= 2): 1 Invalid input. Please enter a number >= 2. Enter a positive integer (>= 2): 29 29 is a prime number! There are 10 prime numbers from 2 to 29. Check another number? (y/n): y Enter a positive integer (>= 2): 100 100 is not prime. Its smallest factor is 2. There are 25 prime numbers from 2 to 100. Check another number? (y/n): n Goodbye!

Hints

Submission

Save your program as prime_analyzer.pas and compile with:

fpc prime_analyzer.pas
./prime_analyzer

🚀 Student Starter Code

Use the following template to get started. Fill in each blank (______) with the appropriate code. Read the comments carefully for hints!

Instructions

  1. Save this code as prime_analyzer.pas
  2. Read through all the comments to understand the program structure
  3. Fill in each blank with the appropriate code
  4. Compile and test your program
program PrimeAnalyzer;

{
  Prime Number Analyzer - Student Starter Code
  ============================================
  Complete the sections marked with TODO to finish this program.
  
  This program will:
  1. Ask the user for a positive integer >= 2
  2. Validate the input (reject numbers less than 2)
  3. Determine if the number is prime
  4. Find the smallest factor if not prime
  5. Count all primes from 2 to n
  6. Allow the user to check multiple numbers
  
  Author: [Your Name]
  Date: [Date]
}

var
    n: integer;              { The number to analyze }
    smallestFactor: integer; { Stores the smallest factor if not prime }
    primeCount: integer;     { Counts primes from 2 to n }
    continueRunning: boolean;{ Flag to control main program loop }
    response: char;          { User's yes/no response }


{
  Function: CheckIfPrime
  ----------------------
  Determines whether a given number is prime.
  
  Parameters:
    num - the number to check (assume num >= 2)
    
  Returns:
    true if num is prime, false otherwise
    
  HINT: A number is prime if it has no divisors other than 1 and itself.
        Use a for loop to check if any number from 2 to num-1 divides evenly.
        Use the mod operator: if num mod divisor = 0, then divisor divides num.
}
function CheckIfPrime(num: integer): boolean;
var
    divisor: integer;
    foundDivisor: boolean;
begin
    { Special case: 2 is the smallest prime }
    if num = 2 then
    begin
        CheckIfPrime := true;
        exit;
    end;
    
    { Assume the number is prime until we find a divisor }
    foundDivisor := false;
    
    { TODO: Write a for loop that checks each potential divisor }
    { Loop from 2 to num - 1 }
    { If num mod divisor = 0, we found a divisor (not prime) }
    
    for divisor := 2 to ______ do
    begin
        if num mod divisor = ______ then
        begin
            foundDivisor := ______;
            break;  { Exit the loop early - no need to keep checking }
        end;
    end;
    
    { TODO: Set the return value }
    { If we found a divisor, the number is NOT prime }
    { HINT: Use "not foundDivisor" to return true when no divisor was found }
    
    CheckIfPrime := ______;
end;


{
  Function: FindSmallestFactor
  ----------------------------
  Finds the smallest factor of a number (other than 1).
  
  Parameters:
    num - the number to find the factor of (assume num >= 2 and not prime)
    
  Returns:
    The smallest factor > 1
    
  HINT: This is similar to CheckIfPrime, but instead of just checking
        if a divisor exists, you return the first divisor you find.
}
function FindSmallestFactor(num: integer): integer;
var
    divisor: integer;
begin
    { TODO: Write a for loop to find the smallest divisor }
    { Start from 2 and go up to num - 1 }
    { Return as soon as you find a divisor }
    
    for divisor := ______ to num - 1 do
    begin
        if ______ mod ______ = 0 then
        begin
            FindSmallestFactor := ______;
            exit;  { Return immediately when we find the smallest factor }
        end;
    end;
    
    { If no factor found (shouldn't happen if num is not prime), return num }
    FindSmallestFactor := num;
end;


{
  Function: CountPrimesUpTo
  -------------------------
  Counts how many prime numbers exist from 2 up to and including limit.
  
  Parameters:
    limit - the upper bound (inclusive)
    
  Returns:
    The count of prime numbers in the range [2, limit]
    
  HINT: Loop through all numbers from 2 to limit.
        For each number, call CheckIfPrime.
        If it's prime, increment a counter.
}
function CountPrimesUpTo(limit: integer): integer;
var
    num: integer;
    count: integer;
begin
    count := 0;
    
    { TODO: Write a for loop from 2 to limit }
    { For each number, check if it's prime using CheckIfPrime }
    { If prime, increment count using Inc(count) }
    
    for num := ______ to ______ do
    begin
        if ______________(______) then
            Inc(______);
    end;
    
    CountPrimesUpTo := count;
end;


{ ===== MAIN PROGRAM ===== }
begin
    { Display program header }
    writeln('=== Prime Number Analyzer ===');
    writeln;
    
    { Initialize the main loop control variable }
    continueRunning := true;
    
    { Main program loop - continues until user chooses to quit }
    while continueRunning do
    begin
    
        { ================================================ }
        { PART 1: Input Validation                         }
        { ================================================ }
        { TODO: Use a repeat-until loop to get valid input }
        { Keep asking until the user enters a number >= 2  }
        
        { HINT: The structure is:
            repeat
                write(...);
                readln(...);
                if n < 2 then
                    writeln('error message');
            until ;
        }
        
        repeat
            write('Enter a positive integer (>= 2): ');
            readln(______);
            
            if ______ < 2 then
                writeln('Invalid input. Please enter a number >= 2.');
                
        until ______ >= ______;
        
        
        { ================================================ }
        { PART 2: Check if Prime and Display Result        }
        { ================================================ }
        { TODO: Call CheckIfPrime to determine if n is prime }
        { If prime: display "n is a prime number!"           }
        { If not prime: find smallest factor and display it  }
        
        { HINT: Use an if-else statement }
        
        if ______________(______) then
        begin
            { n is prime }
            writeln(______, ' is a prime number!');
        end
        else
        begin
            { n is not prime - find and display smallest factor }
            smallestFactor := __________________(______);
            writeln(______, ' is not prime. Its smallest factor is ', ______, '.');
        end;
        
        
        { ================================================ }
        { PART 3: Count Primes from 2 to n                 }
        { ================================================ }
        { TODO: Call CountPrimesUpTo and display the result }
        
        primeCount := ______________(______);
        writeln('There are ', ______, ' prime numbers from 2 to ', ______, '.');
        
        
        { ================================================ }
        { PART 4: Ask to Continue                          }
        { ================================================ }
        { TODO: Ask user if they want to check another number }
        { Read their response into the 'response' variable    }
        { Set continueRunning to false if they don't enter 'y' or 'Y' }
        
        writeln;
        write('Check another number? (y/n): ');
        readln(______);
        writeln;
        
        { Check if user wants to continue }
        { HINT: Use "and" to check if response is neither 'y' nor 'Y' }
        if (response <> '______') and (response <> '______') then
            continueRunning := ______;
            
    end;  { End of main while loop }
    
    { Display goodbye message }
    writeln('Goodbye!');
end.

Hints for Each Section

Section Key Hints
CheckIfPrime Loop goes to num - 1. Check if remainder equals 0. Return not foundDivisor.
FindSmallestFactor Start the loop at 2. Check num mod divisor. Return divisor when found.
CountPrimesUpTo Loop from 2 to limit. Call CheckIfPrime(num). Increment count.
Input Validation Read into n. Check if n < 2. Loop until n >= 2.
Prime Check Call CheckIfPrime(n). Call FindSmallestFactor(n).
Count Display Call CountPrimesUpTo(n). Display primeCount and n.
Continue Loop Read into response. Check for 'y' and 'Y'. Set to false to exit.

Testing Your Program

Test with these inputs to verify your solution:

Input Expected Output
1 "Invalid input" message, asks again
2 "2 is a prime number!", 1 prime
7 "7 is a prime number!", 4 primes
10 "10 is not prime. Smallest factor is 2.", 4 primes
29 "29 is a prime number!", 10 primes
100 "100 is not prime. Smallest factor is 2.", 25 primes

Common Errors to Watch For

  • Semicolon before else — Don't put a semicolon before the else keyword
  • := vs = — Use := for assignment, = for comparison
  • Parentheses with and/or — Always use parentheses: (a > 0) and (b > 0)
  • Function return values — Set the return value using FunctionName := value;