Skip to content

Instantly share code, notes, and snippets.

@gingerBill
Created May 14, 2024 12:20
Show Gist options
  • Save gingerBill/1d37d8cc34f5ff67ff2b6c4896934a44 to your computer and use it in GitHub Desktop.
Save gingerBill/1d37d8cc34f5ff67ff2b6c4896934a44 to your computer and use it in GitHub Desktop.
A translation of ALGOL68 code to Odin, showing the similarities of the entire ALGOL family
package main
import "core:fmt"
import "core:os"
error :: proc(s: string) -> ! {
fmt.eprintln("\n error:", s); os.exit(1)
}
one_to :: proc(n: int) -> List {
f :: proc(m, n: int) -> List {
if m > n { return nil }
return cons(m, f(m+1, n))
}
return f(1, n)
}
List :: ^Node
Node :: struct { h: int, t: List }
cons :: proc(n: int, l: List) -> List { return new_clone(Node{n, l}) }
hd :: proc(l: List) -> int {
if l == nil { error("hd nil") }
return l.h
}
tl :: proc(l: List) -> List {
if l == nil { error("tl nil") }
return l.t
}
show :: proc(l: List) {
if l == nil { return }
fmt.println(hd(l))
show(tl(l))
}
filter :: proc(p: proc(List, int) -> bool, top, l: List) -> List {
if l == nil { return nil }
if p(top, hd(l)) {
return cons(hd(l), filter(p, top, tl(l)))
}
return filter(p, top, tl(l))
}
sieve :: proc(l: List) -> List {
if l == nil { return nil }
not_multiple :: proc(l: List, n: int) -> bool {
return n % hd(l) != 0
}
return cons(hd(l), sieve(filter(not_multiple, l, tl(l))))
}
primes :: proc(n: int) -> List {
return sieve(tl(one_to(n)))
}
main :: proc() {
show(primes(100))
}
BEGIN # Algol-68 prime number sieve, functional style #
PROC error = (STRING s) VOID:
(print(( newline, " error: ", s, newline)); GOTO stop);
PROC one to = (INT n) LIST:
(PROC f = (INT m,n) LIST: (m>n | NIL | cons(m, f(m+1,n))); f(1,n));
MODE LIST = REF NODE;
MODE NODE = STRUCT (INT h, LIST t);
PROC cons = (INT n, LIST l) LIST: HEAP NODE := (n,l);
PROC hd = (LIST l) INT: ( l IS NIL | error("hd NIL"); SKIP | h OF l );
PROC tl = (LIST l) LIST: ( l IS NIL | error("tl NIL"); SKIP | t OF l );
PROC show = (LIST l) VOID: ( l ISNT NIL | print((" ",whole(hd(l),0))); show(tl(l)));
PROC filter = (PROC (INT) BOOL p, LIST l) LIST:
IF l IS NIL THEN NIL
ELIF p(hd(l)) THEN cons(hd(l), filter(p,tl(l)))
ELSE filter(p, tl(l))
FI;
PROC sieve = (LIST l) LIST:
IF l IS NIL THEN NIL
ELSE
PROC not multiple = (INT n) BOOL: n MOD hd(l) ~= 0;
cons(hd(l), sieve( filter( not multiple, tl(l) )))
FI;
PROC primes = (INT n) LIST: sieve( tl( one to(n) ));
show( primes(100) )
END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment