summaryrefslogtreecommitdiff
path: root/src/util.lisp
diff options
context:
space:
mode:
authorSiddarth Suresh <155843085+SiddarthSuresh98@users.noreply.github.com>2025-04-10 18:37:40 -0400
committerGitHub <noreply@github.com>2025-04-10 18:37:40 -0400
commit5dbf0b63988b42c112ca0087cbbbb090566df5c1 (patch)
treece8ee03b9d25b739a2e687c69b14d9221420e4fa /src/util.lisp
parentcc1e5892a25949b996d69a0b07f151a276ef2570 (diff)
parentdf508744ec2975cec0ba05e8a4358c1c41265c4c (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.lisp64
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.")