├── fourmilab
├── .gitignore
├── Mill.java
├── library
│ ├── ln.ae
│ ├── exp.ae
│ ├── sine.ae
│ ├── sqrt.ae
│ ├── arctan.ae
│ └── cosine.ae
├── Attendant.java
├── analyticalEngine.java
├── examples
│ ├── inverse.ae
│ └── functable.ae
├── PrintingApparatus.java
├── CardPunchingApparatus.java
├── tests
│ ├── exp_test.ae
│ ├── sqrt_test.ae
│ ├── arctan_test.ae
│ ├── ln_test.ae
│ ├── sine_test.ae
│ └── cosine_test.ae
├── README.md
├── OutputApparatus.java
├── Store.java
├── CurveDrawingApparatus.java
├── AnnunciatorPanel.java
├── Makefile
├── CardReader.java
├── frameCurveDrawingApparatus.java
├── WebFrameCurveDrawingApparatus.java
└── aes.java
├── .gitignore
├── .gitattributes
├── src
├── analytical_engine-card-tracing_card.adb
├── analytical_engine-card-operation_card.adb
├── analytical_engine-card-tracing_card.ads
├── analytical_engine-card-stepping_card.adb
├── analytical_engine-card-number_card.adb
├── analytical_engine-card-operation_card.ads
├── analytical_engine-card-comment_card.ads
├── analytical_engine-card-stepping_card.ads
├── analytical_engine-card-combinatorial_card.ads
├── analytical_engine-card-combinatorial_card.adb
├── analytical_engine-card-number_card.ads
├── analytical_engine-card-action_card.ads
├── analytical_engine-card-variable_card.ads
├── analytical_engine-card-action_card.adb
├── analytical_engine.ads
├── analytical_engine-annunciator_panel.adb
├── analytical_engine-card-variable_card.adb
├── analytical_engine-attendant.ads
├── analytical_engine-annunciator_panel-command_line.ads
├── analytical_engine-annunciator_panel-command_line.adb
├── analytical_engine-output.adb
├── analytical_engine-output-printer.ads
├── analytical_engine-annunciator_panel.ads
├── analytical_engine-output.ads
├── analytical_engine-store.ads
├── analytical_engine-framework.adb
├── analytical_engine-card_reader.ads
├── analytical_engine-store.adb
├── aes.adb
├── analytical_engine-mill.ads
├── analytical_engine-framework.ads
├── analytical_engine-card-attendant_request.ads
├── analytical_engine-output-printer.adb
├── analytical_engine-card-attendant_request.adb
├── analytical_engine-card_reader.adb
├── analytical_engine-card.ads
├── analytical_engine-mill.adb
└── analytical_engine-card.adb
├── Makefile
├── aes.gpr
├── check_for_prime.ae
├── COPYING.RUNTIME
├── bernouilli.ae
├── bernouilli5.ae
├── README.md
└── COPYING3
/fourmilab/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 |
3 | .build
4 |
5 | aes
6 | aes.exe
7 |
--------------------------------------------------------------------------------
/fourmilab/Mill.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simonjwright/analytical-engine/HEAD/fourmilab/Mill.java
--------------------------------------------------------------------------------
/fourmilab/library/ln.ae:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simonjwright/analytical-engine/HEAD/fourmilab/library/ln.ae
--------------------------------------------------------------------------------
/fourmilab/Attendant.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simonjwright/analytical-engine/HEAD/fourmilab/Attendant.java
--------------------------------------------------------------------------------
/fourmilab/library/exp.ae:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simonjwright/analytical-engine/HEAD/fourmilab/library/exp.ae
--------------------------------------------------------------------------------
/fourmilab/library/sine.ae:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simonjwright/analytical-engine/HEAD/fourmilab/library/sine.ae
--------------------------------------------------------------------------------
/fourmilab/library/sqrt.ae:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simonjwright/analytical-engine/HEAD/fourmilab/library/sqrt.ae
--------------------------------------------------------------------------------
/fourmilab/library/arctan.ae:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simonjwright/analytical-engine/HEAD/fourmilab/library/arctan.ae
--------------------------------------------------------------------------------
/fourmilab/library/cosine.ae:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simonjwright/analytical-engine/HEAD/fourmilab/library/cosine.ae
--------------------------------------------------------------------------------
/fourmilab/analyticalEngine.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simonjwright/analytical-engine/HEAD/fourmilab/analyticalEngine.java
--------------------------------------------------------------------------------
/fourmilab/examples/inverse.ae:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simonjwright/analytical-engine/HEAD/fourmilab/examples/inverse.ae
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # The fourmilab/ Java code shouldn't affect Github's opinion of this
2 | # project's language.
3 |
4 | fourmilab/* linguist-vendored
5 |
--------------------------------------------------------------------------------
/fourmilab/PrintingApparatus.java:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | The Printing Apparatus
4 |
5 | This class is parent to all fancier implementations of printers.
6 | It just prints on standard output.
7 |
8 | */
9 |
10 | class PrintingApparatus extends OutputApparatus {
11 |
12 | // Print a string
13 |
14 | void Output(String s) {
15 | System.out.print(s);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-tracing_card.adb:
--------------------------------------------------------------------------------
1 | with Analytical_Engine.Framework;
2 |
3 | package body Analytical_Engine.Card.Tracing_Card is
4 |
5 | procedure Execute (C : Tracing_Card;
6 | In_The_Framework : in out Framework.Instance)
7 | is
8 | begin
9 | In_The_Framework.Panel.Set_Tracing (To => C.Tracing);
10 | end Execute;
11 |
12 | end Analytical_Engine.Card.Tracing_Card;
13 |
--------------------------------------------------------------------------------
/fourmilab/CardPunchingApparatus.java:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | The Card Punching Apparatus
4 |
5 | This class is parent to all fancier implementations
6 | of card punches. It just prints the cards on standard
7 | output.
8 |
9 | */
10 |
11 | class CardPunchingApparatus extends OutputApparatus {
12 |
13 | // Punch a card
14 |
15 | void Output(String s) {
16 | System.out.println(s);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-operation_card.adb:
--------------------------------------------------------------------------------
1 | with Analytical_Engine.Framework;
2 |
3 | package body Analytical_Engine.Card.Operation_Card is
4 |
5 | procedure Execute
6 | (C : Operation_Card;
7 | In_The_Framework : in out Analytical_Engine.Framework.Instance)
8 | is
9 | begin
10 | In_The_Framework.Mill.Set_Operation (C.Op);
11 | end Execute;
12 |
13 | end Analytical_Engine.Card.Operation_Card;
14 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-tracing_card.ads:
--------------------------------------------------------------------------------
1 | private package Analytical_Engine.Card.Tracing_Card is
2 |
3 | pragma Elaborate_Body;
4 |
5 | type Tracing_Card is new Card with record
6 | Tracing : Boolean;
7 | end record;
8 | overriding
9 | procedure Execute (C : Tracing_Card;
10 | In_The_Framework : in out Framework.Instance);
11 |
12 | subtype Card is Tracing_Card;
13 |
14 | end Analytical_Engine.Card.Tracing_Card;
15 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-stepping_card.adb:
--------------------------------------------------------------------------------
1 | with Analytical_Engine.Framework;
2 |
3 | package body Analytical_Engine.Card.Stepping_Card is
4 |
5 | procedure Execute (C : Stepping_Card;
6 | In_The_Framework : in out Framework.Instance)
7 | is
8 | begin
9 | In_The_Framework.Mill.Step_Axes (Direction => C.Direction,
10 | Amount => C.Step_Count);
11 | end Execute;
12 |
13 | end Analytical_Engine.Card.Stepping_Card;
14 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-number_card.adb:
--------------------------------------------------------------------------------
1 | with Analytical_Engine.Framework; -- was 'limited with' in parent spec
2 |
3 | package body Analytical_Engine.Card.Number_Card is
4 |
5 | procedure Execute
6 | (C : Number_Card;
7 | In_The_Framework : in out Analytical_Engine.Framework.Instance)
8 | is
9 | begin
10 | In_The_Framework.Store.Set (Col => C.Target_Column,
11 | To => C.Value.all);
12 | end Execute;
13 |
14 | end Analytical_Engine.Card.Number_Card;
15 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-operation_card.ads:
--------------------------------------------------------------------------------
1 | with Analytical_Engine.Mill;
2 |
3 | private package Analytical_Engine.Card.Operation_Card is
4 |
5 | pragma Elaborate_Body;
6 |
7 | type Operation_Card is new Card with record
8 | Op : Mill.Operation;
9 | end record;
10 | overriding
11 | procedure Execute (C : Operation_Card;
12 | In_The_Framework : in out Framework.Instance);
13 |
14 | subtype Card is Operation_Card;
15 |
16 | end Analytical_Engine.Card.Operation_Card;
17 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-comment_card.ads:
--------------------------------------------------------------------------------
1 | private package Analytical_Engine.Card.Comment_Card is
2 |
3 | type Comment_Card is new Card with null record;
4 | overriding
5 | procedure Execute (C : Comment_Card;
6 | In_The_Framework : in out Framework.Instance);
7 |
8 | subtype Card is Comment_Card;
9 |
10 | private
11 |
12 | procedure Execute (C : Comment_Card;
13 | In_The_Framework : in out Framework.Instance)
14 | is null;
15 |
16 | end Analytical_Engine.Card.Comment_Card;
17 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-stepping_card.ads:
--------------------------------------------------------------------------------
1 | with Analytical_Engine.Mill;
2 |
3 | private package Analytical_Engine.Card.Stepping_Card is
4 |
5 | pragma Elaborate_Body;
6 |
7 | type Stepping_Card is new Card with record
8 | Direction : Mill.Step;
9 | Step_Count : Positive;
10 | end record;
11 | overriding
12 | procedure Execute (C : Stepping_Card;
13 | In_The_Framework : in out Framework.Instance);
14 |
15 | subtype Card is Stepping_Card;
16 |
17 | end Analytical_Engine.Card.Stepping_Card;
18 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-combinatorial_card.ads:
--------------------------------------------------------------------------------
1 | private package Analytical_Engine.Card.Combinatorial_Card is
2 |
3 | pragma Elaborate_Body;
4 |
5 | type Combinatorial_Card is new Card with record
6 | Advance : Boolean;
7 | Conditional : Boolean;
8 | Card_Count : Positive;
9 | end record;
10 | overriding
11 | procedure Execute (C : Combinatorial_Card;
12 | In_The_Framework : in out Framework.Instance);
13 |
14 | subtype Card is Combinatorial_Card;
15 |
16 | end Analytical_Engine.Card.Combinatorial_Card;
17 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-combinatorial_card.adb:
--------------------------------------------------------------------------------
1 | with Analytical_Engine.Framework;
2 |
3 | package body Analytical_Engine.Card.Combinatorial_Card is
4 |
5 | procedure Execute (C : Combinatorial_Card;
6 | In_The_Framework : in out Framework.Instance)
7 | is
8 | begin
9 | if not C.Conditional or else In_The_Framework.Mill.Run_Up_Set then
10 | In_The_Framework.Card_Reader.Step
11 | (if C.Advance then C.Card_Count else -C.Card_Count);
12 | end if;
13 | end Execute;
14 |
15 | end Analytical_Engine.Card.Combinatorial_Card;
16 |
--------------------------------------------------------------------------------
/fourmilab/tests/exp_test.ae:
--------------------------------------------------------------------------------
1 |
2 | V104 Iteration variable
3 | V103 Increment
4 | V101 Loop limit
5 | V105 0
6 |
7 | A set decimal places to 20
8 |
9 | A write numbers with decimal point
10 | A write in columns
11 |
12 | N101 1.1
13 | N103 0.1
14 | N104 0.0
15 | N105 0
16 |
17 | (?
18 | +
19 | L104
20 | L105
21 | S000
22 |
23 | A write annotation e to the power
24 | +
25 | L000
26 | P
27 | A write annotation =
28 |
29 | A include cards fixn/exp.ae
30 |
31 | +
32 | L000
33 | P
34 | A write new line
35 |
36 | +
37 | L104
38 | L103
39 | S104
40 |
41 | -
42 | L104
43 | L101
44 | )
45 |
--------------------------------------------------------------------------------
/fourmilab/tests/sqrt_test.ae:
--------------------------------------------------------------------------------
1 |
2 | V104 Iteration variable
3 | V103 Increment
4 | V101 Loop limit
5 | V105 0
6 |
7 | A set decimal places to 20
8 |
9 | A write numbers with decimal point
10 | A write in columns
11 |
12 | N101 11.0
13 | N103 1.0
14 | N104 0
15 | N105 0
16 |
17 | (?
18 | +
19 | L104
20 | L105
21 | S000
22 |
23 | A write annotation Square root of
24 | +
25 | L000
26 | P
27 | A write annotation =
28 |
29 | A include cards fixn/sqrt.ae
30 |
31 | +
32 | L000
33 | P
34 | A write new line
35 |
36 | +
37 | L104
38 | L103
39 | S104
40 |
41 | -
42 | L104
43 | L101
44 | )
45 |
--------------------------------------------------------------------------------
/fourmilab/tests/arctan_test.ae:
--------------------------------------------------------------------------------
1 |
2 | V104 Iteration variable
3 | V103 Increment
4 | V101 Loop limit
5 | V105 0
6 |
7 | A set decimal places to 20
8 |
9 | A write numbers with decimal point
10 | A write in columns
11 |
12 | N101 1.1
13 | N103 0.1
14 | N104 0
15 | N105 0
16 |
17 | (?
18 | +
19 | L104
20 | L105
21 | S000
22 |
23 | A write annotation Arc Tangent of
24 | +
25 | L000
26 | P
27 | A write annotation =
28 |
29 | A include cards fixn/arctan.ae
30 |
31 | +
32 | L000
33 | P
34 | A write new line
35 |
36 | +
37 | L104
38 | L103
39 | S104
40 |
41 | -
42 | L104
43 | L101
44 | )
45 |
--------------------------------------------------------------------------------
/fourmilab/tests/ln_test.ae:
--------------------------------------------------------------------------------
1 |
2 | V104 Iteration variable
3 | V103 Increment
4 | V101 Loop limit
5 | V105 0
6 |
7 | A set decimal places to 20
8 |
9 | A write numbers with decimal point
10 | A write in columns
11 |
12 | N101 11.0
13 | N103 1.0
14 | N104 1.0
15 | N105 0
16 |
17 | (?
18 | +
19 | L104
20 | L105
21 | S000
22 |
23 | A write annotation Natural logarithm of
24 | +
25 | L000
26 | P
27 | A write annotation =
28 |
29 | A include cards fix20/ln.ae
30 |
31 | +
32 | L000
33 | P
34 | A write new line
35 |
36 | +
37 | L104
38 | L103
39 | S104
40 |
41 | -
42 | L104
43 | L101
44 | )
45 |
--------------------------------------------------------------------------------
/fourmilab/README.md:
--------------------------------------------------------------------------------
1 | # Java source and function library
2 |
3 | This directory contains
4 |
5 | * Java source code for the
6 | [Analytical Engine emulator](http://www.fourmilab.ch/babbage/cmdline.html)
7 | * source code for the
8 | [mathematical function library](http://www.fourmilab.ch/babbage/library.html)
9 | in library/, examples/ and test/.
10 |
11 | from the [Fourmilab web site](http://www.fourmilab.ch/babbage/).
12 |
13 | The author states that *Source code is intended for experienced Java
14 | programmers only. You're free to use the source code in any way, but
15 | you're entirely on your own; no assistance or support of any kind is
16 | provided.*
17 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-number_card.ads:
--------------------------------------------------------------------------------
1 | with GNATCOLL.GMP.Integers;
2 |
3 | with Analytical_Engine.Store;
4 |
5 | private package Analytical_Engine.Card.Number_Card is
6 |
7 | pragma Elaborate_Body;
8 |
9 | type Big_Integer_P is access GNATCOLL.GMP.Integers.Big_Integer;
10 | -- because Big_Integer is limited
11 |
12 | type Number_Card is new Card with record
13 | Target_Column : Store.Column;
14 | Value : Big_Integer_P;
15 | end record;
16 | overriding
17 | procedure Execute (C : Number_Card;
18 | In_The_Framework : in out Framework.Instance);
19 |
20 | subtype Card is Number_Card;
21 |
22 | end Analytical_Engine.Card.Number_Card;
23 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-action_card.ads:
--------------------------------------------------------------------------------
1 | private package Analytical_Engine.Card.Action_Card is
2 |
3 | pragma Elaborate_Body;
4 |
5 | type Action_Kind is (Ring_Bell, Halt_Engine, Print_Last_Result);
6 |
7 | type Action_Card (Act : Action_Kind) is new Card with record
8 | case Act is
9 | when Halt_Engine =>
10 | Msg : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
11 | when others =>
12 | null;
13 | end case;
14 | end record;
15 | overriding
16 | procedure Execute (C : Action_Card;
17 | In_The_Framework : in out Framework.Instance);
18 |
19 | subtype Card is Action_Card;
20 |
21 | end Analytical_Engine.Card.Action_Card;
22 |
--------------------------------------------------------------------------------
/fourmilab/tests/sine_test.ae:
--------------------------------------------------------------------------------
1 |
2 | V104 Iteration variable
3 | V103 Increment
4 | V101 Loop limit
5 | V105 0
6 |
7 | A set decimal places to 40
8 |
9 | A write numbers with decimal point
10 | A write in columns
11 |
12 | N101 7.0
13 | N103 1.0
14 | N104 0
15 | N105 0
16 |
17 | (?
18 | +
19 | L104
20 | L105
21 | S000
22 |
23 | A write annotation Sine of
24 | +
25 | L000
26 | P
27 | A write annotation =
28 |
29 | A include cards fixn/sine.ae
30 |
31 | +
32 | L000
33 | P
34 |
35 | A include cards fixn/arcsine.ae
36 |
37 | A write annotation Arcsine =
38 |
39 | +
40 | L000
41 | P
42 |
43 | A write new line
44 |
45 | +
46 | L104
47 | L103
48 | S104
49 |
50 | -
51 | L104
52 | L101
53 | )
54 |
--------------------------------------------------------------------------------
/fourmilab/tests/cosine_test.ae:
--------------------------------------------------------------------------------
1 |
2 | V104 Iteration variable
3 | V103 Increment
4 | V101 Loop limit
5 | V105 0
6 |
7 | A set decimal places to 20
8 |
9 | A write numbers with decimal point
10 | A write in columns
11 |
12 | N101 7.0
13 | N103 1.0
14 | N104 0
15 | N105 0
16 |
17 | (?
18 | +
19 | L104
20 | L105
21 | S000
22 |
23 | A write annotation Cosine of
24 | +
25 | L000
26 | P
27 | A write annotation =
28 |
29 | A include cards fixn/cosine.ae
30 |
31 | +
32 | L000
33 | P
34 |
35 | A include cards fixn/arccosine.ae
36 |
37 | A write annotation Arccosine =
38 |
39 | +
40 | L000
41 | P
42 |
43 | A write new line
44 |
45 | +
46 | L104
47 | L103
48 | S104
49 |
50 | -
51 | L104
52 | L101
53 | )
54 |
--------------------------------------------------------------------------------
/fourmilab/OutputApparatus.java:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Output Apparatus
4 |
5 | This class is parent to the Card Punching, Printing,
6 | and Copper Plate Punching Apparatuses.
7 |
8 | */
9 |
10 | abstract class OutputApparatus {
11 | AnnunciatorPanel panel;
12 | Attendant attendant;
13 |
14 | /* Output a string. The new line character denotes the
15 | end of a record, and may occur in the middle of the
16 | string. */
17 |
18 | abstract void Output(String s);
19 |
20 | /* Provide references to the annunciator panel and
21 | attendant for Apparatus implementations which may need to
22 | communicate with them. */
23 |
24 | public void setPanelAndAttendant(AnnunciatorPanel p, Attendant a) {
25 | panel = p;
26 | attendant = a;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-variable_card.ads:
--------------------------------------------------------------------------------
1 | with Analytical_Engine.Mill;
2 | with Analytical_Engine.Store;
3 |
4 | private package Analytical_Engine.Card.Variable_Card is
5 |
6 | pragma Elaborate_Body;
7 |
8 | type Variable_Card is new Card with record
9 | Axis : Mill.Axis; -- Ingress axes are to mill, egress to store
10 | Column : Store.Column;
11 | Preserve : Boolean; -- If false and the value is being sent to
12 | -- the mill, the source column is reset to
13 | -- zero after the value has been
14 | -- retrieved.
15 | end record;
16 | overriding
17 | procedure Execute (C : Variable_Card;
18 | In_The_Framework : in out Framework.Instance);
19 |
20 | subtype Card is Variable_Card;
21 |
22 | end Analytical_Engine.Card.Variable_Card;
23 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-action_card.adb:
--------------------------------------------------------------------------------
1 | with Analytical_Engine.Framework;
2 |
3 | with GNATCOLL.GMP.Integers;
4 |
5 | package body Analytical_Engine.Card.Action_Card is
6 |
7 | use GNATCOLL.GMP.Integers;
8 |
9 | procedure Execute (C : Action_Card;
10 | In_The_Framework : in out Framework.Instance)
11 | is
12 | begin
13 | case C.Act is
14 | when Halt_Engine =>
15 | In_The_Framework.Panel.Log_Attendant_Message
16 | ("Halt: " & To_Wide_String (C.Msg));
17 | In_The_Framework.Card_Reader.Halt;
18 | when Ring_Bell =>
19 | In_The_Framework.Panel.Log_Attendant_Message ("Ting!");
20 | when Print_Last_Result =>
21 | declare
22 | Result : Big_Integer;
23 | begin
24 | In_The_Framework.Mill.Get_Egress (Result);
25 | In_The_Framework.Output.Output (Result);
26 | end;
27 | end case;
28 | end Execute;
29 |
30 | end Analytical_Engine.Card.Action_Card;
31 |
--------------------------------------------------------------------------------
/src/analytical_engine.ads:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | package Analytical_Engine with Pure is
23 | end Analytical_Engine;
24 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Copyright (C) Simon Wright
2 |
3 | # This file is part of the Analytical Engine Ada emulator
4 | # project. This file is free software; you can redistribute it and/or
5 | # modify it under terms of the GNU General Public License as published
6 | # by the Free Software Foundation; either version 3, or (at your
7 | # option) any later version. This file is distributed in the hope that
8 | # it will be useful, but WITHOUT ANY WARRANTY; without even the
9 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 | # PURPOSE.
11 |
12 | # As a special exception under Section 7 of GPL version 3, you are
13 | # granted additional permissions described in the GCC Runtime Library
14 | # Exception, version 3.1, as published by the Free Software
15 | # Foundation.
16 |
17 | # You should have received a copy of the GNU General Public License
18 | # and a copy of the GCC Runtime Library Exception along with this
19 | # program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | # If not, see .
21 |
22 | EXE := $(suffix $(notdir $(shell which gnat)))
23 |
24 | all: aes$(EXE)
25 |
26 | aes$(EXE): force
27 | gprbuild -p -P aes.gpr
28 |
29 | .PHONY: all force
30 |
--------------------------------------------------------------------------------
/fourmilab/Store.java:
--------------------------------------------------------------------------------
1 |
2 | import java.util.*;
3 |
4 | // The Store
5 |
6 | class Store {
7 | private Vector rack; // Rack of variable columns
8 | AnnunciatorPanel panel;
9 | Attendant attendant;
10 | private boolean trace = false;
11 |
12 | public Store(AnnunciatorPanel p, Attendant a) {
13 | panel = p;
14 | attendant = a;
15 | reset();
16 | }
17 |
18 | public void set(int which, BigInt v) {
19 | rack.setElementAt(v, which);
20 | panel.changeStoreColumn(which, rack);
21 | if (trace) {
22 | attendant.traceLog("Store: V" + which + " = " + v);
23 | }
24 | }
25 |
26 | public void set(int which, long v) {
27 | set(which, new BigInt(v));
28 | }
29 |
30 | public BigInt get(int which) {
31 | BigInt v;
32 |
33 | if (rack.elementAt(which) == null) {
34 | set(which, 0);
35 | }
36 | v = (BigInt) rack.elementAt(which);
37 | if (trace) {
38 | attendant.traceLog("Store: Mill <= V" + which + "(" + v + ")");
39 | }
40 | return v;
41 | }
42 |
43 | public void reset() {
44 | rack = new Vector(1000);
45 | rack.setSize(1000);
46 | panel.changeStoreColumn(-1, rack);
47 | }
48 |
49 | public void setTrace(boolean t) {
50 | trace = t;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/analytical_engine-annunciator_panel.adb:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | package body Analytical_Engine.Annunciator_Panel is
23 |
24 | procedure Set_Tracing (This : in out Instance; To : Boolean) is
25 | begin
26 | This.Tracing := To;
27 | end Set_Tracing;
28 |
29 | end Analytical_Engine.Annunciator_Panel;
30 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-variable_card.adb:
--------------------------------------------------------------------------------
1 | with Analytical_Engine.Framework;
2 |
3 | with GNATCOLL.GMP.Integers;
4 |
5 | package body Analytical_Engine.Card.Variable_Card is
6 |
7 | use GNATCOLL.GMP.Integers;
8 |
9 | procedure Execute
10 | (C : Variable_Card;
11 | In_The_Framework : in out Analytical_Engine.Framework.Instance)
12 | is
13 | Value : Big_Integer;
14 | begin
15 | case C.Axis is
16 | when Mill.Ingress =>
17 | In_The_Framework.Store.Get (Col => C.Column,
18 | Result => Value,
19 | Preserve => C.Preserve);
20 | In_The_Framework.Mill.Set_Ingress (Value);
21 | when Mill.Ingress_Primed =>
22 | In_The_Framework.Store.Get (Col => C.Column,
23 | Result => Value,
24 | Preserve => C.Preserve);
25 | In_The_Framework.Mill.Set_Ingress_Primed (Value);
26 | when Mill.Egress =>
27 | In_The_Framework.Mill.Get_Egress (Value);
28 | In_The_Framework.Store.Set (Col => C.Column, To => Value);
29 | when Mill.Egress_Primed =>
30 | In_The_Framework.Mill.Get_Egress_Primed (Value);
31 | In_The_Framework.Store.Set (Col => C.Column, To => Value);
32 | end case;
33 | end Execute;
34 |
35 | end Analytical_Engine.Card.Variable_Card;
36 |
--------------------------------------------------------------------------------
/src/analytical_engine-attendant.ads:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Analytical_Engine.Annunciator_Panel;
23 | private with Ada.Finalization;
24 | package Analytical_Engine.Attendant is
25 |
26 | type Instance (Panel : not null Annunciator_Panel.Class_P)
27 | is tagged limited private;
28 |
29 | type Instance_P is access all Instance;
30 |
31 | private
32 |
33 | type Instance (Panel : not null Annunciator_Panel.Class_P)
34 | is new Ada.Finalization.Limited_Controlled with null record;
35 |
36 | end Analytical_Engine.Attendant;
37 |
--------------------------------------------------------------------------------
/fourmilab/CurveDrawingApparatus.java:
--------------------------------------------------------------------------------
1 | /*
2 | The Curve Drawing Apparatus
3 |
4 | This class is parent to all implementations which actually
5 | do anything.
6 |
7 | */
8 |
9 | import java.awt.Color;
10 |
11 | class CurveDrawingApparatus {
12 | AnnunciatorPanel panel;
13 | Attendant attendant;
14 | boolean initdone = false;
15 | BigInt px = BigInt.ZERO, py = BigInt.ZERO;
16 | Color penColour = Color.black;
17 |
18 | CurveDrawingApparatus(AnnunciatorPanel p, Attendant a) {
19 | setPanelAndAttendant(p, a);
20 | }
21 |
22 | CurveDrawingApparatus() {
23 | panel = null;
24 | attendant = null;
25 | }
26 |
27 | public void setPanelAndAttendant(AnnunciatorPanel p, Attendant a) {
28 | panel = p;
29 | attendant = a;
30 | }
31 |
32 | boolean initialised() {
33 | return initdone = true;
34 | }
35 |
36 | public synchronized void dispose() {
37 | }
38 |
39 | public void setX(BigInt x) {
40 | px = x;
41 | }
42 |
43 | public void setY(BigInt y) {
44 | py = y;
45 | }
46 |
47 | // moveTo -- Move, with the pen up, to the current co-ordinates
48 |
49 | public void moveTo() {
50 | }
51 |
52 | // drawTo -- Draw, with the pen down, to the current co-ordinates
53 |
54 | public void drawTo() {
55 | }
56 |
57 | // changePen -- Change the pen for one of a different colour
58 |
59 | public void changePen(Color cpen) {
60 | penColour = cpen;
61 | }
62 |
63 | // changePaper -- Start a new plot on a new sheet of paper
64 |
65 | public void changePaper() {
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/analytical_engine-annunciator_panel-command_line.ads:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | package Analytical_Engine.Annunciator_Panel.Command_Line is
23 |
24 | pragma Elaborate_Body;
25 |
26 | type Instance is new Annunciator_Panel.Instance with private;
27 |
28 | overriding
29 | procedure Log_Attendant_Message (Panel : Instance; Msg : Wide_String);
30 |
31 | overriding
32 | procedure Log_Trace_Message (Panel : Instance; Msg : Wide_String);
33 |
34 | private
35 |
36 | type Instance is new Annunciator_Panel.Instance with null record;
37 |
38 | end Analytical_Engine.Annunciator_Panel.Command_Line;
39 |
--------------------------------------------------------------------------------
/src/analytical_engine-annunciator_panel-command_line.adb:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Ada.Wide_Text_IO; use Ada.Wide_Text_IO;
23 | package body Analytical_Engine.Annunciator_Panel.Command_Line is
24 |
25 | procedure Log_Attendant_Message (Panel : Instance; Msg : Wide_String)
26 | is
27 | pragma Unreferenced (Panel);
28 | begin
29 | Put_Line (Msg);
30 | end Log_Attendant_Message;
31 |
32 | procedure Log_Trace_Message (Panel : Instance; Msg : Wide_String)
33 | is
34 | pragma Unreferenced (Panel);
35 | begin
36 | Put_Line (Msg);
37 | end Log_Trace_Message;
38 |
39 | end Analytical_Engine.Annunciator_Panel.Command_Line;
40 |
--------------------------------------------------------------------------------
/src/analytical_engine-output.adb:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | package body Analytical_Engine.Output is
23 |
24 | procedure Set_Picture
25 | (This : in out Instance;
26 | To : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String)
27 | is
28 | begin
29 | This.Picture := To;
30 | end Set_Picture;
31 |
32 | procedure Clear_Picture (This : in out Instance)
33 | is
34 | begin
35 | This.Picture := Ada.Strings.Wide_Unbounded.Null_Unbounded_Wide_String;
36 | end Clear_Picture;
37 |
38 | procedure Writing_Style (This : in out Instance; In_Rows : Boolean)
39 | is
40 | begin
41 | This.In_Rows := In_Rows;
42 | end Writing_Style;
43 |
44 | end Analytical_Engine.Output;
45 |
--------------------------------------------------------------------------------
/src/analytical_engine-output-printer.ads:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Analytical_Engine.Annunciator_Panel;
23 | package Analytical_Engine.Output.Printer is
24 |
25 | pragma Elaborate_Body;
26 |
27 | type Instance (Panel : not null Annunciator_Panel.Class_P)
28 | is new Analytical_Engine.Output.Instance with private;
29 |
30 | overriding
31 | procedure Output
32 | (To : Instance; S : Wide_String);
33 | overriding
34 | procedure Output
35 | (To : Instance; I : GNATCOLL.GMP.Integers.Big_Integer);
36 |
37 | private
38 |
39 | type Instance (Panel : not null Annunciator_Panel.Class_P)
40 | is new Analytical_Engine.Output.Instance (Panel => Panel)
41 | with null record;
42 |
43 | end Analytical_Engine.Output.Printer;
44 |
--------------------------------------------------------------------------------
/fourmilab/examples/functable.ae:
--------------------------------------------------------------------------------
1 |
2 | Demonstrate mathematical function library by calculating
3 | a table of values of the various functions.
4 |
5 | V104 Iteration variable
6 | V103 Increment
7 | V101 Loop limit
8 | V105 0
9 | V106 Current value
10 |
11 | A set decimal places to 7
12 |
13 | A write numbers as +9.9999999
14 | A write in columns
15 |
16 | N101 2.1
17 | N103 0.1
18 | N104 1.0
19 | N105 0
20 |
21 | A write annotation x exp x ln x sin x cos x atan x sqrt x
22 | Model output line: 1.0000000 2.7182818 0.0000000 0.8414710 0.5403023 0.7853982 1.0000000
23 | A write new line
24 |
25 | (?
26 | +
27 | L104
28 | L105
29 | S000
30 | S106
31 |
32 | P
33 |
34 | A write annotation
35 |
36 | A include cards fixn/exp.ae
37 |
38 | +
39 | L000
40 | P
41 | A write annotation
42 |
43 | +
44 | L106
45 | L105
46 | S000
47 |
48 | A include cards fixn/ln.ae
49 |
50 | +
51 | L000
52 | P
53 | A write annotation
54 |
55 |
56 | +
57 | L106
58 | L105
59 | S000
60 |
61 | A include cards fixn/sine.ae
62 |
63 | +
64 | L000
65 | P
66 | A write annotation
67 |
68 | +
69 | L106
70 | L105
71 | S000
72 |
73 | A include cards fixn/cosine.ae
74 |
75 | +
76 | L000
77 | P
78 | A write annotation
79 |
80 | +
81 | L106
82 | L105
83 | S000
84 |
85 | A include cards fixn/arctan.ae
86 |
87 | +
88 | L000
89 | P
90 | A write annotation
91 |
92 | +
93 | L106
94 | L105
95 | S000
96 |
97 | A include cards fixn/sqrt.ae
98 |
99 | +
100 | L000
101 | P
102 | A write annotation
103 |
104 | A write new line
105 |
106 | Update cycle variables and test for completion
107 |
108 | +
109 | L104
110 | L103
111 | S104
112 |
113 | -
114 | L104
115 | L101
116 | )
117 |
--------------------------------------------------------------------------------
/aes.gpr:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with "gnatcoll_gmp";
23 |
24 | project Aes is
25 |
26 | type Optimization is ("debug", "performance");
27 | Opt : Optimization := external ("OPTIMIZATION", "debug");
28 |
29 | for Source_Dirs use ("src");
30 | for Object_Dir use ".build";
31 | for Exec_Dir use ".";
32 |
33 | for Main use ("aes.adb");
34 |
35 | package Builder is
36 | for Default_Switches ("ada") use ("-g");
37 | end Builder;
38 |
39 | package Compiler is
40 | Switches := ("-gnatwa", "-gnatW8");
41 | case Opt is
42 | when "debug" =>
43 | Switches := Switches & ("-gnatqQafoy", "-O0");
44 | when "performance" =>
45 | Switches := Switches & ("-gnatqQfy", "-O2", "-gnatp");
46 | end case;
47 | for Default_Switches ("ada") use Switches;
48 | end Compiler;
49 |
50 | package Binder is
51 | for Default_Switches ("ada") use ("-E");
52 | end Binder;
53 |
54 | end Aes;
55 |
--------------------------------------------------------------------------------
/src/analytical_engine-annunciator_panel.ads:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | -- private with Ada.Finalization;
23 | package Analytical_Engine.Annunciator_Panel is
24 |
25 | pragma Elaborate_Body;
26 |
27 | type Instance is abstract tagged limited private;
28 | type Class_P is access Instance'Class;
29 |
30 | procedure Log_Attendant_Message
31 | (This : Instance; Msg : Wide_String) is abstract;
32 |
33 | procedure Log_Trace_Message
34 | (This : Instance; Msg : Wide_String) is abstract;
35 |
36 | procedure Set_Tracing (This : in out Instance; To : Boolean);
37 |
38 | function Tracing (This : Instance) return Boolean;
39 |
40 | private
41 |
42 | type Instance is abstract tagged limited record
43 | -- is abstract new Ada.Finalization.Limited_Controlled with record
44 | Tracing : Boolean := False;
45 | end record;
46 |
47 | function Tracing (This : Instance) return Boolean is (This.Tracing);
48 |
49 | end Analytical_Engine.Annunciator_Panel;
50 |
--------------------------------------------------------------------------------
/src/analytical_engine-output.ads:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Analytical_Engine.Annunciator_Panel;
23 | with Ada.Finalization;
24 | with Ada.Strings.Wide_Unbounded;
25 | with GNATCOLL.GMP.Integers;
26 |
27 | package Analytical_Engine.Output is
28 |
29 | type Instance (Panel : not null Annunciator_Panel.Class_P)
30 | is abstract new Ada.Finalization.Limited_Controlled with private;
31 | type Class_P is access all Instance'Class;
32 |
33 | procedure Output
34 | (To : Instance; S : Wide_String) is abstract;
35 | procedure Output
36 | (To : Instance; I : GNATCOLL.GMP.Integers.Big_Integer) is abstract;
37 |
38 | procedure Set_Picture
39 | (This : in out Instance;
40 | To : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String);
41 | procedure Clear_Picture (This : in out Instance);
42 |
43 | procedure Writing_Style (This : in out Instance; In_Rows : Boolean);
44 |
45 | private
46 |
47 | type Instance (Panel : not null Annunciator_Panel.Class_P)
48 | is abstract new Ada.Finalization.Limited_Controlled with record
49 | Picture : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
50 | In_Rows : Boolean := True;
51 | end record;
52 |
53 | end Analytical_Engine.Output;
54 |
--------------------------------------------------------------------------------
/src/analytical_engine-store.ads:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Analytical_Engine.Annunciator_Panel;
23 | with Analytical_Engine.Attendant;
24 | with GNATCOLL.GMP.Integers; use GNATCOLL.GMP.Integers;
25 | private with Ada.Finalization;
26 | package Analytical_Engine.Store is
27 |
28 | type Column is range 0 .. 999;
29 |
30 | type Instance
31 | (Panel : not null Annunciator_Panel.Class_P;
32 | Attendant : not null Analytical_Engine.Attendant.Instance_P)
33 | is tagged limited private;
34 | type Instance_P is access all Instance;
35 |
36 | procedure Allow_Overwrite_Nonzero (Allow : Boolean);
37 |
38 | procedure Set (This : in out Instance; Col : Column; To : Big_Integer);
39 |
40 | procedure Get (This : in out Instance;
41 | Col : Column;
42 | Result : out Big_Integer;
43 | Preserve : Boolean);
44 |
45 | Store_Error : exception;
46 |
47 | private
48 |
49 | type Column_Array is array (Column) of Big_Integer;
50 |
51 | type Instance
52 | (Panel : not null Annunciator_Panel.Class_P;
53 | Attendant : not null Analytical_Engine.Attendant.Instance_P)
54 | is new Ada.Finalization.Limited_Controlled with record
55 | Columns : Column_Array;
56 | end record;
57 |
58 | end Analytical_Engine.Store;
59 |
--------------------------------------------------------------------------------
/src/analytical_engine-framework.adb:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | package body Analytical_Engine.Framework is
23 |
24 | function Create
25 | (With_Panel : not null Analytical_Engine.Annunciator_Panel.Class_P;
26 | With_Output : not null Analytical_Engine.Output.Class_P)
27 | return Instance
28 | is
29 | With_Attendant : constant Analytical_Engine.Attendant.Instance_P
30 | := new Analytical_Engine.Attendant.Instance (Panel => With_Panel);
31 | begin
32 | return E : Instance (Panel => With_Panel,
33 | Attendant => With_Attendant) do
34 |
35 | E.Mill := new Analytical_Engine.Mill.Instance
36 | (Panel => With_Panel,
37 | Attendant => With_Attendant);
38 |
39 | E.Store := new Analytical_Engine.Store.Instance
40 | (Panel => With_Panel,
41 | Attendant => With_Attendant);
42 |
43 | E.Card_Reader := new Analytical_Engine.Card_Reader.Instance
44 | (Panel => With_Panel,
45 | Attendant => With_Attendant);
46 |
47 | E.Output := With_Output;
48 | end return;
49 | end Create;
50 |
51 | procedure Run (This : in out Instance) is
52 | begin
53 | This.Card_Reader.Execute (In_The_Framework => This);
54 | end Run;
55 |
56 | end Analytical_Engine.Framework;
57 |
--------------------------------------------------------------------------------
/check_for_prime.ae:
--------------------------------------------------------------------------------
1 | . Checks whether a number is prime. The example value (203) celebrates
2 | . the 203rd anniversary of Ada's 1815 birth in 2018.
3 |
4 | N001 203 the number to be checked
5 |
6 | N000 0 constant 0 - actually the default
7 | N002 1 constant 1
8 | N003 2 constant 2
9 | N004 3 starting test divisor
10 |
11 | . column 10 is used as a scratch register; it must be zero before
12 | . storing into it, so always load using Z10
13 |
14 | A write in columns
15 |
16 | . if target number is < 4, it's prime
17 | + add 1 to 3, makes 4
18 | L004
19 | L002
20 | S010
21 | - subtract 4 from target number
22 | L001
23 | Z010 leave column 10 zero
24 | CF?1 skip if sign changed (target < 4)
25 | CF+9 continue
26 | A write numbers as ##9
27 | + report the target is prime
28 | L001
29 | L000
30 | P
31 | A write annotation is prime
32 | A write new line
33 | H
34 |
35 | . if target number is divisible by 2, it isn't prime
36 | /
37 | L001
38 | L003
39 | S010 store remainder
40 | - check for zero
41 | Z010 load remainder, leaving column 10 zeroed
42 | L002 subtract 1
43 | CF?1 skip to print/halt if sign changed (i.e. was zero)
44 | CF+8 continue to check next divisor
45 | A write numbers as ##9
46 | + print the target number
47 | L001
48 | L000
49 | P
50 | A write annotation is divisible by 2
51 | A write new line
52 | H
53 |
54 | . main loop
55 | / divide target by test value
56 | L001
57 | L004
58 | S010 store remainder (column 10 must be zero previously)
59 | - check for zero
60 | Z010 load remainder, leaving column 10 zeroed
61 | L002 subtract 1
62 | CF?1 skip to print/halt if sign changed (i.e. was zero)
63 | CF+15 continue to check next divisor
64 |
65 | . divisor found!
66 | A write numbers as ##9
67 | + print the target number
68 | L001
69 | L000
70 | P
71 | A write annotation is divisible by
72 | A write numbers as ##9
73 | + print the divisor
74 | L004
75 | L000
76 | P
77 | A write new line
78 | H
79 |
80 | + check next possible factor
81 | Z004 load current candidate, clear store
82 | L003 add 2
83 | S004 store result
84 | * square the candidate
85 | L004
86 | L004
87 | S010
88 | -
89 | L001 load target
90 | Z010 load (candidate squared), leaving column 10 zeroed
91 | CF?1 skip if sign changed (i.e. no divisor found)
92 | CB+39 back to main loop
93 |
94 | . no divisor found!
95 | A write numbers as ##9
96 | + report the target is prime
97 | L001
98 | L000
99 | P
100 | A write annotation is prime
101 | A write new line
102 | H
103 |
--------------------------------------------------------------------------------
/src/analytical_engine-card_reader.ads:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Analytical_Engine.Annunciator_Panel;
23 | with Analytical_Engine.Attendant;
24 | with Analytical_Engine.Card;
25 |
26 | limited with Analytical_Engine.Framework;
27 |
28 | private with Ada.Containers.Indefinite_Vectors;
29 | private with Ada.Finalization;
30 | package Analytical_Engine.Card_Reader is
31 |
32 | type Instance
33 | (Panel : not null Analytical_Engine.Annunciator_Panel.Class_P;
34 | Attendant : not null Analytical_Engine.Attendant.Instance_P)
35 | is tagged limited private;
36 | type Instance_P is access all Instance;
37 |
38 | Card_Reader_Error : exception;
39 |
40 | procedure Reset (This : out Instance);
41 |
42 | procedure Add_Cards (This : in out Instance; From_File_Named : String);
43 | -- If From_File_Named is the empty string, use standard input.
44 |
45 | procedure Execute (This : in out Instance;
46 | In_The_Framework : in out Framework.Instance);
47 |
48 | procedure Step (This : in out Instance; By : Integer);
49 |
50 | procedure Halt (This : in out Instance);
51 |
52 | private
53 |
54 | package Chains is new Ada.Containers.Indefinite_Vectors
55 | (Element_Type => Card.Card'Class,
56 | "=" => Card.Equals,
57 | Index_Type => Positive);
58 |
59 | type Instance
60 | (Panel : not null Annunciator_Panel.Class_P;
61 | Attendant : not null Analytical_Engine.Attendant.Instance_P)
62 | is new Ada.Finalization.Limited_Controlled with record
63 | Index : Positive := 1;
64 | Halted : Boolean := True;
65 | Chain : Chains.Vector;
66 | end record;
67 |
68 | end Analytical_Engine.Card_Reader;
69 |
--------------------------------------------------------------------------------
/fourmilab/AnnunciatorPanel.java:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Annunciator Panel
4 |
5 | The annunciator panel comprises all means by which the Analytical
6 | Engine notifies its attendant of its current state and work in
7 | progress. Whenever a relevant change occurs, the panel is
8 | notified so that the change can be displayed.
9 |
10 | This is the default annunciator panel, which does nothing. This
11 | is used as a superclass by panels which display the current state
12 | in various ways.
13 |
14 | */
15 |
16 | import java.util.*;
17 |
18 | class AnnunciatorPanel {
19 |
20 | // MILL NOTIFICATIONS
21 |
22 | // Changes of state in one of the Mill's axes
23 |
24 | public void changeIngress(int which, BigInt v) {
25 | }
26 |
27 | public void changeEgress(int which, BigInt v) {
28 | }
29 |
30 | // Change in the run up lever
31 |
32 | public void changeRunUp(boolean run_up) {
33 | }
34 |
35 | // Change in current operation in the mill
36 |
37 | public void changeOperation(String op) {
38 | }
39 |
40 | // Change to the run/stop state of the mill
41 |
42 | public void changeMillRunning(boolean running, String message) {
43 | if (!running) {
44 | if (message != null && (message = message.trim()).length() > 0) {
45 | attendantLogMessage("Halt: " + message + "\n");
46 | }
47 | }
48 | }
49 | public void changeMillRunning(boolean running) {
50 | changeMillRunning(running, "");
51 | }
52 |
53 | // Ring the bell
54 |
55 | public void ringBell() {
56 | System.out.print("\007");
57 | System.out.flush();
58 | }
59 |
60 | // STORE NOTIFICATIONS
61 |
62 | // Change to a column in the Store
63 |
64 | public void changeStoreColumn(int which, Vector v) {
65 | }
66 |
67 | // CARD READER NOTIFICATIONS
68 |
69 | /* Mount a new card chain. When a chain is dismounted
70 | and the card reader is reset, this is called with a
71 | null argument. Note that the card reader is reset
72 | before the first card chain is mounted. */
73 |
74 | public void mountCardReaderChain(Vector v) {
75 | }
76 |
77 | // Turn to a new card
78 |
79 | public void changeCardReaderCard(Card c, int cardNumber) {
80 | }
81 |
82 | // ATTENDANT NOTIFICATIONS
83 |
84 | // Log a communication from the Attendant
85 |
86 | public void attendantLogMessage(String s) {
87 | System.out.print(s);
88 | System.out.flush();
89 | }
90 |
91 | // Write an item into the mill operation trace
92 |
93 | public void attendantWriteTrace(String s) {
94 | attendantLogMessage(s);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/analytical_engine-store.adb:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Ada.Characters.Conversions;
23 | with Ada.Strings.Fixed;
24 |
25 | package body Analytical_Engine.Store is
26 |
27 | Zero : constant Big_Integer := Make ("0");
28 |
29 | Overwrite_Nonzero_Allowed : Boolean := False;
30 |
31 | procedure Allow_Overwrite_Nonzero (Allow : Boolean)
32 | is
33 | begin
34 | Overwrite_Nonzero_Allowed := Allow;
35 | end Allow_Overwrite_Nonzero;
36 |
37 | function "+" (Item : String) return Wide_String
38 | renames Ada.Characters.Conversions.To_Wide_String;
39 |
40 | procedure Set (This : in out Instance; Col : Column; To : Big_Integer)
41 | is
42 | begin
43 | if not Overwrite_Nonzero_Allowed
44 | and then This.Columns (Col) /= Zero
45 | then
46 | raise Store_Error with "storing on non-zero column";
47 | end if;
48 | if This.Panel.Tracing then
49 | This.Panel.Log_Trace_Message
50 | (+("Store: "
51 | & Image (To)
52 | & " => V"
53 | & Ada.Strings.Fixed.Trim (Col'Img, Ada.Strings.Both)));
54 | end if;
55 | Set (This.Columns (Col), To => To);
56 | end Set;
57 |
58 | procedure Get (This : in out Instance;
59 | Col : Column;
60 | Result : out Big_Integer;
61 | Preserve : Boolean)
62 | is
63 | begin
64 | if This.Panel.Tracing then
65 | This.Panel.Log_Trace_Message
66 | (+("Store: V"
67 | & Ada.Strings.Fixed.Trim (Col'Img, Ada.Strings.Both)
68 | & "("
69 | & Image (This.Columns (Col))
70 | & ") => Mill" & (if Preserve then "" else ", zeroed")));
71 | end if;
72 | Set (Result, To => This.Columns (Col));
73 | if not Preserve then
74 | Set (This.Columns (Col), To => Zero);
75 | end if;
76 | end Get;
77 |
78 | end Analytical_Engine.Store;
79 |
--------------------------------------------------------------------------------
/fourmilab/Makefile:
--------------------------------------------------------------------------------
1 |
2 | CLASSPATH = /usr/java/classes:.
3 |
4 | WEBTEST = /ftp/babbage/test
5 | WEBREL = /ftp/babbage
6 | WEBSIMDIR = $(WEBREL)/websim
7 | ARCHDIR = $(WEBREL)/release
8 | EXAMPLEDIR = $(WEBREL)/Examples
9 |
10 | #OPTIMISE = -O
11 | OPTIMISE = -g
12 |
13 | # Object file component definitions
14 |
15 | SIMULATOR_CORE = \
16 | analyticalEngine.class \
17 | AnnunciatorPanel.class \
18 | Attendant.class \
19 | BigInt.class \
20 | Card.class \
21 | CardPunchingApparatus.class \
22 | CardReader.class \
23 | CardSource.class \
24 | CurveDrawingApparatus.class \
25 | Mill.class \
26 | OutputApparatus.class \
27 | PrintingApparatus.class \
28 | Store.class
29 |
30 | COMMAND_LINE = \
31 | aes.class \
32 | curvePlot.class \
33 | frameCurveDrawingApparatus.class
34 |
35 | JAVA_APPLET = \
36 | aeapp.class \
37 | AnimatedAnnunciatorPanel.class \
38 | AnimatedPrintingApparatus.class \
39 | annunciatorDisplay.class \
40 | attendantDisplay.class \
41 | cardReaderDisplay.class \
42 | graphicalLabel.class \
43 | loadPanel.class \
44 | millDisplay.class \
45 | printerDisplay.class \
46 | storeDisplay.class \
47 | WebCurvePlot.class \
48 | WebFrameCurveDrawingApparatus.class \
49 | Util.class
50 |
51 | C_ALL = $(SIMULATOR_CORE) $(COMMAND_LINE) $(JAVA_APPLET)
52 |
53 | # Source code component definitions
54 |
55 | S_SIMULATOR_CORE = \
56 | analyticalEngine.java \
57 | AnnunciatorPanel.java \
58 | Attendant.java \
59 | BigInt.java \
60 | CardPunchingApparatus.java \
61 | CardReader.java \
62 | CurveDrawingApparatus.java \
63 | Mill.java \
64 | OutputApparatus.java \
65 | PrintingApparatus.java \
66 | Store.java
67 |
68 | S_COMMAND_LINE = \
69 | aes.java \
70 | frameCurveDrawingApparatus.java
71 |
72 | S_JAVA_APPLET = \
73 | aeapp.java \
74 | WebFrameCurveDrawingApparatus.java
75 |
76 | S_ALL = Makefile $(S_SIMULATOR_CORE) $(S_COMMAND_LINE) $(S_JAVA_APPLET)
77 |
78 |
79 | all: commandline applet
80 |
81 | applet: $(SIMULATOR_CORE) $(JAVA_APPLET)
82 |
83 | commandline: $(SIMULATOR_CORE) $(COMMAND_LINE)
84 |
85 |
86 | test: all
87 | appletviewer ae.html
88 |
89 | clean:
90 | rm -f *.bak *.class aesource.tar.gz aeclass.tar.gz
91 |
92 | websim: applet
93 | rm -f $(WEBSIMDIR)/*.class
94 | cp -p $(SIMULATOR_CORE) $(JAVA_APPLET) $(WEBSIMDIR)
95 |
96 | archive: all
97 | rm -f $(ARCHDIR)/aesource.zip $(ARCHDIR)/aeclass.zip
98 | zip $(ARCHDIR)/aesource.zip $(S_ALL)
99 | zip $(ARCHDIR)/aeclass.zip $(C_ALL)
100 |
101 | examples:
102 | rm -f $(ARCHDIR)/examples.zip
103 | ( cd $(EXAMPLEDIR) ; zip $(ARCHDIR)/examples.zip *.ae )
104 |
105 | webtest: all
106 | # rm -rf $(WEBTEST)
107 | # tar cfv /tmp/a.tar .
108 | # mkdir $(WEBTEST)
109 | # ( cd $(WEBTEST) ; tar xfv /tmp/a.tar )
110 |
111 | webrel: all
112 | # rm -rf $(WEBREL)
113 | # tar cfv /tmp/a.tar .
114 | # mkdir $(WEBREL)
115 | # ( cd $(WEBREL) ; tar xfv /tmp/a.tar )
116 |
117 |
118 |
119 | .java.class:
120 | javac $(OPTIMISE) -encoding ISO-8859-1 -classpath $(CLASSPATH) $*.java
121 |
122 | .SUFFIXES: .java .class
123 |
--------------------------------------------------------------------------------
/fourmilab/CardReader.java:
--------------------------------------------------------------------------------
1 |
2 | import java.util.*;
3 |
4 | // A single Card
5 |
6 | class Card {
7 | String text; // Contents of card
8 | int index; // Index in chain of cards
9 | CardSource source; // Index in list of sources
10 |
11 | public Card(String s, int i, CardSource si) {
12 | text = s;
13 | index = i;
14 | source = si;
15 | }
16 |
17 | public String toString() {
18 | String s = "";
19 |
20 | s += (index + 1) + ". (" + source.sourceName + ":" +
21 | ((index - source.startIndex) + 1) + ") " + text;
22 | return s;
23 | }
24 | }
25 |
26 | // Card Source Descriptors (non-period: for debugging)
27 |
28 | class CardSource {
29 | String sourceName; // Source of card (usually file name)
30 | int startIndex; // First index from this source
31 |
32 | public CardSource(String sn, int si) {
33 | sourceName = sn;
34 | startIndex = si;
35 | }
36 | }
37 |
38 | // The Card Reader
39 |
40 | class CardReader {
41 | private AnnunciatorPanel panel;
42 | private Attendant attendant;
43 | private Vector cards = null; // No cards initially mounted
44 | private int ncards = 0;
45 | private int nextCardNumber = 0; // Next card to read
46 |
47 | CardReader(AnnunciatorPanel p, Attendant a) {
48 | panel = p;
49 | attendant = a;
50 | reset();
51 | }
52 |
53 | public void reset() {
54 | panel.mountCardReaderChain(cards = null);
55 | ncards = 0;
56 | nextCardNumber = 0;
57 | }
58 |
59 | public void firstCard() {
60 | nextCardNumber = 0;
61 | if (ncards > 0) {
62 | panel.changeCardReaderCard((Card) cards.elementAt(nextCardNumber),
63 | nextCardNumber);
64 | }
65 | }
66 |
67 | public Card nextCard() {
68 | try {
69 | Card c = (Card) cards.elementAt(nextCardNumber);
70 | nextCardNumber++;
71 | panel.changeCardReaderCard(c, nextCardNumber);
72 | return c;
73 | } catch (ArrayIndexOutOfBoundsException e) {
74 | return null;
75 | }
76 | }
77 |
78 | public boolean advance(int n) {
79 | if ((nextCardNumber + n) >= ncards) {
80 | return false;
81 | }
82 | nextCardNumber += n;
83 | return true;
84 | }
85 |
86 | public boolean repeat(int n) {
87 | if ((nextCardNumber - n) < 0) {
88 | return false;
89 | }
90 | nextCardNumber -= n;
91 | return true;
92 | }
93 |
94 | public void listAll(OutputApparatus apparatus, boolean verbatim) {
95 | int i;
96 |
97 | for (i = 0; i < ncards; i++) {
98 | if (verbatim) {
99 | apparatus.Output(((Card) cards.elementAt(i)).text);
100 | } else {
101 | apparatus.Output(cards.elementAt(i).toString() + "\n");
102 | }
103 | }
104 | }
105 |
106 | // Mount a chain of cards in the reader
107 |
108 | public void mountCards(Vector cardChain) {
109 | if (cardChain != null) {
110 | reset();
111 | }
112 | panel.mountCardReaderChain(cards = cardChain);
113 | ncards = cards.size();
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/aes.adb:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Ada.Exceptions;
23 | with Ada.IO_Exceptions;
24 | with Ada.Text_IO;
25 | with GNAT.Command_Line;
26 |
27 | with Analytical_Engine.Annunciator_Panel.Command_Line;
28 | with Analytical_Engine.Card;
29 | with Analytical_Engine.Card_Reader;
30 | with Analytical_Engine.Framework;
31 | with Analytical_Engine.Output.Printer;
32 | with Analytical_Engine.Store;
33 |
34 | use Analytical_Engine;
35 |
36 | procedure Aes is
37 |
38 | Command_Line_Config : GNAT.Command_Line.Command_Line_Configuration;
39 | Tracing : aliased Boolean := False;
40 | Allow_Overwrite_Nonzero : aliased Boolean := False;
41 |
42 | Panel : constant Annunciator_Panel.Class_P
43 | := new Annunciator_Panel.Command_Line.Instance;
44 | F : Framework.Instance
45 | := Framework.Create
46 | (With_Panel => Panel,
47 | With_Output => new Output.Printer.Instance (Panel));
48 |
49 | begin
50 | GNAT.Command_Line.Set_Usage
51 | (Command_Line_Config,
52 | Usage => "[card-chain-file]",
53 | Help =>
54 | "Run the chain of cards in card-chain-file (or standard input)");
55 | GNAT.Command_Line.Define_Switch
56 | (Command_Line_Config,
57 | Tracing'Access,
58 | "-t",
59 | Long_Switch => "--trace",
60 | Help => "Trace execution (like card T1)");
61 | GNAT.Command_Line.Define_Switch
62 | (Command_Line_Config,
63 | Allow_Overwrite_Nonzero'Access,
64 | "-z",
65 | Long_Switch => "--overwrite-nonzero",
66 | Help => "Allow storing to a non-zero column");
67 |
68 | GNAT.Command_Line.Getopt (Command_Line_Config);
69 |
70 | Panel.Set_Tracing (Tracing);
71 | Store.Allow_Overwrite_Nonzero (Allow_Overwrite_Nonzero);
72 |
73 | declare
74 | Chain_File_Name : constant String := GNAT.Command_Line.Get_Argument;
75 | begin
76 | F.Card_Reader.Add_Cards (Chain_File_Name);
77 | end;
78 |
79 | F.Run;
80 | exception
81 | when E :
82 | Ada.IO_Exceptions.Name_Error | Ada.IO_Exceptions.Use_Error =>
83 | Ada.Text_IO.Put_Line
84 | (Ada.Text_IO.Standard_Error,
85 | "Couldn't open " & Ada.Exceptions.Exception_Message (E));
86 | when E : Analytical_Engine.Card.Card_Error =>
87 | Ada.Text_IO.Put_Line
88 | (Ada.Text_IO.Standard_Error,
89 | "Card error: " & Ada.Exceptions.Exception_Message (E));
90 | when GNAT.Command_Line.Exit_From_Command_Line
91 | | GNAT.Command_Line.Invalid_Switch => null;
92 | end Aes;
93 |
--------------------------------------------------------------------------------
/COPYING.RUNTIME:
--------------------------------------------------------------------------------
1 | GCC RUNTIME LIBRARY EXCEPTION
2 |
3 | Version 3.1, 31 March 2009
4 |
5 | Copyright (C) 2009 Free Software Foundation, Inc.
6 |
7 | Everyone is permitted to copy and distribute verbatim copies of this
8 | license document, but changing it is not allowed.
9 |
10 | This GCC Runtime Library Exception ("Exception") is an additional
11 | permission under section 7 of the GNU General Public License, version
12 | 3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
13 | bears a notice placed by the copyright holder of the file stating that
14 | the file is governed by GPLv3 along with this Exception.
15 |
16 | When you use GCC to compile a program, GCC may combine portions of
17 | certain GCC header files and runtime libraries with the compiled
18 | program. The purpose of this Exception is to allow compilation of
19 | non-GPL (including proprietary) programs to use, in this way, the
20 | header files and runtime libraries covered by this Exception.
21 |
22 | 0. Definitions.
23 |
24 | A file is an "Independent Module" if it either requires the Runtime
25 | Library for execution after a Compilation Process, or makes use of an
26 | interface provided by the Runtime Library, but is not otherwise based
27 | on the Runtime Library.
28 |
29 | "GCC" means a version of the GNU Compiler Collection, with or without
30 | modifications, governed by version 3 (or a specified later version) of
31 | the GNU General Public License (GPL) with the option of using any
32 | subsequent versions published by the FSF.
33 |
34 | "GPL-compatible Software" is software whose conditions of propagation,
35 | modification and use would permit combination with GCC in accord with
36 | the license of GCC.
37 |
38 | "Target Code" refers to output from any compiler for a real or virtual
39 | target processor architecture, in executable form or suitable for
40 | input to an assembler, loader, linker and/or execution
41 | phase. Notwithstanding that, Target Code does not include data in any
42 | format that is used as a compiler intermediate representation, or used
43 | for producing a compiler intermediate representation.
44 |
45 | The "Compilation Process" transforms code entirely represented in
46 | non-intermediate languages designed for human-written code, and/or in
47 | Java Virtual Machine byte code, into Target Code. Thus, for example,
48 | use of source code generators and preprocessors need not be considered
49 | part of the Compilation Process, since the Compilation Process can be
50 | understood as starting with the output of the generators or
51 | preprocessors.
52 |
53 | A Compilation Process is "Eligible" if it is done using GCC, alone or
54 | with other GPL-compatible software, or if it is done without using any
55 | work based on GCC. For example, using non-GPL-compatible Software to
56 | optimize any GCC intermediate representations would not qualify as an
57 | Eligible Compilation Process.
58 |
59 | 1. Grant of Additional Permission.
60 |
61 | You have permission to propagate a work of Target Code formed by
62 | combining the Runtime Library with Independent Modules, even if such
63 | propagation would otherwise violate the terms of GPLv3, provided that
64 | all Target Code was generated by Eligible Compilation Processes. You
65 | may then convey such a combination under terms of your choice,
66 | consistent with the licensing of the Independent Modules.
67 |
68 | 2. No Weakening of GCC Copyleft.
69 |
70 | The availability of this Exception does not imply any general
71 | presumption that third-party software is unaffected by the copyleft
72 | requirements of the license of GCC.
73 |
74 |
--------------------------------------------------------------------------------
/fourmilab/frameCurveDrawingApparatus.java:
--------------------------------------------------------------------------------
1 |
2 | // Frame (stand-alone application window) Curve Drawing Apparatus
3 |
4 | import java.awt.*;
5 | import java.util.*;
6 |
7 | class curvePlot extends Canvas {
8 | AnnunciatorPanel panel;
9 | Attendant attendant;
10 | Polygon p = null;
11 | Dimension s;
12 | private final static BigInt
13 | K10e25 = BigInt.valueOf("10000000000000000000000000"),
14 | Kround = BigInt.valueOf( "5000000000000000000000000");
15 | Vector pvect = new Vector();
16 | boolean isPenDown = true;
17 | Color penColour = Color.black;
18 | int ax, ay;
19 |
20 | // Constructor
21 |
22 | curvePlot(AnnunciatorPanel p, Attendant a) {
23 | panel = p;
24 | attendant = a;
25 | }
26 |
27 | private static final int scaleNum(BigInt v, int scale) {
28 | //System.out.println("Scale in: " + v + " scale = " + scale);
29 | v = v.add(v.multiply(scale / 2), Kround.multiply(v.test()));
30 | //System.out.println(v);
31 | v = BigInt.quotient(v, K10e25);
32 | //System.out.println(v);
33 | //System.out.println("Pixel: " + (v.intValue() + (scale / 2)));
34 | return v.intValue() + (scale / 2);
35 | }
36 |
37 | public void paint(Graphics g) {
38 | Enumeration e = pvect.elements();
39 |
40 | g.setColor(penColour);
41 | while (e.hasMoreElements()) {
42 | g.drawPolygon((Polygon) e.nextElement());
43 | }
44 | }
45 |
46 | public void penDown() {
47 | isPenDown = true;
48 | }
49 |
50 | public void penUp() {
51 | if (isPenDown) {
52 | p = null;
53 | }
54 | }
55 |
56 | public void addPoint(BigInt px, BigInt py) {
57 | int ax, ay;
58 |
59 | s = size();
60 | ax = scaleNum(px, s.width);
61 | ay = s.height - scaleNum(py, s.height);
62 | if (isPenDown) {
63 | if (p == null) {
64 | p = new Polygon();
65 | pvect.addElement(p);
66 | p.addPoint(ax, ay);
67 | }
68 | p.addPoint(ax, ay);
69 | invalidate();
70 | }
71 | }
72 |
73 | public void setPenColour(Color c) {
74 | penColour = c;
75 | }
76 | }
77 |
78 | class frameCurveDrawingApparatus extends CurveDrawingApparatus {
79 | Frame f = null;
80 | curvePlot cp;
81 |
82 | frameCurveDrawingApparatus(AnnunciatorPanel p, Attendant a) {
83 | super(p, a);
84 | }
85 |
86 | frameCurveDrawingApparatus() {
87 | super();
88 | }
89 |
90 | boolean initialised() {
91 | if (f == null) {
92 | f = new Frame("Curve Drawing Apparatus");
93 | f.add("Center", cp = new curvePlot(panel, attendant));
94 | cp.resize(400, 400);
95 | f.pack();
96 | f.show();
97 | }
98 | return super.initialised();
99 | }
100 |
101 | public void moveTo() {
102 | if (initialised()) {
103 | cp.penUp();
104 | // cp.addPoint(px, py);
105 | }
106 | }
107 |
108 | public void drawTo() {
109 | if (initialised()) {
110 | cp.penDown();
111 | cp.addPoint(px, py);
112 | cp.repaint();
113 | }
114 | }
115 |
116 | public void changePen(Color c) {
117 | if (initialised()) {
118 | cp.setPenColour(c);
119 | }
120 | }
121 |
122 | public void changePaper() {
123 | if (f != null) {
124 | f.dispose();
125 | f = null;
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/src/analytical_engine-mill.ads:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Analytical_Engine.Annunciator_Panel;
23 | with Analytical_Engine.Attendant;
24 | with GNATCOLL.GMP.Integers; use GNATCOLL.GMP.Integers;
25 |
26 | package Analytical_Engine.Mill is
27 |
28 | type Axis is
29 | (Ingress,
30 | Ingress_Primed,
31 | Egress,
32 | Egress_Primed);
33 |
34 | type Operation_Base is
35 | (None,
36 | Add,
37 | Subtract,
38 | Multiply,
39 | Divide);
40 | subtype Operation is Operation_Base range Add .. Operation_Base'Last;
41 |
42 | type Step is (Up, Down);
43 |
44 | Mill_Error : exception;
45 |
46 | type Instance
47 | (Panel : not null Annunciator_Panel.Class_P;
48 | Attendant : not null Analytical_Engine.Attendant.Instance_P)
49 | is tagged limited private;
50 | type Instance_P is access Instance;
51 |
52 | procedure Set_Operation (This : in out Instance; To : Operation);
53 |
54 | procedure Set_Ingress (This : in out Instance; To : Big_Integer);
55 |
56 | procedure Set_Ingress_Primed (This : in out Instance; To : Big_Integer);
57 |
58 | procedure Get_Egress (This : Instance; Result : out Big_Integer);
59 |
60 | procedure Get_Egress_Primed (This : Instance; Result : out Big_Integer);
61 |
62 | function Run_Up_Set (This : Instance) return Boolean;
63 | -- Run_Up is set False when an operation starts, and set True if
64 | -- the operation overflows or (in the case of addition or
65 | -- subtraction) produces a result whose sign is different from
66 | -- that of the first argument.
67 |
68 | procedure Step_Axes (This : in out Instance;
69 | Direction : Step;
70 | Amount : Positive);
71 | -- If Direction is Up (card amount),
74 | -- the egress axes are scaled down by 10**amount (so you need to
75 | -- do this for a multiplication after the multiplier is supplied).
76 |
77 | private
78 |
79 | type Instance
80 | (Panel : not null Annunciator_Panel.Class_P;
81 | Attendant : not null Analytical_Engine.Attendant.Instance_P)
82 | is tagged limited record
83 | Op : Operation_Base := None;
84 | Ingress_Valid : Boolean := False;
85 | Ingress : Big_Integer; -- initialized to zero
86 | Ingress_Primed : Big_Integer;
87 | Egress : Big_Integer;
88 | Egress_Primed : Big_Integer;
89 | Run_Up : Boolean := False;
90 | end record;
91 |
92 | function Run_Up_Set (This : Instance) return Boolean is (This.Run_Up);
93 |
94 | end Analytical_Engine.Mill;
95 |
--------------------------------------------------------------------------------
/fourmilab/WebFrameCurveDrawingApparatus.java:
--------------------------------------------------------------------------------
1 |
2 | // Web Applet Curve Drawing Apparatus
3 |
4 | import java.awt.*;
5 | import java.util.*;
6 |
7 | class WebCurvePlot extends Canvas {
8 | AnnunciatorPanel panel;
9 | Attendant attendant;
10 | Polygon p = null;
11 | Dimension s;
12 | private final static BigInt //1234567890123456789012345678901234567890
13 | K10e25 = BigInt.valueOf("10000000000000000000000000"),
14 | Kround = BigInt.valueOf( "5000000000000000000000000");
15 | Vector pvect = new Vector();
16 | boolean isPenDown = true;
17 | Color penColour = Color.black;
18 | int ax, ay;
19 |
20 | // Constructor
21 |
22 | WebCurvePlot(AnnunciatorPanel p, Attendant a) {
23 | panel = p;
24 | attendant = a;
25 | }
26 |
27 | private static final int scaleNum(BigInt v, int scale) {
28 | //System.out.println("Scale in: " + v + " scale = " + scale);
29 | v = v.add(v.multiply(scale / 2), Kround.multiply(v.test()));
30 | //System.out.println(v);
31 | v = BigInt.quotient(v, K10e25);
32 | //System.out.println(v);
33 | //System.out.println("Pixel: " + (v.intValue() + (scale / 2)));
34 | return v.intValue() + (scale / 2);
35 | }
36 |
37 | public void paint(Graphics g) {
38 | Enumeration e = pvect.elements();
39 |
40 | g.setColor(penColour);
41 | while (e.hasMoreElements()) {
42 | g.drawPolygon((Polygon) e.nextElement());
43 | }
44 | }
45 |
46 | public void penDown() {
47 | isPenDown = true;
48 | }
49 |
50 | public void penUp() {
51 | if (isPenDown) {
52 | p = null;
53 | }
54 | }
55 |
56 | public void addPoint(BigInt px, BigInt py) {
57 | int ax, ay;
58 |
59 | s = size();
60 | ax = scaleNum(px, s.width);
61 | ay = s.height - scaleNum(py, s.height);
62 | if (isPenDown) {
63 | if (p == null) {
64 | p = new Polygon();
65 | pvect.addElement(p);
66 | p.addPoint(ax, ay);
67 | }
68 | p.addPoint(ax, ay);
69 | invalidate();
70 | }
71 | }
72 |
73 | public void setPenColour(Color c) {
74 | penColour = c;
75 | }
76 | }
77 |
78 | class WebFrameCurveDrawingApparatus extends CurveDrawingApparatus {
79 | Frame f = null;
80 | WebCurvePlot cp;
81 |
82 | WebFrameCurveDrawingApparatus(AnnunciatorPanel p, Attendant a) {
83 | super(p, a);
84 | }
85 |
86 | WebFrameCurveDrawingApparatus() {
87 | super();
88 | }
89 |
90 | boolean initialised() {
91 | if (f == null) {
92 | f = new Frame("Curve Drawing Apparatus");
93 | f.add("Center", cp = new WebCurvePlot(panel, attendant));
94 | cp.resize(400, 400);
95 | f.pack();
96 | f.show();
97 | }
98 | return super.initialised();
99 | }
100 |
101 | public synchronized void dispose() {
102 | if (f != null) {
103 | f.dispose();
104 | f = null;
105 | }
106 | }
107 |
108 | public void moveTo() {
109 | if (initialised()) {
110 | cp.penUp();
111 | // cp.addPoint(px, py);
112 | }
113 | }
114 |
115 | public void drawTo() {
116 | if (initialised()) {
117 | cp.penDown();
118 | cp.addPoint(px, py);
119 | cp.repaint();
120 | }
121 | }
122 |
123 | public void changePen(Color c) {
124 | if (initialised()) {
125 | cp.setPenColour(c);
126 | }
127 | }
128 |
129 | public void changePaper() {
130 | if (f != null) {
131 | f.dispose();
132 | f = null;
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/bernouilli.ae:
--------------------------------------------------------------------------------
1 | This is meant to be a transcription of AAL's program for computing
2 | what she called the fourth Bernouilli number B7 (what Wikipedia would
3 | call B8).
4 |
5 | I've scaled by 10 places where real arithmetic is implied
6 | (i.e. dividends are shifted up 10 digits unless already scaled,
7 | products are shifted down by 10 digits if both multiplicands are
8 | scaled). Divide the result by 10**10 to get B7.
9 |
10 | A bug in operation 4 has been fixed (the comment requires V4/V5,
11 | AAL's code does V5/V4).
12 |
13 | Another bug was at operation 24: the value accumulated in V13 is ×the
14 | negative× of the required value, see Note G Equation 9.
15 |
16 | useful constants
17 | n001 1
18 | n002 2
19 |
20 | which bernouilli number is required?
21 | n003 4
22 |
23 | b0 = 1
24 | b1 = 0.1666666666
25 | n021 01666666666
26 | b3 = -0.0333333333
27 | n022 -00333333333
28 | b5 = 0.0238095238
29 | n023 00238095238
30 |
31 | operation 1
32 | ×
33 | l002
34 | l003
35 | s004
36 | s005
37 | s006
38 |
39 | operation 2
40 | -
41 | z004
42 | l001
43 | s004
44 |
45 | operation 3
46 | +
47 | z005
48 | l001
49 | s005
50 |
51 | operation 4, with bug fixed
52 | ÷
53 | z004
54 | <10
55 | z005
56 | s011'
57 |
58 | operation 5
59 | ÷
60 | z011
61 | l002
62 | s011'
63 |
64 | operation 6
65 | -
66 | z013
67 | z011
68 | s013
69 |
70 | operation 7
71 | l003
72 | l001
73 | s010
74 | --------------------
75 | operation 8
76 | +
77 | l002
78 | l007
79 | s007
80 |
81 | operation 9
82 | ÷
83 | l006
84 | <10
85 | l007
86 | s011'
87 |
88 | operation 10, using b1 (v021)
89 | ×
90 | l021
91 | l011
92 | >10
93 | s012
94 |
95 | operation 11
96 | +
97 | z012
98 | z013
99 | s013
100 |
101 | operation 12
102 | -
103 | z010
104 | l001
105 | s010
106 | --------------------
107 | operation 13
108 | -
109 | z006
110 | l001
111 | s006
112 |
113 | operation 14
114 | +
115 | l001
116 | z007
117 | s007
118 |
119 | operation 15
120 | ÷
121 | l006
122 | <10
123 | l007
124 | s008'
125 |
126 | operation 16
127 | ×
128 | z008
129 | z011
130 | >10
131 | s011
132 |
133 | operation 17
134 | -
135 | z006
136 | l001
137 | s006
138 |
139 | operation 18
140 | +
141 | l001
142 | z007
143 | s007
144 |
145 | operation 19
146 | ÷
147 | l006
148 | <10
149 | l007
150 | s009'
151 |
152 | operation 20
153 | ×
154 | z009
155 | z011
156 | >10
157 | s011
158 |
159 | operation 21, using b3 (v022)
160 | ×
161 | l022
162 | l011
163 | >10
164 | s012
165 |
166 | operation 22
167 | +
168 | z012
169 | z013
170 | s013
171 |
172 | operation 23
173 | -
174 | z010
175 | l001
176 | s010
177 | .................... repeat starts here
178 | operation 13
179 | -
180 | z006
181 | l001
182 | s006
183 |
184 | operation 14
185 | +
186 | l001
187 | z007
188 | s007
189 |
190 | operation 15
191 | ÷
192 | l006
193 | <10
194 | l007
195 | s008'
196 |
197 | operation 16
198 | ×
199 | z008
200 | z011
201 | >10
202 | s011
203 |
204 | operation 17
205 | -
206 | z006
207 | l001
208 | s006
209 |
210 | operation 18
211 | +
212 | l001
213 | z007
214 | s007
215 |
216 | operation 19
217 | ÷
218 | l006
219 | <10
220 | l007
221 | s009'
222 |
223 | operation 20
224 | ×
225 | z009
226 | z011
227 | >10
228 | s011
229 |
230 | operation 21 (NB using b5, v023 this time)
231 | ×
232 | l023
233 | l011
234 | >10
235 | s012
236 |
237 | operation 22
238 | +
239 | z012
240 | z013
241 | s013
242 |
243 | operation 23
244 | -
245 | z010
246 | l001
247 | s010
248 | --------------------
249 | operation 24, with bug fixed
250 | -
251 | l024
252 | l013
253 | s024
254 | the result!! calculations were scaled by 10 places
255 | a write numbers as 9.9999999999
256 | p
257 |
258 | operation 25
259 | +
260 | l001
261 | z003
262 | s003
263 | -- and clear V6, V7 (should have been done earlier, operation 19)
264 | n006 0
265 | n007 0
266 |
--------------------------------------------------------------------------------
/src/analytical_engine-framework.ads:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Analytical_Engine.Annunciator_Panel;
23 | with Analytical_Engine.Output;
24 | with Analytical_Engine.Attendant;
25 | with Analytical_Engine.Mill;
26 | with Analytical_Engine.Store;
27 | with Analytical_Engine.Card_Reader;
28 |
29 | private with Ada.Finalization;
30 |
31 | package Analytical_Engine.Framework is
32 |
33 | type Instance (<>) is tagged limited private;
34 |
35 | function Panel (This : Instance)
36 | return Analytical_Engine.Annunciator_Panel.Class_P;
37 | function Attendant (This : Instance)
38 | return Analytical_Engine.Attendant.Instance_P;
39 | function Mill (This : Instance)
40 | return Analytical_Engine.Mill.Instance_P;
41 | function Store (This : Instance)
42 | return Analytical_Engine.Store.Instance_P;
43 | function Card_Reader (This : Instance)
44 | return Analytical_Engine.Card_Reader.Instance_P;
45 | function Output (This : Instance)
46 | return Analytical_Engine.Output.Class_P;
47 |
48 | function Create
49 | (With_Panel : not null Analytical_Engine.Annunciator_Panel.Class_P;
50 | With_Output : not null Analytical_Engine.Output.Class_P)
51 | return Instance;
52 |
53 | procedure Run (This : in out Instance);
54 |
55 | private
56 |
57 | type Instance (Panel : not null Annunciator_Panel.Class_P;
58 | Attendant : not null Analytical_Engine.Attendant.Instance_P)
59 | is new Ada.Finalization.Limited_Controlled with record
60 |
61 | Mill : Analytical_Engine.Mill.Instance_P;
62 | -- (Panel => Panel,
63 | -- Attendant => Attendant);
64 |
65 | Store : Analytical_Engine.Store.Instance_P;
66 | -- (Panel => Panel,
67 | -- Attendant => Attendant);
68 |
69 | Card_Reader : Analytical_Engine.Card_Reader.Instance_P;
70 | -- (Panel => Panel,
71 | -- Attendant => Attendant);
72 |
73 | Output : Analytical_Engine.Output.Class_P;
74 |
75 | end record;
76 |
77 | function Panel (This : Instance)
78 | return Analytical_Engine.Annunciator_Panel.Class_P is
79 | (This.Panel);
80 |
81 | function Attendant (This : Instance)
82 | return Analytical_Engine.Attendant.Instance_P is
83 | (This.Attendant);
84 |
85 | function Mill (This : Instance)
86 | return Analytical_Engine.Mill.Instance_P is
87 | (This.Mill);
88 |
89 | function Store (This : Instance)
90 | return Analytical_Engine.Store.Instance_P is
91 | (This.Store);
92 |
93 | function Card_Reader (This : Instance)
94 | return Analytical_Engine.Card_Reader.Instance_P is
95 | (This.Card_Reader);
96 |
97 | function Output (This : Instance)
98 | return Analytical_Engine.Output.Class_P is
99 | (This.Output);
100 |
101 | end Analytical_Engine.Framework;
102 |
--------------------------------------------------------------------------------
/fourmilab/aes.java:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Analytical Engine Simulator
4 |
5 | This is a command-line program which loads one or more chains of
6 | cards from files named on the command line, then (unless inhibited
7 | by a command line option), starts the Engine and displays the
8 | results on standard output. See the how-to-call information
9 | in the usage() method for a list of available options.
10 |
11 | This program runs on a user's machine under a local copy of a
12 | Java interpreter. Hence, all server security options are
13 | disabled, as only local file access is possible.
14 |
15 | */
16 |
17 | public class aes {
18 |
19 | /* If you have a default path for library items, specify it in
20 | the following declaration (and don't forget to include the
21 | "@@" where the file name goes). Set this to null if you
22 | have no default library path. This can be overridden by
23 | an -sTemplate option which appears before the file which
24 | contains the library request. */
25 |
26 | static String defaultLibraryTemplate = "/ftp/babbage/Library/@@.ae";
27 |
28 | static void up(String s) {
29 | System.out.println(s);
30 | }
31 |
32 | static void usage() {
33 | up("Options:");
34 | up(" -c Don't mount comment cards");
35 | up(" -l List program as mounted by attendant");
36 | up(" -n No execution of program");
37 | up(" -p Punch copy of program as mounted by attendant");
38 | up(" -sLST Use LST as library search template");
39 | up(" -t Print trace of program execution");
40 | up(" -u Print this message");
41 | }
42 |
43 | public static void main(String argv[]) {
44 | AnnunciatorPanel panel = new AnnunciatorPanel();
45 | analyticalEngine e = new analyticalEngine(panel);
46 | int i;
47 | boolean listing = false, execute = true, trace = false,
48 | punched = false, comments = true;
49 |
50 | e.setLibraryTemplate(defaultLibraryTemplate);
51 | e.allowFileInclusion(true);
52 |
53 | for (i = 0; i < argv.length; i++) {
54 | if (argv[i].charAt(0) == '-') {
55 | if (argv[i].length() > 1) {
56 | switch (argv[i].charAt(1)) {
57 | case 'c':
58 | comments = false;
59 | break;
60 |
61 | case 'l':
62 | listing = true;
63 | break;
64 |
65 | case 'n':
66 | execute = false;
67 | break;
68 |
69 | case 'p':
70 | listing = punched = true;
71 | break;
72 |
73 | case 's':
74 | e.setLibraryTemplate(argv[i].length() < 3 ?
75 | null : argv[i].substring(2));
76 | break;
77 |
78 | case 't':
79 | trace = true;
80 | break;
81 |
82 | case 'u':
83 | usage();
84 | return;
85 | }
86 | }
87 | } else {
88 | e.loadCardsFromFile(argv[i]);
89 | if (e.error()) {
90 | break;
91 | }
92 | }
93 | }
94 |
95 | /*
96 | Gratuitous test case for loadCardsFromString
97 |
98 | e.loadCardsFromString(
99 | "A write in rows\n" +
100 | "A write numbers as 9\n" +
101 | "N120 10000\n" +
102 | "N121 3\n" +
103 | "/\n" +
104 | "L120\n" +
105 | "L121\n" +
106 | "S122'\n" +
107 | "P\n"
108 | );
109 | /**/
110 |
111 | if (!e.error()) {
112 | e.setCurveDrawingApparatus((CurveDrawingApparatus) new
113 | frameCurveDrawingApparatus());
114 | e.scrutinise(comments);
115 |
116 | if (listing) {
117 | e.dumpCards(punched);
118 | }
119 |
120 | if (!e.error() && execute) {
121 | e.setTrace(trace);
122 | e.run();
123 | }
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-attendant_request.ads:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | -- with Ada.Strings.Unbounded;
23 |
24 | -- limited with Analytical_Engine.Framework;
25 |
26 | -- private with Ada.Finalization;
27 | -- private with Analytical_Engine.Mill;
28 | -- private with Analytical_Engine.Store;
29 | -- private with GNATCOLL.GMP.Integers;
30 | -- private with System;
31 |
32 | private package Analytical_Engine.Card.Attendant_Request is
33 |
34 | function Read (From : Wide_String) return Card'Class
35 | with Pre => From'Length > 0
36 | and then (From (From'First) = 'A'
37 | or else From (From'First) = 'a');
38 |
39 | private
40 |
41 | -- type Attendant_Request_Kind is
42 | -- (Calculation_Trace,
43 | -- Advancing_Or_Backing_Block,
44 | -- Alternation,
45 | -- End_Block,
46 | -- Library_Inclusion,
47 | -- Decimal_Place_Expansion,
48 |
49 | type Picture_Card is new Card with record
50 | Picture : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
51 | end record;
52 | overriding
53 | procedure Execute (C : Picture_Card;
54 | In_The_Framework : in out Framework.Instance);
55 |
56 | -- Numeric_Output_Format_With_Decimal_Point,
57 |
58 | type Row_Column_Card is new Card with record
59 | In_Rows : Boolean;
60 | end record;
61 | overriding
62 | procedure Execute (C : Row_Column_Card;
63 | In_The_Framework : in out Framework.Instance);
64 |
65 | type Annotation_Card is new Card with record
66 | Annotation : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
67 | end record;
68 | overriding
69 | procedure Execute (C : Annotation_Card;
70 | In_The_Framework : in out Framework.Instance);
71 |
72 | type New_Line_Card is new Card with null record;
73 | overriding
74 | procedure Execute (C : New_Line_Card;
75 | In_The_Framework : in out Framework.Instance);
76 |
77 | -- Not_A_Request);
78 |
79 | -- type Attendant_Request_T (Kind : Attendant_Request_Kind) is record
80 | -- case Kind is
81 | -- when Calculation_Trace =>
82 | -- Trace : Boolean;
83 | -- when Advancing_Or_Backing_Block =>
84 | -- Advancing : Boolean;
85 | -- Conditionally : Boolean;
86 | -- Cards : Positive;
87 | -- when Alternation =>
88 | -- null;
89 | -- when End_Block =>
90 | -- End_Advancing : Boolean;
91 | -- when Library_Inclusion =>
92 | -- Library : Boolean;
93 | -- Name : Unbounded_String;
94 | -- when Decimal_Place_Expansion =>
95 | -- Places : Positive;
96 | -- when Numeric_Output_Format_As_Picture =>
97 | -- Picture : Unbounded_String;
98 | -- when Numeric_Output_Format_With_Decimal_Point =>
99 | -- null;
100 | -- when Write_In_Rows =>
101 | -- null;
102 | -- when Write_In_Columns =>
103 | -- null;
104 | -- when Write_Annotation =>
105 | -- Annotation : Unbounded_String;
106 | -- when Write_New_Line =>
107 | -- null;
108 | -- when Not_A_Request =>
109 | -- null;
110 | -- end case;
111 | -- end record;
112 |
113 | end Analytical_Engine.Card.Attendant_Request;
114 |
--------------------------------------------------------------------------------
/bernouilli5.ae:
--------------------------------------------------------------------------------
1 | This is meant to be an extension of AAL's program for computing what
2 | she called the fourth Bernouilli number B9 (what Wikipedia would call
3 | B10).
4 |
5 | I've scaled by 10 places where real arithmetic is implied
6 | (i.e. dividends are shifted up 10 digits unless already scaled,
7 | products are shifted down by 10 digits if both multiplicands are
8 | scaled). Divide the result by 10**10 to get B9.
9 |
10 | A bug in operation 4 has been fixed (the comment requires V4/V5,
11 | AAL's code does V5/V4).
12 |
13 | Another bug was at operation 24: the value accumulated in V13 is *the
14 | negative* of the required value, see Note G Equation 9.
15 |
16 | useful constants
17 | n001 1
18 | n002 2
19 |
20 | which bernouilli number is required?
21 | n003 5
22 |
23 | b0 = 1
24 | b1 = 0.1666666666
25 | n021 01666666667
26 | b3 = -0.0333333333
27 | n022 -00333333333
28 | b5 = 0.0238095238
29 | n023 00238095238
30 | b7 = -0.0333333333
31 | n024 -00333333333
32 | b9 = 0.0757575758 (expected!)
33 |
34 | operation 1
35 | *
36 | l002
37 | l003
38 | s004
39 | s005
40 | s006
41 |
42 | operation 2
43 | -
44 | z004
45 | l001
46 | s004
47 |
48 | operation 3
49 | +
50 | z005
51 | l001
52 | s005
53 |
54 | operation 4, with bug fixed
55 | /
56 | z004
57 | <10
58 | z005
59 | s011'
60 |
61 | operation 5
62 | /
63 | z011
64 | l002
65 | s011'
66 |
67 | operation 6
68 | -
69 | z013
70 | z011
71 | s013
72 |
73 | operation 7
74 | l003
75 | l001
76 | s010
77 | --------------------
78 | operation 8
79 | +
80 | l002
81 | l007
82 | s007
83 |
84 | operation 9
85 | /
86 | l006
87 | <10
88 | l007
89 | s011'
90 |
91 | operation 10, using b1 (v021)
92 | *
93 | l021
94 | l011
95 | >10
96 | s012
97 |
98 | operation 11
99 | +
100 | z012
101 | z013
102 | s013
103 |
104 | operation 12
105 | -
106 | z010
107 | l001
108 | s010
109 | --------------------
110 | operation 13
111 | -
112 | z006
113 | l001
114 | s006
115 |
116 | operation 14
117 | +
118 | l001
119 | z007
120 | s007
121 |
122 | operation 15
123 | /
124 | l006
125 | <10
126 | l007
127 | s008'
128 |
129 | operation 16
130 | *
131 | z008
132 | z011
133 | >10
134 | s011
135 |
136 | operation 17
137 | -
138 | z006
139 | l001
140 | s006
141 |
142 | operation 18
143 | +
144 | l001
145 | z007
146 | s007
147 |
148 | operation 19
149 | /
150 | l006
151 | <10
152 | l007
153 | s009'
154 |
155 | operation 20
156 | *
157 | z009
158 | z011
159 | >10
160 | s011
161 |
162 | operation 21, using b3 (v022)
163 | *
164 | l022
165 | l011
166 | >10
167 | s012
168 |
169 | operation 22
170 | +
171 | z012
172 | z013
173 | s013
174 |
175 | operation 23
176 | -
177 | z010
178 | l001
179 | s010
180 | .................... first repeat starts here
181 | operation 13
182 | -
183 | z006
184 | l001
185 | s006
186 |
187 | operation 14
188 | +
189 | l001
190 | z007
191 | s007
192 |
193 | operation 15
194 | /
195 | l006
196 | <10
197 | l007
198 | s008'
199 |
200 | operation 16
201 | *
202 | z008
203 | z011
204 | >10
205 | s011
206 |
207 | operation 17
208 | -
209 | z006
210 | l001
211 | s006
212 |
213 | operation 18
214 | +
215 | l001
216 | z007
217 | s007
218 |
219 | operation 19
220 | /
221 | l006
222 | <10
223 | l007
224 | s009'
225 |
226 | operation 20
227 | *
228 | z009
229 | z011
230 | >10
231 | s011
232 |
233 | operation 21 (NB using b5, v023 this time)
234 | *
235 | l023
236 | l011
237 | >10
238 | s012
239 |
240 | operation 22
241 | +
242 | z012
243 | z013
244 | s013
245 |
246 | operation 23
247 | -
248 | z010
249 | l001
250 | s010
251 | .................... second repeat starts here
252 | operation 13
253 | -
254 | z006
255 | l001
256 | s006
257 |
258 | operation 14
259 | +
260 | l001
261 | z007
262 | s007
263 |
264 | operation 15
265 | /
266 | l006
267 | <10
268 | l007
269 | s008'
270 |
271 | operation 16
272 | *
273 | z008
274 | z011
275 | >10
276 | s011
277 |
278 | operation 17
279 | -
280 | z006
281 | l001
282 | s006
283 |
284 | operation 18
285 | +
286 | l001
287 | z007
288 | s007
289 |
290 | operation 19
291 | /
292 | l006
293 | <10
294 | l007
295 | s009'
296 |
297 | operation 20
298 | *
299 | z009
300 | z011
301 | >10
302 | s011
303 |
304 | operation 21 (NB using b7, v024 this time)
305 | *
306 | l024
307 | l011
308 | >10
309 | s012
310 |
311 | operation 22
312 | +
313 | z012
314 | z013
315 | s013
316 |
317 | operation 23
318 | -
319 | z010
320 | l001
321 | s010
322 | --------------------
323 | operation 24, with bug fixed
324 | -
325 | z025
326 | l013
327 | s025
328 | the result!!
329 | p
330 |
331 | operation 25
332 | +
333 | l001
334 | z003
335 | s003
336 | -- and clear V6, V7 - why?
337 | n006 0
338 | n007 0
339 |
--------------------------------------------------------------------------------
/src/analytical_engine-output-printer.adb:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Ada.Characters.Conversions;
23 | with Ada.Wide_Text_IO; use Ada.Wide_Text_IO;
24 |
25 | package body Analytical_Engine.Output.Printer is
26 |
27 | procedure Output (To : Instance; S : Wide_String)
28 | is
29 | begin
30 | if S = (1 => Ada.Characters.Conversions.To_Wide_Character (ASCII.LF))
31 | then
32 | New_Line;
33 | else
34 | Put (S);
35 | if To.In_Rows then
36 | New_Line;
37 | end if;
38 | end if;
39 | end Output;
40 |
41 | procedure Output
42 | (To : Instance; I : GNATCOLL.GMP.Integers.Big_Integer)
43 | is
44 | function "+" (Item : String) return Wide_String
45 | renames Ada.Characters.Conversions.To_Wide_String;
46 | Picture : constant Wide_String
47 | := Ada.Strings.Wide_Unbounded.To_Wide_String (To.Picture);
48 | begin
49 | if Picture'Length = 0 then
50 | To.Output (+GNATCOLL.GMP.Integers.Image (I));
51 | else
52 | declare
53 | use type GNATCOLL.GMP.Integers.Big_Integer;
54 | Negative : constant Boolean := I < 0;
55 | Image : constant Wide_String :=
56 | +GNATCOLL.GMP.Integers.Image (abs I);
57 | Index : Natural := Image'Length;
58 | Sign_Output : Boolean := False;
59 | Result : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
60 | use type Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
61 | begin
62 | for C of reverse Picture loop
63 | case C is
64 | when '9' =>
65 | -- Digit, unconditionally
66 | if Index = 0 then
67 | Result := '0' & Result;
68 | else
69 | Result := Image (Index) & Result;
70 | Index := Index - 1;
71 | end if;
72 | when '#' =>
73 | -- Digit, if number not exhausted
74 | if Index > 0 then
75 | Result := Image (Index) & Result;
76 | Index := Index - 1;
77 | end if;
78 | when ',' =>
79 | -- Comma, if digits remain to be output
80 | if Index > 0
81 | -- or else (for some C of Picture => C = '9')
82 | then
83 | Result := ',' & Result;
84 | end if;
85 | when '-' =>
86 | -- Sign, if negative
87 | if Negative then
88 | Result := '-' & Result;
89 | Sign_Output := True;
90 | end if;
91 | when '@' | '±' =>
92 | -- Plus or minus sign
93 | Result := (if Negative then '-' else '+') & Result;
94 | Sign_Output := True;
95 | when '+' =>
96 | -- Sign if negative, space if positive
97 | Result := (if Negative then '-' else ' ') & Result;
98 | Sign_Output := True;
99 | when others =>
100 | Result := C & Result;
101 | end case;
102 | end loop;
103 | -- insert any number "left over"
104 | Result := Image (1 .. Index) & Result;
105 | if Negative and not Sign_Output then
106 | Result := '-' & Result;
107 | end if;
108 | To.Output (Ada.Strings.Wide_Unbounded.To_Wide_String (Result));
109 | end;
110 | end if;
111 | end Output;
112 |
113 | end Analytical_Engine.Output.Printer;
114 |
--------------------------------------------------------------------------------
/src/analytical_engine-card-attendant_request.adb:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Ada.Characters.Conversions;
23 | with Ada.Strings.Wide_Unbounded;
24 |
25 | with Analytical_Engine.Framework;
26 |
27 | with GNAT.Regpat;
28 |
29 | package body Analytical_Engine.Card.Attendant_Request is
30 |
31 | Picture_Matcher : constant GNAT.Regpat.Pattern_Matcher
32 | := GNAT.Regpat.Compile ("a\s+write\s+numbers\s+as (.+)$",
33 | Flags => GNAT.Regpat.Case_Insensitive);
34 |
35 | Row_Column_Matcher : constant GNAT.Regpat.Pattern_Matcher
36 | := GNAT.Regpat.Compile ("a\s+write\s+in\s(rows|columns)$",
37 | Flags => GNAT.Regpat.Case_Insensitive);
38 |
39 | Annotation_Matcher : constant GNAT.Regpat.Pattern_Matcher
40 | := GNAT.Regpat.Compile ("a\s+write\s+annotation (.+)$",
41 | Flags => GNAT.Regpat.Case_Insensitive);
42 |
43 | New_Line_Matcher : constant GNAT.Regpat.Pattern_Matcher
44 | := GNAT.Regpat.Compile ("a\s+write\s+new\s+line\s*$",
45 | Flags => GNAT.Regpat.Case_Insensitive);
46 |
47 | Max_Parens : constant := 10; -- overkill
48 |
49 | function "+" (Item : Wide_String) return String
50 | is (Ada.Characters.Conversions.To_String (Item, Substitute => ' '));
51 |
52 | function Read (From : Wide_String) return Card'Class is
53 | Matches : GNAT.Regpat.Match_Array (0 .. Max_Parens);
54 | use type GNAT.Regpat.Match_Location;
55 | begin
56 | GNAT.Regpat.Match (Picture_Matcher, +From, Matches);
57 | if Matches (0) /= GNAT.Regpat.No_Match then
58 | return C : Picture_Card do
59 | C.Source := To_Unbounded_Wide_String (From);
60 | C.Picture :=
61 | To_Unbounded_Wide_String
62 | (From (Matches (1).First .. Matches (1).Last));
63 | end return;
64 | end if;
65 |
66 | GNAT.Regpat.Match (Row_Column_Matcher, +From, Matches);
67 | if Matches (0) /= GNAT.Regpat.No_Match then
68 | return C : Row_Column_Card do
69 | C.Source := To_Unbounded_Wide_String (From);
70 | C.In_Rows := From (Matches (1).First .. Matches (1).Last) = "rows";
71 | end return;
72 | end if;
73 |
74 | GNAT.Regpat.Match (Annotation_Matcher, +From, Matches);
75 | if Matches (0) /= GNAT.Regpat.No_Match then
76 | return C : Annotation_Card do
77 | C.Source := To_Unbounded_Wide_String (From);
78 | C.Annotation :=
79 | To_Unbounded_Wide_String
80 | (From (Matches (1).First .. Matches (1).Last));
81 | end return;
82 | end if;
83 |
84 | GNAT.Regpat.Match (New_Line_Matcher, +From, Matches);
85 | if Matches (0) /= GNAT.Regpat.No_Match then
86 | return C : New_Line_Card do
87 | C.Source := To_Unbounded_Wide_String (From);
88 | end return;
89 | end if;
90 | raise Card_Error
91 | with "unrecognised attendant request card";
92 | end Read;
93 |
94 | -- type Attendant_Request_Kind is
95 | -- (Calculation_Trace,
96 | -- Advancing_Or_Backing_Block,
97 | -- Alternation,
98 | -- End_Block,
99 | -- Library_Inclusion,
100 | -- Decimal_Place_Expansion,
101 |
102 | procedure Execute (C : Picture_Card;
103 | In_The_Framework : in out Framework.Instance) is
104 | begin
105 | In_The_Framework.Output.Set_Picture (C.Picture);
106 | end Execute;
107 |
108 | -- Numeric_Output_Format_With_Decimal_Point,
109 |
110 | procedure Execute (C : Row_Column_Card;
111 | In_The_Framework : in out Framework.Instance) is
112 | begin
113 | In_The_Framework.Output.Writing_Style (In_Rows => C.In_Rows);
114 | end Execute;
115 |
116 | procedure Execute (C : Annotation_Card;
117 | In_The_Framework : in out Framework.Instance) is
118 | begin
119 | In_The_Framework.Output.Output (To_Wide_String (C.Annotation));
120 | end Execute;
121 |
122 | procedure Execute (C : New_Line_Card;
123 | In_The_Framework : in out Framework.Instance) is
124 | pragma Unreferenced (C);
125 | use Ada.Characters.Conversions;
126 | begin
127 | In_The_Framework.Output.Output ((1 => To_Wide_Character (ASCII.LF)));
128 | end Execute;
129 |
130 | -- Not_A_Request);
131 |
132 | end Analytical_Engine.Card.Attendant_Request;
133 |
--------------------------------------------------------------------------------
/src/analytical_engine-card_reader.adb:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Ada.Characters.Conversions;
23 | with Ada.Exceptions;
24 | with Ada.Strings.Fixed;
25 | with Ada.Strings.Wide_Unbounded;
26 | with Ada.Wide_Text_IO;
27 | with Analytical_Engine.Framework;
28 |
29 | package body Analytical_Engine.Card_Reader is
30 |
31 | function "+" (Item : String) return Wide_String
32 | renames Ada.Characters.Conversions.To_Wide_String;
33 | function "+" (Item : Wide_String) return String
34 | is (Ada.Characters.Conversions.To_String (Item, Substitute => ' '));
35 |
36 | procedure Reset (This : out Instance)
37 | is
38 | begin
39 | This.Index := 1;
40 | This.Chain.Clear;
41 | end Reset;
42 |
43 | procedure Add_Cards (This : in out Instance; From_File_Named : String)
44 | is
45 | procedure Add (From : Ada.Wide_Text_IO.File_Type; Named : String);
46 | procedure Add (From : Ada.Wide_Text_IO.File_Type; Named : String)
47 | is
48 | use Ada.Strings.Wide_Unbounded;
49 | Line_Number : Positive := 1;
50 | Source : constant Unbounded_Wide_String
51 | := To_Unbounded_Wide_String (+Named);
52 | begin
53 | loop
54 | declare
55 | Line : constant Wide_String := Ada.Wide_Text_IO.Get_Line (From);
56 | begin
57 | declare
58 | C : Card.Card'Class := Card.Read (Line);
59 | begin
60 | C.Line_Number := Line_Number;
61 | C.Source_File := Source;
62 | This.Chain.Append (C);
63 | end;
64 | exception
65 | when E : Card.Card_Error =>
66 | raise Card.Card_Error
67 | with Ada.Exceptions.Exception_Message (E)
68 | & " at "
69 | & Named
70 | & ":"
71 | & Ada.Strings.Fixed.Trim (Line_Number'Img,
72 | Ada.Strings.Both)
73 | & " "
74 | & (+Line);
75 | when others =>
76 | raise Card.Card_Error
77 | with "error reading card at "
78 | & Named
79 | & ":"
80 | & Ada.Strings.Fixed.Trim (Line_Number'Img,
81 | Ada.Strings.Both)
82 | & " "
83 | & (+Line);
84 | end;
85 | Line_Number := Line_Number + 1;
86 | end loop;
87 | end Add;
88 | begin
89 | if From_File_Named'Length = 0 then
90 | begin
91 | Add (Ada.Wide_Text_IO.Standard_Input, "");
92 | exception
93 | when Ada.Wide_Text_IO.End_Error => null;
94 | end;
95 | else
96 | declare
97 | F : Ada.Wide_Text_IO.File_Type;
98 | begin
99 | Ada.Wide_Text_IO.Open (F,
100 | Name => From_File_Named,
101 | Mode => Ada.Wide_Text_IO.In_File,
102 | Form => "wcem=8");
103 | Add (F, From_File_Named);
104 | Ada.Wide_Text_IO.Close (F);
105 | exception
106 | when Ada.Wide_Text_IO.End_Error =>
107 | Ada.Wide_Text_IO.Close (F);
108 | end;
109 | end if;
110 | end Add_Cards;
111 |
112 | procedure Execute (This : in out Instance;
113 | In_The_Framework : in out Framework.Instance)
114 | is
115 | begin
116 | This.Index := 1;
117 | This.Halted := False;
118 | Execution : loop
119 | declare
120 | C : constant Card.Card'Class := This.Chain (This.Index);
121 | begin
122 | if In_The_Framework.Panel.Tracing then
123 | In_The_Framework.Panel.Log_Trace_Message
124 | (+("Card"
125 | & This.Index'Img
126 | & " "
127 | & C.Image));
128 | end if;
129 | This.Index := This.Index + 1;
130 | C.Execute (In_The_Framework);
131 | exception
132 | when E : others =>
133 | In_The_Framework.Panel.Log_Trace_Message
134 | (+("Error at card"
135 | & Integer'Image (This.Index - 1)
136 | & " "
137 | & C.Image
138 | & " "
139 | & Ada.Exceptions.Exception_Message (E)));
140 | exit Execution;
141 | end;
142 | exit Execution when This.Halted
143 | or else This.Index > Integer (This.Chain.Length);
144 | end loop Execution;
145 | This.Halted := True;
146 | end Execute;
147 |
148 | procedure Step (This : in out Instance; By : Integer)
149 | is
150 | begin
151 | if not (This.Index + By in 1 .. Integer (This.Chain.Length)) then
152 | raise Card_Reader_Error with "step out of range";
153 | end if;
154 | This.Index := This.Index + By;
155 | end Step;
156 |
157 | procedure Halt (This : in out Instance)
158 | is
159 | begin
160 | This.Halted := True;
161 | end Halt;
162 |
163 | end Analytical_Engine.Card_Reader;
164 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Analytical Engine Emulator
2 |
3 | This is an Ada translation of the Java emulator at
4 | [Fourmilab](http://www.fourmilab.ch/babbage/).
5 |
6 | In due course, it is hoped to create a web-based emulator (using
7 | [Gnoga](http://www.gnoga.com)). In the mean time, there is a command
8 | line based version.
9 |
10 | ## Copying
11 |
12 | The Java source of the Fourmilab emulator is included in this
13 | repository for reference (in the `fourmilab/` subdirectory); the
14 | Analytical Engine code's author states _Emulator source code is
15 | intended for experienced Java developers, and is utterly
16 | unsupported. The program is in the public domain and you can do
17 | anything you like with it, but you're entirely on your own._, while
18 | `BigInt.java` is copyrighted by the Massachusetts Institute of
19 | Technology.
20 |
21 | The Ada source is licensed under the
22 | [GNU General Public License (version 3)][] with the
23 | [GCC Runtime Library exception][].
24 |
25 | [GNU General Public License (version 3)]: http://www.gnu.org/licenses/gpl.html
26 | [GCC Runtime Library exception]: http://www.gnu.org/licenses/gcc-exception-faq.html
27 |
28 | ## Building
29 |
30 | The Ada emulator is written using [Ada2012][], and uses the
31 | [GNU Multiple Precision Arithmetic library][], via the
32 | [GMP binding in GNATCOLL][].
33 |
34 | If you have one of the [FSF GCC binaries for OS X][] (6.1 or later), a
35 | suitable library is provided. Otherwise, GMP and GNATCOLL are
36 | reasonably straightforward to build.
37 |
38 | [Ada2012]: http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-TOC.html
39 |
40 | [GNU Multiple Precision Arithmetic library]: https://gmplib.org
41 |
42 | [GMP binding in GNATCOLL]: https://github.com/AdaCore/gnatcoll/blob/master/src/gmp/gnatcoll-gmp-integers.ads
43 |
44 | [FSF GCC binaries for OS X]: https://sourceforge.net/projects/gnuada/files/GNAT_GCC%20Mac%20OS%20X/
45 |
46 | ## Running
47 |
48 | There are three switches:
49 |
50 | * `-h` or `--help`: outputs help.
51 | * `-t` or `--trace`: trace execution (like card T1)
52 | * `-z` or `--overwrite-nonzero`: allow storing to a non-zero column
53 |
54 | and, as usual, run by
55 |
56 | ./aes [switches] [card-chain-file]
57 |
58 | (uses standard input if no card chain file is supplied).
59 |
60 | The "storing to a non-zero column" issue is referenced in [this paper][]
61 | by Rainer Glaschick, section 3.5, Memory peculiarities. It would have
62 | been necessary to ensure that a column that was to be written to was
63 | zero beforehand; the operation of storing a value involved racks
64 | transferring the value on the source to the destination as the source
65 | digits were rotated back to zeros.
66 |
67 | If `-z` is given, overwriting will be allowed; otherwise, an error
68 | will be reported and execution will halt.
69 |
70 | [this paper]: http://rclab.de/rclab/_media/analyticalengine/aal_noteg_glaschick_v1.2.pdf
71 |
72 | ## Programming Cards
73 |
74 | The design here is as in the [Fourmilab Java implementation][]. To
75 | date only the card types below have been implemented:
76 |
77 | * Number Cards
78 | * Operation Cards
79 | * Variable Cards
80 | * Stepping Up and Down Cards
81 | * Combinatorial Cards
82 | * Action Cards
83 | * Comment Cards
84 | * Attendant Request Cards:
85 | * Calculation Trace Cards
86 | * Numeric Output Format Cards
87 | * Output Annotation Cards
88 |
89 | These card types have not been implemented (yet):
90 |
91 | * Curve Drawing Cards
92 | * Attendant Request Cards:
93 | * Advancing and Backing Block Cards
94 | * Card Library Inclusion Requests
95 | * Decimal Place Expansion Cards
96 |
97 | As in the [Fourmilab Java implementation][], multiplication can be
98 | indicated by `*` or `×`, division by `/` or `÷`.
99 |
100 | [Fourmilab Java implementation]: https://www.fourmilab.ch/babbage/cards.html
101 |
102 | When counting for Combinatorial Cards (conditional and unconditional
103 | jumps), remember that comment cards (blank cards, or cards starting
104 | with a period or white space) need to be included!
105 |
106 | ### Changes
107 |
108 | * As a minor change, lower case can be used: `n001 42` is acceptable
109 | (it stores 42 into column 1).
110 | * Text after the required content is ignored, so comments can be included: `n001 42 the answer` is acceptable.
111 |
112 | ## Examples
113 |
114 | The file `bernouilli.ae` is an implementation of the Lovelace design
115 | in Note G of the [Sketch of the Analytical Engine][] (the last
116 | section), with two errors corrected:
117 |
118 | * in operation 4, the operands are reversed (it should be V4 / V5,
119 | not V5 / V4).
120 | * in operation 24, the result placed in V24 should be **-**V13.
121 |
122 | AAL's notes don't discuss the fact that the Engine only implemented
123 | integer arithmetic, which means that a naive attempt at dividing 7 by
124 | 9 at operation 4 will result in 0 remainder 7, not the 0.777777777 one
125 | might have hoped for. To deal with this, all real values are scaled by
126 | 10 decimal places;
127 |
128 | * the precalculated value of B1, 0.1666666666, is stored as
129 | 1666666666, and similarly for B3, B5.
130 | * dividends are scaled up by 10 decimal places.
131 | * products are scaled down by 10 decimal places.
132 |
133 | For more on this, see the notes on _Stepping Up and Down Cards_ in the
134 | [Fourmilab Java implementation][].
135 |
136 | [Sketch of the Analytical Engine]: https://www.fourmilab.ch/babbage/sketch.html
137 |
138 | The file `bernouilli5.ae` adds another "iteration" to the above
139 | program; the previously computed B7 is stored on column 24, and
140 | operations 13 to 23 are repeated once more (now using column 24 as
141 | input at operation 21).
142 |
143 | The file `check_for_prime.ae` determines whether a number is
144 | prime. It's set to check 203 (AAL's 203rd birthday was in 2018).
145 |
146 | ## Performance
147 |
148 | The [Deep Learning with the Analytical Engine][] project, with the
149 | [Deep Learning with the Analytical Engine repository][], reports on an
150 |
151 | > implementation of a convolutional neural network as a program for
152 | > Charles Babbage's Analytical Engine, capable of recognising
153 | > handwritten digits to a high degree of accuracy (98.5% if provided
154 | > with a sufficient amount of training data and left running
155 | > sufficiently long).
156 |
157 | The program consists of over 400,000 cards! (it was generated by
158 | Python scripts from a high-level description). It requires `-z` to
159 | run. As a timing test, the program was run for the first 10 images
160 | only: in Java, this took 18 seconds, of which 10 seconds was initial
161 | processing, in Ada (where the initial processing was about a second)
162 | with `-O0 -gnata` 44 seconds, with `-O2 -gnatp` 22 seconds. So the Ada
163 | implementation is about 3 times slower than the Java one. More work to
164 | be done!
165 |
166 | [Deep Learning with the Analytical Engine]: https://cp4space.wordpress.com/2016/02/06/deep-learning-with-the-analytical-engine/
167 | [Deep Learning with the Analytical Engine repository]: https://gitlab.com/apgoucher/DLAE
168 |
--------------------------------------------------------------------------------
/src/analytical_engine-card.ads:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Ada.Strings.Wide_Unbounded;
23 |
24 | limited with Analytical_Engine.Framework;
25 |
26 | private with Ada.Characters.Conversions;
27 | private with Ada.Strings.Wide_Maps;
28 | private with System;
29 |
30 | package Analytical_Engine.Card is
31 |
32 | -- Notes from http://www.fourmilab.ch/babbage/cards.html.
33 |
34 | -- Program Cards
35 |
36 | -- A program for The Analytical Engine is composed of a chain of
37 | -- cards of different varieties and content. In our emulation of
38 | -- the Engine, the chain is represented by a series of lines in a
39 | -- text file, one card per line. To run a calculation on the
40 | -- Engine, the card chain prepared by the analyst is submitted to
41 | -- the Engine's human attendant, who examines it for possible
42 | -- errors and requests for actions by the Attendant (for example,
43 | -- to include the cards for a previously-prepared standard
44 | -- computation such as the extraction of the square root of a
45 | -- number at a certain point in the submitted chain).
46 |
47 | -- After completing all requests for attendant assistance in
48 | -- preparing the chain and determining that it is free of obvious
49 | -- errors, the attendant mounts the chain on the Card Reader and
50 | -- causes the Engine to begin to process it. The operation of the
51 | -- Engine may be halted by reaching the end of the chain, by a
52 | -- card which directs the Engine to stop, or by a card which
53 | -- pauses the processing of the Engine and requests (by a visible
54 | -- annotation written on the card) the attendant to take some
55 | -- action and then resume the operation of the Engine.
56 |
57 | type Card is abstract tagged record
58 | Line_Number : Natural := 0;
59 | Source_File : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
60 | Source : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
61 | end record;
62 | type Card_P is access Card'Class;
63 |
64 | procedure Execute
65 | (C : Card;
66 | In_The_Framework : in out Analytical_Engine.Framework.Instance)
67 | is abstract;
68 | function Equals (L, R : Card'Class) return Boolean;
69 |
70 | Card_Error : exception;
71 |
72 | function Read (From : Wide_String) return Card'Class;
73 |
74 | function Image (C : Card) return String;
75 |
76 | private
77 |
78 | use Ada.Strings.Wide_Unbounded;
79 |
80 | function Equals (L, R : Card'Class) return Boolean is
81 | (System."=" (L'Address, R'Address));
82 |
83 | function "+" (Item : String) return Wide_String
84 | renames Ada.Characters.Conversions.To_Wide_String;
85 |
86 | White_Space : constant Ada.Strings.Wide_Maps.Wide_Character_Set
87 | := Ada.Strings.Wide_Maps.To_Set (+(" " & ASCII.HT));
88 | White_Space_Or_Plus : constant Ada.Strings.Wide_Maps.Wide_Character_Set
89 | := Ada.Strings.Wide_Maps.To_Set (+(" +" & ASCII.HT));
90 |
91 | -- type Number_Card is new Card with record
92 | -- Target_Column : Store.Column;
93 | -- Value : Big_Integer_P;
94 | -- end record;
95 | -- overriding
96 | -- procedure Execute (C : Number_Card;
97 | -- In_The_Framework : in out Framework.Instance);
98 |
99 | -- type Operation_Card is new Card with record
100 | -- Op : Mill.Operation;
101 | -- end record;
102 | -- overriding
103 | -- procedure Execute (C : Operation_Card;
104 | -- In_The_Framework : in out Framework.Instance);
105 |
106 | -- type Variable_Card is new Card with record
107 | -- Axis : Mill.Axis; -- Ingress axes are to mill, egress to store
108 | -- Column : Store.Column;
109 | -- Preserve : Boolean; -- If false and the value is being sent to
110 | -- -- the mill, the source column is reset to
111 | -- -- zero after the value has been
112 | -- -- retrieved.
113 | -- end record;
114 | -- overriding
115 | -- procedure Execute (C : Variable_Card;
116 | -- In_The_Framework : in out Framework.Instance);
117 |
118 | -- type Stepping_Card is new Card with record
119 | -- Direction : Mill.Step;
120 | -- Step_Count : Positive;
121 | -- end record;
122 | -- overriding
123 | -- procedure Execute (C : Stepping_Card;
124 | -- In_The_Framework : in out Framework.Instance);
125 |
126 | -- type Combinatorial_Card is new Card with record
127 | -- Advance : Boolean;
128 | -- Conditional : Boolean;
129 | -- Card_Count : Positive;
130 | -- end record;
131 | -- overriding
132 | -- procedure Execute (C : Combinatorial_Card;
133 | -- In_The_Framework : in out Framework.Instance);
134 |
135 | -- type Action_Kind is (Ring_Bell, Halt_Engine, Print_Last_Result);
136 | -- type Action_Card (Act : Action_Kind) is new Card with record
137 | -- case Act is
138 | -- when Halt_Engine =>
139 | -- Msg : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
140 | -- when others =>
141 | -- null;
142 | -- end case;
143 | -- end record;
144 | -- overriding
145 | -- procedure Execute (C : Action_Card;
146 | -- In_The_Framework : in out Framework.Instance);
147 |
148 | -- type Comment_Card is new Card with null record;
149 | -- overriding
150 | -- procedure Execute (C : Comment_Card;
151 | -- In_The_Framework : in out Framework.Instance);
152 |
153 | -- type Tracing_Card is new Card with record
154 | -- Tracing : Boolean;
155 | -- end record;
156 | -- overriding
157 | -- procedure Execute (C : Tracing_Card;
158 | -- In_The_Framework : in out Framework.Instance);
159 |
160 | -- type Curve_Drawing_Card is new Card with private;
161 |
162 | -- Attendant cards: see Analytical_Engine.Card.Attendant_Request.
163 |
164 | end Analytical_Engine.Card;
165 |
--------------------------------------------------------------------------------
/src/analytical_engine-mill.adb:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Ada.Characters.Conversions;
23 |
24 | package body Analytical_Engine.Mill is
25 |
26 | Max_Value : constant Big_Integer
27 | := Make ("100000000000000000000000000000000000000000000000000");
28 | Min_Value : constant Big_Integer := -Max_Value;
29 | Zero : constant Big_Integer := Make ("0");
30 |
31 | function "+" (Item : String) return Wide_String
32 | renames Ada.Characters.Conversions.To_Wide_String;
33 |
34 | procedure Clear_Ingress (This : in out Instance'Class);
35 | procedure Clear_Egress (This : in out Instance'Class);
36 |
37 | procedure Set_Operation (This : in out Instance; To : Operation)
38 | is
39 | begin
40 | This.Op := To;
41 | end Set_Operation;
42 |
43 | procedure Set_Ingress (This : in out Instance; To : Big_Integer)
44 | is
45 | begin
46 | if This.Ingress_Valid then
47 | This.Run_Up := False;
48 | case This.Op is
49 | when None =>
50 | raise Mill_Error with "operation not set";
51 | when Add =>
52 | Add (This.Egress, This.Ingress, To);
53 | if This.Egress >= Max_Value then
54 | This.Run_Up := True;
55 | Subtract (This.Egress, This.Egress, Max_Value);
56 | elsif This.Egress <= Min_Value then
57 | This.Run_Up := True;
58 | Add (This.Egress, This.Egress, Max_Value);
59 | elsif (Sign (This.Ingress) >= 0 and Sign (This.Egress) < 0)
60 | or else (Sign (This.Ingress) < 0 and Sign (This.Egress) >= 0)
61 | then
62 | This.Run_Up := True;
63 | end if;
64 | if This.Panel.Tracing then
65 | This.Panel.Log_Trace_Message
66 | (+("Mill: "
67 | & Image (This.Ingress)
68 | & " + "
69 | & Image (To)
70 | & " = "
71 | & Image (This.Egress)
72 | & (if This.Run_Up then ", run_up" else "")));
73 | end if;
74 | when Subtract =>
75 | Subtract (This.Egress, This.Ingress, To);
76 | if This.Egress >= Max_Value then
77 | This.Run_Up := True;
78 | Subtract (This.Egress, This.Egress, Max_Value);
79 | elsif This.Egress <= Min_Value then
80 | This.Run_Up := True;
81 | Add (This.Egress, This.Egress, Max_Value);
82 | elsif (Sign (This.Ingress) >= 0 and Sign (This.Egress) < 0)
83 | or else (Sign (This.Ingress) < 0 and Sign (This.Egress) >= 0)
84 | then
85 | This.Run_Up := True;
86 | end if;
87 | if This.Panel.Tracing then
88 | This.Panel.Log_Trace_Message
89 | (+("Mill: "
90 | & Image (This.Ingress)
91 | & " - "
92 | & Image (To)
93 | & " = "
94 | & Image (This.Egress)
95 | & (if This.Run_Up then ", run_up" else "")));
96 | end if;
97 | when Multiply =>
98 | Multiply (This.Egress, This.Ingress, To);
99 | Divide (This.Egress_Primed, This.Egress, Max_Value);
100 | Get_Rem (This.Egress, This.Egress, Max_Value);
101 | if This.Panel.Tracing then
102 | This.Panel.Log_Trace_Message
103 | (+("Mill: "
104 | & Image (This.Ingress)
105 | & " * "
106 | & Image (To)
107 | & " = "
108 | & Image (This.Egress_Primed)
109 | & ","
110 | & Image (This.Egress)));
111 | end if;
112 | when Divide =>
113 | if Sign (To) = 0 then
114 | This.Run_Up := True; -- egress axes left at zero
115 | else
116 | Multiply (This.Egress, This.Ingress_Primed, Max_Value);
117 | Add (This.Egress, This.Egress, This.Ingress);
118 | Divide (This.Egress_Primed, This.Egress, To);
119 | if This.Egress_Primed >= Max_Value
120 | or else This.Egress_Primed <= Min_Value
121 | then
122 | -- The Java code resets both egress axes; would
123 | -- this have been Babbage's solution? or would
124 | -- it have been "undefined behaviour"?
125 | This.Clear_Egress;
126 | This.Run_Up := True;
127 | else
128 | Get_Rem (This.Egress, This.Egress, To);
129 | end if;
130 | end if;
131 | if This.Panel.Tracing then
132 | This.Panel.Log_Trace_Message
133 | (+("Mill: "
134 | & Image (This.Ingress)
135 | & " / "
136 | & Image (To)
137 | & " = "
138 | & Image (This.Egress_Primed)
139 | & ", rem "
140 | & Image (This.Egress)
141 | & (if This.Run_Up then ", run_up" else "")));
142 | end if;
143 | end case;
144 | Clear_Ingress (This);
145 | else
146 | This.Clear_Egress;
147 | Set (This.Ingress, To);
148 | This.Ingress_Valid := True;
149 | end if;
150 | end Set_Ingress;
151 |
152 | procedure Set_Ingress_Primed (This : in out Instance; To : Big_Integer)
153 | is
154 | begin
155 | Set (This.Ingress_Primed, To);
156 | end Set_Ingress_Primed;
157 |
158 | procedure Get_Egress (This : Instance; Result : out Big_Integer)
159 | is
160 | begin
161 | Set (Result, This.Egress);
162 | end Get_Egress;
163 |
164 | procedure Get_Egress_Primed (This : Instance; Result : out Big_Integer)
165 | is
166 | begin
167 | Set (Result, This.Egress_Primed);
168 | end Get_Egress_Primed;
169 |
170 | procedure Step_Axes (This : in out Instance;
171 | Direction : Step;
172 | Amount : Positive)
173 | is
174 | Ten : constant Big_Integer := Make ("10");
175 | Scale : Big_Integer := Make ("1");
176 | begin
177 | for J in 1 .. Amount loop
178 | Multiply (Scale, Scale, Ten);
179 | end loop;
180 | case Direction is
181 | when Up =>
182 | if This.Op /= Divide then
183 | raise Mill_Error with "Step up when operation not /";
184 | end if;
185 | -- Scale the ingress axes
186 | declare
187 | Tmp : Big_Integer;
188 | begin
189 | Multiply (Tmp, This.Ingress_Primed, Max_Value);
190 | Add (Tmp, Tmp, This.Ingress);
191 | Multiply (Tmp, Tmp, Scale);
192 | Divide (This.Ingress_Primed, Tmp, Max_Value);
193 | Get_Rem (This.Ingress, Tmp, Max_Value);
194 | if This.Panel.Tracing then
195 | This.Panel.Log_Trace_Message
196 | (+("Mill: "
197 | & Image (Tmp)
198 | & " <"
199 | & Amount'Img
200 | & " = "
201 | & Image (This.Ingress_Primed)
202 | & "," & Image (This.Ingress)));
203 | end if;
204 | end;
205 | when Down =>
206 | -- Scale the egress axes
207 | if This.Op /= Multiply then
208 | raise Mill_Error with "Step down when operation not *";
209 | end if;
210 | declare
211 | Input : Big_Integer;
212 | Result : Big_Integer;
213 | begin
214 | Multiply (Input, This.Egress_Primed, Max_Value);
215 | Add (Input, Input, This.Egress);
216 | Divide (Result, Input, Scale);
217 | Divide (This.Egress_Primed, Result, Max_Value);
218 | Get_Rem (This.Egress, Result, Max_Value);
219 | if This.Panel.Tracing then
220 | This.Panel.Log_Trace_Message
221 | (+("Mill: "
222 | & Image (Input)
223 | & " >"
224 | & Amount'Img
225 | & " = "
226 | & Image (This.Egress_Primed)
227 | & "," & Image (This.Egress)));
228 | end if;
229 | end;
230 | end case;
231 | end Step_Axes;
232 |
233 | procedure Clear_Ingress (This : in out Instance'Class)
234 | is
235 | begin
236 | This.Ingress_Valid := False;
237 | Set (This.Ingress, Zero);
238 | Set (This.Ingress_Primed, Zero);
239 | end Clear_Ingress;
240 |
241 | procedure Clear_Egress (This : in out Instance'Class)
242 | is
243 | begin
244 | Set (This.Egress, Zero);
245 | Set (This.Egress_Primed, Zero);
246 | end Clear_Egress;
247 |
248 | end Analytical_Engine.Mill;
249 |
--------------------------------------------------------------------------------
/src/analytical_engine-card.adb:
--------------------------------------------------------------------------------
1 | -- Copyright (C) Simon Wright
2 | --
3 | -- This file is part of the Analytical Engine Ada emulator
4 | -- project. This file is free software; you can redistribute it
5 | -- and/or modify it under terms of the GNU General Public License as
6 | -- published by the Free Software Foundation; either version 3, or
7 | -- (at your option) any later version. This file is distributed in
8 | -- the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9 | -- even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 | -- PARTICULAR PURPOSE.
11 | --
12 | -- As a special exception under Section 7 of GPL version 3, you are
13 | -- granted additional permissions described in the GCC Runtime
14 | -- Library Exception, version 3.1, as published by the Free Software
15 | -- Foundation.
16 | --
17 | -- You should have received a copy of the GNU General Public License
18 | -- and a copy of the GCC Runtime Library Exception along with this
19 | -- program; see the files COPYING3 and COPYING.RUNTIME respectively.
20 | -- If not, see .
21 |
22 | with Ada.Wide_Characters.Handling;
23 | with Ada.Strings.Fixed;
24 | with Ada.Strings.Wide_Fixed;
25 | with GNATCOLL.GMP.Integers;
26 |
27 | with Analytical_Engine.Card.Attendant_Request;
28 | with Analytical_Engine.Mill;
29 | with Analytical_Engine.Store;
30 |
31 | with Analytical_Engine.Card.Action_Card;
32 | with Analytical_Engine.Card.Combinatorial_Card;
33 | with Analytical_Engine.Card.Comment_Card;
34 | with Analytical_Engine.Card.Number_Card;
35 | with Analytical_Engine.Card.Operation_Card;
36 | with Analytical_Engine.Card.Stepping_Card;
37 | with Analytical_Engine.Card.Tracing_Card;
38 | with Analytical_Engine.Card.Variable_Card;
39 |
40 | package body Analytical_Engine.Card is
41 |
42 | use GNATCOLL.GMP.Integers;
43 |
44 | -- Note, these values are actually 1 more (less) than the maximum
45 | -- (minimum) possible value that can be held on a column.
46 | Max_Value : constant Big_Integer
47 | := Make ("100000000000000000000000000000000000000000000000000");
48 | Min_Value : constant Big_Integer := -Max_Value;
49 |
50 | function "+" (Item : Wide_String) return String
51 | is (Ada.Characters.Conversions.To_String (Item, Substitute => ' '));
52 |
53 | function Read (From : Wide_String) return Card'Class
54 | is
55 | Start : Positive := From'First;
56 | Leading : Wide_Character;
57 | begin
58 | if From'Length = 0 or else From (Start) in ' ' | '.' then
59 | return C : Comment_Card.Card do
60 | C.Source := To_Unbounded_Wide_String (From);
61 | end return;
62 | end if;
63 | Leading := Ada.Wide_Characters.Handling.To_Upper (From (Start));
64 | Start := Start + 1;
65 | case Leading is
66 | when 'N' =>
67 | return C : Number_Card.Card do
68 | C.Source := To_Unbounded_Wide_String (From);
69 | declare
70 | First : Positive;
71 | Last : Natural;
72 | begin
73 | Ada.Strings.Wide_Fixed.Find_Token
74 | (Source => From,
75 | Set => White_Space,
76 | From => Start,
77 | Test => Ada.Strings.Outside,
78 | First => First,
79 | Last => Last);
80 | if Last = 0 then
81 | raise Card_Error with "invalid number card";
82 | end if;
83 | C.Target_Column :=
84 | Store.Column'Value (+(From (First .. Last)));
85 | Start := Last + 1;
86 | Ada.Strings.Wide_Fixed.Find_Token
87 | (Source => From,
88 | Set => White_Space_Or_Plus, -- GNATCOLL issue 1
89 | From => Start,
90 | Test => Ada.Strings.Outside,
91 | First => First,
92 | Last => Last);
93 | if Last = 0 then
94 | raise Card_Error with "invalid number card";
95 | end if;
96 | C.Value :=
97 | new Big_Integer'(Make (+(From (First .. Last))));
98 | if C.Value.all > Max_Value
99 | or C.Value.all < Min_Value
100 | then
101 | raise Card_Error with "invalid number card";
102 | end if;
103 | end;
104 | end return;
105 | when 'L' | 'Z' | 'S' =>
106 | return C : Variable_Card.Card do
107 | C.Source := To_Unbounded_Wide_String (From);
108 | declare
109 | First : Positive;
110 | Last : Natural;
111 | Primed : Boolean;
112 | begin
113 | Ada.Strings.Wide_Fixed.Find_Token
114 | (Source => From,
115 | Set => White_Space,
116 | From => Start,
117 | Test => Ada.Strings.Outside,
118 | First => First,
119 | Last => Last);
120 | if Last = 0 then
121 | raise Card_Error with "invalid variable card";
122 | end if;
123 | if From (Last) = ''' then
124 | Primed := True;
125 | Last := Last - 1;
126 | else
127 | Primed := False;
128 | end if;
129 | if Primed then
130 | C.Axis := (case Leading is
131 | when 'S' => Mill.Egress_Primed,
132 | when 'L' | 'Z' => Mill.Ingress_Primed,
133 | when others => raise Program_Error);
134 | else
135 | C.Axis := (case Leading is
136 | when 'S' => Mill.Egress,
137 | when 'L' | 'Z' => Mill.Ingress,
138 | when others => raise Program_Error);
139 | end if;
140 | C.Column :=
141 | Store.Column'Value (+(From (First .. Last)));
142 | C.Preserve := Leading = 'L'; -- irrelevant for 'S'
143 | end;
144 | end return;
145 | when '+' | '-' | '*' | '×' | '/' | '÷' =>
146 | return C : Operation_Card.Card do
147 | C.Source := To_Unbounded_Wide_String (From);
148 | C.Op := (case Leading is
149 | when '+' => Mill.Add,
150 | when '-' => Mill.Subtract,
151 | when '*' | '×' => Mill.Multiply,
152 | when '/' | '÷' => Mill.Divide,
153 | when others => raise Program_Error);
154 | end return;
155 | when '>' | '<' =>
156 | return C : Stepping_Card.Card do
157 | C.Source := To_Unbounded_Wide_String (From);
158 | C.Direction := (case Leading is
159 | when '>' => Mill.Down,
160 | when '<' => Mill.Up,
161 | when others => raise Program_Error);
162 | declare
163 | First : Positive;
164 | Last : Natural;
165 | begin
166 | Ada.Strings.Wide_Fixed.Find_Token
167 | (Source => From,
168 | Set => White_Space,
169 | From => Start,
170 | Test => Ada.Strings.Outside,
171 | First => First,
172 | Last => Last);
173 | if Last = 0 then
174 | raise Card_Error with "invalid step up/down card";
175 | end if;
176 | C.Step_Count :=
177 | Positive'Value (+((From (First .. Last))));
178 | if C.Step_Count > 100 then
179 | raise Card_Error with "invalid step up/down card";
180 | end if;
181 | end;
182 | end return;
183 | when 'C' =>
184 | return C : Combinatorial_Card.Card do
185 | C.Source := To_Unbounded_Wide_String (From);
186 | begin
187 | declare
188 | Direction : constant Wide_Character
189 | := Ada.Wide_Characters.Handling.To_Upper (From (Start));
190 | begin
191 | if Direction = 'F' then
192 | C.Advance := True;
193 | elsif Direction = 'B' then
194 | C.Advance := False;
195 | else
196 | raise Card_Error with "invalid combinatorial card";
197 | end if;
198 | end;
199 | Start := Start + 1;
200 | if From (Start) = '?' then
201 | C.Conditional := True;
202 | Start := Start + 1;
203 | elsif From (Start) in '0' .. '9' | '+' then
204 | C.Conditional := False;
205 | else
206 | raise Card_Error with "invalid combinatorial card";
207 | end if;
208 | if Start > From'Last then
209 | raise Constraint_Error;
210 | end if;
211 | declare
212 | First : Positive;
213 | Last : Natural;
214 | begin
215 | Ada.Strings.Wide_Fixed.Find_Token
216 | (Source => From,
217 | Set => White_Space,
218 | From => Start,
219 | Test => Ada.Strings.Outside,
220 | First => First,
221 | Last => Last);
222 | if Last = 0 then
223 | raise Card_Error with "invalid combinatorial card";
224 | end if;
225 | C.Card_Count :=
226 | Positive'Value (+(From (First .. Last)));
227 | end;
228 | exception
229 | when Constraint_Error =>
230 | raise Card_Error with "invalid combinatorial card";
231 | end;
232 | end return;
233 | when 'B' | 'P' | 'H' =>
234 | return C : Action_Card.Card
235 | (Act => (case Leading is
236 | when 'B' => Action_Card.Ring_Bell,
237 | when 'P' => Action_Card.Print_Last_Result,
238 | when 'H' => Action_Card.Halt_Engine,
239 | when others => raise Program_Error)) do
240 | C.Source := To_Unbounded_Wide_String (From);
241 | case Leading is
242 | when 'H' =>
243 | C.Msg := To_Unbounded_Wide_String
244 | (Ada.Strings.Wide_Fixed.Trim
245 | (From (From'First + 1 .. From'Last),
246 | Ada.Strings.Both));
247 | when others => null;
248 | end case;
249 | end return;
250 | when 'T' =>
251 | return C : Tracing_Card.Card do
252 | declare
253 | First : Positive;
254 | Last : Natural;
255 | begin
256 | Ada.Strings.Wide_Fixed.Find_Token
257 | (Source => From,
258 | Set => White_Space,
259 | From => Start,
260 | Test => Ada.Strings.Outside,
261 | First => First,
262 | Last => Last);
263 | if Last = 0 then
264 | raise Card_Error with "invalid tracing card";
265 | end if;
266 | C.Tracing :=
267 | Natural'Value (+(From (First .. Last))) /= 0;
268 | end;
269 | end return;
270 | when 'A' =>
271 | return Attendant_Request.Read (From);
272 | when others =>
273 | raise Card_Error with "unrecognised card";
274 | end case;
275 | end Read;
276 |
277 | function Image (C : Card) return String
278 | is
279 | use Ada.Characters.Conversions;
280 | begin
281 | return
282 | "("
283 | & To_String (To_Wide_String (C.Source_File))
284 | & ":"
285 | & Ada.Strings.Fixed.Trim (C.Line_Number'Img, Ada.Strings.Both)
286 | & ") "
287 | & To_String (To_Wide_String (C.Source));
288 | end Image;
289 |
290 | end Analytical_Engine.Card;
291 |
--------------------------------------------------------------------------------
/COPYING3:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------