├── 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 | --------------------------------------------------------------------------------