Skip to content

Commit 0f63033

Browse files
authored
Add Fibonacci in ALGOL 60 (#5372)
1 parent 889139c commit 0f63033

1 file changed

Lines changed: 139 additions & 0 deletions

File tree

archive/a/algol60/fibonacci.alg

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
begin
2+
procedure usage;
3+
begin
4+
outstring(1, "Usage: please input the count of fibonacci numbers to output\n");
5+
stop
6+
end usage;
7+
8+
comment Input a digit character from stdin and return the following:
9+
- "0" to "9" maps to 0 to 9
10+
- "+" maps to 10
11+
- "-" maps to 11
12+
- whitespace maps to 12
13+
- comma maps to 13
14+
- null byte maps to -1
15+
- invalid bytes map to -2;
16+
integer procedure indigit;
17+
begin
18+
comment Mapping:
19+
- "0" to "9" maps to 1 to 10
20+
- "+" maps to 11
21+
- "-" maps to 12
22+
- "," mapps to 13
23+
- "\t" maps to 14
24+
- "\r" maps to 15
25+
- "\n" maps to 16
26+
- " " maps to 17
27+
- null byte maps to 18
28+
- invalid byte maps 0;
29+
integer ch;
30+
inchar(0, "0123456789+-,\t\r\n ", ch);
31+
if ch < 1 then ch := -2
32+
else if ch < 14 then ch := ch - 1
33+
else if ch < 18 then ch := 12
34+
else ch := -1;
35+
indigit := ch
36+
end indigit;
37+
38+
comment Input an integer from stdin into 'result' and parse it.
39+
The last character is read into 'ch'.
40+
return true if integer is valid, false otherwise;
41+
boolean procedure inValidInteger(result, ch);
42+
integer result, ch;
43+
begin
44+
boolean valid;
45+
integer s;
46+
47+
result := 0;
48+
valid := false;
49+
s := 1;
50+
51+
comment Ignore whitespace;
52+
for ch := indigit while ch = 12 do;
53+
54+
comment Process signs: ignore "+" and invert sign if "-";
55+
signloop:
56+
if ch = 10 | ch = 11 then
57+
begin
58+
if ch = 11 then s := -s;
59+
ch := indigit;
60+
goto signloop
61+
end;
62+
63+
comment Process digits: update value;
64+
valueloop:
65+
if ch >= 0 & ch <= 9 then
66+
begin
67+
comment Invalid if overflow or underflow;
68+
valid := false;
69+
if (s > 0 & (maxint - ch) % 10 < result) |
70+
(s < 0 & (-1 - maxint + ch) % 10 > result) then goto done;
71+
72+
result := result * 10 + s * ch;
73+
ch := indigit;
74+
valid := true;
75+
goto valueloop
76+
end;
77+
78+
comment Ignore whitespace;
79+
for ch := ch while ch = 12 do ch := indigit;
80+
81+
done:
82+
inValidInteger := valid
83+
end inValidInteger;
84+
85+
comment Output integer without space. This is needed since ALGOL60
86+
'outinteger' automatically adds a space after the integer.
87+
Source: 'outinteger' function source code in Appendix 2 of
88+
https://www.algol60.org/reports/algol60_mr.pdf;
89+
procedure outIntegerNoSpace(x);
90+
value x;
91+
integer x;
92+
begin
93+
procedure digits(x);
94+
value x;
95+
integer x;
96+
begin
97+
integer d;
98+
d := x % 10;
99+
x := x - 10 * d;
100+
if d != 0 then digits(d);
101+
outchar(1, "0123456789", x + 1);
102+
end digits;
103+
if x < 0 then outstring(1, "-");
104+
digits(abs(x));
105+
end outIntegerNoSpace;
106+
107+
procedure fibonacci(n);
108+
value n;
109+
integer n;
110+
begin
111+
integer a, b, c, i;
112+
113+
a := 0;
114+
b := 1;
115+
for i := 1 step 1 until n do
116+
begin
117+
c := a + b;
118+
a := b;
119+
b := c;
120+
outIntegerNoSpace(i);
121+
outstring(1, ": ");
122+
outIntegerNoSpace(a);
123+
outstring(1, "\n");
124+
end
125+
end fibonacci;
126+
127+
integer argc, result, ch;
128+
129+
comment Get number of parameters. Exit if too few;
130+
ininteger(0, argc);
131+
if argc < 1 then usage;
132+
133+
comment Get integer value from 1st argument. Exit if invalid, not
134+
end of argument, or negative;
135+
if !inValidInteger(result, ch) | ch != -1 | result < 0 then usage;
136+
137+
comment Output Fibonacci values;
138+
fibonacci(result);
139+
end

0 commit comments

Comments
 (0)