blob: e52d7aa2e935ef314e2abcc7c7e9cfc95fa67324 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
(in-package #:util)
(defun asm-extension? (file)
"Returns t if FILE is extended with .asm, nil otherwise."
(string= (pathname-type file) "asm"))
(defun generate-file-name (file)
"Given a .asm file, generates an identically named .rv file."
(subseq file 0 (- (length file) 4)))
(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))
(let ((max-val (1- (expt 2 len))))
(format nil "~V,'0b" len (logand num max-val))))
(defun word-to-bytes (int)
"Given a 32-bit integer, outputs a list of 4 bytes."
(list (logand #xff (ash int -24))
(logand #xff (ash int -16))
(logand #xff (ash int -8))
(logand #xff int)))
(defun insert-in-middle (list element)
"Inserts ELEMENT in the second slot of LIST."
(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))
(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.")
(defvar i-type
'("LOAD" "LOADV" "ADDI" "SUBI" "SFTRI" "SFTLI" "ANDI" "ORI" "XORI" "STORE" "STOREV")
"I-type instructions.")
(defvar j-type
'("JMP" "JRL" "JAL" "BEQ" "BGT" "BUF" "BOF" "PUSH" "POP" "RET" "NOP")
"J-type instructions.")
|