prosper/README.md

87 lines
1.9 KiB
Markdown
Raw Permalink Normal View History

2021-02-21 17:22:08 +00:00
# Prosper
Prosper is a Forth-like stack-based language. While taking specific influence from Forth, it does not attempt to emulate or implement the ANS Forth standards.
Currently, the language is entirely interactive -- to explore, simply run `go run .` in the root of this project and an interactive session will begin.
## Syntax
Prosper is stack-based, as mentioned, so all the standard stack semantics are present:
```forth
2021-02-21 17:22:08 +00:00
> 1 2 3 4 + * -
ok
> .
-13 ok
```
New words can be defined using `: ;`:
```forth
2021-02-21 17:22:08 +00:00
> : SQUARE DUP * ;
ok
> 10 SQUARE .
100 ok
```
It has a single loop construct, `DO LOOP`:
```forth
2021-02-21 17:22:08 +00:00
> : TOFIVE 5 0 DO I . LOOP ;
ok
> TOFIVE
0 1 2 3 4 ok
```
Branches using `IF ELSE THEN` work:
```forth
2021-02-21 17:22:08 +00:00
> : EMOJI 0 < IF 128201 EMIT ELSE 128200 EMIT THEN ;
ok
> 100 EMOJI
📈 ok
> -100 EMOJI
📉 ok
```
2021-02-22 21:55:33 +00:00
Here's a Fibonacci implementation:
2021-02-28 18:21:27 +00:00
```forth
2021-02-22 21:55:33 +00:00
> : FIB 2DUP + ;
ok
> : FIBN 0 1 ROT 1 DO FIB ROT DROP LOOP SWAP DROP ;
ok
> 10 FIBN .
55 ok
```
2021-02-26 02:04:35 +00:00
Propser also has a basic off-stack memory model using variables, constants, and pointers:
2021-02-28 18:21:27 +00:00
```forth
2021-02-25 02:27:52 +00:00
> VARIABLE FOO
ok
> 10 FOO !
ok
> FOO @
ok
> .
10 ok
2021-02-26 02:04:35 +00:00
> 100 CONSTANT HUNDRED
ok
> HUNDRED HUNDRED * .
10000 ok
2021-02-25 02:27:52 +00:00
```
2021-02-21 17:22:08 +00:00
And, of course, it knows how to quit:
```forth
2021-02-21 17:22:08 +00:00
> BYE
bye
```
## Future Plans
2021-02-28 18:21:27 +00:00
* Rearchitect how compilation works -- currently, non-built-in words are stored as raw sets of strings, which means in the case of things like IF/ELSE/THEN we have to re-parse the tree and use the IFStack to track the parse status. It'd be better to compile to some intermediate representation so that the compiler can store the JMP locations inline and execution just flows from instruction to instruction instead of re-parsing the entire descent-tree every time.
* More looping constructs (`EXIT`, `?DO`, and `WHILE` would be nice).
* Add ways for Prosper words to hook into the input/output streams (probably required for self-hosting a prosper compiler in prosper, which is a long way off).