diff options
author | aleksei <aleksei@aj.org> | 2024-04-13 11:09:45 +1000 |
---|---|---|
committer | aleksei <aleksei@aj.org> | 2024-04-13 11:09:45 +1000 |
commit | 3b2b63913b1a550c8469acd3943abafbf22ccd13 (patch) | |
tree | d948d603f0eb380c6f171df568dd11e02a84733c | |
parent | fafbeb6051a15232df1858ce64ff0375597b5044 (diff) |
macro table gen. , syntax-rule works with *grammar*
-rw-r--r-- | 6502.lisp | 2 | ||||
-rw-r--r-- | grammar.lisp | 58 | ||||
-rw-r--r-- | main.lisp | 24 | ||||
-rw-r--r-- | utilities.lisp | 16 |
4 files changed, 72 insertions, 28 deletions
@@ -203,7 +203,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (BRK 0 (implied)))) ;; Generated list of opcodes. -(setf +(defparameter *opcodes* (extract-keys *instructions*)) diff --git a/grammar.lisp b/grammar.lisp index 2a3cb03..d91317f 100644 --- a/grammar.lisp +++ b/grammar.lisp @@ -18,37 +18,51 @@ 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))) - +;; Rules for interpreting the purpose of some line. (setf *grammar* - '((label + '( + (label (lambda (l) - (eq (last-char (first l)) #\:))) - (macro + (and (eq (last-char (first l)) #\:) + (eq (length l) 1)))) + (label-instruction (lambda (l) - (eq (second l) "="))) + (and (eq (last-char (first l)) #\:) + (member (read-from-string (second l)) *opcodes*)))) (attribute (lambda (l) - (eq (char (first l) 0) #\.))) + (equal (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))))) + (member (read-from-string (first l)) *opcodes*))) + (macro + (lambda (l) + (equal (second l) "="))) + (unknown + (lambda (l) + t)))) + + +(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)))) + + +(syntax-rule '("LABEL:" "LDA" "$05") *grammar*) + +(syntax-rule '("LDA" "$05") *grammar*) +(syntax-rule '("AS" "=" "THAT") *grammar*) -(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 '("LABEL:") *grammar*) -(syntax-rule '("LDA:" "$05") *grammar*) +(syntax-rule '("hhhh") *grammar*) +(syntax-rule '(".org" "$FF00") *grammar*) @@ -24,3 +24,27 @@ We can test only the addressin modes we know the opcode to have This not only solves this problem, it just makes more sense. |# + +(setf *the-program* + (program "~/clasm-6502/wozmon.s")) + +(defun macro-list (program-list) + "Create an associative list of program-list macros." + (let ((return-alist nil)) + (dolist (i program-list) + (if (equal (syntax-rule (cadr i) *grammar*) 'macro) + (setf return-alist + (cons (list (first (cadr i)) (car (last (cadr i)))) + return-alist)) + nil)) + return-alist)) + +*the-program* + +(macro-list *the-program*) + + +(last (cadr '(100 ("Hey" "There")))) + + +(defun pass-attributes (program-list)) diff --git a/utilities.lisp b/utilities.lisp index 414f0f2..c231f72 100644 --- a/utilities.lisp +++ b/utilities.lisp @@ -19,7 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |# (defun extract-keys (alist) - "Extract the keys of associative lists." + "Extract the keys of an associative list." (let ((return-value nil)) (progn (dolist (i alist) @@ -27,8 +27,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (cons (car i) return-value))) (reverse return-value)))) +(defun last-char (s) + (char s (- (length s) 1))) + (defun hexd? (string) - "Is a string a hexd number?" + "Is string a hexadecimal number?" (let ((stack ())) (dotimes (i (length string)) (push @@ -45,9 +48,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (eval stack))) (defun hex2dec (string) - "Convert an arbitrarily sized hexd number (as string) to a positive decimal." + "Convert an arbitrarily sized hexadecimal number (as string) to a positive decimal." (if (hexd? string) - (flet ((hex (c) ;Return character as hexadecimal + ;; Return a character as a hexadecimal digit. + (flet ((hex (c) (cond ((and (char-not-lessp c #\0) (char-not-greaterp c #\9)) @@ -58,6 +62,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (+ (- (char-code (char-downcase c)) (char-code #\a)) 10))))) (let ((return-value 0)) + ;; Loop through string and convert. (do ((i 0 (incf i)) (j (- (length string) 1) (decf j))) ((minusp j) ()) @@ -66,4 +71,5 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (* (expt 16 j) (hex (char string i)))))) return-value)) - nil)) + ;; Return nil if string was not a hexadecimal number. + nil)) |