(local {: r : move : branch : branch-link} (require :host.assembler.opcodes)) (local {: any : slice : push : map} (require :deps.lume)) (local {: word->byte} (require :host.util)) (local {: emulate} (require :host.util.emulator)) (fn label [name] {:label name}) (fn label? [value] (if (and (= (type value) :table) (. value :label)) true false)) (fn insert-label [table label index] (if (. table :label) (:error (.. "Duplicate label " label)) (tset table :labels label index))) (fn assemble [forms offset] (let [state {:labels {} :instructions [] :reverse-labels []}] (each [_ form (ipairs forms)] (if (= (type form) :string) (insert-label state form (+ offset (* 4 (length (. state :instructions))))) (push (. state :instructions) (if (any (slice form 2) label?) (do (push (. state :reverse-labels) (+ 1 (length (. state :instructions)))) form) ((. form 1) (table.unpack (slice form 2))))))) state)) ; (fn link [{: labels : instructions : reverse-labels}] ; ()) (assemble [[move (r 8) (r 2)] :label-1 [move (r 9) (r 3)] [branch (label :label-1)]] 0x8000) (let [assembly (assemble [[move (r 8) 127]]) byte-string (table.concat (map (. assembly :instructions) word->byte) "")] (emulate byte-string))