Download Game! Currently 66 players and visitors. Last logged in:ZenickAceduckDesertDregas

Blitzer's Blog >> 72269

Back to blogs index
Posted: 11 Sep 2026 07:41 [ permalink ]
This is exactly how an operating system matures from a novelty into a
powerful, self-hosting ecosystem. Building an AST Debugger/Editor as a native
application means the OS can introspect, build, and modify itself in
real-time.
When visualizing the live execution statemapping the dataStack, callStack, and
lexical environmentswe can evolve the HTML/JS AST editing interfaces and
intent history event loggers you have already been working with into a live,
bi-directional memory inspector that sits right on your desktop.
To get there, we must first lay the track for interactive apps. We need to
upgrade the harness to route inputs, and upgrade the app to listen for them.
Here is the two-step implementation to make your "Distributed AST App" window
respond to your Android touch intents.
Step 1: The Microkernel Process Router
We need to teach the Node harness which Worker thread owns which window.
Open your src/runtime/harness.js and add a process table to the Harness class
constructor:
 constructor() {
    // ... existing setup ...
    this.processTable = new Map(); // Maps Window ID to Worker Instance
  }

Next, update the sys-resume block inside your wss.on('connection') listener.
We are adding the routing logic to store the worker reference when a window is
drawn, and route intents to it when the browser sends them:
       // Handle the Resume click
        if (intent[1] === "sys-resume") {
          const fileId = intent[2];
          try {
             const astPayload = await this.loadAppState(fileId);
             const bytecode = compile(astPayload);
             const sab = new SharedArrayBuffer(12);
             
             const worker = new Worker(path.join(__dirname, '../vm/worker-entry
.js'), {
               workerData: { bytecode, sab, gasLimit: 500000 }
             });

             // [ROUTER UPDATE]: Map the window ID to the worker when it
requests a render
             worker.on('message', (msg) => {
               if (msg.type === 'DISPATCH' && msg.target === 'ui-render') {
                 const winDef = msg.args[0];
                 // Register this window to this specific VM thread
                 this.processTable.set(winDef.id, worker);
                 systemState = systemState.filter(w => w.id !== winDef.id);
                 systemState.push(winDef);
        ws.send(JSON.stringify(["state-sync", systemState]));
               }
             });
          } catch(e) {
             console.error("[Drive] Failed to boot VM from state", e);
          }
        }
        // [ROUTER UPDATE]: Intercept window intents and route them to the
correct VM
        if (intent[1] === "window-move" || intent[1] === "window-focus" ||
intent[1] === "key-press") {
          const targetWinId = intent[2];
          // Fast-path local visual update to keep UI snappy
          if (intent[1] === "window-move") {
            const win = systemState.find(w => w.id === targetWinId);
            if (win) { win.x = intent[3]; win.y = intent[4]; ws.send(JSON.strin
gify(["state-sync", systemState])); }
          }
          // Forward the intent to the AST application
          const targetWorker = this.processTable.get(targetWinId);
          if (targetWorker) {
            targetWorker.postMessage({ type: 'INVOKE', func: 'on_event', args:
[intent] });
          } else {
            console.warn(`[Router] Dropped intent. No process found for
window: ${targetWinId}`);
          }
        }

Step 2: The Stateful, Interactive AST Payload
Now we rewrite mock_app.json on Google Drive.
Instead of just rendering once and halting, this AST defines global state
variables (app_x, app_y), defines a render function, and most importantly,
defines an on_event function that the microkernel will invoke whenever you
touch the window.
Update your mock_app.json file in Drive to this array:
[
  "do",
  ["def", "app_x", 50],
  ["def", "app_y", 250],
  ["def", "render", [],
    ["dispatch", 
      ["str", "ui-render"], 
      ["array", 
        ["record", 
          ["str", "id"], ["str", "win-ast-app"],
          ["str", "title"], ["str", "Distributed AST App"],
          ["str", "x"], "app_x", 
          ["str", "y"], "app_y",
          ["str", "w"], 350, 
          ["str", "h"], 150,
          ["str", "z"], 50,
          ["str", "content"], ["str", "<div style='padding:15px;'>My X, Y
coordinates are managed by JSON-Lisp.<br><br>Try dragging me!</div>"]
        ]
      ],
      ["record"]
    ]
  ],
  ["def", "on_event", ["intent_data"],
    ["do",
      ["def", "event_type", ["get_idx", 1, "intent_data"]],
      
      ["if", ["eq", "event_type", ["str", "window-move"]],
        ["do",
          ["set", "app_x", ["get_idx", 3, "intent_data"]],
          ["set", "app_y", ["get_idx", 4, "intent_data"]],
          ["call", "render", []]
        ],
        false
      ]
    ]
  ],
  ["call", "render", []]
]

(Note: I used standard AST opcodes like get_idx, if, and set/def based on your
previous JL-AST compiler dump. Adjust slightly if your specific dialect
requires it).
The AST Debugger / Editor Blueprint
Once this routing loop is closed, the Debugger is just another AST app that
leverages the existing Drive API. Here is how we will structure the
experiment:
The API Expansion: We add a new dispatch target to the harness called
sys-ast-api.
The Debugger App: We write an AST app (saved on Drive) that renders a window
with a large HTML <textarea> or tree visualizer.
The Editor Loop:
The debugger dispatches ["sys-ast-api", "read-file", "mock_app.json"].
The harness reads it from Drive and fires worker.postMessage to pass the JSON
back into the debugger VM.
The debugger renders it in the UI.
You edit the JSON on your Android screen, click Save, and the debugger
dispatches ["sys-ast-api", "write-file", "mock_app.json", newData].
Suspend & Memory Dump: We implement a ["sys-ast-api", "dump-memory",
"win-ast-app"] dispatch. The harness queries the routing map, asks the target
Worker to serialize its current dataStack and callStack, and pipes that JSON
directly into your Debugger UI window.
Try updating the harness and the Drive file. If you resume mock_app.json, you
should be able to drag the window, have the UI send the intent to Node, Node
send it to the Worker, the Worker update its variables, and dispatch the new
ui-render state back!