diff options
author | aleksei <aleksei@aj.org> | 2024-04-12 13:53:21 +1000 |
---|---|---|
committer | aleksei <aleksei@aj.org> | 2024-04-12 13:53:21 +1000 |
commit | 84ad1b97a5095cf6010593ec96e7d43d77fc0fa5 (patch) | |
tree | 36a00eb699bb0ce7cd7d18dc1bf608d9714538c0 | |
parent | 82632e220e3a0c2f72c463f8c07b9678d7399972 (diff) |
Added syntax evaluation for asm lines
-rw-r--r-- | 6502.lisp | 16 | ||||
-rw-r--r-- | grammar.lisp | 54 | ||||
-rw-r--r-- | main.lisp | 22 |
3 files changed, 75 insertions, 17 deletions
@@ -202,6 +202,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (NOP 234 (implied)) (BRK 0 (implied)))) + + +(defun extract-keys (list) + "Extract the keys of associative lists." + (let ((ret nil)) + (progn + (dolist (i list) + (setf ret + (cons (car i) ret))) + (reverse ret)))) + +;; Generated list of opcodes. +(setf + *opcodes* + (extract-keys *instructions*)) + (defun valid-instruction? (instruction addressing-mode) "Is instruction and addressing mode combination correct?" (cond diff --git a/grammar.lisp b/grammar.lisp new file mode 100644 index 0000000..2a3cb03 --- /dev/null +++ b/grammar.lisp @@ -0,0 +1,54 @@ +;; -*- 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 last-char (s) + (char s (- (length s) 1))) + +(setf + *grammar* + '((label + (lambda (l) + (eq (last-char (first l)) #\:))) + (macro + (lambda (l) + (eq (second l) "="))) + (attribute + (lambda (l) + (eq (char (first l) 0) #\.))) + (instruction + (lambda (l) + (if (or (member (read-from-string (first l)) *opcodes*) + (member (read-from-string (second l)) *opcodes*)) + t nil))))) + + +(defun syntax-rule (item list) + "Test a line against a list of syntax rules." + (dolist (i (extract-keys list)) + (let ((z (funcall + (eval (cadr (assoc i list))) + item))) + (cond ((not (equal + z nil)) + (return i)) + (t nil))))) + +(syntax-rule '("LDA:" "$05") *grammar*) + @@ -18,21 +18,9 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |# +#| +To solve the problem of the colliding syntax rules +We can test only the addressin modes we know the opcode to have +This not only solves this problem, it just makes more sense. +|# -(defun last-char (s) - (char s (- (length s) 1))) - -(defun label? (s) - (eq (last-char s) #\:)) - - -(setf - *grammar* - (('label - (lambda (l) - )))) - -(defun read_code () - (incf *source-line-number*) - () - ) |