124 lines
3.2 KiB
Plaintext
124 lines
3.2 KiB
Plaintext
;; Erlang VM — stub opcode dispatcher (Phase 9).
|
|
;;
|
|
;; Mimics the OCaml-side EXTENSION shape from
|
|
;; plans/sx-vm-opcode-extension.md so opcodes 9b-9g can be designed
|
|
;; and tested in SX before 9a (`hosts/ocaml/`) lands the real
|
|
;; registration plumbing. When 9a is available, these stubs become
|
|
;; the cross-host SX-side mirror of the C/OCaml handlers and the
|
|
;; bytecode compiler emits them directly.
|
|
;;
|
|
;; Opcode IDs follow the plan's tier partition:
|
|
;; 0-127 reserved for SX core
|
|
;; 128-199 guest extensions (e.g. erlang, lua)
|
|
;; 200-247 port-/platform-specific
|
|
;;
|
|
;; Erlang owns 128-159 for now.
|
|
|
|
(define er-vm-opcodes (list {}))
|
|
|
|
(define er-vm-opcodes-get (fn () (nth er-vm-opcodes 0)))
|
|
|
|
(define
|
|
er-vm-opcodes-reset!
|
|
(fn () (set-nth! er-vm-opcodes 0 {})))
|
|
|
|
(define
|
|
er-vm-register-opcode!
|
|
(fn
|
|
(id name handler)
|
|
(dict-set! (er-vm-opcodes-get) (str id) {:name name :id id :handler handler})
|
|
(er-mk-atom "ok")))
|
|
|
|
(define
|
|
er-vm-lookup-opcode-by-id
|
|
(fn
|
|
(id)
|
|
(let
|
|
((reg (er-vm-opcodes-get)) (k (str id)))
|
|
(if (dict-has? reg k) (get reg k) nil))))
|
|
|
|
(define
|
|
er-vm-lookup-opcode-by-name
|
|
(fn
|
|
(name)
|
|
(let
|
|
((reg (er-vm-opcodes-get))
|
|
(ks (keys (er-vm-opcodes-get)))
|
|
(found (list nil)))
|
|
(for-each
|
|
(fn
|
|
(i)
|
|
(let
|
|
((entry (get reg (nth ks i))))
|
|
(when
|
|
(= (get entry :name) name)
|
|
(set-nth! found 0 entry))))
|
|
(range 0 (len ks)))
|
|
(nth found 0))))
|
|
|
|
(define er-vm-list-opcodes (fn () (keys (er-vm-opcodes-get))))
|
|
|
|
(define
|
|
er-vm-dispatch
|
|
(fn
|
|
(id operands)
|
|
(let
|
|
((entry (er-vm-lookup-opcode-by-id id)))
|
|
(if
|
|
(= entry nil)
|
|
(error (str "Erlang VM: unknown opcode id " id))
|
|
((get entry :handler) operands)))))
|
|
|
|
(define
|
|
er-vm-dispatch-by-name
|
|
(fn
|
|
(name operands)
|
|
(let
|
|
((entry (er-vm-lookup-opcode-by-name name)))
|
|
(if
|
|
(= entry nil)
|
|
(error (str "Erlang VM: unknown opcode name '" name "'"))
|
|
((get entry :handler) operands)))))
|
|
|
|
;; ── Phase 9b — pattern-match opcodes ────────────────────────────
|
|
;; Each handler takes a list (pattern-ast value env) and returns
|
|
;; true/false, mutating env on success (same contract as the
|
|
;; existing er-match-tuple / er-match-cons / er-match-binary).
|
|
;; Wire these as wrappers for now; the real opcodes will eventually
|
|
;; have register-machine semantics and skip the AST-walk overhead.
|
|
|
|
(define
|
|
er-vm-register-erlang-opcodes!
|
|
(fn
|
|
()
|
|
(er-vm-register-opcode!
|
|
128
|
|
"OP_PATTERN_TUPLE"
|
|
(fn
|
|
(operands)
|
|
(er-match-tuple
|
|
(nth operands 0)
|
|
(nth operands 1)
|
|
(nth operands 2))))
|
|
(er-vm-register-opcode!
|
|
129
|
|
"OP_PATTERN_LIST"
|
|
(fn
|
|
(operands)
|
|
(er-match-cons
|
|
(nth operands 0)
|
|
(nth operands 1)
|
|
(nth operands 2))))
|
|
(er-vm-register-opcode!
|
|
130
|
|
"OP_PATTERN_BINARY"
|
|
(fn
|
|
(operands)
|
|
(er-match-binary
|
|
(nth operands 0)
|
|
(nth operands 1)
|
|
(nth operands 2))))
|
|
(er-mk-atom "ok")))
|
|
|
|
(er-vm-register-erlang-opcodes!)
|