Fix 2015/burton (add missing file, apply patch)

On Dave Burton's web page he provided a patch with a bug fix in his
entry. This patch has been applied to prog.c (not the alt code).

Added the missing file spoilers.markdown (but changed the extension to
.md).

Format fixes in README.md. Didn't check the full file yet. That'll
almost certainly come another time in another pull request.
This commit is contained in:
Cody Boone Ferguson committed 2023-03-31 06:25:11 -07:00
1 parent d7cb97d1ad
commit 8f601361e1
3 files changed
+46 -12

No files matched your search

+6 -6
View File
@@ -9,7 +9,7 @@
make
```
### To run:
## To run:
```sh
./prog "expression"
@@ -23,7 +23,7 @@ or:
Type in expressions on standard input.
### Try:
## Try:
```sh
./prog '?0x3343<<2'
@@ -49,7 +49,7 @@ grep '[0-9]' prog.c
man ./calc.1
```
## Alternate code
## Alternate code:
An alternate version of this entry, `prog.alt.c`, is provided.
This alternate code is discussed in the "prog.c vs prog.alt.c" section of the
@@ -210,7 +210,7 @@ With -Wall -std=c99, both are quite noisy, and all can be ignored:
* `value computed is not used [-Wunused-value]`
* `operation on 'j' may be undefined [-Wsequence-point]`
### Test Suite
### Test Suite:
If the program name begins with an "e", it echoes stdin to stdout.
This allows for a convenient test suite:
@@ -220,9 +220,9 @@ ln -s prog eprog
PATH=. eprog < test.in | diff - test.out
```
### Spoilers
### Spoilers:
If you do not want to puzzle out how it works, see `spoilers.markdown`.
If you do not want to puzzle out how it works, see [spoilers.md](spoilers.md).
## Copyright and CC BY-SA 4.0 License:
+6 -6
View File
@@ -14,8 +14,8 @@ I H char O;
I H short Y;
I H long long Z;
O S[]="syntax_error!"
"M@K~|JOEF\\^~_NHI]"; L*N,*K,*
O S[]="syntax_error="
"M@K~|JOEF\\^~_NHIA"; L*N,*K,*
B,*E,*T,*A,*x,D; Q(*k)(),v; V z(P),j,_,*
o,b,f,u,s,c,a,t,e,d; J l; Q _k(P){ R*K?*K++:
~-d; } V r(L a){ R a&&putchar(a); } L n(){ R*T=j=
@@ -90,21 +90,21 @@ I H long long Z;
,L**K){ V*A; q(K); W(w())**
K-c*c-b||p(B),_i(!setjmp(l)?T=B
,M(((A=(*o=m()==c-~s&&(j=a|T[-b])&&
s-m()==~s)?&o[j-a*u]:(T=B,&_)),*A=F())
c-m()==-c)?&o[j-a*u]:(T=B,&_)),*A=F())
),B:(L*)S); } V z(P){ V
s; W(m() &&v<=f*c
s; W(m() &&v< f*c
)R v<t ?(v-f)*
z():( v-=u<<
f)<f ?v?--v
?G() : i(z(
)):~ z( ):
(v-= f) <u
(v-= f) <f
?v?s = F()
,m() ==a>>
b?s :G ():
_:! (v-=
t)? --T,_f
(): v-f?o[
(): v==b?o[
(T[ -b]|a)-
a*u]: !z();
G(); }
+34
View File
@@ -0,0 +1,34 @@
### Spoilers
Calc is a recursive-descent parser. It allocates from the stack deep enough
that all expressions are exhausted before the recursion stack depth reaches the
allocations. The memory map and source is documented in src.doc.rot13. Tokens
are encoded using values 0-20, where 0 is an invalid token, 1 is minus, 2 is
space, 3 is plus, etc. The necessary constants are derived at the start of the program,
using the guarantee that globals are initialized to zero; so a correct null pointer
is obtained from an uninitialized global pointer variable, and the integers from
uninitialized global int variables. If x is a global int, then !x is 1, and the
derivation proceeds from there, using some identities that are confusingly similar
and interestingly combined (increasing obfuscation):
obc clr
--- ---
-~x x+1
~-x x-1
y-~x y+x+1
The derived constants are a compromise between simple expressions, maximum utility,
and minimum number of variables used.
Command line arguments are copied into the upper half of the input buffer,
separated by a space. This allows the code to have a single input parser by using
a pointer-to-func to either getchar() if live, or a getchar() simulator.
A small amount of obfuscation comes from void functions declared int, but missing return.
This is necessary to allow these functions in ternary ?: expressions and paired with && and ||;
but the requisite returns would add symbol count at no benefit to obscurity or functionality.
Function decomposition was mostly chosen to avoid curly braces:
if a for-loop required multiple statements, the body became a new function.
Last, but not least: sharing state via global variables is an ancient and honored
form of obfuscation, and remarkably effective.