Merge pull request #78 from xexyl/1991-brnstnd

This commit is contained in:
Landon Curt Noll authored and GitHub committed 2023-03-17 13:33:19 -07:00
commit 8c1bdd4e23
2 files changed
+99 -88

No files matched your search

+95 -84
View File
@@ -7,63 +7,74 @@
make all make all
NOTE: This entry might not compile when using modern compilers. NOTE: [Cody Boone Ferguson](/winners#Cody_Boone_Ferguson) fixed this for modern
systems. There were two invalid operands to binary expression (`char *` and
`void` and `int` and `void`) to resolve and a feature of the C pre-processor
which no longer works had to be changed as well. In particular `#define C =G` in
a macro to make `+=` and similar operators no longer works. The invalid operands
to binary expressions were resolved with the comma operator. Thank you Cody for
your assistance!
### To run
### Try:
./brnstnd < sorta.i2+2 ./brnstnd < sorta.i2+2
./brnstnd < sorta.iwhosort
See also the other `sorta.*` files.
## Judges' comments ## Judges' comments
For info on more examples, read the sorta.README file. For info on more examples, read the sorta.README file.
The author wished to win the "most useful program" award and The author wished to win the "most useful program" award and
documented this in the source code. The judges were unmoved documented this in the source code. The judges were unmoved
by this blatant attempt to influence the contest and rejected by this blatant attempt to influence the contest and rejected
this idea... so we gave it the Best of Show award instead!! this idea... so we gave it the Best of Show award instead!!
NOTE: One should remove the final trailing newline to obtain the NOTE: One should remove the final trailing newline to obtain the
original source file. This step is not needed to compile original source file. This step is not needed to compile
this entry. this entry.
To have a chance to compile under a modern CPP, we had to To have a chance to compile under a modern CPP, we had to
replace `#D` with `#define`. replace `#D` with `#define`.
## Author's comments ## Author's comments
This is an interpreter for the programming language SORTA, a systems This is an interpreter for the programming language SORTA, a systems
and numerical programming language with features sorta from C, sorta and numerical programming language with features sorta from C, sorta
from FORTH, and sorta from Ada. from FORTH, and sorta from Ada.
SORTA lets you manipulate files and spawn programs easily, has bitwise SORTA lets you manipulate files and spawn programs easily, has bitwise
operators, and gives you absolutely brilliant error messages like '?' operators, and gives you absolutely brilliant error messages like '?'
(that's the C bit). SORTA programs work with a stack (that's the FORTH (that's the C bit). SORTA programs work with a stack (that's the FORTH
bit)---actually two stacks, one for integers and one for strings. And bit)---actually two stacks, one for integers and one for strings. And
all SORTA operations are strongly typed, detect practically any failure, all SORTA operations are strongly typed, detect practically any failure,
and garbage-collect (that's the Ada bit). and garbage-collect (that's the Ada bit).
SORTA also contains features you might not expect from such a small SORTA also contains features you might not expect from such a small
interpreter: arbitrary-length string input and concatenation, for interpreter: arbitrary-length string input and concatenation, for
instance, not to mention infinite-depth tail recursion. instance, not to mention infinite-depth tail recursion.
SORTA ignores its arguments (though it makes them available to the SORTA ignores its arguments (though it makes them available to the
script); it takes all commands, character by character, from its script); it takes all commands, character by character, from its
standard input. Unrecognized commands are repeated with a ?. standard input. Unrecognized commands are repeated with a ?.
SORTA maintains an ``i stack'' for integers and an ``s stack'' for SORTA maintains an ``i stack'' for integers and an ``s stack'' for
strings. It also keeps track of ``programs,'' one for each character. strings. It also keeps track of ``programs,'' one for each character.
Operations are silently ignored if the relevant stacks are too low, Operations are silently ignored if the relevant stacks are too low,
except as noted for s, S, and !. If the i stack or s stack (or the stack except as noted for s, S, and !. If the i stack or s stack (or the stack
of buffered macro commands) grows too high, SORTA will exit silently of buffered macro commands) grows too high, SORTA will exit silently
with exit code 2. (Compile parameter -Do=250 controls what ``too high'' with exit code 2. (Compile parameter -Do=250 controls what ``too high''
means; you should not make o larger than 250.) I don't think it's means; you should not make o larger than 250.) I don't think it's
possible to crash the interpreter. possible to crash the interpreter.
Here, then, is the SORTA programming language. All non-digits delimit Here, then, is the SORTA programming language. All non-digits delimit
numeric constants. Spaces and newlines are ignored except as numeric numeric constants. Spaces and newlines are ignored except as numeric
delimiters. delimiters.
Basic operations: Basic operations:
q: quit q: quit
number: push that number on top of the i stack number: push that number on top of the i stack
@@ -112,7 +123,7 @@
fails, any operation involving current members of the s stack has fails, any operation involving current members of the s stack has
undefined effects, and -1 is pushed onto the i stack. undefined effects, and -1 is pushed onto the i stack.
High-level language operations: High-level language operations:
:x: copy the top of the s stack into a program labeled by character x :x: copy the top of the s stack into a program labeled by character x
=x: pop the top of the i stack. If it was nonzero, execute the program =x: pop the top of the i stack. If it was nonzero, execute the program
@@ -120,55 +131,55 @@
will merge with any digits after =x; in that case you usually want will merge with any digits after =x; in that case you usually want
to add a space at the end of the program. to add a space at the end of the program.
Common idioms: To drop the top of the s stack, ld. To do a <, 1s>. To Common idioms: To drop the top of the s stack, ld. To do a <, 1s>. To
unconditionally execute the program labeled by character x, 1=x (or any unconditionally execute the program labeled by character x, 1=x (or any
nonzero number followed by =x). To print the top of the i stack nonzero number followed by =x). To print the top of the i stack
non-destructively, #` (or #$ if you don't want the newline). To non-destructively, #` (or #$ if you don't want the newline). To
subtract, _+. To do mod or and or any of the other missing operations, subtract, _+. To do mod or and or any of the other missing operations,
combine the available operations as illustrated below. To introduce a combine the available operations as illustrated below. To introduce a
comment, [ this is a comment string which is promptly eliminated ]ld. comment, [ this is a comment string which is promptly eliminated ]ld.
SORTA's requirements: it wants fork(), execvp(), open(), SORTA's requirements: it wants fork(), execvp(), open(),
close(), dup(), pipe(), and wait(), so it obviously won't even compile close(), dup(), pipe(), and wait(), so it obviously won't even compile
on a non-UNIX machine. It also assumes that you have a size-256 on a non-UNIX machine. It also assumes that you have a size-256
character set and that the characters between '0' and '9' are exactly character set and that the characters between '0' and '9' are exactly
the digits in order. It does *not* depend on ASCII, despite the code the digits in order. It does *not* depend on ASCII, despite the code
appearance. Also note that SORTA does not attempt to declare malloc(), appearance. Also note that SORTA does not attempt to declare malloc(),
so you will get some warnings about illegal pointer combinations. Also so you will get some warnings about illegal pointer combinations. Also
note that there are unreached statements in SORTA. note that there are unreached statements in SORTA.
While the program source of course depends highly on #defines for While the program source of course depends highly on #defines for
obfuscation, I like to think that this code has those little touches, obfuscation, I like to think that this code has those little touches,
those professionally sharpened edges that mark true software those professionally sharpened edges that mark true software
engineering. Observe, for instance, how i and s are the string and engineering. Observe, for instance, how i and s are the string and
integer stacks respectively. It's these little things that make you integer stacks respectively. It's these little things that make you
feel at home in an otherwise utterly useless piece of code. They're feel at home in an otherwise utterly useless piece of code. They're
what make an obfuscation work. what make an obfuscation work.
The character pool (``I'' after cpp) makes it rather painful to The character pool (``I'' after cpp) makes it rather painful to
see the effect of commands at a glance. I can just imagine people see the effect of commands at a glance. I can just imagine people
spending hours bouncing between the pool and the rest of the code, spending hours bouncing between the pool and the rest of the code,
or accidentally changing the pool without realizing its importance. or accidentally changing the pool without realizing its importance.
Without documentation and example scripts, someone would find it Without documentation and example scripts, someone would find it
a challenge to figure out what the arrays are used for, let alone a challenge to figure out what the arrays are used for, let alone
that SORTA is a scripting language. that SORTA is a scripting language.
Another nice feature is that the SORTA language itself encourages Another nice feature is that the SORTA language itself encourages
you to write not merely obfuscated but plain incomprehensible you to write not merely obfuscated but plain incomprehensible
scripts (like the examples below---after working with the language scripts (like the examples below---after working with the language
for a while, I guess I can read it pretty easily, but I also think for a while, I guess I can read it pretty easily, but I also think
FORTH is a beautiful language). The numbers running around FORTH is a beautiful language). The numbers running around
everywhere will make people think of ASCII, even though the code is everywhere will make people think of ASCII, even though the code is
not ASCII-dependent. What's your first thought when you see not ASCII-dependent. What's your first thought when you see
several arrays[256]? This is pretty standard obfuscation otherwise. several arrays[256]? This is pretty standard obfuscation otherwise.
I like the way that unbalanced macro braces can throw off the I like the way that unbalanced macro braces can throw off the
reader in ``if(c>0){y+1]=z[c];'', and I had fun covering the reader in ``if(c>0){y+1]=z[c];'', and I had fun covering the
alphabet with #defines, but that's nothing special. alphabet with #defines, but that's nothing special.
Possible future extensions to SORTA include string extraction and Possible future extensions to SORTA include string extraction and
matching, reading from files into strings, and encrypting the string matching, reading from files into strings, and encrypting the string
pool to further confuse the judges. I don't think I can fit this into pool to further confuse the judges. I don't think I can fit this into
the size limit, unfortunately. the size limit, unfortunately.
Copyright (c) 1991, Landon Curt Noll & Larry Bassel. Copyright (c) 1991, Landon Curt Noll & Larry Bassel.
All Rights Reserved. Permission for personal, educational or non-profit use is All Rights Reserved. Permission for personal, educational or non-profit use is
+4 -4
View File
@@ -33,10 +33,10 @@ f(c>='0'&&c<='9'){f(!n)N=0;n=1;e=10*e+(c-'0')h}n=0;J(39,m
sprintf(d=M(13),"%d",e)) sprintf(d=M(13),"%d",e))
J(37,q&&puts(g))J(34,q&&printf("%s",g))J(27,H(p,_,s))O('[',']')J(56,f(p){c=e;N=c;})J(2,m--p)J(10,N=a)J(4,f(q){N=L(g);X(S--]);})J(1,f(q){S+1]=T(g);++q;})J(53,m J(37,q&&puts(g))J(34,q&&printf("%s",g))J(27,H(p,_,s))O('[',']')J(56,f(p){c=e;N=c;})J(2,m--p)J(10,N=a)J(4,f(q){N=L(g);X(S--]);})J(1,f(q){S+1]=T(g);++q;})J(53,m
e>=0&&e<a&&(d=T(A[u]))) e>=0&&e<a&&(d=T(A[u])))
J(54,q>1&&(--q,U(S+1],i+q)))J(5,q&&p>1&&(_-1]=open(g,_-1],e),--p,X(S--])))J(47,m J(54,q>1&&(--q,U(S+1],i+q)))J(5,q&&p>1&&(_-1]=open(g,_-1],e),--p,X(S--]),1))J(47,m
close(u)) close(u))
J(26,m(e=dup(e)))O('"','"')J(51,H(q,S,i))J(49,N=fork())J(12,wait(&N)+1||(e=-1))J(68,{++p;pipe(s+p++)==-1&&(e=-1);})F('q',v J(26,m(e=dup(e)))O('"','"')J(51,H(q,S,i))J(49,N=fork())J(12,wait(&N)+1||(e=-1))J(68,{++p;pipe(s+p++)==-1&&(e=-1);})F('q',v
0) 0)
F('=',W{R x;f(m u)f(x=l){k+=n=L(x);V;Y(*x)K[--k]=*x++;k+=n;n=0;}b})J(15,f(q)W{l&&X(l);l=T(g);b})J(33,f(c=q){*i=g;g=0;Y(--q&&**(i+q))g++;f(q){N=execvp(*i,i+q+1);q=c;}})J(38,P F('=',W{R x;f(m u)f(x=l){k+=n=L(x);V;Y(*x)K[--k]=*x++;k+=n;n=0;}b})J(15,f(q)W{l&&(X(l),1);l=T(g);b})J(33,f(c=q){*i=g;g=0;Y(--q&&**(i+q))g++;f(q){N=execvp(*i,i+q+1);q=c;}})J(38,P
c&&(e/C)) c&&(e/=G))
J(35,Q=e>G)F('+',Q+C)J(42,Q*C)J(41,Q=~(e&G))J(57,m(e=-e))J(3,)F('\n',)putchar(c);puts(73+I);}} J(35,Q=e>G)F('+',Q+=G)J(42,Q*=G)J(41,Q=~(e&G))J(57,m(e=-e))J(3,)F('\n',)putchar(c);puts(73+I);}}