Analytical Engine Programming Cards

From Esolang
Jump to navigation Jump to search
Analytical Engine Programming Cards
Paradigm(s) imperative
Designed by John Walker
Appeared in 2000
Computational class Turing complete
Reference implementation Web emulator
Major implementations Java cmd line interpreter
Influenced by Analytical Engine
File extension(s) .ae

The history of general purpose programmable computers begins with Charles Babbage's Analytical Engine. In an effort to give modern audiences an experience of what it would have been work like to work with such a machine, John Walker devised the Analytical Engine Programming Cards programming language as an interface to an Analytical Engine emulator. The language was most likely defined in the year 2000, although the concepts obviously date back to 1837 and the inception of the Analytical Engine itself.

Babbage's design

An Analytical Engine consists of 1000 columns, each representing a stored 50-decimal-digit integer. These can be connected to three special purpose input columns called Ingress Axes on a central processing unit called the Mill. The Mill is capable of performing a handful of arithmetic operations on the Ingress Axes with the results being set on two output columns called Egress Axes. Egress Axes can also be connected to the storage columns or to a special-purpose printing press. A full computation, then, will tend to look like:

  1. Read one or two storage columns into the input columns OR read one or two numbers from cards into the input columns
  2. Set the Mill to perform an operation and run it until the result is on the output columns
  3. Write one or both output columns back to storage and/or to the printer

By Babbage's design, there are three different control mechanisms, independently controlled by three different chains of Jacquard-style punch cards.

  1. The Variable cards set the connections between storage columns and input output columns. That is, they select which variables will be read into the Mill and written back from the Mill.
  2. The Number cards can be read to set input columns directly to a given number. In modern parlance, they would be called "immediates."
  3. The Operation cards set which operation (addition, subtraction, multiplication, or division) the Mill is to perform, including any stepping up (left shifting) of the Ingress Axes or stepping down (right shifting) of the Egress Axes.

Although the only data type is the 50-decimal-digit integer, fixed point decimals can be represented by assuming the presence of a decimal point that is not physically represented in the machine. The Step Up and Step Down features make it possible to perform multiplication and division while keeping this abstract representation intact.

The first Ingress Axis has and auxiliary column called the Primed Ingress Axis. The Primed Ingress Axis contains the 50 most significant digits for input into a division. The Egress Axis also has an auxiliary column. The Primed Egress Axis contains the most 50 significant digits of the result of a multiplication, or, in the case of a division, the quotient (while the remainder appears on the regular Egress Axis.)

Control flow is performed by advancing or reversing the punch card chains contingent, perhaps, on the setting of the Run-up Lever which can be set by the Mill while carrying out the arithmetical operations. The Run-up Lever is automatically cleared by an arithmetic operation that does not set it.

John Walker's Assumptions

Because the original programmers of the Analytical Engine (Luigi Menabrea, Ada Lovelace, and Babbage himself) did not seem to care too much about exactly how the three-chain system was to be represented textually, and in fact, combined the operation of all three into a single tabular representation, John Walker has skirted the issue of synchronizing these three separate system by combining all three types of punch card into a single sequence. In this way, they do not need to be distinguished or programmed separately. As such, all command syntax for the Analytical Engine Programming Cards language can be summarized in a single table (below).

John Walker has also incorporated assumptions about the humans operating the engine into the language. That is, his emulator can process directives addressed to these attendants under the assumption that, because the machine is so slow, the attendants will have spare time to compile an Analytical Engine Programming Cards program into the actual punch card chains to be mounted onto the machine, as well as to follow simple instructions that can be read off of the cards while the machine is executing or after it has finished. For example, they can fully specify a number on a Number Card by prepending enough zeroes to make it 50 digits long, convert references to specific locations in a program into card counts for commands that advance or reverse the chains, insert a sequence of cards from their library, report the text written on the back of a card at a particular time, configure the printing press to write out data in a certain format, or record and report an execution trace for a portion of a running program. In other words, under the guise of making assumptions about the human attendants, Walker has added several features present in more modern high-level languages as well as some basic debugging operations.

An Analytical Engine Programming Cards program consists of a sequence of commands each on its own line, similar to an assembly language. The first one or two characters is the opcode, which may, depending on the operation, be followed by one or two arguments.

John Walker assumes that the Curve Drawing Apparatus would use a fixed decimal respresentation of 25 decimal places to draw curves in the fixed domain and range from -1 to 1. It would be on the user to scale their outputs to that domain and range.


Engine Cards

