diff options
Diffstat (limited to 'src/instr.lisp')
-rw-r--r-- | src/instr.lisp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/instr.lisp b/src/instr.lisp new file mode 100644 index 0000000..a5c94c6 --- /dev/null +++ b/src/instr.lisp @@ -0,0 +1,49 @@ +(defpackage #:sarcasm.instr + (:use #:cl) + (:shadow cl:return cl:if cl:block cl:loop cl:t) + (:local-nicknames + (#:a #:alexandria-2))) + +(in-package #:sarcasm.instr) + +(defclass instr () ()) + +(eval-when (:compile-toplevel :load-toplevel :execute) + (defun expand-instr-plist (plist) + (destructuring-bind (&key instr code type) plist + (let* ((class-name + (intern (string-upcase (first instr)))) + (immediates + (cl:loop + :for arg :in (rest instr) + :for slot-name := (intern (string-upcase arg)) + :for reader := (intern (format nil "~a-~a" class-name slot-name)) + :for initarg := (a:make-keyword slot-name) + :collect `(,slot-name + :reader ,reader + :initarg ,initarg + :initform (error "~a required" ',slot-name))))) + `(defclass ,class-name (instr) + ((instr-name + :allocation :class + :type string + :initform ,(first instr) + :reader instr-name) + (instr-code + :allocation :class + :type (vector (unsigned-byte 8) ,(length code)) + :initform (make-array ,(length code) + :element-type '(unsigned-byte 8) + :initial-contents ',code)) + (instr-type + :allocation :class + :type t + :initform ',type) + ,@immediates)))))) + +(macrolet ((create-instr-classes (raw) + `(progn + ,@(mapcar #'expand-instr-plist raw)))) + (create-instr-classes #.sarcasm.raw-instrs:raw-instrs)) + + |