diff --git a/wip-duuqnd/compiler.lisp b/wip-duuqnd/compiler.lisp index 415c672..66926ea 100644 --- a/wip-duuqnd/compiler.lisp +++ b/wip-duuqnd/compiler.lisp @@ -1,7 +1,8 @@ -(defpackage #:compiler +(defpackage #:user-side-compiler + (:nicknames #:usc) (:use #:cl)) -(in-package #:compiler) +(in-package #:user-side-compiler) (defvar *label-counter* 0) @@ -13,9 +14,14 @@ (defclass reference () ()) +(defgeneric ref-constantp (reference) (:method (reference) nil)) + (defclass reference-constant (reference) ((%value :accessor ref-value :initarg :value))) +(defmethod ref-constantp ((reference reference-constant)) + t) + (defmethod print-object ((object reference-constant) stream) (print-unreadable-object (object stream :type t) (format stream "~D" (ref-value object)))) @@ -34,7 +40,6 @@ (format-inst t "LDY #~D" (ref-index ref)) (format-inst t "LDA VARVEC,Y")) - (defclass node () ((%next :accessor next :accessor normal-next :initform nil))) diff --git a/wip-duuqnd/instruction-list.txt b/wip-duuqnd/instruction-list.txt new file mode 100644 index 0000000..0ff29c8 Binary files /dev/null and b/wip-duuqnd/instruction-list.txt differ diff --git a/wip-duuqnd/instruction.lisp b/wip-duuqnd/instruction.lisp new file mode 100644 index 0000000..ba20b59 --- /dev/null +++ b/wip-duuqnd/instruction.lisp @@ -0,0 +1,54 @@ +(in-package #:user-side-compiler) + +(defgeneric check-arguments (instruction)) + +(defclass instruction () + ((%mnemonic :allocation :class :reader mnemonic :initarg :mnemonic) + (%operand :accessor operand :initarg :operand) + (%next :accessor next :accessor normal-next :initarg :next))) + +(defclass complete-mixin () + ((%opcode :allocation :class :reader opcode :initarg :opcode))) + +(defclass immediate-mixin () ()) +(defclass implied-mixin () ()) +(defclass zero-page-mixin () ()) +(defclass zero-page-x-mixin (zero-page-mixin) ()) +(defclass absolute-mixin () ()) +(defclass absolute-x-mixin (absolute-mixin) ()) +(defclass absolute-y-mixin (absolute-mixin) ()) +(defclass indirect-x-mixin (zero-page-mixin) ()) +(defclass indirect-y-mixin (zero-page-mixin) ()) + +(defun addressing-mode-to-class-name (mode-keyword) + (cadr (assoc mode-keyword + '((:implied implied-mixin) + (:immediate immediate-mixin) + (:zero-page zero-page-mixin) + (:zero-page-x zero-page-x-mixin) + (:zero-page-y zero-page-y-mixin) + (:absolute absolute-mixin) + (:absolute-x absolute-x-mixin) + (:absolute-y absolute-y-mixin) + (:indirect-x indirect-x-mixin) + (:indirect-y indirect-y-mixin))))) + +(defclass branching-mixin () + ((%branch-next :accessor branch-next :initarg :branch-next))) + +(defmacro define-instruction (mnemonic branching-p &rest modes-and-codes) + (let* ((name (string-upcase mnemonic)) + (base-name (intern (format nil "INST-~A" name)))) + `(progn + (defclass ,base-name (instruction) + ((%mnemonic :allocation :class :initform ',mnemonic))) + ,@(loop :for (mode code) :in modes-and-codes + :collect `(defclass ,(intern (format nil "INST-~A-~A" + name mode)) + ,(append + `(,base-name + ,(addressing-mode-to-class-name mode) + complete-mixin) + (when branching-p + '(branching-mixin))) + ((%opcode :allocation :class :initform ,code)))))))