A very concise EsotericProgrammingLanguage, both in form and in implementation (<1k bytes of 68k assembly), one of the zillions of languages designed by WouterVanOortmerssen. False is like ForthLanguage with one-character commands but with control structures replaced by quoted code blocks (first-class command sequences). See it at: http://wouter.fov120.com/false/index.html
It looks like it's more powerful than most esoteric languages.
From the web page:
{ factorial program in false! }
[$1=$[\%1\]?~[$1-f;!*]?]f: { The function itself }
"calculate the factorial of [1..8]: "
ß^ß'0-$$0>~\8>|$
"result: "
~[\f;!.]?
["illegal input!"]?"
"
{ loop demo }
"Factorials of [8..1]: "
9[1-$][$f;!.' ,]#%"
"
{ print primes up to 100 }
99 9[1-$][\$@$@$@$@\/*=[1-$$[%\1-$@]?0=[\$.' ,\]?]?]#
I prefer a dialect which has OVER (^) and /MOD (/) from Forth, and where ? takes both if and else blocks. The primes example then becomes:
99 9[1-$][^^/%[][1-$[%1-$][^.]?]?]#
or far more efficiently:
99 3[^^>][^^/^>[[2+][%2-3]?][%^.%2-3]?]#.2.%
Try it out in a JavaScript interpreter for both variants of False that runs in a web page: http://www.quirkster.com/js/false-js.html. -- IanOsgood
Skeleton key showing equivalent Forth and (stack before -- stack after):
- { comment } ( Forth comment )
- $ DUP ( a -- a a )
- \ SWAP ( a b -- b a )
- % DROP ( a -- )
- @ ROT ( a b c -- b c a )
- ~ NOT (logical inverse) ( a -- ~a )
- [...] push a lambda expression (block) onto the stack ( -- block )
- this is like :NONAME in ANS Forth, and a block is like an execution token (xt)
- The easiest way to implement this is as a simple pointer into the text of the program.
- ? IF execute the block on top of the stack if the flag underneath it is non-zero (true) ( ... st flag block -- ... st ) [block sees ( st -- )]
- the idiom "c$[a]?~[b]?" is equivalent to "c IF a ELSE b ENDIF". Note that the first block sees the duplicated flag when it executes and also must preserve the flag for the second block. Convenience was certainly sacrificed for simplicity of the interpreter here.
- a..z push the address of one of the 26 variables onto the stack ( -- v )
- ; @ fetch contents of variable ( v -- a )
- : ! store value into variable ( a v -- )
- "[...]f:" is like ": f ... ;" in Forth
- ! EXECUTE the block on top of the stack ( st block -- st' )
- "f;!" is like "f" in Forth if f is a colon definition
- +,-,*,/ add, (a b -- a+b), subtract ( a b -- a-b ), multiply ( a b -- a*b ), divide ( a b -- a/b )
- ^ KEY reads one char from stdin and pushes it on the top of stack ( -- a )
- ß (beta) flushes stdin and stdout and is said to be necessary when "we get input on the same console as the output"
- This may be a quirk of its original AmigaComputer implementation
- Possibly. I didn't remember quirks like this with Amiga CON: I/O that were much different than Unix buffering semantics, but maybe I've just forgotten over the years.
- In Portable False beta is replaced by "B"
- ' [CHAR] parse next character and push its ASCII value ( -- a )
- > greater than ( a b -- a>b )
- | OR ( a b -- a|b )
- " parse string until matching " and print it to stdout (like ." in Forth, but is able to cross lines to capture newlines)
- . print top of stack to stdout as a number ( a -- )
- # WHILE execute the top block while the next block down evaluates to non-zero ( st cond-block body-block -- st' ) [cond-block does ( st -- st' flag ) and body-block does ( st -- st' )]
- , EMIT print the top of stack to stdout as a character (a -- )
Very nice summary, thanks. You're welcome! --
IanOsgood
I've recently been messing with dc [DeeCee], and False is quite a bit like it, but False is more useful and less esoteric as a programming language... -- JesseMillikan
CategoryProgrammingLanguage