Merge pull request #1757 from xexyl/lynn2019
Add 2019/lynn/try.sh, other files, updates
This commit is contained in:
11 files changed
+234
-69
No files matched your search
@@ -51,11 +51,12 @@ under a free license.
|
|||||||
|
|
||||||
This program has also been successfully compiled on Windows, with both the [Tiny
|
This program has also been successfully compiled on Windows, with both the [Tiny
|
||||||
C Compiler](https://bellard.org/tcc/) and Microsoft's C/C++ compiler. However,
|
C Compiler](https://bellard.org/tcc/) and Microsoft's C/C++ compiler. However,
|
||||||
the latter reports warnings about loss of information when converting floats,
|
the latter reports warnings about loss of information when converting `float`s,
|
||||||
and that `void (*)()` and `void (*)(void)` are not the same thing.
|
and that `void (*)()` and `void (*)(void)` are not the same thing.
|
||||||
|
|
||||||
Interesting fact: The size of the program from `./iocccsize -i` is 2019.
|
Interesting fact: The size of the program from `./iocccsize -i` is 2019.
|
||||||
|
|
||||||
|
|
||||||
#### How to use:
|
#### How to use:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -98,6 +99,7 @@ print `Bad input file` or `Wave file must be 16 bits,1-2 channels.` depending on
|
|||||||
what it thinks the problem is. If the output file cannot be opened, the program
|
what it thinks the problem is. If the output file cannot be opened, the program
|
||||||
will print `Can't open output file`.
|
will print `Can't open output file`.
|
||||||
|
|
||||||
|
|
||||||
### Assumptions:
|
### Assumptions:
|
||||||
|
|
||||||
1. The code is compiled using the C99 or C11 standard.
|
1. The code is compiled using the C99 or C11 standard.
|
||||||
@@ -107,6 +109,7 @@ represents the number zero.
|
|||||||
4. `int16_t` and `int32_t` are 2's-complement, `sizeof(int16_t) == 2` and
|
4. `int16_t` and `int32_t` are 2's-complement, `sizeof(int16_t) == 2` and
|
||||||
`sizeof(int32_t) == 4`.
|
`sizeof(int32_t) == 4`.
|
||||||
|
|
||||||
|
|
||||||
### Obfuscations
|
### Obfuscations
|
||||||
|
|
||||||
The main obfuscation is that digital signal processing algorithms are inherently
|
The main obfuscation is that digital signal processing algorithms are inherently
|
||||||
@@ -143,8 +146,8 @@ to decipher it.
|
|||||||
`#define`s are used to abbreviate the code, which has a side effect of making it
|
`#define`s are used to abbreviate the code, which has a side effect of making it
|
||||||
very slightly harder to read.
|
very slightly harder to read.
|
||||||
|
|
||||||
* `k` is just a general-purpose replacement for 16.
|
* `k` is just a general-purpose replacement for `16`.
|
||||||
* `i` is the number of delay-lines to allocate and use (currently 24).
|
* `i` is the number of delay-lines to allocate and use (currently `24`).
|
||||||
* `q` is an abbreviation for multiplying two elements of `w[]` together.
|
* `q` is an abbreviation for multiplying two elements of `w[]` together.
|
||||||
* `u()` is used to display percentages with proper rounding.
|
* `u()` is used to display percentages with proper rounding.
|
||||||
* `j()` imposes an upper limit on a floating-point value, and then negates it.
|
* `j()` imposes an upper limit on a floating-point value, and then negates it.
|
||||||
@@ -186,7 +189,7 @@ As many values as possible have been crammed into arrays. `float w[]` contains:
|
|||||||
|
|
||||||
All of the strings are concatenated together and "encrypted" by breaking the
|
All of the strings are concatenated together and "encrypted" by breaking the
|
||||||
string into 4-byte chunks (by casting it to an `int32_t*`), and then XORing the
|
string into 4-byte chunks (by casting it to an `int32_t*`), and then XORing the
|
||||||
sequence of ints with a known numeric sequence. The "decryption" is not done
|
sequence of `int`s with a known numeric sequence. The "decryption" is not done
|
||||||
in-place, to avoid writing over the string constant.
|
in-place, to avoid writing over the string constant.
|
||||||
|
|
||||||
`int32_t *c` is a pointer that points into `f[]`, except that it is often
|
`int32_t *c` is a pointer that points into `f[]`, except that it is often
|
||||||
|
|||||||
+6
-2
@@ -68,7 +68,8 @@ CINCLUDE=
|
|||||||
|
|
||||||
# Optimization
|
# Optimization
|
||||||
#
|
#
|
||||||
OPT=
|
# We disable the optimiser because the entry has problems with it enabled.
|
||||||
|
OPT= -O0
|
||||||
|
|
||||||
# Default flags for ANSI C compilation
|
# Default flags for ANSI C compilation
|
||||||
#
|
#
|
||||||
@@ -137,8 +138,11 @@ all: data ${TARGET}
|
|||||||
clean clobber install love haste waste maker easter_egg \
|
clean clobber install love haste waste maker easter_egg \
|
||||||
sandwich supernova deep_magic magic charon pluto
|
sandwich supernova deep_magic magic charon pluto
|
||||||
|
|
||||||
|
|
||||||
|
# We FORCE the use of -O0 even if someone overrides it because this entry has
|
||||||
|
# problems with it enabled.
|
||||||
${PROG}: ${PROG}.c
|
${PROG}: ${PROG}.c
|
||||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
${CC} ${CFLAGS} -O0 $< -o $@ ${LDFLAGS}
|
||||||
${LN} -sf ${PROG} tbfs
|
${LN} -sf ${PROG} tbfs
|
||||||
|
|
||||||
test: ${PROG}
|
test: ${PROG}
|
||||||
|
|||||||
+35
-15
@@ -4,6 +4,21 @@
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
NOTE: we disable the optimiser because this program has problems with it
|
||||||
|
enabled.
|
||||||
|
|
||||||
|
|
||||||
|
### Bugs and (Mis)features:
|
||||||
|
|
||||||
|
The current status of this entry is:
|
||||||
|
|
||||||
|
```
|
||||||
|
STATUS: INABIAF - please **DO NOT** fix
|
||||||
|
```
|
||||||
|
|
||||||
|
For more detailed information see [2019 karns in bugs.md](/bugs.md#2019-karns).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## To use:
|
## To use:
|
||||||
|
|
||||||
@@ -11,22 +26,25 @@ make
|
|||||||
./prog < textfile_that_fits_on_the_screen
|
./prog < textfile_that_fits_on_the_screen
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You might want to type:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
reset
|
||||||
|
```
|
||||||
|
|
||||||
|
after running the program to restore the terminal to its previous state.
|
||||||
|
|
||||||
|
|
||||||
### Try:
|
### Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./prog < README.md
|
./try.sh
|
||||||
|
|
||||||
./prog < prog.c
|
|
||||||
|
|
||||||
./prog < maze
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The last two can be done in a sequence, first showing the respective files at
|
If you have more time you might want to try:
|
||||||
the terminal, like:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./try.sh
|
./prog < README.md
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -37,10 +55,10 @@ not, YMMV -- teach you how to find your way in a maze. The algorithm is
|
|||||||
well-known but the drawing is amazing!
|
well-known but the drawing is amazing!
|
||||||
|
|
||||||
Before running, make sure that your terminal can accommodate the whole file.
|
Before running, make sure that your terminal can accommodate the whole file.
|
||||||
Before running "make test", make it about 120x40 to be safe, ensuring that you
|
Before running `make test`, make it about 120x40 to be safe, ensuring that you
|
||||||
see the @ sign as well as the exclamation mark.
|
see the `@` sign as well as the exclamation mark.
|
||||||
|
|
||||||
...Oh, and the first M in YMMV stands for "mazing".
|
...Oh, and the first `M` in YMMV stands for "mazing".
|
||||||
|
|
||||||
A puzzle for the reader: Can you change the program to consider a diagonal
|
A puzzle for the reader: Can you change the program to consider a diagonal
|
||||||
movement as one step?
|
movement as one step?
|
||||||
@@ -50,15 +68,17 @@ movement as one step?
|
|||||||
|
|
||||||
### The Program:
|
### The Program:
|
||||||
|
|
||||||
This program is pretty simple! It performs a breadth first search on the
|
This program is pretty simple! It performs a [breadth first
|
||||||
specified graph. The graph can be any ascii text file that has an 'at'
|
search](https://en.wikipedia.org/wiki/Breadth-first_search) on the
|
||||||
character, which is going to be the starting location, and a '!' character
|
specified graph. The graph can be any ASCII text file that has an 'at' (`@`)
|
||||||
|
character, which is going to be the starting location, and a `!` character
|
||||||
which will be the destination.
|
which will be the destination.
|
||||||
|
|
||||||
The nodes on this graph that are spaces are connected with any directly
|
The nodes on this graph that are spaces are connected with any directly
|
||||||
adjacent nodes that are also spaces. Nodes that aren't spaces are not
|
adjacent nodes that are also spaces. Nodes that aren't spaces are not
|
||||||
connected with anything.
|
connected with anything.
|
||||||
|
|
||||||
|
|
||||||
### Compiling and Running:
|
### Compiling and Running:
|
||||||
|
|
||||||
This program usually compiles under both GCC and clang. Build with:
|
This program usually compiles under both GCC and clang. Build with:
|
||||||
@@ -67,7 +87,7 @@ This program usually compiles under both GCC and clang. Build with:
|
|||||||
$(CC) -std=c99 -o tbfs prog.c
|
$(CC) -std=c99 -o tbfs prog.c
|
||||||
```
|
```
|
||||||
|
|
||||||
where $(CC) is cc, gcc, clang, or some other c compiler.
|
where `$(CC)` is cc, gcc, clang, or some other C compiler.
|
||||||
|
|
||||||
You can then run it with:
|
You can then run it with:
|
||||||
|
|
||||||
|
|||||||
+7
-12
@@ -1,8 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
#
|
#
|
||||||
# Demo of IOCCC 26 (2019) 'Most in need of whitespace' entry by Joshua Karns.
|
# try.sh - demonstrate IOCCC winner 2019/karns
|
||||||
#
|
|
||||||
# Doesn't run the program on README.md as it's longer and slower.
|
|
||||||
#
|
#
|
||||||
|
|
||||||
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||||
@@ -20,13 +18,11 @@ clear
|
|||||||
# display prog.c to the user
|
# display prog.c to the user
|
||||||
echo "$ cat prog.c"
|
echo "$ cat prog.c"
|
||||||
cat prog.c
|
cat prog.c
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# run the program on itself
|
# run the program on its own source code
|
||||||
echo "$ ./prog < prog.c"
|
read -r -n 1 -p "Press any key to run: ./prog < prog.c: "
|
||||||
sleep 2
|
echo 1>&2
|
||||||
./prog < prog.c
|
./prog < prog.c
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# reset terminal for colours
|
# reset terminal for colours
|
||||||
reset
|
reset
|
||||||
@@ -34,13 +30,12 @@ reset
|
|||||||
# display maze
|
# display maze
|
||||||
echo "$ cat maze"
|
echo "$ cat maze"
|
||||||
cat maze
|
cat maze
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# run the program on maze
|
# run the program on maze
|
||||||
echo "$ ./prog < maze"
|
read -r -n 1 -p "Press any key to run: ./prog < maze: "
|
||||||
sleep 2
|
echo 1>&2
|
||||||
./prog < maze
|
./prog < maze
|
||||||
|
|
||||||
sleep 2
|
read -r -n 1 -p "Press any key to exit: "
|
||||||
# reset terminal
|
# reset terminal
|
||||||
reset
|
reset
|
||||||
@@ -3,6 +3,9 @@
|
|||||||
*.dSYM
|
*.dSYM
|
||||||
fib
|
fib
|
||||||
fib.c
|
fib.c
|
||||||
|
ghcfib
|
||||||
|
ghcfib.hi
|
||||||
|
ghcfib.o
|
||||||
hint
|
hint
|
||||||
hint.c
|
hint.c
|
||||||
indent
|
indent
|
||||||
|
|||||||
+60
-36
@@ -5,6 +5,17 @@ make
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Bugs and (Mis)features:
|
||||||
|
|
||||||
|
The current status of this entry is:
|
||||||
|
|
||||||
|
```
|
||||||
|
STATUS: INABIAF - please **DO NOT** fix
|
||||||
|
```
|
||||||
|
|
||||||
|
For more detailed information see [2019 lynn in bugs.md](/bugs.md#2019-lynn).
|
||||||
|
|
||||||
|
|
||||||
## To use:
|
## To use:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -15,15 +26,14 @@ make
|
|||||||
### Try:
|
### Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
(./prog < fib.hs; cat prog.c) > fib.c
|
./try.sh
|
||||||
cc fib.c -o fib
|
|
||||||
./fib
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Judges' remarks:
|
## Judges' remarks:
|
||||||
|
|
||||||
A fully functional compiler. The example prints out the 30th Fibonacci number.
|
A fully functional compiler. The example prints out the 30th [Fibonacci
|
||||||
|
number](https://en.wikipedia.org/wiki/Fibonacci_sequence).
|
||||||
|
|
||||||
|
|
||||||
## Author's remarks:
|
## Author's remarks:
|
||||||
@@ -39,7 +49,7 @@ system? The solution is simple: no type checking. It also means no
|
|||||||
typeclasses. Just pass dictionaries explicitly.
|
typeclasses. Just pass dictionaries explicitly.
|
||||||
|
|
||||||
* `ZeroPauseGarbageCollection`: Instead of disruptive stop-the-world garbage
|
* `ZeroPauseGarbageCollection`: Instead of disruptive stop-the-world garbage
|
||||||
collection, we only tidy up when the world stops of its own accord, that is,
|
collection, we only tidy up when the world stops on its own accord, that is,
|
||||||
on program termination.
|
on program termination.
|
||||||
|
|
||||||
* `OneHundredPercentPure`: Gone is the catch-all lawless IO monad. And no
|
* `OneHundredPercentPure`: Gone is the catch-all lawless IO monad. And no
|
||||||
@@ -47,6 +57,7 @@ typeclasses. Just pass dictionaries explicitly.
|
|||||||
|
|
||||||
* `SyntaxForTheMasses`: See below.
|
* `SyntaxForTheMasses`: See below.
|
||||||
|
|
||||||
|
|
||||||
### Building:
|
### Building:
|
||||||
|
|
||||||
Build the compiler:
|
Build the compiler:
|
||||||
@@ -59,7 +70,7 @@ cc -o prog prog.c
|
|||||||
|
|
||||||
#### Fibonacci numbers:
|
#### Fibonacci numbers:
|
||||||
|
|
||||||
Test the compiler on `fib.hs`:
|
Test the compiler on [fib.hs](fib.hs):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
(./prog < fib.hs ; cat prog.c) > fib.c
|
(./prog < fib.hs ; cat prog.c) > fib.c
|
||||||
@@ -67,19 +78,20 @@ Test the compiler on `fib.hs`:
|
|||||||
|
|
||||||
Compiling the output produces a binary that prints the 30th Fibonacci number.
|
Compiling the output produces a binary that prints the 30th Fibonacci number.
|
||||||
|
|
||||||
The file `ghcfib.hs` includes `fib.hs` with some glue code, and shows GHC also
|
The file [ghcfib.hs](ghcfib.hs) includes [fib.hs](fib.hs) with some glue code,
|
||||||
accepts our subset of Haskell:
|
and shows GHC also accepts our subset of Haskell:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
ghc ghcfib.hs
|
ghc ghcfib.hs
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
#### Self-hosting compiler:
|
#### Self-hosting compiler:
|
||||||
|
|
||||||
To avoid spoiling this entry by revealing the original Haskell source, we
|
To avoid spoiling this entry by revealing the original Haskell source, we
|
||||||
instead provide `hint.hs`, the output of a certain stage of the compiler when
|
instead provide [hint.hs](hint.hs), the output of a certain stage of the
|
||||||
run on itself. This intermediate output is hopefully difficult to understand,
|
compiler when run on itself. This intermediate output is hopefully difficult to
|
||||||
yet is accepted by our compiler:
|
understand, yet is accepted by our compiler:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
(./prog < hint.hs ; cat prog.c) > hint.c
|
(./prog < hint.hs ; cat prog.c) > hint.c
|
||||||
@@ -90,13 +102,15 @@ make hint
|
|||||||
The output program behaves like the compiler itself.
|
The output program behaves like the compiler itself.
|
||||||
|
|
||||||
Unlike the original source from which it is derived, GHC fails to compile
|
Unlike the original source from which it is derived, GHC fails to compile
|
||||||
`hint.hs`. This is because values have been replaced with their Scott encodings
|
[hint.hs](hint.hs). This is because values have been replaced with their [Scott
|
||||||
|
encodings](https://en.wikipedia.org/wiki/Mogensen-Scott_encoding)
|
||||||
by this stage, which messes up type-checks; we'd need `equirecursive` types for
|
by this stage, which messes up type-checks; we'd need `equirecursive` types for
|
||||||
it to work.
|
it to work.
|
||||||
|
|
||||||
|
|
||||||
#### Regexes:
|
#### Regexes:
|
||||||
|
|
||||||
The file `lol.hs` contains an adaptation of [Doug McIlroy's elegant code from
|
The file [lol.hs](lol.hs) contains an adaptation of [Doug McIlroy's elegant code from
|
||||||
"Enumerating the strings of regular
|
"Enumerating the strings of regular
|
||||||
languages"](https://www.cs.dartmouth.edu/~doug/nfa.pdf). We exercise it by
|
languages"](https://www.cs.dartmouth.edu/~doug/nfa.pdf). We exercise it by
|
||||||
showing the first entries of the length-ordered list of all strings consisting
|
showing the first entries of the length-ordered list of all strings consisting
|
||||||
@@ -114,10 +128,12 @@ A GHC wrapper is provided:
|
|||||||
ghc ghclol.hs
|
ghc ghclol.hs
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Strongly-connected components:
|
### Strongly-connected components:
|
||||||
|
|
||||||
See `scc.hs` (and its GHC wrapper `ghcscc.hs`) for an elegant way to print the
|
See [scc.hs](scc.hs) (and its GHC wrapper [ghcscc.hs](ghcscc.hs)) for an elegant
|
||||||
strongly-connected components of a graph in reverse topological order.
|
way to print the strongly-connected components of a graph in reverse topological
|
||||||
|
order.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
(./prog < scc.hs ; cat prog.c) > scc.c
|
(./prog < scc.hs ; cat prog.c) > scc.c
|
||||||
@@ -128,15 +144,16 @@ It expects the input to be in a similar format as a previous entry
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
make scc
|
make scc
|
||||||
./scc < ../../2018/vokes/example-1.txt
|
./scc < example-1.txt
|
||||||
./scc < ../../2018/vokes/example-2.txt
|
./scc < example-2.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
The output should agree, though our program omits line numbers and does not
|
The output should agree, though our program omits line numbers and does not
|
||||||
sort entries within a line. (Also, our program only treats spaces as
|
sort entries within a line. (Also, our program only treats spaces as
|
||||||
whitespace, and supports any non-space character in a vertex name.)
|
whitespace, and supports any non-space character in a vertex name.)
|
||||||
|
|
||||||
### Syntax ###
|
|
||||||
|
### Syntax
|
||||||
|
|
||||||
Some claim Haskell syntax is frightening because braces and semicolons are
|
Some claim Haskell syntax is frightening because braces and semicolons are
|
||||||
optional. Some complain about a zoo of twisty little operators, all alike. Our
|
optional. Some complain about a zoo of twisty little operators, all alike. Our
|
||||||
@@ -144,11 +161,13 @@ compiler addresses such concerns by making braces and semicolons compulsory,
|
|||||||
disabling layout-based rules, making every operator left-associative with same
|
disabling layout-based rules, making every operator left-associative with same
|
||||||
precedence, and only defining 6 primitive functions:
|
precedence, and only defining 6 primitive functions:
|
||||||
|
|
||||||
: + - * / <=
|
```
|
||||||
|
: + - * / <=
|
||||||
|
```
|
||||||
|
|
||||||
The arithmetic operations behave as they do in C on unsigned ints, and `(:)` is
|
The arithmetic operations behave as they do in C on `unsigned int`s, and `(:)` is
|
||||||
Haskell's cons function. Like Haskell and unlike C, `(<=)` returns a Bool
|
Haskell's `cons` function. Like Haskell and unlike C, `(<=)` returns a `Bool`
|
||||||
(which are Church booleans behind the scenes) and not an Int.
|
(which are Church booleans behind the scenes) and not an `Int`.
|
||||||
|
|
||||||
No ifs, ands, or buts. Define them yourself. No tuples. Who needs them when
|
No ifs, ands, or buts. Define them yourself. No tuples. Who needs them when
|
||||||
algebraic data types delivers a better product? There is no do. No where. No
|
algebraic data types delivers a better product? There is no do. No where. No
|
||||||
@@ -160,11 +179,12 @@ Within global scope or a let expression, each definition can only refer to
|
|||||||
itself or previous definitions. This implies we can only achieve mutual
|
itself or previous definitions. This implies we can only achieve mutual
|
||||||
recursion by having one function pass itself to others.
|
recursion by having one function pass itself to others.
|
||||||
|
|
||||||
### Caveats ###
|
|
||||||
|
### Caveats
|
||||||
|
|
||||||
The only primitive type is `Int`. In particular, they represent characters. To
|
The only primitive type is `Int`. In particular, they represent characters. To
|
||||||
interoperate with GHC, our compiler treats any undefined functions as the
|
interoperate with GHC, our compiler treats any undefined functions as the
|
||||||
identity function, so that we may freely use `ord` and `chr` (or `fromEnum` and
|
`identity` function, so that we may freely use `ord` and `chr` (or `fromEnum` and
|
||||||
`toEnum`) to make our code acceptable to both compilers.
|
`toEnum`) to make our code acceptable to both compilers.
|
||||||
|
|
||||||
The main function is the last function to successfully parse. It should have
|
The main function is the last function to successfully parse. It should have
|
||||||
@@ -172,7 +192,7 @@ type `[Int] -> [Int]`, and our compiler treats this like the function passed
|
|||||||
into `Prelude.interact`, that is, the entire standard input is passed to this
|
into `Prelude.interact`, that is, the entire standard input is passed to this
|
||||||
function, and the result is printed to standard output.
|
function, and the result is printed to standard output.
|
||||||
|
|
||||||
Bool must be defined as:
|
`Bool` must be defined as:
|
||||||
|
|
||||||
```
|
```
|
||||||
data Bool = True | False;
|
data Bool = True | False;
|
||||||
@@ -181,14 +201,14 @@ data Bool = True | False;
|
|||||||
so that it matches the Scott-encoded booleans internally used by the primitive
|
so that it matches the Scott-encoded booleans internally used by the primitive
|
||||||
function `(<=)`.
|
function `(<=)`.
|
||||||
|
|
||||||
The alternatives in a case expressions must list every data constructor in
|
The alternatives in a `case` expressions must list every data constructor in
|
||||||
the order they are defined. For example, if we have:
|
the order they are defined. For example, if we have:
|
||||||
|
|
||||||
```
|
```
|
||||||
data Foo a b = Bar a | Baz | Qux Int [b]
|
data Foo a b = Bar a | Baz | Qux Int [b]
|
||||||
```
|
```
|
||||||
|
|
||||||
then a case expression that examines a term of this type must have the form:
|
then a `case` expression that examines a term of this type must have the form:
|
||||||
|
|
||||||
```
|
```
|
||||||
case x of
|
case x of
|
||||||
@@ -203,9 +223,10 @@ semicolons as separators, not terminators.
|
|||||||
|
|
||||||
The effect of erroneous input is undefined. It may be best to develop with GHC,
|
The effect of erroneous input is undefined. It may be best to develop with GHC,
|
||||||
but even then, be mindful of changes needed because of issues caused by the
|
but even then, be mindful of changes needed because of issues caused by the
|
||||||
uniform operator precedence and the touchy format of case alternatives.
|
uniform operator precedence and the touchy format of `case` alternatives.
|
||||||
|
|
||||||
### Why? ###
|
|
||||||
|
### Why?
|
||||||
|
|
||||||
One-letter variable names abound in IOCCC entries, and for good reason. These
|
One-letter variable names abound in IOCCC entries, and for good reason. These
|
||||||
tiny pieces of confetti are hard to read, and leave room for more code. Then
|
tiny pieces of confetti are hard to read, and leave room for more code. Then
|
||||||
@@ -221,6 +242,7 @@ or rather, a compiler that accepts a subset of Haskell sufficiently large to
|
|||||||
self-host. You might say I wrote a tool for this contest, then ran it on itself
|
self-host. You might say I wrote a tool for this contest, then ran it on itself
|
||||||
to make an entry for it.
|
to make an entry for it.
|
||||||
|
|
||||||
|
|
||||||
### Obfuscation techniques:
|
### Obfuscation techniques:
|
||||||
|
|
||||||
Even with Kiselyov's algorithm and some term rewriting, the compiler only fit
|
Even with Kiselyov's algorithm and some term rewriting, the compiler only fit
|
||||||
@@ -236,7 +258,7 @@ ternary operators, and so on.
|
|||||||
* Huffman coding.
|
* Huffman coding.
|
||||||
* Base-85 because high bits are frowned upon.
|
* Base-85 because high bits are frowned upon.
|
||||||
* Mixed radix encoding to game iocccsize. From a past winner
|
* Mixed radix encoding to game iocccsize. From a past winner
|
||||||
([2018/bellard](/2018/bellard/prog.c)), it seems 9 11 12 32 are the only
|
([2018/bellard](/2018/bellard/README.md)), it seems 9 11 12 32 are the only
|
||||||
whitespace octets that may appear verbatim in string literals.
|
whitespace octets that may appear verbatim in string literals.
|
||||||
* Choosing what to encode in Huffman/base-85 and what to encode in mixed radix
|
* Choosing what to encode in Huffman/base-85 and what to encode in mixed radix
|
||||||
was a delicate balancing act. In the end, I only had a few bytes to spare, which
|
was a delicate balancing act. In the end, I only had a few bytes to spare, which
|
||||||
@@ -244,16 +266,16 @@ I spent on gratuitous confusion.
|
|||||||
* The effects of some functions depend on the order their arguments are
|
* The effects of some functions depend on the order their arguments are
|
||||||
evaluated, yet the program works either way. Why?
|
evaluated, yet the program works either way. Why?
|
||||||
* Ugly macros for the runtime system's jump table for lazy reduction. A previous
|
* Ugly macros for the runtime system's jump table for lazy reduction. A previous
|
||||||
winner ([2013/endoh1](/2013/endoh1/endoh1.c)) has a cuter solution, which I
|
winner ([2013/endoh1](/2013/endoh1/README.md)) has a cuter solution, which I
|
||||||
avoid because of originality concerns and also because my combinators are
|
avoid because of originality concerns and also because my combinators are
|
||||||
compressed.
|
compressed.
|
||||||
* Relies on the inability of C comments to nest.
|
* Relies on the inability of C comments to nest.
|
||||||
* Cheaper and more complicated to print comma-separated ints (and header and
|
* Cheaper and more complicated to print comma-separated `int`s (and header and
|
||||||
footer) in C.
|
footer) in C.
|
||||||
* Primitive functions use a trick described in depth by [Naylor and Runciman,
|
* Primitive functions use a trick described in depth by [Naylor and Runciman,
|
||||||
"The Reduceron reconfigured and
|
"The Reduceron reconfigured and
|
||||||
re-evaluated"](https://www.cs.york.ac.uk/fp/reduceron/jfp-reduceron.pdf). We
|
re-evaluated"](https://www.cs.york.ac.uk/fp/reduceron/jfp-reduceron.pdf). We
|
||||||
represent the integer n with a term equivalent to `Y(BT)n`; it works because
|
represent the integer `n` with a term equivalent to `Y(BT)n`; it works because
|
||||||
`Y(BT)ne = e(Y(BT)n)`.
|
`Y(BT)ne = e(Y(BT)n)`.
|
||||||
* A sentinel in the heap often confused me, so ought to confuse others.
|
* A sentinel in the heap often confused me, so ought to confuse others.
|
||||||
|
|
||||||
@@ -263,19 +285,20 @@ compiler. See [hint.hs](hint.hs).
|
|||||||
* Mercilessly point-free. Everything is a combinator.
|
* Mercilessly point-free. Everything is a combinator.
|
||||||
* Scott encoding. Everything is a combinator.
|
* Scott encoding. Everything is a combinator.
|
||||||
* Sum types are oddly ordered and may even contain unused data constructors to
|
* Sum types are oddly ordered and may even contain unused data constructors to
|
||||||
reduce code duplication. (In C terms, unions may have extra fields, and they're
|
reduce code duplication. (In C terms, `union`s may have extra fields, and they're
|
||||||
ordered in such a way so we can reuse code to access certain fields.)
|
ordered in such a way so we can reuse code to access certain fields.)
|
||||||
* The `undefined` function compiles to the `(.)` function.
|
* The `undefined` function compiles to the `(.)` function.
|
||||||
* Replaced the only `(&&)` with `(||)` and `not` using De Morgan's law, which
|
* Replaced the only `(&&)` with `(||)` and `not` using De Morgan's law, which
|
||||||
makes some comparisons less comprehensible.
|
makes some comparisons less comprehensible.
|
||||||
* [Kiselyov only published "λ to SKI, Semantically" last
|
* [Kiselyov only published "λ to SKI, Semantically" last
|
||||||
year](http://okmij.org/ftp/tagless-final/ski.pdf).
|
year](http://okmij.org/ftp/tagless-final/ski.pdf).
|
||||||
* Recursion via the fixpoint (Y) combinator, which is represented by the
|
* Recursion via the fixpoint (`Y`) combinator, which is represented by the
|
||||||
variable `""` during one stage of compilation.
|
variable `""` during one stage of compilation.
|
||||||
* Involves theory that may be less familiar to C programmers: maps, folds,
|
* Involves theory that may be less familiar to C programmers: maps, folds,
|
||||||
parser combinators, lambda calculus, bracket abstraction, denotational
|
parser combinators, lambda calculus, bracket abstraction, denotational
|
||||||
semantics, etc.
|
semantics, etc.
|
||||||
|
|
||||||
|
|
||||||
### Warnings:
|
### Warnings:
|
||||||
|
|
||||||
On my system, it compiles cleanly with `-Wall` with older standards, e.g.
|
On my system, it compiles cleanly with `-Wall` with older standards, e.g.
|
||||||
@@ -284,6 +307,7 @@ On my system, it compiles cleanly with `-Wall` with older standards, e.g.
|
|||||||
Compiling the compiler output with `-Wall` triggers a warning about a
|
Compiling the compiler output with `-Wall` triggers a warning about a
|
||||||
strange-looking comment.
|
strange-looking comment.
|
||||||
|
|
||||||
|
|
||||||
### Behind-the-scenes commentary:
|
### Behind-the-scenes commentary:
|
||||||
|
|
||||||
[My website reveals how this compiler
|
[My website reveals how this compiler
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
0 4 8
|
||||||
|
1 0
|
||||||
|
2 1 3
|
||||||
|
3 2
|
||||||
|
4 1
|
||||||
|
5 4 6
|
||||||
|
6 5 2
|
||||||
|
7 3 6 7
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
0 1
|
||||||
|
1 2 4 5
|
||||||
|
2 3 6
|
||||||
|
3 2 7
|
||||||
|
4 0 5
|
||||||
|
5 6 5
|
||||||
|
6 5
|
||||||
|
7 3 6
|
||||||
Executable
+52
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2019/lynn
|
||||||
|
#
|
||||||
|
|
||||||
|
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||||
|
# this way allows us to have the user specify a different compiler in an easy
|
||||||
|
# way.
|
||||||
|
if [[ -z "$CC" ]]; then
|
||||||
|
CC="cc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
make CC="$CC" all >/dev/null || exit 1
|
||||||
|
|
||||||
|
# clear screen after compilation so that only the entry is shown
|
||||||
|
clear
|
||||||
|
|
||||||
|
echo "$ (./prog < fib.hs; cat prog.c) > fib.c" 1>&2
|
||||||
|
(./prog < fib.hs; cat prog.c) > fib.c
|
||||||
|
echo "$ cc -Wno-everything fib.c -o fib" 1>&2
|
||||||
|
cc -Wno-everything fib.c -o fib
|
||||||
|
echo "$ ./fib" 1>&2
|
||||||
|
./fib
|
||||||
|
echo 1>&2
|
||||||
|
read -r -n 1 -p "Press any key to continue: "
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
echo "$ (./prog < lol.hs ; cat prog.c) > lol.c" 1>&2
|
||||||
|
(./prog < lol.hs ; cat prog.c) > lol.c
|
||||||
|
echo "$ make lol" 1>&2
|
||||||
|
make lol
|
||||||
|
read -r -n 1 -p "Press any key to run: ./lol: "
|
||||||
|
echo 1>&2
|
||||||
|
./lol
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to continue: "
|
||||||
|
echo 1>&2
|
||||||
|
echo "$ (./prog < scc.hs ; cat prog.c) > scc.c" 1>&2
|
||||||
|
(./prog < scc.hs ; cat prog.c) > scc.c
|
||||||
|
echo "$ make scc" 1>&2
|
||||||
|
make scc
|
||||||
|
read -r -n 1 -p "Press any key to run: ./scc < example-1.txt: "
|
||||||
|
echo 1>&2
|
||||||
|
./scc < example-1.txt
|
||||||
|
read -r -n 1 -p "Press any key to run: ./scc < example-2.txt: "
|
||||||
|
echo 1>&2
|
||||||
|
./scc < example-2.txt
|
||||||
|
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
@@ -3466,6 +3466,44 @@ As a backtrace quine this entry is **SUPPOSED to segfault** so this should not b
|
|||||||
touched either.
|
touched either.
|
||||||
|
|
||||||
|
|
||||||
|
## 2019 karns
|
||||||
|
|
||||||
|
### STATUS: INABIAF - please **DO NOT** fix
|
||||||
|
### Source code: [2019/karns/prog.c](2019/karns/prog.c)
|
||||||
|
### Information: [2019/karns/README.md](2019/karns/README.md)
|
||||||
|
|
||||||
|
The author stated the following:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- The program must be ran in a terminal that supports ANSI escape codes for
|
||||||
|
moving the cursor and changing colors.
|
||||||
|
- Segfaults happen sometimes.
|
||||||
|
- I don't know what memory management there is, if any.
|
||||||
|
- The program will not compile by an ANSI C compiler: it uses for loops, and
|
||||||
|
it uses C++ style comments. It should compile cleanly using a C99 standard.
|
||||||
|
- Breadth first search is slow (and very slow on certain maps), but my A star
|
||||||
|
version of this program is too big.
|
||||||
|
- Lots of extra whitespace may be needed if you want to feed in an arbitrary
|
||||||
|
file.
|
||||||
|
- It fails to compile on GCC sometimes (according to a friend of mine, I've
|
||||||
|
not encountered this myself).
|
||||||
|
- The program could be obfuscated much further.
|
||||||
|
- The program contains some unused code and data.
|
||||||
|
|
||||||
|
|
||||||
|
## 2019 lynn
|
||||||
|
|
||||||
|
### STATUS: INABIAF - please **DO NOT** fix
|
||||||
|
### Source code: [2019/lynn/prog.c](2019/lynn/prog.c)
|
||||||
|
### Information: [2019/lynn/README.md](2019/lynn/README.md)
|
||||||
|
|
||||||
|
The author wrote that there are a number of differences from what one might
|
||||||
|
expect. Rather than duplicate the information we refer you to the author's
|
||||||
|
remarks in the sections [Syntax](/2019/lynn/README.md#syntax) and
|
||||||
|
[Caveats](/2019/lynn/README.md#caveats).
|
||||||
|
|
||||||
|
|
||||||
## 2019 poikola
|
## 2019 poikola
|
||||||
|
|
||||||
### STATUS: INABIAF - please **DO NOT** fix
|
### STATUS: INABIAF - please **DO NOT** fix
|
||||||
|
|||||||
@@ -4233,6 +4233,16 @@ He also added the script [try.sh](/2019/karns/try.sh) to showcase the entry a
|
|||||||
bit more easily.
|
bit more easily.
|
||||||
|
|
||||||
|
|
||||||
|
## <a name="2019_lynn"></a>[2019/lynn](/2019/lynn/prog.c) ([README.md](/2019/lynn/README.md]))
|
||||||
|
|
||||||
|
[Cody](#cody) added the [try.sh](/2019/lynn/try.sh) script.
|
||||||
|
|
||||||
|
Cody also added the [example-1.txt](/2019/lynn/example-1.txt) and
|
||||||
|
[example-2.txt](/2019/lynn/example-2.txt) text files from
|
||||||
|
[2018/vokes](/2018/vokes/README.md) so that the entry does not rely on any other
|
||||||
|
entry existing.
|
||||||
|
|
||||||
|
|
||||||
## <a name="2019_yang"></a>[2019/yang](/2019/yang/prog.c) ([README.md](/2019/yang/README.md]))
|
## <a name="2019_yang"></a>[2019/yang](/2019/yang/prog.c) ([README.md](/2019/yang/README.md]))
|
||||||
|
|
||||||
[Cody](#cody) added the [try.sh](/2019/yang/try.sh) script which also involved
|
[Cody](#cody) added the [try.sh](/2019/yang/try.sh) script which also involved
|
||||||
|
|||||||
Reference in new issue
Block a user