BCPL

Appeared in:
1966
Influenced by:
Influenced:
Paradigm:
Typing discipline:
Versions and implementations (Collapse all | Expand all):
Programming language

BCPL (from Basic/Bootstrap CPL) is a programming language created by Martin Richards of the University of Cambridge in 1966 (first implementation followed in 1967).

BCPL was based on an earlier CPL, strapped of parts which make compilation difficult. Variable types were removed, as well as syntax structures with complicated scoping rules. The syntax was simplified, and separate compilation of program segments was enabled.

BCPL was created as a language for system programming and compilers development: one of the purposes was to write a CPL compiler in it (hence the name “Bootstrap CPL”). The author of the language succeeded: the first BCPL compiler written in BCPL was only about 1000 lines long and required less than 20 kB of memory to run.

Back in 1970s the language was widely used: by 1979 compilers existed for at least 25 platforms, there were even operational systems written in it (TRIPOS and AmigaDOS). It influenced the development of B, which in turn became the prototype for C. The concept of giving the programmer the ultimate power without language-imposed restrictions was BCPL-born. Nowadays the language has no practical use, however, there is one modern implementation of BCPL, created by Martin Richards himself for Cintpos (a version of TRIPOS).

BCPL introduced and implemented several innovations which became quite common elements in the design of later languages. Thus, it was the first curly bracket programming language (one using { } as block delimiters), and it was the first language to use // to mark inline comments. It is presumed to be the first language in which the famous Hello, World! program was written. To enable the cross-platform portability of the language and the programs written in it, the concept of virtual machine was invented. The compiler consisted of two parts — the front-end which parsed the program and converted it to o-code (object code) and the back-end which interpreted this object code or compiled it into machine-dependent codes. Porting the language to another platform meant re-writing only the back-end, which took only about 1/5 of the overall compiler size.

The only data type provided by BCPL is an integer, typically 16-bit, and later 32-bit. The language is contextually typed, meaning that the variable is treated as a number, a character, a pointer, a bit pattern or a logical value depending on the operator applied to it. There are no checks for whether this operator can be applied to this particular value — taking care of this is programmer’s duty. Some implementations added floating-point numbers and special operators to process them.

The only data structure is an array — a sequence of cells. One could store pointers to other entities in the cells, creating multidimensional arrays and more complicated structures.

BCPL’s blocks and flow control structures are mostly inherited from CPL. A block can be used instead of a command or an expression; in the second case there should be a VALOF word before the block and RESULTIS word somewhere inside. Each block can contain declarations of local variables and procedures. Later the language was expanded with the concept of coroutines, which made system programming even more convenient.

Procedure names can be treated as values; in this case they are pointers to corresponding code fragments. They can be stored in variables, be passed as arguments to procedures etc. Interprocedural jumps are enabled by pseudo-functions level() and longjmp(). The principles of handling procedures was later borrowed by C.

The libraries of the language are very few; they contain only basic input/output routines and dynamic memory allocation functions.

Elements of syntax:

Inline comments //
Case-sensitivity yes
Variable assignment <varname> := <value>, <varname> : <value>
Variable declaration with assignment let varname = value
Grouping expressions ( ... )
Block { ... } or $( ... $)
Physical (shallow) equality =
Physical (shallow) inequality ~=
Function definition f(para1, para2, ...) = valof $( ... $) or let f(para1, para2, ...) be $( ... $)
Function call f(a,b,...f) or f[a,b,...]
If - then if <condition> do <trueBlock>
If - then - else test <condition> then <trueBlock> or <falseBlock>; <condition> -> <trueBlock>, <falseBlock>
While condition do while <condition> do <loopBody>
Do until condition <loopBody> repeatuntil <condition>
For each value in a numeric range, 1 increment for i = 1 to 10 do <loopBody>

Examples:

Hello, World!:

Example for versions 64-bit BCPL Cintcode System (1 Nov 2006)

$( ... $) is another form of delimiting a block. *n prints a newline.

GET "libhdr"

LET start() = VALOF
$( writes("Hello, World!*n")
   RESULTIS 0
$)

Factorial:

Example for versions 64-bit BCPL Cintcode System (1 Nov 2006)

This example uses recursive factorial definition. Calculating 15! and larger results in math overflow, thus the result ends like this:

12! = 479001600
13! = 6227020800
14! = 87178291200
15! = 18000
16! = 000
GET "libhdr"

LET start() = VALOF
{ FOR i = 0 TO 16 DO writef("%n! = %n*n", i, factorial(i))
  RESULTIS 0
}

AND factorial(n) = n=0 -> 1, n*factorial(n-1)

Fibonacci numbers:

Example for versions 64-bit BCPL Cintcode System (1 Nov 2006)

This example uses recursive definition of Fibonacci numbers.

GET "libhdr"

LET start() = VALOF
{ FOR i = 0 TO 15 DO writef("%n, ", fibonacci(i))
  writef("...*n")
  RESULTIS 0
}

AND fibonacci(n) = n<2 -> 1, fibonacci(n-1)+fibonacci(n-2)