diff options
author | Siddarth Suresh <155843085+SiddarthSuresh98@users.noreply.github.com> | 2025-04-10 18:37:40 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-10 18:37:40 -0400 |
commit | 5dbf0b63988b42c112ca0087cbbbb090566df5c1 (patch) | |
tree | ce8ee03b9d25b739a2e687c69b14d9221420e4fa /src/util.lisp | |
parent | cc1e5892a25949b996d69a0b07f151a276ef2570 (diff) | |
parent | df508744ec2975cec0ba05e8a4358c1c41265c4c (diff) |
Merge pull request #2 from bdunahu/bdunahu
Finish parser, add .text and .data directives, variable names, label processing
Diffstat (limited to 'src/util.lisp')
-rw-r--r-- | src/util.lisp | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/src/util.lisp b/src/util.lisp index 5edee4a..f3035fe 100644 --- a/src/util.lisp +++ b/src/util.lisp @@ -4,24 +4,66 @@ "Returns t if FILE is extended with .asm, nil otherwise." (string= (pathname-type file) "asm")) -;; TODO this won't work for negative numbers of odd sizes quite yet. + (defun format-as-binary (num len) "Formats NUM as a binary number, and pads to LEN with zeros." (declare (type number num)) (declare (type (integer 0 *) len)) - (format nil "~V,'0b" len num)) + (let ((max-val (1- (expt 2 len)))) + (format nil "~V,'0b" len (logand num max-val)))) + +(defun insert-in-middle (list element) + (append (list (car list)) (list element) (cdr list))) + +(defun iota (n) + "Generates a number sequence from 0 to N." + (when (> n 0) + (do ((i 0 (1+ i)) + (item 0 (1+ item)) + (result nil (push item result))) + ((= i n) (nreverse result))))) + +(defun riffle (lst1 lst2) + "Given LST1 and LST2, returns a new list which is the an alternating sequence +of the elements from both lists. Returns nil if the lists are not equal size." + (when (eq (length lst1) (length lst2)) + (loop for l1 in lst1 + for l2 in lst2 + append (list l1 l2)))) + +(defvar variable-table (make-hash-table :test #'equalp)) +(defvar label-table (make-hash-table :test #'equalp)) -(defparameter type-r - '(ADD SUB MUL QUOT REM SFTR SFTL AND OR NOT XOR ADDV SUBV MULV DIVV CMP CEV) +(defun add-variable (name value) + (if (gethash name variable-table) + (error "~@<Variable declared twice: ~S.~@:>" name) + (setf (gethash name variable-table) value))) + +(defun add-label (name value) + (if (gethash name label-table) + (error "~@<Label declared twice: ~S.~@:>" name) + (setf (gethash name label-table) value))) + +(defun get-variable (name) + (alexandria:if-let ((value (gethash name variable-table))) + value + (progn (maphash #'(lambda (k v) (format t "~A => ~A~%" k v)) variable-table) + (error "~@<Variable ~S not declared.~@:>" name)))) + +(defun get-label (name) + (alexandria:if-let ((value (gethash name label-table))) + value + (error "~@<Label ~S not found.~@:>" name))) + +(defvar r-type + '("ADD" "SUB" "MUL" "QUOT" "REM" "SFTR" "SFTL" "AND" "OR" + "NOT" "XOR" "ADDV" "SUBV" "MULV" "DIVV" "CMP" "CEV") "R-type instructions.") -(defparameter type-i - '(LOAD LOADV ADDI SUBI SFTRI SFTLI ANDI ORI XORI STORE STOREV) +(defvar i-type + '("LOAD" "LOADV" "ADDI" "SUBI" "SFTRI" "SFTLI" "ANDI" "ORI" "XORI" "STORE" "STOREV") "I-type instructions.") -(defparameter type-j - '(JMP JRL JAL BEQ BGT BUF BOF PUSH POP) +(defvar j-type + '("JMP" "JRL" "JAL" "BEQ" "BGT" "BUF" "BOF" "PUSH" "POP") "J-type instructions.") - -(defparameter label-loc '() - "A symbol table mapping label names to line indices.") |