Skip to content

Commit

Permalink
Merge pull request #39 from mossprescott/scheme
Browse files Browse the repository at this point in the history
Implement a Scheme REPL based on the Ribbit VM
  • Loading branch information
mossprescott authored Mar 30, 2024
2 parents 33e4ee3 + 8368b5e commit e8b7147
Show file tree
Hide file tree
Showing 35 changed files with 8,243 additions and 325 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
pip install -r requirements.txt
- name: Test with pytest
run: |
pytest -v --doctest-modules
pytest -v --doctest-modules --ignore alt/scheme/ribbit
- name: Lint with flake8
run: |
pip install flake8
Expand Down
31 changes: 26 additions & 5 deletions alt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,29 @@ See each module for instructions.

## Enhanced chips

Four alternative implementations use more or less chip hardware to make programs run faster, or to fit larger programs in ROM:
Four alternative implementations use more or less chip hardware to make programs run faster, or to
fit larger programs in ROM:

[alt/sp.py](sp.py) adds instructions for pushing/popping values to/from the stack, making programs more compact.
[alt/sp.py](sp.py) adds instructions for pushing/popping values to/from the stack, making programs
more compact and efficient.

[alt/threaded.py](threaded.py) adds lightweight CALL/RTN instructions, enabling a very compact "threaded interpreter" translation, which runs a little slower.
[alt/threaded.py](threaded.py) adds lightweight CALL/RTN instructions, enabling a very compact
"threaded interpreter" translation, which runs a little slower.

[alt/shift.py](shift.py) adds a "shiftr" instruction, and rewrites "push constant 16; call Math.divide" to use it instead; also a more efficient Math.multiply using shiftr.
[alt/shift.py](shift.py) adds a "shiftr" instruction, and rewrites
"push constant 16; call Math.divide" to use it instead; also a more efficient Math.multiply using shiftr.

[alt/eight.py](eight.py) is, finally, a _smaller_ CPU, by using an 8-bit ALU and 2 cycles per instruction.

[alt/big.py](big.py) has a single, flat memory space, with maximum RAM and the ability to read
data from ROM (and code from RAM.) This is much more flexible and realistic, but adds a cycle to
fetch each instruction from the shared memory system. Moving static data to ROM can dramtically
improve code size and performance, but because the computer uses character-mode graphics, these
metrics don't provide a direct comparison (even if you did port the VM and OS, which I haven't.)
This architecture is intended to support more sophisticated languages (e.g. BASIC, Scheme, or Forth),
and interactive programming.


## Enhanced compiler/translators

These implementations all use the standard CPU, and try to generate more efficient code for it:
Expand All @@ -30,6 +43,12 @@ local variables and expression evaluation, reserving the stack only for subrouti
[alt/reduce.py](reduce.py) adds an optimization phase after parsing and before the normal compiler runs, which
replaces certain function calls with lower-overhead "reduced" alternatives.


## Alternative languages

[alt/scheme](scheme/) provides a compiler and REPL for the Scheme language (circa R4RS), using the "big" architecture.


## Results

| Location | Nands | ROM size | Cycles per frame | Cycles for init |
Expand All @@ -39,10 +58,12 @@ replaces certain function calls with lower-overhead "reduced" alternatives.
| [alt/threaded.py](threaded.py) | 1,549 (+23%) | 8,100 (-68%) | 49,600 (+20%) | 173,750 (+34%) |
| [alt/shift.py](shift.py) | 1,311 (+4%) | 26,050 (+1%) | 19,800 (-52%) | _same_ |
| [alt/eight.py](eight.py) | 1,032 (-18%) | _same_ | +100% | +100% |
| [alt/big.py](big.py) | 1,448 (+14%) | ? | ? | ? |
| [alt/lazy.py](lazy.py) | _same_ | 23,650 (-8%) | 37,300 (-10%) | 111,000 (-14%) |
| [alt/reg.py](reg.py) | _same_ | 20,900 (-19%) | 19,150 (-54%) | 59,000 (-54%) |
| [alt/reg.py](reg.py) | _same_ | 18,200 (-29%) | 12,450 (-70%) | 55,250 (-57%) |
| [alt/reduce.py](reduce.py) | _same_ | 27,350 (+6.5%) | 20,300 (-51%) | _same_ |


**ROM Size** is the total number of instructions in ROM when Pong is compiled and translated
from the Jack source.

Expand Down
Loading

0 comments on commit e8b7147

Please sign in to comment.