diff --git a/2005/mikeash/README.md b/2005/mikeash/README.md index ba11ce52b..b2da23d02 100644 --- a/2005/mikeash/README.md +++ b/2005/mikeash/README.md @@ -5,22 +5,33 @@ make ``` +### Bugs and (Mis)features: + +The current status of this entry is: + +``` +STATUS: INABIAF - please **DO NOT** fix +``` + +For more detailed information see [2005 mikeash in bugs.md](/bugs.md#2005-mikeash). + + ## To use: ```sh ./mikeash ``` +NOTE: the author stated that they tested this under i386 machines but this works +under 64-bit (x86_64, arm64) machines too. + ### Try: ```sh -./mikeash < mikeash.c -./mikeash < mikeash.c | diff - mikeash.c +./try.sh ``` -NOTE: the author stated that they tested this under i386 machines but this works -under 64-bit (x86_64, arm64) machines too. ## Judges' remarks: @@ -46,7 +57,7 @@ interpreter for an extremely limited and highly broken subset of [Common Lisp](https://en.wikipedia.org/wiki/Common_Lisp). It requires C99 because of `C99`'s ability to declare variables in the -initializer of a for loop. Unfortunately, C99 mode typically warns about +initializer of a `for` loop. Unfortunately, C99 mode typically warns about implicitly declared functions, and preprocessor directives prevent the program from being valid [Common Lisp](https://en.wikipedia.org/wiki/Common_Lisp). As a result, several warnings will be printed about implicit declarations of @@ -70,9 +81,10 @@ used: echo '(format t "~s" (* (+ 2 2 ) (- 5 (/ 9 3 ))))' | ./mikeash ``` -This evaluates the expression `(2+2) * (5 - 9/3)` giving the correct -result, 8. Note that due to the highly ad-hoc nature of the tokenizer, -the spaces before the closing parentheses are mandatory. +This evaluates the expression `(2+2) * (5 - 9/3)` giving the correct result, +`8"` (with the same issue of no newline after the `"`). Note that due to the +highly ad-hoc nature of the tokenizer, the spaces before the closing parentheses +are mandatory. The program can also be run in an interactive mode, by simply executing `./mikeash` and then typing lisp expressions, but this is difficult due to the @@ -104,8 +116,8 @@ constants such as `#\x`. * The `char-upcase` function will give strange results if passed something other than a lowercase character. -* The format function takes exactly three parameters. The first parameter is -ignored; output always goes to stdout. The second parameter must have exactly +* The `format` function takes exactly three parameters. The first parameter is +ignored; output always goes to `stdout`. The second parameter must have exactly one `~s` format specifier in it, and no other format specifiers are permitted. * The arithmetic functions take exactly two parameters. @@ -126,7 +138,7 @@ diff mikeash.c mikeash2.c The program can also be run from an implementation of [common lisp](https://en.wikipedia.org/wiki/Common_Lisp). To do -this, run the [common lisp compiler and then type the following command: +this, run the common lisp compiler and then type the following command: ``` (load "mikeash.c") @@ -134,6 +146,9 @@ this, run the [common lisp compiler and then type the following command: The source code of [mikeash.c](mikeash.c) will be printed. + +### Obfuscation + `Lispob` is obfuscated in several ways. First, it's actually two programs in one, which actually share a small amount of code. Running a C code beautifier will destroy the [LISP][] program contained within. Second and diff --git a/2005/mikeash/try.sh b/2005/mikeash/try.sh new file mode 100755 index 000000000..3d5f1c5d4 --- /dev/null +++ b/2005/mikeash/try.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# +# try.sh - demonstrate IOCCC winner 2005/mikeash +# + +# 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 "$ ./mikeash < mikeash.c" 1>&2 +./mikeash < mikeash.c + +echo 1>&2 +echo "The next command should print nothing." 1>&2 +read -r -n 1 -p "Press any key to continue: " +echo "$ ./mikeash < mikeash.c | diff - mikeash.c" 1>&2 +./mikeash < mikeash.c | diff - mikeash.c + +echo 1>&2 +echo "For the next two commands we will add a newline after the command's output" 1>&2 +echo "for your convenience as they will not print a newline themselves." 1>&2 +echo 1>&2 +echo "The next command should show: \"4." 1>&2 +read -r -n 1 -p "Press any key to continue: " +echo "$ echo '(format t "~s" (+ 2 2 ))' | ./mikeash" 1>&2 +echo '(format t "~s" (+ 2 2 ))' | ./mikeash +echo 1>&2 + +echo "The next command will evaluate the expression: (2+2) * (5 - 9/3), giving 8\"." 1>&2 +read -r -n 1 -p "Press any key to continue: " +echo "$ echo '(format t "~s" (* (+ 2 2 ) (- 5 (/ 9 3 ))))' | ./mikeash" 1>&2 +echo '(format t "~s" (* (+ 2 2 ) (- 5 (/ 9 3 ))))' | ./mikeash +echo 1>&2 diff --git a/bugs.md b/bugs.md index 07ef7a244..a5e042c88 100644 --- a/bugs.md +++ b/bugs.md @@ -2209,6 +2209,51 @@ does not exist. This entry requires that `sed` and `make` are in the path. +## 2005 mikeash + +### STATUS: INABIAF - please **DO NOT** fix +### Source code: [2005/mikeash/mikeash.c](2005/mikeash/mikeash.c) +### Information: [2005/mikeash/README.md](2005/mikeash/README.md) + +The author states: + +* The only built-in functions are `defvar`, `format`, `substitute`, +`char-upcase`, `+`, `-`, `*`, and `/`. + +* Only one variable is available. This variable is called `q`, although any +symbol name starting with the letter `q` will be mapped to this variable. + +* Only the first letter of a function name is significant. For example, +`format`, `f`, `farm`, and various other words starting with `f` will all map to +the `format` function. + +* The `defvar` function completely ignores its first parameter. It will always +store the result of evaluating its second parameter in `q`. Unlike in [Common +Lisp](https://en.wikipedia.org/wiki/Common_Lisp), multiple invocations of +`defvar` on the same variable will overwrite old values. + +* Character constants are limited to `#\Newline` and single-character +constants such as `#\x`. + +* The `char-upcase` function will give strange results if passed something +other than a lowercase character. + +* The `format` function takes exactly three parameters. The first parameter is +ignored; output always goes to `stdout`. The second parameter must have exactly +one `~s` format specifier in it, and no other format specifiers are permitted. + +* The arithmetic functions take exactly two parameters. + +* All tokens must be separated from a following `)` by whitespace. + +* A lot of other things. Notably, the language which this program interprets is +nowhere near +[Turing-complete](https://en.wikipedia.org/wiki/Turing_completeness). + +Basically, the [LISP][] interpreter is good for some basic math operations, and +for running itself. + + ## 2005 mynx ### STATUS: INABIAF - please **DO NOT** fix diff --git a/thanks-for-fixes.md b/thanks-for-fixes.md index 0bf2ed2f9..de6fa774d 100644 --- a/thanks-for-fixes.md +++ b/thanks-for-fixes.md @@ -3017,6 +3017,15 @@ updated in both the string and the code to be `'n'`. The array size of `c` was updated by 1 out of caution just in case as the array is used to store at least part of the string. +It might be worth noting that the author stated that the reason for the `\N` is +due to LISP having different escape sequences. The code was modified so that +feeding the program itself will print itself, showing no difference, which is +what is supposed to happen. It is not known, however, if having to change the +`\N` to `\n` ended up breaking any LISP. The other examples given by the author +also show correct output though. + +Cody also added the [try.sh](2005/mikeash/try.sh) script. + ## [2005/mynx](2005/mynx/mynx.c) ([README.md](2005/mynx/README.md]))