Merge pull request #78 from xexyl/1991-brnstnd
This commit is contained in:
2 files changed
+99
-88
No files matched your search
+95
-84
@@ -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
|
||||||
|
|||||||
@@ -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);}}
|
||||||
Reference in new issue
Block a user