This commit is contained in:
2026-02-21 14:18:15 -05:00
parent 6953e6b9b3
commit 67f8639ee7
5 changed files with 604 additions and 1467 deletions

View File

@@ -32,7 +32,7 @@ Learn ColorForth and be able to build a ColorForth derivative from scratch simil
Based on the curation in `./references/`, the resulting system MUST adhere to these non-standard rules:
1. **Sourceless Environment (x68):** No string parsing at runtime. Code exists purely as an array of 32-bit tokens.
1. **Sourceless Environment (x68):** No string parsing at runtime. Code exists purely as an array of 32-bit tokens.
- **Token Layout:** 28 bits of payload (compressed name/index/value) + 4 bits for the semantic "Color" Tag.
2. **Visual Editor as the OS:** The editor directly maps to the token array. It does not read text files. It uses the 4-bit tags to colorize the tokens live.
3. **Register-Only Stack:** The traditional Forth data stack in memory is completely eliminated.
@@ -44,25 +44,40 @@ Based on the curation in `./references/`, the resulting system MUST adhere to th
## Current Development Roadmap (attempt_1)
The prototype currently implements a functional WinAPI modal editor, a 2-register (`RAX`/`RDX`) JIT compiler with an `O(1)` visual linker, x68 32-bit instruction padding, implicit definition boundaries (Magenta Pipe), and an initial FFI Bridge (`emit_ffi_dance`).
The prototype currently implements:
- A functional WinAPI modal editor backed by `microui` for immediate-mode floating panels.
- A 2-register (`RAX`/`RDX`) JIT compiler with an `O(1)` visual linker (`tape_to_code_offset` table).
- x68-style 32-bit instruction padding via `pad32()` using `0x90` NOPs.
- Implicit definition boundaries (Magenta Pipe / `STag_Define`) emitting `JMP rel32` over the body and `xchg rax, rdx` at the entry point.
- An FFI Bridge (`x64_FFI_PROLOGUE`, `x64_FFI_MAP_ARGS`, `x64_FFI_CALL_ABS`, `x64_FFI_EPILOGUE`) for calling WinAPI functions safely from JIT'd code.
- Persistence via F1 (save) / F2 (load) to `cartridge.bin`.
- A Lambda tag (`STag_Lambda`) that compiles a code block out-of-line and leaves its address in `RAX`.
- A well-defined **x64 Emission DSL** (`#pragma region x64 Emission DSL`) with named REX prefixes, register encodings, ModRM/SIB composition macros, opcode constants, and composite instruction inline functions.
### x64 Emission DSL Discipline
All JIT code emission in `main.c` MUST use the x64 Emission DSL defined in the `#pragma region x64 Emission DSL` block. Raw magic bytes are forbidden. The allowed primitives are:
- **Composite helpers:** `x64_XCHG_RAX_RDX()`, `x64_MOV_RDX_RAX()`, `x64_MOV_RAX_RDX()`, `x64_ADD_RAX_RDX()`, `x64_SUB_RAX_RDX()`, `x64_IMUL_RAX_RDX()`, `x64_DEC_RAX()`, `x64_TEST_RAX_RAX()`, `x64_RET_IF_ZERO()`, `x64_RET_IF_SIGN()`, `x64_FETCH()`, `x64_STORE()`, `x64_CALL_RAX()`, `x64_RET()`.
- **Prologue/Epilogue:** `x64_JIT_PROLOGUE()`, `x64_JIT_EPILOGUE()`.
- **FFI:** `x64_FFI_PROLOGUE()`, `x64_FFI_MAP_ARGS()`, `x64_FFI_CALL_ABS(addr)`, `x64_FFI_EPILOGUE()`.
- **Raw emission only via named constants:** `emit8(x64_op_*)`, `emit8(x64_REX*)`, `emit8(x64_modrm(*))`, `emit32(val)`, `emit64(val)`.
- **Exception:** Forward jump placeholders (`JMP rel32`, `CALL rel32`) that have no composite helper may use `emit8(x64_op_JMP_rel32)` / `emit8(x64_op_CALL_rel32)` directly with a following `emit32(0)` placeholder, pending a dedicated DSL wrapper.
Here is a breakdown of the next steps to advance the `attempt_1` implementation towards a complete ColorForth derivative:
1. ~~**Refine the FFI / Tape Drive Argument Scatter:**~~ (Completed via `PRIM_PRINT` updating to load R8/R9 from `vm_globals`)
* Currently, the FFI bridge only maps `RAX` and `RDX` to the C-ABI `RCX` and `RDX`.
* Implement "Preemptive Scatter" logic so the FFI bridge correctly reads subsequent arguments (e.g., `R8`, `R9`) directly from pre-defined offsets in the `vm_globals` tape drive instead of just zeroing them out.
1. ~~**Refine the FFI / Tape Drive Argument Scatter:**~~ (Completed)
2. ~~**Implement the Self-Modifying Cartridge (Persistence):**~~ (Completed via F1/F2 save/load)
3. ~~**Refine Visual Editor Interactions:**~~ (Completed via `microui` integration)
4. ~~**Audit and enforce x64 Emission DSL usage throughout `main.c`:**~~ (Completed — all raw magic bytes replaced with named DSL constants and composite helpers)
2. **Expanded Annotation Layer (Variable-Length Comments):**
* The current `anno_arena` strictly allocates 8 bytes (a `U8`) per token.
* Refactor the visual editor and annotation memory management to allow for arbitrarily long text blocks (comments) to be attached to specific tokens without disrupting the `O(1)` compilation mapping.
5. **Add DSL wrappers for forward jump placeholders:**
- `x64_JMP_fwd_placeholder(U4* offset_out)` — emits `E9 00000000` and writes the patch offset.
- `x64_patch_fwd(U4 offset)` — patches a previously emitted placeholder with the current code position.
- This will eliminate the last remaining raw `emit8`/`emit32` pairs in `compile_and_run_tape`.
3. ~~**Implement the Self-Modifying Cartridge (Persistence):**~~ (Completed via F1/F2 save/load)
* The tape and annotations are currently lost when the program closes.
* Move away from purely transient `VirtualAlloc` buffers to a memory-mapped file approach (or a manual Save/Load equivalent in WinAPI) to allow the "executable as source" to persist between sessions.
6. **Expanded Annotation Layer (Variable-Length Comments):**
- The current `anno_arena` strictly allocates 8 bytes (a `U8`) per token.
- Refactor the visual editor and annotation memory management to allow for arbitrarily long text blocks (comments) to be attached to specific tokens without disrupting the `O(1)` compilation mapping.
4. ~~**Refine Visual Editor Interactions:**~~ (Completed via `microui` integration)
* Implement a proper internal text-editing cursor within the `STag_Data` and `STag_Format` (annotation) tokens, rather than relying on backspace-truncation and appendage.
* Migrated to `microui` for immediate mode GUI floating panels, auto-layout token sizing (for a natural text look), and window resizing.
5. **Continuous Validation & Complex Control Flow:**
* Expand the primitive set to allow for more complex, AST-less control flow (e.g., handling Lambdas or specific Basic Block jumps).
7. **Continuous Validation & Complex Control Flow:**
- Expand the primitive set to allow for more complex, AST-less control flow (e.g., handling Basic Block jumps `[ ]`).
- Investigate adding a `RET_IF_ZERO` + tail-call pattern for loops without explicit branch instructions.