Download orchestrator/shadow/runtime/forth/interpreter.mjs from Snapkitty/snapkitty-clojure-lisp-bridge: direct link, hf CLI and curl.
- Browser
- Download file 5.96 kB
-
https://huggingface.co/Snapkitty/snapkitty-clojure-lisp-bridge/resolve/main/orchestrator/shadow/runtime/forth/interpreter.mjs
- Command line
-
hf download hf://Snapkitty/snapkitty-clojure-lisp-bridge/orchestrator/shadow/runtime/forth/interpreter.mjs
-
curl -L -o interpreter.mjs https://huggingface.co/Snapkitty/snapkitty-clojure-lisp-bridge/resolve/main/orchestrator/shadow/runtime/forth/interpreter.mjs
5.96 kB
| // Sovereign Forth Runtime — the ancient output engine. | |
| // Stack-based. 1970s lineage. Charles Moore's language. | |
| // We use it because dependency graphs ARE stacks — | |
| // push dependency, resolve, pop. Natural representation. | |
| // This interpreter runs .forth files the worm generates. | |
| export class ForthMachine { | |
| constructor() { | |
| this.stack = []; | |
| this.rstack = []; // return stack | |
| this.dict = {}; // word definitions | |
| this.memory = new Map(); | |
| this.output = []; | |
| this._installBuiltins(); | |
| } | |
| // ── Stack ops ───────────────────────────────────────── | |
| push(v) { this.stack.push(v); } | |
| pop() { if (!this.stack.length) throw new Error('stack underflow'); return this.stack.pop(); } | |
| peek() { return this.stack[this.stack.length - 1]; } | |
| dup() { this.push(this.peek()); } | |
| swap() { const a = this.pop(), b = this.pop(); this.push(a); this.push(b); } | |
| drop() { this.pop(); } | |
| over() { const a = this.pop(), b = this.peek(); this.push(a); this.push(b); this.push(a); } | |
| emit(s) { this.output.push(String(s)); } | |
| // ── Execute a Forth source string ───────────────────── | |
| run(source) { | |
| const tokens = this._tokenize(source); | |
| let i = 0; | |
| while (i < tokens.length) { | |
| const tok = tokens[i]; | |
| // Word definition: : name ... ; | |
| if (tok === ':') { | |
| const name = tokens[++i]; | |
| const body = []; | |
| while (tokens[++i] !== ';') body.push(tokens[i]); | |
| this.dict[name.toLowerCase()] = body; | |
| i++; | |
| continue; | |
| } | |
| // Variable declaration | |
| if (tok === 'variable') { | |
| const name = tokens[++i].toLowerCase(); | |
| this.memory.set(name, 0); | |
| this.dict[name] = () => this.push(name); | |
| this.dict[name + '!'] = () => { const v = this.pop(); this.memory.set(name, v); }; | |
| this.dict[name + '@'] = () => this.push(this.memory.get(name) ?? 0); | |
| i++; | |
| continue; | |
| } | |
| // String literal: ." text " | |
| if (tok === '."') { | |
| let str = ''; | |
| while (tokens[++i] !== '"') str += tokens[i] + ' '; | |
| this.emit(str.trim()); | |
| i++; | |
| continue; | |
| } | |
| this._execToken(tok); | |
| i++; | |
| } | |
| } | |
| _execToken(tok) { | |
| const low = tok.toLowerCase(); | |
| // Number literal | |
| if (!isNaN(tok) && tok !== '') { this.push(Number(tok)); return; } | |
| // Float | |
| if (!isNaN(parseFloat(tok))) { this.push(parseFloat(tok)); return; } | |
| // String push | |
| if (tok.startsWith('"') && tok.endsWith('"')) { | |
| this.push(tok.slice(1, -1)); return; | |
| } | |
| // User-defined word | |
| if (this.dict[low]) { | |
| const word = this.dict[low]; | |
| if (typeof word === 'function') { word(); return; } | |
| if (Array.isArray(word)) { word.forEach(t => this._execToken(t)); return; } | |
| } | |
| throw new Error(`unknown word: ${tok}`); | |
| } | |
| _tokenize(src) { | |
| return src | |
| .replace(/\( [^)]*\)/g, '') // strip ( comments ) | |
| .replace(/\\[^\n]*/g, '') // strip \ line comments | |
| .split(/\s+/) | |
| .filter(Boolean); | |
| } | |
| _installBuiltins() { | |
| const d = this.dict; | |
| // Arithmetic | |
| d['+'] = () => { const b = this.pop(), a = this.pop(); this.push(a + b); }; | |
| d['-'] = () => { const b = this.pop(), a = this.pop(); this.push(a - b); }; | |
| d['*'] = () => { const b = this.pop(), a = this.pop(); this.push(a * b); }; | |
| d['/'] = () => { const b = this.pop(), a = this.pop(); this.push(a / b); }; | |
| d['mod'] = () => { const b = this.pop(), a = this.pop(); this.push(a % b); }; | |
| // Comparison | |
| d['='] = () => { const b = this.pop(), a = this.pop(); this.push(a === b ? -1 : 0); }; | |
| d['<'] = () => { const b = this.pop(), a = this.pop(); this.push(a < b ? -1 : 0); }; | |
| d['>'] = () => { const b = this.pop(), a = this.pop(); this.push(a > b ? -1 : 0); }; | |
| d['0='] = () => this.push(this.pop() === 0 ? -1 : 0); | |
| d['0<'] = () => this.push(this.pop() < 0 ? -1 : 0); | |
| // Stack | |
| d['dup'] = () => this.dup(); | |
| d['drop'] = () => this.drop(); | |
| d['swap'] = () => this.swap(); | |
| d['over'] = () => this.over(); | |
| d['rot'] = () => { const c=this.pop(),b=this.pop(),a=this.pop(); this.push(b);this.push(c);this.push(a); }; | |
| d['depth']= () => this.push(this.stack.length); | |
| d['.'] = () => this.emit(this.pop()); | |
| d['cr'] = () => this.emit('\n'); | |
| d['space']= () => this.emit(' '); | |
| // Logic | |
| d['and'] = () => { const b=this.pop(),a=this.pop(); this.push(a & b); }; | |
| d['or'] = () => { const b=this.pop(),a=this.pop(); this.push(a | b); }; | |
| d['invert']= () => this.push(~this.pop()); | |
| d['not'] = () => this.push(this.pop() === 0 ? -1 : 0); | |
| // Memory | |
| d['!'] = () => { const addr=this.pop(), val=this.pop(); this.memory.set(addr, val); }; | |
| d['@'] = () => this.push(this.memory.get(this.pop()) ?? 0); | |
| // Sovereign words — the graveyard vocabulary | |
| d['gravity'] = () => { /* gravity score is on stack */ }; | |
| d['alive?'] = () => this.push(this.peek() >= 0.6 ? -1 : 0); | |
| d['broken?'] = () => { const g=this.peek(); this.push(g >= 0.3 && g < 0.6 ? -1 : 0); }; | |
| d['orphan?'] = () => this.push(this.peek() < 0.3 ? -1 : 0); | |
| d['invert-repo']= () => this.emit(`[INVERT] ${this.pop()}`); | |
| d['seal'] = () => this.emit(`[SEAL] ${this.pop()}`); | |
| d['flag'] = () => this.emit(`[FLAG] ${this.pop()}`); | |
| d['repair'] = () => this.emit(`[REPAIR] ${this.pop()}`); | |
| } | |
| getOutput() { return this.output.join(''); } | |
| } | |
| // Run a Forth file and return output | |
| export function runForth(source) { | |
| const machine = new ForthMachine(); | |
| machine.run(source); | |
| return machine.getOutput(); | |
| } | |