RPNCalc
RPNCalc (technically RPNCalc V4) is a Turing-complete, stack-based, dynamically-typed (vaguely *useful*) programming language that originally started off as a calculator on osmarks.net. It has 2 'dialects', a JS-based interpreted dialect and a dialect that compiles to x86-64 on Linux (sometimes referred to as RPNCC - RPNCalc Compiled). Both the dialects have the same syntax, but subtly different semantics.
Language Features
RPNCalc has support for inline lambdas, curried functions and closures. Lambdas can either be constructed in 'forth-style' (with arguments flipped):
(swap; a b -> b a)
or
(a b -> b a)
or 'curried style' (with arguments being popped off the stack one-by-one):
(swap; b -> (a -> b a))
or
(b -> (a -> b a))
Lambdas in RPNCalc return a list that represents their stack in a 'return stack' when they finished executing, which is subsequently merged back into the parent stack. To have support for higher-level functions, when a Lambda's return stack returns a nested lambda, the nested lambda is immediately applied onto the stack.
RPNCalc additionally has support for recursive local definitions, for example:
(def1; code executed upon definition) (def2; def2 is a recursive definition)
The other major part of RPNCalc syntax is the special 'push' operator, which allows the user to avoid the merging process when a function returns, instead pushing a closure to the stack. Here, the dialects differ; if in the JS dialect you push a return stack, each element of the stack is pushed to the parent stack, while in the x86-64 version a pointer to the list is pushed instead. For example, in RPNCC:
(# include list #) [ 1 : 2 : 3 : 4 : 5 : 6 ] '(x -> x 1 +) map
RPNCC StdLib
RPNCC exposes an assembly interface, and through it some useful functions are defined. These functions are grouped into RPNCC modules, namely:
arith
list
bool
mutref
io
arith
exposes the basic arithmetic functions +
, -
, *
and /
list
exposes the 'nil list' ([]
or [
) and the 'cons/pair' operator (:
and ]
)
bool
exposes the comparison operators &=
(equality by reference), ==
(recursive equality), the booleans true
and false
, as well as the 'if-else' branching operator (if-else
or ?:
)
mutref
exposes mutable references, through the <>
operator (construct a mutable reference with a given value) the <<
operator (set a mutable reference to a given value and return the reference) and the >>
operator (extract a value from a mutable reference).
io
exposes the IO operations putchar
, putbyte
, and putint
.