Pascal

Lagrange Pascal

History

Pascal is an imperative programming language. This means statements in Pascal are like commands given to the computer to perform. It is also a procedural language, which means it has functions, function calls, blocks, and scope. It is known for having simple syntax and clear structure.

Pascal was designed by Niklaus Wirth in 1970. Wirth had previously been involved in creating and extending ALGOL, which was the first language to have a detailed, formal definition. Wirth and Tony Hoare had proposed making some changes to ALGOL, but their proposal was rejected. So, in 1966, they made their own language with the changes, and called it ALGOL W. Wirth later improved on ALGOL W and called the result Pascal. In his own words, Wirth said “In search of a language suitable for teaching programming in a structured fashion, and for the development of system software, I designed Pascal (1968-1972), free of conflicting demands from a large committee and with a clear purpose in mind.”

In 1983, Borland International released Turbo Pascal, which was an IDE and compiler for a slightly-modified Pascal. Turbo Pascal compiled code extremely fast for the time: several thousand lines of code per minute. This caused Turbo Pascal to become the unofficial standard language for programming on personal computers.

Pascal is also widely known as a programming language used for educational purposes. This is a correct observation; in the 1980s, Pascal had become widely accepted at universities. Additionally, Educational Testing Service used Pascal for computer science AP tests for high school students from the inception of the tests until 1999. However, Pascal also has a history of use in systems programming and application development. In 1983, Apple released the first mass market personal computer which ran with a GUI, which they called Lisa. Lisa's software was primarily coded in Pascal. Pascal was also used to develop software for the Macintosh. The 1990 version of Photoshop was written in Pascal, and the User Interface for Skype was originally written in Object Pascal (an Object-Oriented variant of Pascal).

A major factor in Pascal's loss of popularity and use was the onset of C. The UNIX operating system was given to universities for free, and UNIX was coded in C. Therefore, lots of CS education shifted to the C language. Additionally, several large companies started to focus on languages other than Pascal. One of the biggest languages they shifted to was C.

Today, Pascal sees relatively little use. However, it is still a very valid language for education and development purposes, and is still used for those purposes.

Web Image

Description

Named after French mathematician and philosopher Blaise Pascal

Designed for teaching and learning

Focus on portability

Focus on readability and simplicity

Clear syntax

One of the first programming languages to embrace structured programming concepts

(Modular and organized code through functions, procedures, and loops)

Strongly typed

One of the first languages to have sets as a data structure

Case-insensitive

No longer popular


Translators and Installation Instructions

Pascal has many different translators, compilers, and interpreters that can be used to translate a Pascal or Object Pascal program. A full list of these can be seen in a link below, however, here are a few main ones that are mostly used picked from the website.

The installation for these translators is pretty straightforward but depends on what system you are using. Simply go to the website for which translator you would like to use, go to the downloads tab and download the file that corresponds to your system. From there follow the directions to install onto your device and get programming!

Link to the list of translators: List of compilers and interpreters

Link to the websites for the translators discussed:

Links to the downloads for the translators discussed:

Comparison of Characteristics and Features

Characteristic/Feature Pascal Java C
Variable Declaration
var name : type;
type name;
type name;
Single Line Comments
{this is a comment} or 
            //this is a comment(not pure pascal)
            
//this is a comment
//this is a comment
Multi Line Comments
(*this is a multi line comment*)
/*this is a multi line comment*/
/*this is a multi line comment*/
Function Declaration/Definition
function foo(argument: type1; ...): function_type
begin
**code**
end;
static void foo(ArgumentType name,...){
**code**
}
void foo(ArgumentType name,...){
**code**
}
Function Call
functionCall();
functionCall();
functionCall();
Standard Data Types
Integer, Real, Character, Boolean
Integer, Float, Character, Boolean, Byte, Short, Long, Double
Character, Integer, Short, Long, Float, Double
Dynamically Allocated Memory
no(free pascal does)
yes
            new()
            Garbage collector
            
yes
            malloc()
            free()
            
