(local {: r : move : branch : branch-link} (require :host.assembler.opcodes)) (local {: any : slice : push} (require :deps.lume)) (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}] ()) (macro x [...] `[,(unpack (icollect [_ form (ipairs ...)] '[,(. form 1)]))]) (macrodebug (x (move (r 9) (r 8)))) (assemble [[move (r 8) (r 2)] :label-1 [move (r 9) (r 3)] [branch (label :label-1)]] 0x8000)