Introduction
Welcome to SLP-PASCAL, the Standard Pascal interpreter for Emulator.ca Systems.
In 1970, Niklaus Wirth sat down at ETH Zurich and designed a programming language with a single, radical conviction: that a language should teach you to think clearly. While the software world was drowning in FORTRAN spaghetti and COBOL verbosity, Wirth created Pascal---a language that enforced discipline. Every variable must be declared before use. Every block must be properly nested. Every program must have a clear beginning and a definite end. It was, in the best sense of the word, opinionated.
Pascal became the language of choice for teaching structured programming in universities throughout the 1970s and 1980s. Generations of computer science students wrote their first programs in Pascal, learning to think in terms of procedures, data types, and control flow before they ever encountered the wilder corners of systems programming. When Borland released Turbo Pascal in 1983, it brought the language to personal computers at a price students could afford. UCSD Pascal brought it to the Apple II. Anders Hejlsberg (later the creator of C# and TypeScript) made his name writing Turbo Pascal's blazingly fast compiler. For a time, Pascal was everywhere.
What made Pascal special was not any single feature, but its philosophy of enforced good habits. Strong typing catches errors at compile time, not at three in the morning. Block structure makes program flow visible at a glance. Explicit variable declarations mean you always know what you are working with. Pascal does not trust you to be disciplined---it requires it.
SLP-PASCAL brings this heritage to your EC-series terminal. Within moments of connecting, you can be writing programs, experimenting with data structures, and rediscovering why so many programmers look back on Pascal with genuine fondness. The interactive interpreter lets you enter programs and execute them immediately, or type individual statements for quick experimentation.
This implementation provides:
- Standard Pascal (ISO 7185) language support
- Interactive program entry with immediate compilation and execution
- Direct statement execution at the command prompt
- WASM-based interpreter for responsive performance
- Worker-based architecture that prevents UI blocking
- Full RS-232 signal participation
- All standard data types: INTEGER, REAL, BOOLEAN, CHAR, STRING, arrays, and records
- Procedures and functions with value and VAR parameters
- Comprehensive standard function library
SLP-PASCAL runs as a WASM interpreter in a dedicated Web Worker thread. This means your terminal remains responsive even during long-running computations. Press ESC at any time to interrupt execution and return to the command prompt.
Quick Start
Connect to SLP-PASCAL and try these examples to get a feel for the language:
+------------------------------------------------------------------+
| QUICK START SESSION |
+------------------------------------------------------------------+
| ATDT555-0370 |
| CONNECT 1200 |
| |
| SLP-PASCAL v1.0 |
| Emulator.ca Systems |
| Standard Pascal Interpreter |
| |
| Type HELP for commands, or enter a program. |
| |
| Ready. |
| |
| WRITELN('Hello, World!'); |
| Hello, World! |
| Ready. |
| |
| WRITELN(2 + 3 * 4); |
| 14 |
| Ready. |
| |
| WRITELN((100 - 37) DIV 9); |
| 7 |
| Ready. |
| |
| WRITELN(5 > 3); |
| TRUE |
| Ready. |
+------------------------------------------------------------------+
You can also enter complete programs. Type PROGRAM or VAR to begin program entry mode, then finish with END.:
PROGRAM HelloThrice;
VAR
I: INTEGER;
BEGIN
FOR I := 1 TO 3 DO
WRITELN('Hello, iteration ', I);
END.
The program compiles and runs automatically when you type END. --- or use the ENTER command to type a program and finish with a period on its own line.
Getting Connected
To access the Pascal interpreter, configure your modem for dial-out and issue the following command:
ATDT555-0370
Upon successful connection, you will see the SLP-PASCAL banner and the Ready. prompt:
ATDT555-0370
CONNECT 1200
SLP-PASCAL v1.0
Emulator.ca Systems
Standard Pascal Interpreter
Type HELP for commands, or enter a program.
Ready.
The Ready. prompt means the interpreter is waiting for your input. You may type commands, direct statements, or begin entering a program.
Modem Signals
The Pascal interpreter participates fully in RS-232 signal protocol:
| Signal | Direction | Function |
|---|---|---|
| DTR | DTE->DCE | Asserted when interpreter is ready; dropped to hang up |
| RTS | DTE->DCE | Asserted when interpreter can accept output |
| CTS | DCE->DTE | When deasserted, output is throttled (flow control) |
| DCD | DCE->DTE | Carrier detect --- connection status |
Press ESC at any time to interrupt a running Pascal program. You will see ^C and return to the Ready. prompt.
Language Overview
Pascal programs follow a strict structure. Every complete program has a header, optional declarations, and a main block:
PROGRAM ProgramName;
CONST
MaxValue = 100;
VAR
X, Y: INTEGER;
Name: STRING;
BEGIN
{ main program body }
X := 42;
WRITELN('The answer is ', X);
END.
Key principles:
- Case insensitive:
BEGIN,begin, andBeginare all the same - Semicolons separate statements (not terminate them---no semicolon before
END) - Assignment uses
:=(the equals sign=is for comparison) - Comments use curly braces
{ like this }or parenthesis-star(* like this *) - String literals use single quotes:
'Hello, World!' - The program ends with
END.(note the period)
Data Types
SLP-PASCAL supports the standard Pascal data types:
Simple Types
| Type | Description | Example Values |
|---|---|---|
| INTEGER | 32-bit signed whole numbers | 42, -7, 0 |
| REAL | 64-bit floating point | 3.14, -0.5, 1.0 |
| BOOLEAN | Logical values | TRUE, FALSE |
| CHAR | Single character | 'A', 'z', '7' |
| STRING | Character sequence | 'Hello', 'Pascal' |
Structured Types
Arrays store indexed collections of elements:
VAR
Scores: ARRAY[1..10] OF INTEGER;
Grid: ARRAY[0..4] OF REAL;
Records group related fields under one name:
VAR
Student: RECORD
Name: STRING;
Age: INTEGER;
GPA: REAL;
END;
SLP-PASCAL performs automatic widening conversions where safe: INTEGER values are promoted to REAL in mixed arithmetic. Use TRUNC or ROUND to convert REAL back to INTEGER explicitly.
Control Structures
IF / THEN / ELSE
Conditional execution:
IF X > 0 THEN
WRITELN('Positive')
ELSE
WRITELN('Not positive');
For multiple statements in a branch, use BEGIN...END:
IF Temperature > 30 THEN
BEGIN
WRITELN('It is warm outside.');
WRITELN('Remember to drink water.');
END;
WHILE / DO
Repeats while a condition is true (tests before each iteration):
WHILE Count > 0 DO
BEGIN
WRITELN(Count);
Count := Count - 1;
END;
REPEAT / UNTIL
Repeats until a condition becomes true (tests after each iteration, so the body always executes at least once):
REPEAT
WRITELN('Enter a positive number:');
READLN(N);
UNTIL N > 0;
FOR / TO / DO
Counted loop with automatic increment:
FOR I := 1 TO 10 DO
WRITELN(I, ' squared is ', I * I);
Use DOWNTO to count backwards:
FOR I := 10 DOWNTO 1 DO
WRITELN(I);
WRITELN('Liftoff!');
CASE / OF
Multi-way selection:
CASE DayNumber OF
1: WRITELN('Monday');
2: WRITELN('Tuesday');
3: WRITELN('Wednesday');
4: WRITELN('Thursday');
5: WRITELN('Friday');
6, 7: WRITELN('Weekend');
ELSE
WRITELN('Invalid day');
END;
Procedures and Functions
Procedures
Procedures perform actions but do not return a value:
PROCEDURE Greet(Name: STRING);
BEGIN
WRITELN('Hello, ', Name, '!');
END;
Functions
Functions compute and return a value. Assign to the function name to set the return value:
FUNCTION Square(N: INTEGER): INTEGER;
BEGIN
Square := N * N;
END;
VAR Parameters (Pass by Reference)
Use VAR to pass a parameter by reference, allowing the procedure to modify the caller's variable:
PROCEDURE Swap(VAR A, B: INTEGER);
VAR
Temp: INTEGER;
BEGIN
Temp := A;
A := B;
B := Temp;
END;
Without VAR, parameters are passed by value---changes inside the procedure do not affect the caller's variables. Use VAR only when you intend to modify the argument.
Local Variables
Procedures and functions may declare their own local variables:
FUNCTION Factorial(N: INTEGER): INTEGER;
VAR
Result, I: INTEGER;
BEGIN
Result := 1;
FOR I := 2 TO N DO
Result := Result * I;
Factorial := Result;
END;
Input/Output
Writing Output
| Statement | Description |
|---|---|
WRITE(...) |
Output values without a newline |
WRITELN(...) |
Output values followed by a newline |
WRITELN |
Output a blank line |
You may pass multiple arguments separated by commas. SLP-PASCAL handles formatting automatically:
WRITELN('Name: ', Name, ' Age: ', Age);
WRITELN('Pi is approximately ', 3.14159);
Format specifiers control field width and decimal places:
WRITELN(X:8); { right-justify in 8 columns }
WRITELN(Pi:8:4); { 8 columns wide, 4 decimal places }
Reading Input
| Statement | Description |
|---|---|
READ(...) |
Read values from input |
READLN(...) |
Read values, then skip to next line |
When a program executes READ or READLN, the interpreter prompts with ? and waits for your input:
WRITELN('Enter your name:');
READLN(Name);
WRITELN('Enter your age:');
READLN(Age);
WRITELN('Hello, ', Name, '! You are ', Age, ' years old.');
When READ expects multiple values, you will be prompted for each one individually.
Standard Functions
Arithmetic Functions
| Function | Description | Example |
|---|---|---|
ABS(x) |
Absolute value | ABS(-5) = 5 |
SQR(x) |
Square (x * x) | SQR(4) = 16 |
SQRT(x) |
Square root | SQRT(25.0) = 5.0 |
TRUNC(x) |
Truncate real to integer | TRUNC(3.7) = 3 |
ROUND(x) |
Round real to nearest integer | ROUND(3.7) = 4 |
FRAC(x) |
Fractional part | FRAC(3.7) = 0.7 |
INT(x) |
Integer part as real | INT(3.7) = 3.0 |
RANDOM |
Random real in [0, 1) | varies |
RANDOM(n) |
Random integer in [0, n) | varies |
Trigonometric Functions
| Function | Description |
|---|---|
SIN(x) |
Sine (radians) |
COS(x) |
Cosine (radians) |
TAN(x) |
Tangent (radians) |
ARCTAN(x) |
Arctangent (returns radians) |
EXP(x) |
e raised to the power x |
LN(x) |
Natural logarithm |
LOG(x) |
Base-10 logarithm |
Ordinal Functions
| Function | Description | Example |
|---|---|---|
ORD(c) |
Character or boolean to integer | ORD('A') = 65 |
CHR(n) |
Integer to character | CHR(65) = 'A' |
SUCC(x) |
Next value (integer or char) | SUCC('A') = 'B' |
PRED(x) |
Previous value | PRED(5) = 4 |
ODD(n) |
True if n is odd | ODD(7) = TRUE |
UPCASE(c) |
Uppercase character | UPCASE('a') = 'A' |
LOWERCASE(c) |
Lowercase character | LOWERCASE('Z') = 'z' |
String Functions
| Function | Description | Example |
|---|---|---|
LENGTH(s) |
String length | LENGTH('Hi') = 2 |
COPY(s, i, n) |
Substring of n chars from position i | COPY('Hello', 2, 3) = 'ell' |
CONCAT(a, b, ...) |
Join strings together | CONCAT('Hi', ' ', 'there') = 'Hi there' |
POS(sub, s) |
Position of substring (0 if not found) | POS('lo', 'Hello') = 4 |
String positions in Pascal are 1-based. The first character of a string is at position 1, not 0.
Operators
Arithmetic Operators
| Operator | Description | Example |
|---|---|---|
+ |
Addition (or string concatenation) | 5 + 3 = 8 |
- |
Subtraction | 10 - 4 = 6 |
* |
Multiplication | 6 * 7 = 42 |
/ |
Real division | 7 / 2 = 3.5 |
DIV |
Integer division | 7 DIV 2 = 3 |
MOD |
Remainder | 17 MOD 5 = 2 |
Comparison Operators
| Operator | Description |
|---|---|
= |
Equal to |
<> |
Not equal to |
< |
Less than |
> |
Greater than |
<= |
Less than or equal to |
>= |
Greater than or equal to |
Boolean Operators
| Operator | Description |
|---|---|
AND |
Logical and |
OR |
Logical or |
NOT |
Logical negation |
Example Programs
Hello, World!
The simplest possible program:
PROGRAM Hello;
BEGIN
WRITELN('Hello, World!');
END.
Temperature Converter
Fahrenheit to Celsius with formatted output:
PROGRAM TempConvert;
VAR
Fahrenheit, Celsius: REAL;
BEGIN
WRITELN('Fahrenheit to Celsius Converter');
WRITELN('Enter temperature in Fahrenheit:');
READLN(Fahrenheit);
Celsius := (Fahrenheit - 32.0) * 5.0 / 9.0;
WRITELN(Fahrenheit:6:1, ' F = ', Celsius:6:1, ' C');
END.
Factorial with a Function
Demonstrates functions, loops, and formatted output:
PROGRAM Factorials;
VAR
I: INTEGER;
FUNCTION Factorial(N: INTEGER): INTEGER;
VAR
Result, J: INTEGER;
BEGIN
Result := 1;
FOR J := 2 TO N DO
Result := Result * J;
Factorial := Result;
END;
BEGIN
FOR I := 1 TO 10 DO
WRITELN(I:2, '! = ', Factorial(I));
END.
Fibonacci Sequence
Demonstrates WHILE loops and multiple variable tracking:
PROGRAM Fibonacci;
VAR
A, B, Temp, Count: INTEGER;
BEGIN
A := 0;
B := 1;
Count := 0;
WRITELN('Fibonacci Sequence:');
WHILE Count < 20 DO
BEGIN
WRITE(A, ' ');
Temp := A + B;
A := B;
B := Temp;
Count := Count + 1;
END;
WRITELN;
END.
Bubble Sort
Demonstrates arrays, nested loops, and VAR parameters:
PROGRAM BubbleSort;
VAR
Data: ARRAY[1..8] OF INTEGER;
I, J, Temp: INTEGER;
BEGIN
{ Initialize with unsorted values }
Data[1] := 64; Data[2] := 34;
Data[3] := 25; Data[4] := 12;
Data[5] := 22; Data[6] := 11;
Data[7] := 90; Data[8] := 1;
{ Bubble sort }
FOR I := 1 TO 7 DO
FOR J := 1 TO 7 DO
IF Data[J] > Data[J + 1] THEN
BEGIN
Temp := Data[J];
Data[J] := Data[J + 1];
Data[J + 1] := Temp;
END;
{ Display sorted result }
WRITE('Sorted: ');
FOR I := 1 TO 8 DO
WRITE(Data[I], ' ');
WRITELN;
END.
Command Reference
SLP-PASCAL provides these interactive commands at the Ready. prompt:
| Command | Description |
|---|---|
HELP |
Display available commands |
NEW |
Clear the current program from memory |
ENTER |
Begin program entry mode (type . on its own line to finish) |
LIST |
Display the current program with line numbers |
RUN |
Compile and execute the current program |
Program Entry Modes
There are two ways to enter a program:
Automatic mode: Begin typing a line that starts with
PROGRAMorVAR. The interpreter enters program mode automatically and returns to command mode when it seesEND.Manual mode: Type
ENTERto begin program entry. Type your program, then type a single period (.) on its own line to finish. UseRUNto execute.
Ready.
ENTER
Enter program. Type . on a line by itself to finish.
PROGRAM Demo;
BEGIN
WRITELN('This was entered manually.');
END.
.
Program entered.
Ready.
RUN
This was entered manually.
Ready.
Direct Statements
You may also type individual Pascal statements directly at the Ready. prompt without wrapping them in a PROGRAM:
Ready.
WRITELN('Hello, World!');
Hello, World!
Ready.
WRITELN(SQRT(144.0));
12.0
Ready.
This is handy for quick calculations and experimentation.
Quick Reference Card
+================================================================+
| SLP-PASCAL QUICK REFERENCE |
+================================================================+
| |
| DIAL: ATDT555-0370 |
| |
| COMMANDS |
| HELP NEW ENTER LIST RUN |
| |
| PROGRAM STRUCTURE |
| PROGRAM Name; |
| CONST name = value; |
| VAR name: TYPE; |
| BEGIN ... END. |
| |
| DATA TYPES |
| INTEGER REAL BOOLEAN CHAR STRING |
| ARRAY[lo..hi] OF type RECORD ... END |
| |
| OPERATORS |
| + - * / DIV MOD |
| = <> < > <= >= |
| AND OR NOT |
| |
| CONTROL STRUCTURES |
| IF cond THEN stmt ELSE stmt |
| WHILE cond DO stmt |
| REPEAT stmts UNTIL cond |
| FOR v := a TO b DO stmt |
| FOR v := a DOWNTO b DO stmt |
| CASE expr OF val: stmt END |
| |
| SUBPROGRAMS |
| PROCEDURE Name(params); BEGIN ... END; |
| FUNCTION Name(params): Type; BEGIN ... END; |
| VAR params for pass-by-reference |
| |
| I/O |
| WRITE(...) WRITELN(...) READ(...) READLN(...) |
| |
| STANDARD FUNCTIONS |
| ABS SQR SQRT SIN COS TAN ARCTAN EXP LN LOG |
| TRUNC ROUND FRAC INT ORD CHR SUCC PRED ODD |
| UPCASE LOWERCASE LENGTH COPY CONCAT POS RANDOM |
| |
| COMMENTS |
| { this is a comment } |
| (* this is also a comment *) |
| |
| ASSIGNMENT |
| variable := expression |
| |
| ESC to interrupt execution |
| |
+================================================================+
Troubleshooting
"Undefined variable" Error
Symptom: Error message when using a variable name.
Solution: All variables must be declared in a VAR section before use. Check spelling carefully---Pascal is case-insensitive, but the name must match your declaration.
Program Does Not Run
Symptom: Typing RUN reports "No program to run."
Solution: Ensure you have entered a program first. Use LIST to check whether a program is in memory. If it is empty, enter one using the ENTER command or by starting a line with PROGRAM or VAR.
Unexpected Compilation Errors
Symptom: Error messages when the program is compiled.
Solution: Check your program structure. Common mistakes include:
- Missing semicolons between statements (but not before
END) - Using
=instead of:=for assignment - Forgetting
BEGIN...ENDaround multiple statements in an IF/WHILE/FOR body - Missing the final period after the last
END
Division by Zero
Symptom: Runtime error during DIV, MOD, or / operations.
Solution: Validate divisors before performing division. Use an IF statement to check:
IF Divisor <> 0 THEN
Result := Dividend DIV Divisor
ELSE
WRITELN('Cannot divide by zero.');
SQRT of Negative Number
Symptom: Runtime error from SQRT.
Solution: Ensure the argument is non-negative. Use ABS if you need the square root of a magnitude.
Program Seems Frozen
Symptom: No output and the terminal is unresponsive.
Solution: You may have an infinite loop. Press ESC to interrupt execution and return to the Ready. prompt. Review your loop conditions---make sure WHILE conditions will eventually become false and REPEAT conditions will eventually become true.
Connection Issues
| Problem | Solution |
|---|---|
| Garbled characters | Set terminal to VT100, 80 columns, 8N1 |
| No response after connect | Press ENTER; check baud rate matches |
| Session freezes | Check flow control settings; try ESC |
| Disconnected unexpectedly | Phone line noise; redial with ATDT555-0370 |
Glossary
Assignment --- Setting a variable to a value using the := operator. Not to be confused with =, which tests equality.
Block --- A compound statement enclosed in BEGIN and END. Blocks group multiple statements where Pascal syntax expects a single statement.
Compound Statement --- Another term for a BEGIN...END block.
Constant --- A named value declared with CONST that cannot be changed during program execution.
Expression --- A combination of values, variables, operators, and function calls that evaluates to a single value.
Function --- A subprogram that computes and returns a value. The return value is set by assigning to the function's own name.
Identifier --- A name for a program, variable, constant, procedure, or function. Must begin with a letter and contain only letters, digits, and underscores.
Ordinal Type --- A type whose values can be counted and ordered: INTEGER, CHAR, and BOOLEAN. Used with ORD, SUCC, PRED, and as FOR loop counters.
Parameter --- A value passed to a procedure or function. Value parameters are copies; VAR parameters are references to the original variable.
Procedure --- A subprogram that performs an action but does not return a value. Called as a statement on its own.
Record --- A structured data type that groups related variables (fields) of different types under a single name.
Statement --- A single instruction in a Pascal program: an assignment, procedure call, control structure, or compound statement.
Strong Typing --- Pascal's requirement that every variable have a declared type, and that types be compatible in expressions and assignments. This catches many programming errors at compile time.
VAR Parameter --- A parameter declared with VAR that is passed by reference, allowing the procedure or function to modify the caller's original variable.
See Also
- ISO 7185 --- The international standard for the Pascal programming language
- Pascal User Manual and Report by Jensen and Wirth --- The original language reference
- Oh! Pascal! by Doug Cooper --- A popular introductory textbook
- Turbo Pascal Reference --- Borland's dialect that dominated the PC era
- SLP-BASIC (555-0300) --- If you prefer line-numbered BASIC programming
- SLP-LOGO (555-0310) --- Turtle graphics for a more visual approach
- SLP-FORTH (555-0400) --- Stack-based programming for the adventurous