a stack-based programming language
"INTERCAL allows only 2 different types of variables, the 16-bit integer and the 32-bit integer." - From the INTERCAL Programming Language Revised Reference Manual
STCK (pronounced stick) is is a programming language inspired by Forth. Variables are never declared, values is just placed on a global stack. Syntax is minimal.
The only supported data-type used to be 32-bit integers, but now we handle all that with Church encoding.
You'll need the .NET 7.0 SDK to compile the STCK interpreter.
When the compiler is installed, navigate to the folder /Stck.Console
and run:
dotnet restore
dotnet build
dotnet run
This should compile and launch the interactive interpreter. Execute quit
to get out.
"Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy." - Alan J. Perlis
Pushing symbols
Write a word, any word, and press enter. You now have a symbol on the stack.
$> any-word
[any-word]
Write another one, and then another.
$> another-one and-then-another
[any-word another-one and-then-another]
You now got three symbols on the stack. What can I do with those you might ask, and that would be a nice segway into...
Working with the stack
"A goal of a good Forth programmer is to minimize the use of these words, since they are only moving data around instead of doing useful work." - From the The OLPC Wiki
.
will drop one element from the stack.
[any-word another-one and-then-another]
$> .
[any-word another-one]
swap
will swap the two upmost elements on the stack.
[any-word another-one]
$> swap
[another-one any-word]
dup
will duplicate the topmost element on the stack (TOS)
[another-one any-word]
$> dup
[another-one any-word any-word]
2dup
will duplicate the two topmost elements on the stack.
[another-one any-word any-word]
$> 2dup
[another-one any-word any-word any-word any-word]
Did I mention that you can drop several elements at once?
[another-one any-word any-word any-word any-word]
$> ...
[another-one any-word]
over
will copy the second element on the stack.
[another-one any-word]
$> over
[another-one any-word another-one]
rot
will move the third element to the top of the stack.
[another-one any-word another-one]
$> rot
[any-word another-one another-one]
empty
will check if the stack is empty, and push the result onto the stack as a Church encoded boolean.
[any-word another-one another-one]
$> empty
[any-word another-one another-one [. swap]]
$> clear
[]
$> empty
[[.]]
In addition, the Forth documentation has a good description of different stack operators, along with reference implementations for less basic operators.
Math
"For every epsilon>0 there is a delta>0 such that whenever |x-x_0|<delta, then |f(x)-f(x_0)|<epsilon." - From Wikipedia
All numerals are Church encoded and the following operators are supported: +
(addition), -
(subtraction), *
and %
(modulo). All operators perform on the two upmost elements on the stack, and push the result back on the stack as one number.
[]
$> 1 1 +
[2]
Numerals and booleans are "unchurched" for readability. This can be turned off with the command church
.
[2]
$> church
[[app || << rot rot << swap rot dup rot [app [app || swap rot dup swap [.]]] [app [app || swap rot dup swap [.]]]]]
You can turn on unchurching again with the command unchurch
. Reading stdlib.md might help if that didn't make a lot of sense.
In addition the following predicates are supported for comparing numbers: is-zero
, <=
(less or equal), >=
(greater or equal) and =
(equal).
Booleans
Booleans are also Church encoded, and again stdlib.md is your friend. true
is true and false
is false.
The following boolean operators are supported: not
(not), and
(and), or
(or), xor
(xor), <-
(left implication), ->
(right implication) and <->
(equivalence).
Anonymous stacks (Quotations)
"Anonymous stacks gives STCK the power of lambda functions™" - Anonymous STCK developer
Chunks of STCK code can be pushed to the stack inside of anonymous stacks.
[]
$> [false not]
[[false not]]
Note how false
and not
wasn't executed. At a later time, the contents of an anonymous stack can be applied to the stack using app
.
[[false not]]
$> app
[true]
Anonymous stacks can be nested.
$> [this [is [nested]]]
[[this [is [nested]]]]
$> app
[this [is [nested]]]
$> app
[this is [nested]]
$> app
[this is nested]
A different set of stack operators work on anonymous stacks.
||
(concat) will concatenate two anonymous stacks.
$> [a b] [c d] ||
[[a b c d]]
|
(chop) will chop off the first element of the anonymous stack into a new anonymous stack.
$> [a b c] |
[[a] [b c]]
<<
(ontop) pushes an element to the front of another anonymous stack.
$> [last] first <<
[[first last]]
>>
(ontail) pushes an element to the end of another anonymous stack.
$> [last] first >>
[[last first]]
Conditionals
Conditionals follow the good old then-else-if construct: <a boolean> [this anonymous stack will be applied if true] [this anonymous stack will be applied if false] ?
[]
$> true [this anonymous stack will be applied if true] [this anonymous stack will be applied if false] ?
[this anonymous stack will be applied if [.]]
[]
$> false [hot] [or-not] ?
[or-not]
To be precise ?
is a subroutine that pops three elements from the stack, considers the last one to be a boolean, and applies either one or the other of the arguments.
Subroutines
"What is a definition? Well classically a definition was colon something, and words, and end of definition somewhere." - Chuck Moore
Subroutines are declared by using #
:
[5 +] add-five #
$> 2 add-five
[7]
Comments
"Due to INTERCAL's implementation of comment lines, most error messages are produced during execution instead of during compilation." - From the INTERCAL Programming Language Revised Reference Manual
```
indicates the start and end of a comment. This is useful, as it enables STCK-programs to be embedded in markdown files.
[]
$> ```This is a comment!```
[]
Utility functions
The interpreter defines a couple of utility functions, not strictly part of the STCK language.
hprint
prints the content of the heap. This will list all declared subroutines.
quit
exits the interpreter.
load
loads external STCK-programs.
hyperstck - A hypermedia-driven evaluator for the Stck programming language
REST-STCK - Arbitrary Computation as a Service (ACaaS)