summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksei Eaves <alekseijeaves@protonmail.com>2024-04-16 11:02:08 +1000
committerAleksei Eaves <alekseijeaves@protonmail.com>2024-04-16 11:02:08 +1000
commit24cad130fb3b4f81d029bd9edd6ed4e733507fbf (patch)
tree43aec53b785177a09829206d7ec2cbc483ece000
parent75db422f7b9c73f1057bf3187c73bfaeb6003a0b (diff)
grammar.lisp -> syntax.lisp, added attribute pass and word rule
-rw-r--r--6502.lisp2
-rw-r--r--attributes.lisp39
-rw-r--r--macro.lisp2
-rw-r--r--main.lisp14
-rw-r--r--syntax.lisp141
5 files changed, 195 insertions, 3 deletions
diff --git a/6502.lisp b/6502.lisp
index 38814af..0d566db 100644
--- a/6502.lisp
+++ b/6502.lisp
@@ -40,7 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
;; Generated list of addressing modes.
(defparameter
*addressing-modes*
- (extract-keys *addressing-modes-lengths*))
+ (extract-keys *addressing-mode-lengths*))
;;; Instructions, with decimal opcode and
;;; addressing modes.
diff --git a/attributes.lisp b/attributes.lisp
new file mode 100644
index 0000000..9cfc6b7
--- /dev/null
+++ b/attributes.lisp
@@ -0,0 +1,39 @@
+;; -*- mode: common-lisp -*-
+#|
+clasm-6502: An assembler for the 6502 written in Common Lisp.
+Copyright (C) 2024 Aleksei Eaves
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+|#
+
+(defun attributes-list (program-list)
+ "Grab a progams attributes."
+ (let ((get-attribute-list nil))
+ (dolist (i program-list)
+ (if (eq (syntax-rule (cadr i) *line-syntax*) 'attribute)
+ (setf get-attribute-list
+ (cons (cadr i)
+ get-attribute-list))))
+ get-attribute-list))
+
+(defun attributes-remove (program-list)
+ "Remove a progams attributes."
+ (let ((return-list nil))
+ (dolist (i program-list)
+ (if (not (eq (syntax-rule (cadr i) *line-syntax*) 'attribute))
+ (setf return-list
+ (cons i
+ return-list))))
+ (reverse return-list)))
diff --git a/macro.lisp b/macro.lisp
index 39070ab..f286f10 100644
--- a/macro.lisp
+++ b/macro.lisp
@@ -29,7 +29,7 @@ This owuld make it simple
|#
(defun macro-pass (program-list)
- "Translate a programs macros"
+ "Translate a programs macros."
(let ((macro-association-list
(let ((return-alist nil))
(dolist (i program-list)
diff --git a/main.lisp b/main.lisp
index ccc059a..48fefe0 100644
--- a/main.lisp
+++ b/main.lisp
@@ -28,10 +28,22 @@ ESPECIALLY run through the output of macro-list to find collisions
This owuld make it simple
|#
+;; Utility functions used in all other files.
(load "~/clasm-6502/utilities.lisp")
+;; Data related to the CPU
(load "~/clasm-6502/6502.lisp")
-(load "~/calsm-6502/grammar.lisp")
+;; Syntax rules
+(load "~/clasm-6502/syntax.lisp")
+;; Parse the source file into a list.
+(load "~/clasm-6502/parse-source.lisp")
+;; Process the program list macros.
+(load "~/clasm-6502/macro.lisp")
+
+;; Process the program list attributes
+(load "~/clasm-6502/attributes.lisp")
+
+(load "~/clasm-6502/labels.lisp")
diff --git a/syntax.lisp b/syntax.lisp
new file mode 100644
index 0000000..982397a
--- /dev/null
+++ b/syntax.lisp
@@ -0,0 +1,141 @@
+;; -*- mode: common-lisp -*-
+#|
+clasm-6502: An assembler for the 6502 written in Common Lisp.
+Copyright (C) 2024 Aleksei Eaves
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+|#
+
+;; Rules for the interpretation of lines.
+(defparameter
+ *line-syntax*
+ '(
+ (label
+ (lambda (l)
+ (and (eq (last-char (first l)) #\:)
+ (eq (length l) 1))))
+ (label-instruction
+ (lambda (l)
+ (and (eq (last-char (first l)) #\:)
+ (member (read-from-string (second l)) *opcodes*))))
+ (attribute
+ (lambda (l)
+ (and (equal (char (first l) 0) #\.)
+ (not (equal (first l) ".WORD")))))
+ (word
+ (lambda (l)
+ (and (equal (char (first l) 0) #\.)
+ (equal (first l) ".WORD"))))
+ (instruction
+ (lambda (l)
+ (member (read-from-string (first l)) *opcodes*)))
+ (macro
+ (lambda (l)
+ (equal (second l) "=")))
+ (unknown
+ (lambda (l)
+ t))))
+
+;; Rules for identifying addressing modes.
+(defparameter
+ *addressing-modes-syntax*
+ '((immediate ; #?? ... more complex syntax rules for later
+ (lambda (s)
+ (eq "#" (subseq s 0 1))))
+ (absolute ;"$????"
+ (lambda (s)
+ (and
+ (equal (length s) 5)
+ (equal "$" (subseq s 0 1))
+ (hexd? (subseq s 1 5)))))
+ (zero-page ;"$??"
+ (lambda (s)
+ (and
+ (equal (length s) 3)
+ (equal "$" (subseq s 0 1))
+ (hexd? (subseq s 1 3)))))
+ (implied nil)
+ (indirect-absolute ;($????)
+ (lambda (s)
+ (and
+ (equal (length s) 7)
+ (equal "($" (subseq s 0 2))
+ (hexd? (subseq s 1 5))
+ (equal ")" (subseq s 5 6)))))
+ (absolute-indexed-x ;"$????,X"
+ (lambda (s)
+ (and
+ (equal (length s) 7)
+ (equal "$" (subseq s 0 1))
+ (hexd? (subseq s 1 5))
+ (equal ",X" (subseq s 5 7)))))
+ (absolute-indexed-y ;"$????,Y"
+ (lambda (s)
+ (and
+ (equal (length s) 7)
+ (equal "$" (subseq s 0 1))
+ (hexd? (subseq s 1 5))
+ (equal ",Y" (subseq s 5 7)))))
+ (zero-page-indexed-x ;"$??,X"
+ (lambda (s)
+ (and
+ (equal (length s) 5)
+ (equal (subseq s 0 1) "$")
+ (hexd? (subseq s 1 3))
+ (equal (subseq s 3 5) ",X"))))
+ (zero-page-indexed-y ;"$??,Y"
+ (lambda (s)
+ (and
+ (equal (length s) 5)
+ (equal (subseq s 0 1) "$")
+ (hexd? (subseq s 1 3))
+ (equal (subseq s 3 5) ",Y"))))
+ (indexed-indirect ;"($??,X)"
+ (lambda (s)
+ (and
+ (equal (length s) 7)
+ (equal (subseq s 0 2) "($")
+ (hexd? (subseq s 2 4))
+ (equal (subseq s 4 7) ",X)"))))
+ (indirect-indexed ;"($??),Y"
+ (lambda (s)
+ (and
+ (equal (length s) 7)
+ (equal (subseq s 0 2) "($")
+ (hexd? (subseq s 2 4))
+ (equal (subseq s 4 7) "),Y"))))
+ ;;How to fix that relative and absolute are the same rule?
+ ;;A check upstream would suffice.
+ (relative ;"$????"
+ (lambda (s)
+ (and
+ (equal (length s) 5)
+ (equal (subseq s 0 1) "$")
+ (hexd? (subseq s 1 5)))))
+ (accumulator ;"A"
+ (lambda (s)
+ (and
+ (equal (length s) 1)
+ (equal "A" (subseq s 0 1)))))))
+
+(defun syntax-rule (line list)
+ "Apply a syntax rule against a delimited line from a program."
+ (dolist (i (extract-keys list))
+ (let ((z (funcall (eval (cadr (assoc i list)))
+ line)))
+ (if (not (equal
+ z nil))
+ (return i)
+ nil))))