Merge pull request #35 from fanf2/master
Make 1998/fanf more like the original
This commit is contained in:
4 files changed
+110
-102
No files matched your search
+3
-3
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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.
|
||||||
|
|||||||
Reference in new issue
Block a user