Key: IA1, IA2 - first and second Ingress Axes. IA' - Primed Ingress Axis. EA - Egress Axis. EA' - Primed Egress Axis. [IA',IA1] - number formed by concatenating values on IA' and IA1. [EA',EA] - number formed by concatenating values on EA' and EA. RL= Run-up Lever.

Command Behavior Example
Nx <num> Set storage column x to <num>, which can be any integer written in the usual way. (Columns are numbered 0 to 999.) N341 1232957939 sets column 341 to the value 00000000000000000000000000000000000000001232957939
+ EA = IA1 + IA2. Set RL if sign of EA!=sign of IA1 or if carry-out occurs. +
- EA = IA1 - IA2. Set RL if sign of EA!=sign of IA1 or if borrow-in occurs. -
× or * [EA',EA] = IA1 * IA2 *
÷ or / EA' = [IA',IA1]//IA2 (integer division). EA = [IA',IA1]%IA2 (modulo). Set RL if division result exceeds 50 digits or if IA2=0. /
Lx['] IA['] = value on storage column x L3' puts the value of column 3 on the Primed Ingress Axis
Sx['] Storage column x = value on EA['] S3 puts the value of the Egress Axis on storage column 3.
Zx['] Same as L but it zeroes the storage the column Z3' does the same as L3' but storage column 3 will be zeroed.
<n Left-shift ("step up") [IA',IA1] n decimal digits in-place. If IA'=1 and IA1 = 30000000000000000000000000000000000000000000000002, then <2 will make IA'=130 and IA1=200.
>n Right-shift ("step down") [EA',EA] n decimal digits in-place If EA'=301 and EA=111, then >2 will make EA'=3 and EA=3000000000000000000000000000000000000000000000001.
CF+n Unconditionally skip ahead n lines in the program starting from the line after this one. After CF+11, the line 12 after this will execute next.
CF?n Skip ahead n lines starting from the next line only if RL is set. If an attempt has just been made to divide by zero, CF?5 will skip to the line 6 after this one.
CB+n Unconditionally jump backward n lines in the program starting from the line after this one. After CB+11, the line 10 before this will execute next.
CB?n Jump backward nlines starting from the next line only if RL is set. If a subtraction has just been used to decrement 0, CB?5 will skip to the line 4 before this one.
B Ring a bell B
H Halt (with indicator of last line executed) H
P Print the number on the mill axis the most recent operation most recently modified (optionally formatted as required by a preceding A write numbers instruction) P immediately after a ÷ should print the contents of EA.
. or space Comment .This is is a nop.
D[XY] Set the X or Y position of the curve drawing apparatus to the result of the last arithmetic operation. DX after + positions the curve drawing pen x-coordinate at the contents of EA.
D- Raise curve drawing pen. D- means the next DX and DY will not draw anything.
D+ Lower curve drawing pen. D+

Attendant Cards

Command Behavior Example
T1 Begin Calculation Trace T1 followed by + would log something like Card: 5. ( + to the Attendant's Log
T0 End Calculation Trace T0 will prevent following lines from being logged by a preceding T1
( Unconditional cycle (backing) start: Matching ) n lines hence will be replaced by a CB+n The code enclosed in parentheses is unconditionally looped.
(? Conditional cycle (backing) start: Matching ) n lines hence will be replaced by a CB?n The code enclosed in parentheses is looped while the last operation does not set the run-up lever.
) Cycle end See ( and (?.
{ Unconditional skip (advancing) start: Will be replaced by CF+n where n is the number of lines until a matching } { will jump to the instruction past the matching }.
{? Conditional skip (advancing) start: Will be replaced by CF?n where n is the number of lines until a matching } or }{ See following example.
}{ Conditional skip alternation: Identical semantics to { except that it also serves as a line marker for {?
will perform A if the run-up lever is set, otherwise it will do B.
} Skip (advancing) end See example above.
A include cards filename Insert program from here A include cards MyFunProgram would immediately perform the procedure in
A include from library cards for libname Insert program named libname from standard library here A include from library cards for arctan would perform arctan (because this is defined in the standard library).
A set decimal places to n Allows decimals with n places to be used with N and adds n to < and > commands missing parameters After A set decimal places to 5, a simple < later on will be replaced by <5, while a N001 1.23456 will be replaced by N001 123456.
A write numbers as picture Output numbers according to the format picture A write numbers as 9.99999 99999 99999 99999 will cause the number 123456789012345654321 to be output as 1.23456 78901 23456 54321
A write numbers with decimal point Output numbers with decimal point inserted according to most recent A set decimal places command After A set decimal places to 5 and A write numbers with decimal point, 123456 will be output as 1.23456.
A write in rows Insert a linefeed after every number printed A write in rows
A write in columns Insert one or more tabs after every number printed so that text on each line is aligned in columns A write in columns
A write annotation textual annotation Output textual annotation A write annotation Hello World!
A write new line Output line feed, particularly to start a new line when writing in columns A write new line

Number Formats


See also