Skip to content

Commit 09578bd

Browse files
authored
Merge pull request #35 from fanf2/master
Make 1998/fanf more like the original
2 parents c414132 + 9a2f8dc commit 09578bd

File tree

4 files changed

+112
-104
lines changed

4 files changed

+112
-104
lines changed

1998/fanf/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ include ../../var.mk
4141
CSILENCE= -Wno-pointer-bool-conversion -Wno-unused-parameter -Wno-main \
4242
-Wno-implicit-function-declaration -Wno-address \
4343
-Wno-builtin-declaration-mismatch -Wno-int-conversion \
44-
-Wno-gnu-line-marker
44+
-Wno-gnu-line-marker -Wno-strict-prototypes
4545

4646
# Attempt to silence unknown warning option
4747
#
@@ -132,8 +132,8 @@ all: data ${TARGET}
132132

133133
${PROG}: ${PROG}.c
134134
@echo "This may take some time to complete:"
135-
${CC} ${PROG}.c -E > ${PROG}tmp1.c
136-
${CC} ${PROG}tmp1.c -E > ${PROG}tmp2.c
135+
${CC} ${CSTD} ${PROG}.c -E > ${PROG}tmp1.c
136+
${CC} ${CSTD} ${PROG}tmp1.c -E > ${PROG}tmp2.c
137137
${CC} ${CFLAGS} ${PROG}tmp2.c ${LDFLAGS} -o $@
138138

139139
# alternative executable

1998/fanf/README.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,6 @@ Enter an expression on standard input. To try some we have selected:
2626

2727
## Judges' remarks:
2828

29-
### Historical aside:
30-
31-
At a time the code in [fanf.c](%%REPO_URL%%/1998/fanf/fanf.c) was that of [fanf.orig.c](%%REPO_URL%%/1998/fanf/fanf.orig.c)
32-
but to get this to compile in modern systems it had to be translated to what you
33-
now see. The intermediate steps can still be performed but they might be
34-
different from the past. This should be kept in mind as you read the below
35-
remarks.
36-
3729
This program translates lambda expressions into combinator
3830
expressions. But you do not need to know Lambda Calculus to be
3931
impressed by this program!

1998/fanf/fanf.c

Lines changed: 84 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,55 @@
1+
#define Xinclude #include
2+
Xinclude <stdlib.h>
3+
Xinclude <stdio.h>
14

2-
#define i int
3-
#define n struct n
4-
#define T , char **C) { return (
5-
#define x ){ return (
6-
#define A ->
7-
#define N n*
5+
#define l #define
6+
#define p(p) l p b ( m p u X )
7+
8+
l i int
9+
l n struct n
10+
l x ){ return (
11+
l A ->
12+
l N n*
813

914
n { i c ; N L ; N R ; N U ; N ( * F ) ( N ) ; } ;
1015

11-
#define F A F
12-
#define U A U
13-
#define R A R
14-
#define L A L
15-
#define m q = malloc(sizeof * q ) Z F =
16-
#define e z F ( p ) ) ; }
17-
#define f e N
18-
#define g z L Q s f
19-
#define h ( N p x
20-
#define H h p L U Q
21-
#define s R z R = q
22-
#define t ) ? p : (
23-
#define z , p
24-
#define Z , q
25-
#define Q = p
26-
#define w ! p U t p U L Q z Q U ,
27-
#define D W p R U = 0 z R Q R F ( p R ) z R F != E t
28-
#define W h w
29-
#define X z = q , 0
30-
#define V w p F = v z L Q
31-
#define O m o Z L Q
32-
#define M m E Z A c =
33-
#define r Z R Q
34-
#define u Z U Q
35-
#define a ) ) ) ? 0 : j ( !
36-
#define k ( i c x
37-
#define y 0 ) ; } i
16+
l F A F
17+
l U A U
18+
l R A R
19+
l L A L
20+
l m q = malloc(sizeof * q ) Z F =
21+
l e z F ( p ) ) ; }
22+
l f e N
23+
l g z L Q s f
24+
l h ( N p x
25+
l H h p L U Q
26+
l s R z R = q
27+
l t ) ? p : (
28+
l z , p
29+
l Z , q
30+
l Q = p
31+
l w ! p U t p U L Q z Q U ,
32+
l D W p R U = 0 z R Q R F ( p R ) z R F != E t
33+
l W h w
34+
l X z = q , 0
35+
l V w p F = v z L Q
36+
l O m o Z L Q
37+
l M m E Z A c =
38+
l r Z R Q
39+
l u Z U Q
40+
l a ) ) ) ? 0 : j ( !
41+
l k ( i c x
42+
l y 0 ) ; } i
3843

