# Forth Playground
## Current Status
Paused.
I plan to overhaul two features, as the existing design is limiting and lacks a sense of purity:
- Lambda functions, referred to as quotations in the Forth universe
- Local variables
## Overview
This project bootstraps Forth programming language and implements the following primitives: `VARIABLE`, `ARRAY`, `CREATE`, `DOES>`, `IF`, `BEGIN`, `AGAIN`, `VALUE`, `DEFER`, etc. Infused Ruby-like syntax.
Example:
```forth
DEF COUNTER
CREATE ,
RETURN DUP 1 SWAP +! @
END
0 COUNTER AUTOPK
AUTOPK PUTS # => 1
AUTOPK PUTS # => 2
DEF DIP SWAP >R EXECUTE R> END
3 2 { 7 * } DIP PRINT SPACE PUTS # => (in the order of print/puts) 2 3 7 * = 2 21
DEF TIMES
BEGIN
OVER EXECUTE
1 - DUP ZERO? UNTIL
2DROP
END
{ DUP PRINT SPACE } 5 TIMES CR # => 5 4 3 2 1
HERE 113 , 127 , 2 VECTOR CONST NUMBERS
{ PRINT SPACE } NUMBERS EACH CR # => 127 113
```
URL: https://github.com/oneearedrabbit/forth-playground
## Motivation
Forth was a groundbreaking discovery by Chuck Moore in 1970s. It enabled computational algorithms to run significantly faster than before while maintaining the readability of software programs. Forth strikes a delicate balance between performance and general software development principles.
More importantly, Forth nowadays helps to release an emotional attachment to familiar programming languages and encourages to embrace new (or old) approaches to software development, fostering a sense of creativity and innovation.
Bootstrapping a generic Forth system is straightforward, implying that it can run on any architecture, on any platform, albeit with a slight performance penalty.
This project uses `ArrayBuffer` as its memory model, making it a perfect fit for Forth, as it allows direct memory access and manipulation. The design draws inspiration from eForth with a touch of Ruby syntax.
The interpreter is implemented in the following loop:
```javascript
const start = i32[HERE_CELL];
i32_comma(cfa(find("EVALUATE")));
i32_comma(cfa(find("BRANCH")));
i32_comma(start);
...
let [ip, np] = next1(start);
do {
[ip, np] = table[i32[ip >> 2]](ip, np);
} while (ip >= 0);
```