x86-64 : color ] Forth
┄────────────────────┄
   [ May 24, 2024

Why : color ] Forth ( ?
┄─────────────────────┄
• Dialect of Forth invented
  by Chuck Moore circa 1999
• Many sub-variants,
  all use color "tags" to dispatch
• Emphasis on making Forth even simpler!

Color Conventions
┄───────────────┄
   : define
   [ execute
   ] compile
   { postpone
   % tag
   ~ variable
   ( comment

An Example
┄────────┄
: square ] dup * ;
: cube ] dup square * ;
[ 2 cube .
  ==> 8

Design Approach
┄─────────────┄
• Keep it simple
  ◦ Really understand it
• Make sure it's usable as more than a toy
  ◦ Could I write an eww like browser in it?
• Write mostly Forth ASAP
• Names are hard : cf ( for now

System Goals
┄──────────┄
• Runnable on Windows, but keep the complexity out!
• Design with an eye to make it standalone with UEFI boot
• Defer register convention decisions to Forth
• Use x32 addressing (32-bit addresses, 64-bit data)

Language Goals
┄────────────┄
• Try to use Chuck's quirks as bearable:
  ◦ : - ] invert
  ◦ : or ] xor
  ◦ : if ( use x86 zero flag, no stack effect
  ◦ : -if ( use x86 sign flag, no stack effect
  ◦ : push ] >r : pop ] r>
  ◦ : @ ! ( etc. use word sized indexing
  ◦ Use A register, : @+ !+
  ◦ Emit literals on [ immediate ] to green

How Chuck Built his : color ] Forth ( I think
┄─────────────────────────────────────┄
• Write editor + core in ASM
• Build up rest of the system

My Steps
┄──────┄
• Devise a text syntax (to allow git + vim)
• Write a converter (in and out)
• Write a Vim syntax plugin
• Bootstrap from "minimal colorForth"
• Write the rest in colorForth
• Provide "syscalls"
• Write an editor

: color ] Forth ( "words"
┄───────────────────┄
STRINGS:
  wwww wwww wwww wwww wwww wwww wwww tttt
NUMBERS:
  nnnn nnnn nnnn nnnn nnnn nnnn nnnH tttt
H = hex/decimal
t = tag
n = number bits, to be sign extended
w = word bits "shannon encoded"

Text Conventions
┄──────────────┄
 : define   : define
 [ execute  [ execute
 ] compile  ] compile
 { postpone { postpone
 < tag      % tag
 ~ variable ~ variable
 ( comment  ( comment
┄─────────────────────┄
#decimal  $hex  &screen
 % word-sized-value
Separ`ate Long`ish words

Tag  Syntax Element      Color
┄─┄  ┄────────────┄      ┄───┄
 15  Commented Number    #White / $White
 14  Display Macro       % Blue
 13  Compiler Feedback   ^ Grey
 12  Variable            ~ Magenta
 
 11  COMMENT (caps)      (^^ (White) Obsolete
 10  Comment             (^ (White) Obsolete
  9  comment (lower)     White
  8  Interpreted Number  [ #Yellow $Yellow
 
  7  Compile macro call  { Cyan
  6  Compile number      ] #Green / $Green
  5  Compile big number  ] Green (unsupported)
  4  Compile forth word  ] Green
 
  3  Define forth word   : Red
  2  Interp big number   [ Yellow (unsupported)
  1  Interp forth word   [ Yellow
  0  Word extension      ( color of preceding word )

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

Converter
┄───────┄
• 253 lines of Python
• More complex than I'd like!
• Supports Chuck and Howerd's images
• Forward and backward conversion
  ◦ To allow for check-in with Git

|  usage: colorize [-h] [-d] [filename]
|  
|  Convert back and forth from colorForth encoding
|  
|  positional arguments:
|    filename      filename to process OR - for stdin
|  
|  optional arguments:
|    -h, --help    show this help message and exit
|    -d, --decode  decode instead of encode

VIM Coloring
┄──────────┄
• Vi-improved (my usual text editor)
• Developed by Bram Moolenaar
• Supports regular expression
  based syntax highlighting
• Look for the formatting tags and color!

Bootstrapping
┄───────────┄
• Start with C-interpreted [ execute ( words
• Make machine code [ execute ( words
  work via : c2forth ( thunk
• Make ] compiled ( words
  work via : ,compile ( thunk
• Make ] compiled numbers ( words
  work via : literal ( thunk
• Build up core words and macros
• Implement color words and dispatch
• Transition into machine code interpreter

Only executable bootstrap words:
[ 1, 2, 3, load thru forth macro
[ Numbers
For Debugging:
[ here .

      case 1: /* execute */
        addr = find(name, FORTH_DICT);
        if (addr) {
          CALL(addr);
        } else {
          switch (name) {
            case 0xd3f80000: /* 1, */ *HP++ = *SP++; break;
            case 0xd5f80000: /* 2, */ *HP2++ = *SP++; break;
            case 0xd7f80000: /* 3, */ *HP2++ = *SP; *HP++ = *SP++ >> 16; break;
            case 0xa1ae0000: /* load */ if (load(*SP++)) return 1; break;
            case 0xb1896400: /* forth */ DICT = &FORTH_DICT; break;
            case 0x8ac84c00: /* macro */ DICT = &MACRO_DICT; break;
            case 0xc8828000: /* here */ *--SP = (uint64_t) HP; break;
            case 0xea000000: /* . */ PrintNumber(*SP++); break;
            default: break;
          }
        }
        break;

Registers
┄───────┄
• RAX - tos
• RSI - stack pointer
• RDI - code heap pointer
• R8 - internal vars - parked sp
  ◦ R8 +8 - parked hp
  ◦ R8 +16 - active dictionary
  ◦ R8 +24 - forth dictionary
  ◦ R8 +32 - macro dictionary
  ◦ RCX - temp
• RDX - "a" register

Memory Map
┄────────┄
$8000000      - BASE
$80000FF      - Data Stack ↑
$8000100 (0)  - Parked Data Stack Pointer
$8000108 (1)  - Parked Heap Pointer
$8000110 (2)  - Pointer to active vocabulary
$8000118 (3)  - Pointer to end of FORTH dictionary
$8000120 (4)  - Pointer to end of MACRO dictionary
$8000128 (5)  - RESERVED
$8000130 (6)  - lastc (last color) (after bootstrap)
$8000138 (7)  - @nope (notfound) (after bootstrap)
$8000140 (8)  - RESERVED
$8000148 (9)  - Sleep
$8000150 (10) - PostMessage
$8000158 (11) - PrintNumber
$8000160 (12) - PopEvent
$8000168 (13) - Write
$8000170 (14) - Read
$8000178 (15) - ShellCommand
$8000300      - Macro Vocabulary
$8010000      - Forth Vocabulary
$8020000      - Heap
$8100000      - Loaded Blocks
$9000000      - IO Area
$9000100      - Screen

Dictionary
┄────────┄
0, addr, word, addr, word, addr, word
                                   ↑
0, addr, word, addr, word        MDICT
                       ↑
                      FDICT 
                       ↑
                      DICT

Editor
┄────┄
• Modal - ispired by mix of vi and Chuck's
• Word at a time entry
• Color toggle, search
• Clipboard is a stack!

? 1 2 3 4 5 6 7 8 9 0 - + BACK
   q w e r t y u i o p @ ! *
    a s d f g h j k l ; ' ENTER
     z x c v b n m , . /
          SPACE

░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ✀
 🌈⚾🏳️‍🌈 % r ~ t [ y ( u : i ] o { p ( ░ ░ ░
    ░ ░ ░🔴🔍← ↓ ↑ → ░ ░ ESC
     ░ ✀🗐⎘ ░⇇ ❏🔵⇉ ░
          ESC

Variables
┄───────┄
• Magenta Variables ~ foo (  %0
  ◦ Place variable in the source block
  ◦ Makes moving things in editor break
• Code Variables : foo [ here 0 , ] ;
  ◦ Places variables in a separate data heap
  ◦ Allows a resetable default

Flag Conditionals
┄───────────────┄
• HARD to get them to stick in your head
• Sometimes nice when they leave the stack alone
• But hard to compose several

] x @ 3 or drop if ( x isn't 3 ] then
] x @ ? if ( x is non-zero ] then
] x @ ? -if ( x is negate ] then
] x @ dup 3 or drop if
   ] dup 4 or drop if
     ( x isn't 3 or 4
   ] then
] then drop
] x @ -3 + -if ( x-3 is negative, gotcha ] then
] x @ 3 cmp ifl ( x (signed) less than 3 ] then

  DEMO +
QUESTIONS❓
    🙏
 Thank you!