3944
N q ; N
4045
o H z Q L f
4146
v H U z Q L f
4247
K W V L R f
4348
J W V R f
4449
I h V R f
45-
46-
47-
50+
#if 0
51+
Y W q Q g
52+
#endif
4853
S W w w O L L R r s , O L R r R R g
4954
E D p F Q L A c - p R A c ? J : K f
5055
P D w putchar ( p L R A c ) , m I g
@@ -53,64 +58,64 @@ p ;
5358

5459
i j k c ? O U r u U U X : y b k y d k y
5560

56-
#define d(d) ( ( d a b
57-
#define b(b) ( ( b a d
58-
#define E(E) b ( M E u X )
59-
60-
main ( i c T
61-
62-
#define I b ( m I u X )
63-
#define J b ( m J u X )
64-
#define K b ( m K u X )
65-
66-
61+
l d(d) ( ( d a b
62+
l b(b) ( ( b a d
63+
l E(E) b ( M E u X )
6764

68-
#define P b ( m P u X )
69-
#define G b ( m G u X )
65+
main ( x i ) ! (
7066

71-
#define S b ( m S u X )
72-
#define B b (S (K S) K)
73-
#define SS b (B (B S) B)
74-
#define C b (SS B S (K K))
75-
#define CC b (B (B C) B)
76-
#define BB b (CC B (B B B) B)
67+
p (I)
68+
p (J)
69+
p (K)
70+
#if 0
71+
p (Y)
72+
#endif
73+
p (P)
74+
p (G)
7775

78-
#define Y b (S (C B (S I I)) (C B (S I I)))
76+
p (S)
77+
l B b (S (K S) K)
78+
l SS b (B (B S) B)
79+
l C b (SS B S (K K))
80+
l CC b (B (B C) B)
81+
l BB b (CC B (B B B) B)
7982

80-
#define CI b (C I)
83+
l Y b (S (C B (S I I)) (C B (S I I)))
8184

82-
#define ef E((-1))
83-
#define sp E(' ')
84-
#define ob E('(')
85-
#define cb E(')')
86-
#define lm E('\\')
87-
#define nl E('\n')
88-
#define ht E('\t')
89-
#define qs E('S')
90-
#define qk E('K')
91-
#define qi E('I')
85+
l CI b (C I)
9286

93-
#define pair b (BB (B (B K)) C CI)
94-
#define atom b (B K CI)
87+
l ef E(EOF)
88+
l sp E(' ')
89+
l ob E('(')
90+
l cb E(')')
91+
l lm E('\\')
92+
l nl E('\n')
93+
l ht E('\t')
94+
l qs E('S')
95+
l qk E('K')
96+
l qi E('I')
9597

96-
#define bind b (CC B B C)
98+
l pair b (BB (B (B K)) C CI)
99+
l atom b (B K CI)
97100

98-
#define ore b (SS (CI K))
99-
#define gns b (Y (B (bind G) (CC S (C (ore sp (ore nl ht))) CI)))
101+
l bind b (CC B B C)
100102

101-
#define pr b (Y (CC C (BB CI (B (BB (bind (P ob)) K)) (SS C (CC C (BB BB bind) K) (C (CC bind) (K (P cb))))) P))
103+
l ore b (SS (CI K))
104+
l gns b (Y (B (bind G) (CC S (C (ore sp (ore nl ht))) CI)))
102105

103-
#define trans b (Y (B (bind gns) (S (BB S (C lm) lam) (C (BB S (C ob) brac) (S (C cb (CI (atom sp))) (S (C ef (CI (atom sp))) (B CI atom)))))))
106+
l pr b (Y (CC C (BB CI (B (BB (bind (P ob)) K)) (SS C (CC C (BB BB bind) K) (C (CC bind) (K (P cb))))) P))
104107

105-
#define brac b (S bind (B Y (C (BB B B bind) (S (BB S (BB S (S I)) (CC (BB (B K)) (BB K) pair)) (CC S (CC BB (BB C (C (CI sp)) CI)) pair)))))
108+
l trans b (Y (B (bind gns) (S (BB S (C lm) lam) (C (BB S (C ob) brac) (S (C cb (CI (atom sp))) (S (C ef (CI (atom sp))) (B CI atom)))))))
106109

107-
#define lam b (B (bind gns) (C (CC BB bind (B CI)) abs))
110+
l brac b (S bind (B Y (C (BB B B bind) (S (BB S (BB S (S I)) (CC (BB (B K)) (BB K) pair)) (CC S (CC BB (BB C (C (CI sp)) CI)) pair)))))
111+
112+
l lam b (B (bind gns) (C (CC BB bind (B CI)) abs))
108113

109-
#define abs b (Y (C (BB S (BB C CI) (SS S (BB C (BB B opt)) I)) (CC S (C C (atom qi)) (B (pair (atom qk)) atom))))
114+
l abs b (Y (C (BB S (BB C CI) (SS S (BB C (BB B opt)) I)) (CC S (C C (atom qi)) (B (pair (atom qk)) atom))))
110115

111-
#define make b (B pair (pair (atom qs)))
116+
l make b (B pair (pair (atom qs)))
112117

113-
#define opt b (S (S I (S (BB (CC B) CI (BB K K make)) (S (BB C (BB C (C (CI qk))) (SS (SS S) (S (BB (BB (S I)) S (BB (BB (CC B) CI) (BB K K) make)) (B (CC B (BB (CC C) (BB (C (CI qk)) (pair (atom qk))) pair)) make)) (B (C (BB B C (C (CI qi)))) make))) make))) (B K make))
118+
l opt b (S (S I (S (BB (CC B) CI (BB K K make)) (S (BB C (BB C (C (CI qk))) (SS (SS S) (S (BB (BB (S I)) S (BB (BB (CC B) CI) (BB K K) make)) (B (CC B (BB (CC C) (BB (C (CI qk)) (pair (atom qk))) pair)) make)) (B (C (BB B C (C (CI qi)))) make))) make))) (B K make))
114119

115120
(bind (bind trans pr) (P nl) I)
116121

thanks-for-help.md

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3257,20 +3257,31 @@ Jump to: [top](#)
32573257
### Winning entry source code: [fanf.c](%%REPO_URL%%/1998/fanf/fanf.c)
32583258
</div>
32593259

3260-
[Cody](#cody) fixed this to compile. The problem was the intermediate steps to get to the
3261-
final code that is compiled. The code is now what it essentially becomes when
3262-
processed completely. The intermediate steps can now be performed to see how it
3263-
expands but it can still compile and be used.
3264-
3265-
Cody also added a second arg to `main()` out of an abundance of caution as some
3266-
versions of `clang` complain about the number of args to `main()`. These versions
3267-
claim that only 0, 2 or 3 are allowed but it does allow 1 anyway. It is quite
3268-
possible though that this will change so it is fixed in case this happens. As it
3269-
is mostly just through the C pre-processor Cody added a new macro to make the
3270-
code look like the original with just an extra arg. See the
3271-
FAQ on "[main function args](faq.html#arg_count)"
3272-
for more details.
3273-
3260+
[Cody](#cody) fixed this to compile. Tony Finch fixed it again to be
3261+
more like the original submission. The double preprocessing is a joke
3262+
about C and a joke about OFL so the program is less funny without it.
3263+
3264+
There were a couple of problems with the double preprocessing that
3265+
upset modern compilers:
3266+
3267+
* Recent versions of `gcc` wrap `#line` marks around the expansion
3268+
of `EOF` which broke up `#define ef E(EOF)` across multiple lines.
3269+
This can be avoided by processing `#include` in the second
3270+
preprocessor phase.
3271+
3272+
(Tony vaguely remembers some indecision about when to `#include`,
3273+
in particular whether preprocessing the headers twice would lead
3274+
to trouble. Early `#include` seemed to work and was shorter so
3275+
that was what the original submission did.)
3276+
3277+
* System headers can be sensitive to compiler options, for example
3278+
`restrict` keywords might be omitted when compiling with
3279+
`-std=gnu90`. Consistency options need to be used at all stages.
3280+
3281+
Cody also added a second arg to `main()`. Tony removed both args since
3282+
neither of them are used and it's shorter that way (though it provokes
3283+
a warning about a non-prototype function definition). See the FAQ on
3284+
"[main function args](faq.html#arg_count)" for more details.
32743285

32753286
In some versions of `clang` `-Wno-int-conversion` had to be added to the
32763287
`CSILENCE` variable of the Makefile.

0 commit comments

Comments
 (0)