Re-reimaging colorForth for the Web

June 25, 2022

Brad Nelson / @flagxor

Why still thinking about colorForth?

  • Rich with novel ideas to reduce complexity.
  • Simple enough to fit in my head.

Why the Web?

  • Portable, powerful, relatively simple I/O APIs.
  • JITs and WebAssembly mean it can go fast!
  • It's easy to show people.
  • It let's people run my code without trusting me.

So Many Ideas in colorForth!

Word Sized Words!

  • Most words fit in a single 32-bit machine word.
  • Complexity of strings is elided.
  • Words and numbers are "pre-parsed".

Frequency Coded Words

   0 000    0      10 000 s  8    1100 000 d 16
   0 001 r  1      10 001 m  9    1100 001 v 17
   0 010 t  2      10 010 c 10    1100 010 p 18
   0 011 o  3      10 011 y 11    1100 011 b 19
   0 100 e  4      10 100 l 12    1100 100 h 20
   0 101 a  5      10 101 g 13    1100 101 x 21
   0 110 n  6      10 110 f 14    1100 110 u 22
   0 111 i  7      10 111 w 15    1100 111 q 23

1101 000 k 24    1110 000 8 32    1111 000 ; 40
1101 001 z 25    1110 001 9 33    1111 001 : 41
1101 010 j 26    1110 010 1 34    1111 010 ! 42
1101 011 3 27    1110 011 - 35    1111 011 + 43
1101 100 4 28    1110 100 0 36    1111 100 @ 44
1101 101 5 29    1110 101 . 37    1111 101 * 45
1101 110 6 30    1110 110 2 38    1111 110 , 46
1101 111 7 31    1110 111 / 39    1111 111 ? 47
          

Tagged Words

WORDS
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxx 0000] extension
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxx 0001] interpret (yellow)
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxx 0011] define (red)
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxx 0100] compile (green)
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxx 0111] postpone (cyan)
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxx 1001] comment (white)
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxx 1010] Comment (white)
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxx 1011] COMMENT (white)
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxx 1100] variable (magenta)

NUMBERS
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxH 1000] interpret (yellow)
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxH 0110] compile (green)

BIG NUMBERS
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxH 0010] + [WORD] interpret (yellow)
[xxxx xxxx|xxxx xxxx|xxxx xxxx|xxxH 0101] + [WORD] compile (green)
          

Color Dispatch Table

  • 16 word table (called "spaces" in COLOR.ASM) define what colors do.
  • Vocabulary words and applications can mutate it.
  • A variable (register EDI on Pentium) tracks word being interpreted.
  • Interpreter is dead simple: retreive next word, dispatch on lower 4-bits, repeat.
  • Minimizes plumbing that must live in kernel.

Only two vocabularies

  • forth contains regular words
  • macro contains immediate words
  • cyan words compile rather than execute macros

Unconventional but terse naming

  • or is what's usually called xor since you can live without OR.
  • - is what's usually called invert.

if & -if

  • if doesn't consume its argument!
  • if foo bar then is equivalent to
    dup if foo bar then
  • -if foo bar then is equivalent to
    dup 0< if foo bar then
  • No else, since you can do if ; then to exit.

push & pop

  • >R becomes push
  • R> becomes pop

Fewer Symbols

            0123456789     :;,.@!+-*/?
            abcdefghijklmnopqrstuvwxyz
          
  • < becomes less
  • OR -if

Variable in "Block Space"

  • Variable use space in source var 0
  • Saving and Loading preserve variable state.
  • View current values in source.

Address Register

  • a! and a reference a temporary address register.
  • @+ and !+ read/write and advance.
  • dest a! 0 31 for dup !+ next

Cell Sized Addressing

  • Addresses are in words not bytes.
  • 1+ rather than cell+

Color transitions matter

  • yellow to green triggers literal creation.
  • Seems to match usage of [] in practice often.

Powerful but simple editor

  • Vi like modal editor.
  • Implemented in kernel but easy to expand in code.
  • Clever "gobbling" cursor merges copy / cut / paste / delete.
  • Color encoding complexity kept in editor.

Dispatch Tables

  • Use a word definition as a call table!
  • mylayout pad nop up down left right nop

RainbowForth

  • https://rainbowforth.appspot.com/
  • My attempt at a WebApp!
  • Each Forth word is a function.
  • Terminal done with DOM element manipulation.
  • Boostraps from plaintext Forth.
  • Ignores most colorForth quirks other than color.
  • Encodes color in >128 "special spaces".
  • Incompatible use of blue for ' word.
  • AppEngine datastore used to keep global shared, signed in block state.
  • Editor build in Forth.

RainbowForth Errors

  • Missed out on the radical simplicity of one word, one word.
  • Slow due to non-performant use of JavaScript (was unusable on IE).
  • Should have considered local storage vs hitting network all the time.
  • Should have provided low level graphics.

My Current Attempt, Tint

  • Use Int32Array for heap.
  • Use Asm.js for speed, and eventually blt to canvas / 3d canvas.
  • Put opcodes in a table to re-use them when assembling.
  • Mirror most of colorForth (to start), yielding to JS for I/O.
  • Focus on builting main dispatch table and then implement in high level Forth.
  • Start with a JS editor. Save to local storage, with option to download.

Status

  • Can compile and execute simple words.
  • Theoretically all opcodes complete.
  • JS Editor working.
  • Missing key + graphics bindings.
  • Missing keymap update.
  • Save and load to local storage isn't hooked up to Forth.


flagxor.com
slides

Thank you