Second First: a warning for those who feel funny or weird reading about 'Turing completeness' or alike even though in 2013 Queen Elizabeth II granted royal pardon for Alan Turing with immediate effect. Who today still despises this amnesty does not belong to the target group of this append. This warning is a result of a single instance concerning this matter I observed at another forum (about C) some time ago.
Next, one more warning: in case of imminent danger to get into heavy agonal respiration when reading well known four letter words like 'love' (or an occasional, more physical side effect therefrom), please consider to stop reading this append NOW. This warning is a result of a story about Patti Smith; once she was banned for some time from any interview due having vocalised a term unlawful to be spread through the aether.
It is what it is: the subject of this append is about the enhancement of an HP-15C program from Michael Zinn. I found it described also in another one, from a third forum (not about C) it was removed with full vigour. Michael's program is an interpreter of a language "designed" by Urban Müller, a Swiss living in Switzerland, thus free to use suitable terms to denominate his programming language. (BTW, when I ask those who detest it to propose something more appropriate for a riddle exceeding the common "brain-twister" level, I get no reply.) See him presenting it within 15 minutes -- this link is for documentation purpose only, not as an ad for his employer.
The original specification (a LHA-bundle here) smells like kind of a Turing machine and in fact, it is told to be Turing-complete. Theoretically. Most (or all?) practical implementations are just an automatic machine. Because the language is not fixed in all details there exist plenty different implementations resulting in several "dialects". The relevant variations are:
- tape cells larger than 8 bits, in fact a 15C register,
- cell content may be negative (but that is an understanding anyway),
- code must be transliterated to numbers,
- code may be compiled to pack 10 commands into one register,
- output are numbers, if representing text... you know it,
- "0" signifies end of program instead of EOF or similar.
So don't expect code found 'in the wild' to run unchanged right away.
A real HP-15C is too slow to run demanding routines, for those I use the virtual 15C from HP. With it I encountered soon an imperfection in Michael's interpreter: program code and data (tape) shared the same storage -- those still reading here probably need no depiction what happened.
Missing a "curtain" -- other systems have an overwrite protection, on the HP41 aka "the curtain", kind of barrier between code and data. For the interpreter in question I implemented a likewise limit by using an array (or single-row-n-columns matrix) to hold the tape. Simple, works. If available tape becomes full the code remains untouched. Drawback, a few steps more to prepare the interpreter to run, see step 4 in following recipe. But now at first the interpreter, original was 147 lines, now 105 lines remaining:
- Code: Select all
1-42,21,12 LBL B start interpreter
2-42, 7, 0 FIX 0 make output and prompts look different
3- 0 0
4-44,16,11 STO MATRIX A clr tape
5-42,16, 1 MATRIX 1 set tape ptr
6- 1 1
7- 13 10^x =10 but avoids an ENTER before next number
8- 3 3 1st code register
9-43, 6, 0 F? 0 compacted code?
10- 20 * there are 10 cmd/register
11- 44 2 STO 2 set code ptr
12-42,21,.1 LBL .1 main loop
13- 32 .0 GSB .0 get instruction
14- 44 25 STO I
15- 32 25 GSB I interpret it
16-42, 6, 2 ISG 2 code ptr +=1
17- 43 8 RAD a NOP only
18- 22 .1 GTO .1 loop
19-42,21, 0 LBL 0 "FIN"
20-42, 7, 5 FIX 5 indicate PRGM END
21- 31 STOP PRGM END
22-42,21, 1 LBL 1 ">"
23-42, 6, 1 ISG 1 tape ptr +=1
24- 43 32 RTN NOP
25- 43 32 RTN
26-42,21, 2 LBL 2 "<"
27-42, 5, 1 DSE 1 tape ptr -=1
28- 43 32 RTN or NOP
29- 43 32 RTN
30-42,21, 3 LBL 3 "+"
31-42, 6,11 ISG A cell @tape ptr+=1
32- 43 32 RTN NOP
33- 43 32 RTN
34-42,21, 4 LBL 4 "-"
35-42, 5,11 DSE A cell @tape ptr-=1
36- 43 32 RTN or NOP
37- 43 32 RTN
38-42,21, 5 LBL 5 "."
39- 45 11 RCL A RCL cell @tape ptr
40- 31 STOP wait for acknowledge, see note 1
41- 43 32 RTN
42-42,21, 6 LBL 6 ","
43- 0 0 default
44-43, 4, 9 SF 9 get display blinking
45- 31 STOP prompt for input
46-43, 5, 9 CF 9 end blinking
47- 44 11 STO A save in cell @tape ptr
48- 43 32 RTN
49-42,21, 7 LBL 7 "["
50- 45 11 RCL A RCL cell @tape ptr
51-43,30, 0 x#0? step in?
52- 43 32 RTN CONTINUE
53- 44 0 STO 0 nesting level
54-43, 5, 1 CF 1 fwd
55- 22 9 GTO 9 move code ptr
56-42,21, 8 LBL 8 "]"
57- 45 11 RCL A RCL cell @tape ptr
58- 43 20 x=0? done?
59- 43 32 RTN CONTINUE
60- 2 2
61- 44 0 STO 0 nesting level
62-43, 4, 1 SF 1 backwards
63-42,21, 9 LBL 9 seek my [ or ]
64- 1 1
65-43, 6, 1 F? 1 backwards?
66- 16 CHS
67-44,40, 2 STO+ 2 move code ptr
68- 32 .0 GSB .0 get instruction
69- 6 6 see note 2
70- 30 -
71- 1 1
72-43,30, 5 x=y? [ found?
73-44,30, 0 STO- 0 nesting level
74- 30 -
75- 1 1
76-43,30, 5 x=y? ] found?
77-44,40, 0 STO+ 0 nesting level
78- 45 0 RCL 0
79-43,30, 6 x#y? not matching?
80- 22 9 GTO 9 loop
81- 43 32 RTN
82-42,21,.0 LBL .0 get instruction
83- 45 2 RCL 2 code ptr
84-43, 6, 0 F? 0 compacted code?
85- 22 0 GTO 0 yep, special
86- 44 25 STO I STO ptr
87- 45 24 RCL (i) get code
88- 43 32 RTN
89-42,21, 0 LBL 0 extract code
90- 1 1
91- 0 0
92- 10 / which REG?
93- 44 25 STO I
94- 42 44 FRAC
95- 1 1
96- 30 -
97- 32 0 GSB 0 which digit?
98- 13 10^x
99-45,20,24 RCL* (i) move in place
100- 42 44 FRAC extract it
101-42,21, 0 LBL 0
102- 1 1
103- 0 0
104- 20 *
105- 43 44 INT
implicit RTN
Note 1: Depending the used platform this interpreter is either pretty somniferous or pretty fast (with flawy PSE), so it is highly likely to miss some output. With no printer as recording output device I solve this issue by an acknowledge requesting 'hold' I know from mainframe terminals. This way missing output is no more a mistake of the machine.
Note 2: For a 5..6% speed-up insert after line 69
- Code: Select all
70-43,30, 9 x>=y?
71- 22 9 GTO 9
The "How-To" Recipe
1) Enter the interpreter as shown above. The real machine and the virtual 15C offer as "input device" the keyboard only. Optional you may use attached config and memory file with NutEm/PC.
2) Get some code you like to run, an example from here, or what you prepared on your own (that might you make conscious about the brain-shaking nature of this language, and maybe perceive it's labelled appropriately).
3) Transliterate the code or "compile"/compact it to 10 commands per register as described under 'Compacting code' therein. Attached ZIP contains a program for this step.
4) Following settings can't be automated, so do precisely as advised. Set number of registers according the needs determined in step 3. Code is saved in register 3 upwards. If highest used register is 'r' then do: r f-shift DIM (i). Next remove any matrix: f-shift MATRIX 0. Then check the available storage: g-shift MEM. It will display four numbers 'm n p-q', remember 'n'. Now use all free storage for the tape: 1 ENTER n f-shift DIM A.
5) Enter the code from step 3 in register 3 and up, set flag 0 accordingly: compacted code -- SF 0, one single command per register only -- CF 0.
6) start the interpreter: f-shift B. Now keep your fingers crossed if it pans out as expected... Ad libitum repeate from step 2.
Final hint: if you read up to here you agreed the QPL, which stipulates -- amongst other things -- if you educed an enhancement of the above, you have to inform me about it.