Type Strongly (variable declarations before use) Strongly Strongly
Inheritance no** yes no
Multi-Threading no** yes no
Pascal Types
Pascal Types

Simple Programs

Hello World Program

program HelloWorld;
begin
  writeln ('Hello, world!');
end.
    
Hello Image

Simple Sum Program

program Sum;
var x, y, z : integer;
begin
    x := 1;
    y := 2;
    z := 3;
    writeln (x + y + z);
end.
    
Sum Image

Build and Run Instructions in Onyx

To build/run these programs in Onyx, simply create a text file named whatever you would like, ideally something relevant to the program, however make sure the file name ends with .p, so for example, HelloWorld.p. Then write or copy/paste the code for either program, Hello World or Simple Sum Program, and save this file in a folder that can be easily accessed. Next, go to the file location and simply run the following command: fpc <File Name>. This will create a runnable file that will be named after your File name, then simply use the command ./<File Name>. This will run the program and display an output if there is one.

Step by Step Example:

student@ubuntu:~$ cd pascal/
student@ubuntu:~/pascal$ fpc HelloWorld.p
student@ubuntu:~/pascal$ ./HelloWorld
    

Complex Programs

Triangle Area Program

program TriangleArea;
uses SysUtils;
var userSelection : char;
var x, y, z, base, height : real;
var result : real;
begin
userSelection := 'r';
while userSelection <> 'q' do
    begin
    writeln('Triangle Menu:');
    writeln('''a'': calculate area');
    writeln('''p'': calculate perimeter');
    writeln('''q'': quit');
    writeln('Please enter your selection:');
    readln(userSelection);
    
    if userSelection = 'a' then
        begin
            writeln('Please enter the base dimension:');
            readln(base);
            writeln('Please enter the height dimension:');
            readln(height);
            result := 0.5 * base * height;
            writeln('The area of your triangle is: ' + FloatToStr(result));
        end;
    if userSelection = 'p' then 
        begin
            writeln('Please enter the first dimension:');
            readln(x);
            writeln('Please enter the second dimension:');
            readln(y);
            writeln('Please enter the third dimension:');
            readln(z);
            result := x + y + z;
            writeln('The perimeter of your triangle is: ' + FloatToStr(result));
        end;
    end;
end.
    
Tri Image

Rock Paper Scissors Program

program RockPaperScissors;

uses
  SysUtils, Math, CRT;

var
  PlayerMove, ComputerMove: string;
  Wins, Losses, Ties: Integer;
  Play: Boolean;
  Comp: Integer;

begin
  Wins := 0;
  Losses := 0;
  Ties := 0;
  Play := True;

  while Play do
  begin
    Write('Enter your choice - 1 for Rock, 2 for Paper, and 3 for Scissors: ');
    ReadLn(PlayerMove);

    if PlayerMove = '1' then
      PlayerMove := 'Rock'
    else if PlayerMove = '2' then
      PlayerMove := 'Paper'
    else
      PlayerMove := 'Scissors';

    Randomize;
    Comp := Random(3); 

    if Comp = 0 then
      ComputerMove := 'Rock'
    else if Comp = 1 then
      ComputerMove := 'Paper'
    else
      ComputerMove := 'Scissors';

    WriteLn('Computer chooses ', ComputerMove);

    if PlayerMove = ComputerMove then
    begin
      WriteLn('We tied!');
      Inc(Ties);
    end
    else if (PlayerMove = 'Rock') and (ComputerMove = 'Scissors') or
            (PlayerMove = 'Scissors') and (ComputerMove = 'Paper') or
            (PlayerMove = 'Paper') and (ComputerMove = 'Rock') then
    begin
      WriteLn('Human Wins!');
      Inc(Wins);
    end
    else
    begin
      WriteLn('Computer Wins!');
      Inc(Losses);
    end;

    Write('Play again (y/n)? ');
    if UpCase(ReadKey) = 'Y' then
    else
      Break;
  end;

  WriteLn('You won ', Wins, ' times.');
  WriteLn('You lost ', Losses, ' times.');
  WriteLn('We tied ', Ties, ' times.');
end.
    
RPS Image

Cellular Automata Explorer

uses sysutils, math;


var
 input
 ,ruleNumberString
 ,mode
 ,currentLine
 ,x
 : string;
 simulationLength
 ,simulationHeight
 ,ruleNumber
 ,spaceLocation
 ,i
 : integer;


function getRandomString(len : integer): string;
var i: integer;
begin
 getRandomString := '';
 for i := 1 to len do
 begin
   if (Random(2) < 1) then
     getRandomString := getRandomString + ' '
   else
     getRandomString := getRandomString + x;
 end;
end;


function getCharFromRuleAndParentState(rule: integer; parentState: integer): string; begin
 getCharFromRuleAndParentState := ' ';
 if (rule shr parentState) and 1 = 1 then getCharFromRuleAndParentState := x;
end;


function getStateNumberFromString(stateChar1 : char; stateChar2: char; stateChar3: char): integer;
begin
 getStateNumberFromString := IfThen(stateChar1 = ' ', 0, 4) + IfThen(stateChar2 = ' ', 0, 2) + IfThen(stateChar3 = ' ', 0, 1);
end;


function getNextLine(currentLine: string): string;
var i: integer;
begin
 getNextLine := getCharFromRuleAndParentState(ruleNumber, getStateNumberFromString(currentLine[simulationLength], currentLine[1], currentLine[2]));
 for i := 2 to simulationLength - 1 do
   getNextLine := getNextLine + getCharFromRuleAndParentState(ruleNumber, getStateNumberFromString(currentLine[i - 1], currentLine[i], currentLine[i + 1]));
 getNextLine := getNextLine + getCharFromRuleAndParentState(ruleNumber, getStateNumberFromString(currentLine[simulationLength - 1], currentLine[simulationLength], currentLine[1]));
end;


begin
 x := '#';
 simulationLength := 50;
 simulationHeight := 50;
 writeln();
 writeln('***Elementary Cellular Automata Explorer***');
 writeln();


 input := 'h';
 while input <> 'q' do begin
   if input = 'h' then begin
     writeln('To run a simulation, use the following syntax:');
     writeln('number type');
     writeln(#9, 'Where number is an integer from 0 to 255, and type is either');
     writeln(#9, '"r" for a random starting position,');
     writeln(#9, '"l" to start with a single active cell on the left, or');
     writeln(#9, '"m" to start with a single active cell in the middle.');
     writeln('To quit, type ''q''.');
     writeln('To show this menu, type ''h''.');
   end else begin
     spaceLocation := pos(' ', input);
     ruleNumberString := copy(input, 1, spaceLocation - 1);
     ruleNumber := StrToInt(ruleNumberString);
     mode := copy(input, spaceLocation + 1, length(input));
     case (mode) of
       'l' : begin
         currentLine := x + StringOfChar(' ', simulationLength);
       end; 'm': begin
         currentLine := StringOfChar(' ', simulationLength div 2) + x + StringOfChar(' ', simulationLength div 2);
       end; else begin
         currentLine := getRandomString(simulationLength);
       end;
     end;   
   for i := 1 to simulationHeight do
   begin
     writeln(currentLine);
     currentLine := getNextLine(currentLine);
   end;
   end;
   readln(input);
 end;
end.
 
explorer explorer explorer

Bank Application

	    

Account.p

unit Account; interface uses SysUtils, CustomerU; {Defining the account types - Jaden} {Note that TCustomer will need to be defined in a similar fashion of TAccount} type TAccountType = (CheckingAccount, SavingAccount); TAccount = record number: String; customer: Customer; balance: Real; case AccountType: TAccountType of CheckingAccount: (); SavingAccount: (interest: Real); end; function Balance(account: TAccount): Real; procedure Deposit(var account: TAccount; amount: Real); procedure Withdraw(var account: TAccount; amount: Real); function toString(account: TAccount): String; overload; function getNewAccount(n: string; c: Customer; b: real; t: TAccountType): TAccount; procedure accrue(var account: TAccount; rate: Real); overload; implementation {Balance method for all accounts} function Balance(account: TAccount): Real; begin case account.AccountType of CheckingAccount: Balance := account.balance; SavingAccount: Balance := account.balance; end; end; {Deposit is a procedure because it does not return anything} procedure Deposit(var account: TAccount; amount: Real); begin case account.AccountType of CheckingAccount: account.balance := account.balance + amount; SavingAccount: account.balance := account.balance + amount; end; end; {Withdraw} procedure Withdraw(var account: TAccount; amount: Real); begin case account.AccountType of CheckingAccount: account.balance := account.balance - amount; SavingAccount: account.balance := account.balance - amount; end; end; {toString - note I refer to the customer tostring method name here, you can change if need be} function toString(account: TAccount): String; overload; begin case account.AccountType of CheckingAccount: toString := account.number + ':' + CustomerToString(account.customer) + ':' + FloatToStr(account.balance); SavingAccount: toString := account.number + ':' + CustomerToString(account.customer) + ':' + FloatToStr(account.balance); end; end; procedure accrue(var account: TAccount; rate: Real); overload; begin if account.AccountType = SavingAccount then begin account.interest := account.interest + account.balance * rate; account.balance := account.balance + account.balance * rate; end; end; // Like a constructor, returns a new Account. function getNewAccount(n: string; c: Customer; b: real; t: TAccountType): TAccount; begin getNewAccount.number := n; getNewAccount.customer := c; getNewAccount.balance := b; getNewAccount.AccountType := t; if (t = SavingAccount) then getNewAccount.interest := 0; end; end.

Customer.p

unit CustomerU; interface type Customer = record name: string; end; function getNewCustomer(const AName: string) : Customer; function CustomerToString(const customer: Customer): string; implementation // Like a constructor, returns a new Customer. function getNewCustomer(const AName: string) : Customer; begin getNewCustomer.name := AName; end; function CustomerToString(const customer: Customer): string; begin CustomerToString := customer.name; end; end.

Bank.p

// Uses section, like imports. uses SysUtils, CustomerU, Account; // Type section where we can define our own data types. type // A Bank record is like a struct, which is like a class. Bank = record accounts : array of TAccount; // For keeping track of where we are in the accounts array. currentAccountNumber : integer; end; // Var section where we define all variables to be used in the 'main' block. var myBank : Bank; creatingCustomer : Customer; // Function definitions // Adds a new account to a bank. procedure add(var bank: Bank; account: TAccount); begin bank.accounts[bank.currentAccountNumber] := account; bank.currentAccountNumber := bank.currentAccountNumber + 1; // Interesting: you can increase the size of an array. // I chose this implementation of manually increasing the size of the array // as needed rather than using a pre-defined class from Object Pascal. if (bank.currentAccountNumber = length(bank.accounts)) then begin setLength(bank.accounts, length(bank.accounts) * 2); end; end; // Accrues all accounts in a bank. procedure accrue(var bank: Bank; rate: real); overload; var i : integer; begin for i := 0 to bank.currentAccountNumber - 1 do accrue(bank.accounts[i], rate); end; // Gets string representation of a bank. function toString(var bank: Bank): string; overload; var i : integer; begin toString := ''; for i := 0 to bank.currentAccountNumber - 1 do toString := toString + toString(bank.accounts[i]) + #10; end; // Similar to a constructor, gets a new bank. function getNewBank(): Bank; begin getNewBank.currentAccountNumber := 0; setLength(getNewBank.accounts, 1); end; (* The following block of code is what actually runs first when the program is run. It is like the main or initialization block. *) begin myBank := getNewBank(); creatingCustomer := getNewCustomer('Ann'); add(myBank, getNewAccount('01001', creatingCustomer, 100, CheckingAccount)); add(myBank, getNewAccount('01002', creatingCustomer, 200, SavingAccount)); accrue(myBank, 0.02); writeln(toString(myBank)); end.
bank Image

Specification, Documentation, Manuals, and Tutorials