Merge pull request #35 from fanf2/master

Make 1998/fanf more like the original
This commit is contained in:
Landon Curt Noll authored and GitHub committed 2024-12-30 13:51:59 -08:00
commit 09578bdc8a
4 files changed
+110 -102

No files matched your search

+3 -3
View File
@@ -41,7 +41,7 @@ include ../../var.mk
CSILENCE= -Wno-pointer-bool-conversion -Wno-unused-parameter -Wno-main \ CSILENCE= -Wno-pointer-bool-conversion -Wno-unused-parameter -Wno-main \
-Wno-implicit-function-declaration -Wno-address \ -Wno-implicit-function-declaration -Wno-address \
-Wno-builtin-declaration-mismatch -Wno-int-conversion \ -Wno-builtin-declaration-mismatch -Wno-int-conversion \
-Wno-gnu-line-marker -Wno-gnu-line-marker -Wno-strict-prototypes
# Attempt to silence unknown warning option # Attempt to silence unknown warning option
# #
@@ -132,8 +132,8 @@ all: data ${TARGET}
${PROG}: ${PROG}.c ${PROG}: ${PROG}.c
@echo "This may take some time to complete:" @echo "This may take some time to complete:"
${CC} ${PROG}.c -E > ${PROG}tmp1.c ${CC} ${CSTD} ${PROG}.c -E > ${PROG}tmp1.c
${CC} ${PROG}tmp1.c -E > ${PROG}tmp2.c ${CC} ${CSTD} ${PROG}tmp1.c -E > ${PROG}tmp2.c
${CC} ${CFLAGS} ${PROG}tmp2.c ${LDFLAGS} -o $@ ${CC} ${CFLAGS} ${PROG}tmp2.c ${LDFLAGS} -o $@
# alternative executable # alternative executable
-8
View File
@@ -26,14 +26,6 @@ Enter an expression on standard input. To try some we have selected:
## Judges' remarks: ## Judges' remarks:
### Historical aside:
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)
but to get this to compile in modern systems it had to be translated to what you
now see. The intermediate steps can still be performed but they might be
different from the past. This should be kept in mind as you read the below
remarks.
This program translates lambda expressions into combinator This program translates lambda expressions into combinator
expressions. But you do not need to know Lambda Calculus to be expressions. But you do not need to know Lambda Calculus to be
impressed by this program! impressed by this program!
+84 -79
View File
@@ -1,40 +1,45 @@
#define Xinclude #include
Xinclude <stdlib.h>
Xinclude <stdio.h>
#define i int #define l #define
#define n struct n #define p(p) l p b ( m p u X )
#define T , char **C) { return (
#define x ){ return ( l i int
#define A -> l n struct n
#define N n* l x ){ return (
l A ->
l N n*
n { i c ; N L ; N R ; N U ; N ( * F ) ( N ) ; } ; n { i c ; N L ; N R ; N U ; N ( * F ) ( N ) ; } ;
#define F A F l F A F
#define U A U l U A U
#define R A R l R A R
#define L A L l L A L
#define m q = malloc(sizeof * q ) Z F = l m q = malloc(sizeof * q ) Z F =
#define e z F ( p ) ) ; } l e z F ( p ) ) ; }
#define f e N l f e N
#define g z L Q s f l g z L Q s f
#define h ( N p x l h ( N p x
#define H h p L U Q l H h p L U Q
#define s R z R = q l s R z R = q
#define t ) ? p : ( l t ) ? p : (
#define z , p l z , p
#define Z , q l Z , q
#define Q = p l Q = p
#define w ! p U t p U L Q z Q U , l w ! p U t p U L Q z Q U ,
#define D W p R U = 0 z R Q R F ( p R ) z R F != E t l D W p R U = 0 z R Q R F ( p R ) z R F != E t
#define W h w l W h w
#define X z = q , 0 l X z = q , 0
#define V w p F = v z L Q l V w p F = v z L Q
#define O m o Z L Q l O m o Z L Q
#define M m E Z A c = l M m E Z A c =
#define r Z R Q l r Z R Q
#define u Z U Q l u Z U Q
#define a ) ) ) ? 0 : j ( ! l a ) ) ) ? 0 : j ( !
#define k ( i c x l k ( i c x
#define y 0 ) ; } i l y 0 ) ; } i
N q ; N N q ; N
o H z Q L f o H z Q L f
@@ -42,9 +47,9 @@ v H U z Q L f
K W V L R f K W V L R f
J W V R f J W V R f
I h V R f I h V R f
#if 0
Y W q Q g
#endif
S W w w O L L R r s , O L R r R R g S W w w O L L R r s , O L R r R R g
E D p F Q L A c - p R A c ? J : K f E D p F Q L A c - p R A c ? J : K f
P D w putchar ( p L R A c ) , m I g P D w putchar ( p L R A c ) , m I g
@@ -53,64 +58,64 @@ p ;
i j k c ? O U r u U U X : y b k y d k y i j k c ? O U r u U U X : y b k y d k y
#define d(d) ( ( d a b l d(d) ( ( d a b
#define b(b) ( ( b a d l b(b) ( ( b a d
#define E(E) b ( M E u X ) l E(E) b ( M E u X )
main ( i c T main ( x i ) ! (
#define I b ( m I u X ) p (I)
#define J b ( m J u X ) p (J)
#define K b ( m K u X ) p (K)
#if 0
p (Y)
#endif
p (P)
p (G)
p (S)
l B b (S (K S) K)
l SS b (B (B S) B)
l C b (SS B S (K K))
l CC b (B (B C) B)
l BB b (CC B (B B B) B)
l Y b (S (C B (S I I)) (C B (S I I)))
#define P b ( m P u X ) l CI b (C I)
#define G b ( m G u X )
#define S b ( m S u X ) l ef E(EOF)
#define B b (S (K S) K) l sp E(' ')
#define SS b (B (B S) B) l ob E('(')
#define C b (SS B S (K K)) l cb E(')')
#define CC b (B (B C) B) l lm E('\\')
#define BB b (CC B (B B B) B) l nl E('\n')
l ht E('\t')
l qs E('S')
l qk E('K')
l qi E('I')
#define Y b (S (C B (S I I)) (C B (S I I))) l pair b (BB (B (B K)) C CI)
l atom b (B K CI)
#define CI b (C I) l bind b (CC B B C)
#define ef E((-1)) l ore b (SS (CI K))
#define sp E(' ') l gns b (Y (B (bind G) (CC S (C (ore sp (ore nl ht))) CI)))
#define ob E('(')
#define cb E(')')
#define lm E('\\')
#define nl E('\n')
#define ht E('\t')
#define qs E('S')
#define qk E('K')
#define qi E('I')
#define pair b (BB (B (B K)) C CI) 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))
#define atom b (B K CI)
#define bind b (CC B B C) 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)))))))
#define ore b (SS (CI K)) 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)))))
#define gns b (Y (B (bind G) (CC S (C (ore sp (ore nl ht))) CI)))
l lam b (B (bind gns) (C (CC BB bind (B CI)) abs))
#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)) 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))))
#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))))))) l make b (B pair (pair (atom qs)))
#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))))) 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))
#define lam b (B (bind gns) (C (CC BB bind (B CI)) abs))
#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))))
#define make b (B pair (pair (atom qs)))
#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))
(bind (bind trans pr) (P nl) I) (bind (bind trans pr) (P nl) I)
+23 -12
View File
@@ -3257,20 +3257,31 @@ Jump to: [top](#)
### Winning entry source code: [fanf.c](%%REPO_URL%%/1998/fanf/fanf.c) ### Winning entry source code: [fanf.c](%%REPO_URL%%/1998/fanf/fanf.c)
</div> </div>
[Cody](#cody) fixed this to compile. The problem was the intermediate steps to get to the [Cody](#cody) fixed this to compile. Tony Finch fixed it again to be
final code that is compiled. The code is now what it essentially becomes when more like the original submission. The double preprocessing is a joke
processed completely. The intermediate steps can now be performed to see how it about C and a joke about OFL so the program is less funny without it.
expands but it can still compile and be used.
Cody also added a second arg to `main()` out of an abundance of caution as some There were a couple of problems with the double preprocessing that
versions of `clang` complain about the number of args to `main()`. These versions upset modern compilers:
claim that only 0, 2 or 3 are allowed but it does allow 1 anyway. It is quite
possible though that this will change so it is fixed in case this happens. As it
is mostly just through the C pre-processor Cody added a new macro to make the
code look like the original with just an extra arg. See the
FAQ on "[main function args](faq.html#arg_count)"
for more details.
* Recent versions of `gcc` wrap `#line` marks around the expansion
of `EOF` which broke up `#define ef E(EOF)` across multiple lines.
This can be avoided by processing `#include` in the second
preprocessor phase.
(Tony vaguely remembers some indecision about when to `#include`,
in particular whether preprocessing the headers twice would lead
to trouble. Early `#include` seemed to work and was shorter so
that was what the original submission did.)
* System headers can be sensitive to compiler options, for example
`restrict` keywords might be omitted when compiling with
`-std=gnu90`. Consistency options need to be used at all stages.
Cody also added a second arg to `main()`. Tony removed both args since
neither of them are used and it's shorter that way (though it provokes
a warning about a non-prototype function definition). See the FAQ on
"[main function args](faq.html#arg_count)" for more details.
In some versions of `clang` `-Wno-int-conversion` had to be added to the In some versions of `clang` `-Wno-int-conversion` had to be added to the
`CSILENCE` variable of the Makefile. `CSILENCE` variable of the Makefile.