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.
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
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:
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 |
static void foo(ArgumentType name,...){ |
void foo(ArgumentType name,...){ |
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 |
program HelloWorld; begin writeln ('Hello, world!'); end.
program Sum; var x, y, z : integer; begin x := 1; y := 2; z := 3; writeln (x + y + z); end.
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.
student@ubuntu:~$ cd pascal/ student@ubuntu:~/pascal$ fpc HelloWorld.p student@ubuntu:~/pascal$ ./HelloWorld
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.
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.
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.
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.