Introducing ForthScript - stack-based programming language with automatic memory management and code as data paradigm. Every piece of code in ForthScript is also a piece of data at the same time and vice versa. This is hard to achieve with the syntax we are usually used to. The approach used in LISP is to compose everything from lists, so code and data are represented with lists. We, however, decided, to have a code-as-data paradigm based on resizable arrays. The problem is that arrays don't imply any underlying structure. The only code representation that can live well without structure is stack-based bytecode.
Every single value can be interpreted as an instruction to the ForthScript interpreter, hence complete equivalency between code and data is achieved.
The core of the interpreter is really tiny, but it offers an unlimited power of functional/procedural and reflective programming, as you can manipulate functions and control flow structures as you are manipulating arrays:
# let's create a function to generate pow function for us [$n [$n ([n] n *) ([*] n 1 - *)]@] $gen_pow_func # use it (! is a call) 3 3 gen_pow_func!! to_string writeln # 27
Thanks for cpp-linenoise lib we use, we have REPL for our language, where you can write examples like that without creating files. Here is how REPL session may look like
# [$n [$n ([n] n *) ([*] n 1 - *)]@] $gen_pow_func # 3 3 gen_pow_func!! #
Elements on the stack are printed between [ and ]#.
You can also try to use it as a serialization language (there is a builtin support for casting language primitives to strings and back), but without proper object/tables support it will be kinda quirky.
Anyway, I had already written enough on ForthScript in GitHub README: https://github.com/ForthScript/forthscript (you can also read it from REPL.it of course, but markdown renderer on github works better)
To run ForthScript REPL, you can either click the run button in ForthScript lang repl.it repo or build it manually with instructions in .replit config. You can also run examples by writing
Also, imagine not pasting a simple example of code to this post. How crazy is that! So, here is a quicksort implementation, written in ForthScript with love:
[ $hi $lo $A lo hi < [ A lo hi partition! $p A lo p quicksort_rec! A p 1 + hi quicksort_rec! ] if A ] $quicksort_rec [ $hi $lo $A hi lo + 2 / $mid A mid peek $pivot lo $i hi $j [i j <=] [ [A i peek pivot <] [i 1 + =i] while [A j peek pivot >] [j 1 - =j] while i j >= [ break ] if A i peek $tmp A i A j peek poke A j tmp poke i 1 + =i j 1 - =j ] while j ] $partition [ $A A 0 A len 1 - quicksort_rec!] $quicksort
Special thanks to my only teammate: @amz24856