blob: 3052583d4b1a44cfcbcf9abebb376d9f015d7b24 (
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
|
helper(in-package #:parse)
(define-condition parser-error (error)
((message :initarg :message
:initform nil
:reader message))
(:report (lambda (condition stream)
(format stream "~A" (message condition))))
(:documentation "Dedicated error for an invalid parse."))
(defun tokens->ast (program)
"Given PROGRAM, which is a list of lists of symbols,
filters out the labels and parses."
;; TODO add directives
(let ((program (remove nil (mapcar #'extract-label program)))
(i 0))
(mapcar (lambda (l) (extract-instruction l i)) program)))
(let ((i 0))
(defun extract-label (line)
"Given a series of tokens LINE, determines if LINE is
in the form STRING {colon}. If it is, then it is treated as a
label, and pushed onto the stack with the line index.
Note that this function is intended to be called using mapcar,
so that labels can be added to a map and otherwise removed from
processing."
(trivia:match line
((list (and id (type string))
(satisfies (lambda (x) (equal x 'lex::colon))))
(progn (push (cons (read-from-string id) i) util:label-loc) nil))
(_ (progn (incf i) line)))))
(defun extract-instruction (line i)
"Given instruction LINE, determines the expected type format and passes
LINE and the index I to the the respective function."
;; TODO add pseudo-ops (i.e., nop, mov, ...)
(let* ((type-map '((r-type . extract-r-type)
(i-type . extract-i-type)
(j-type . extract-j-type)))
(keyword (car line))
(type-fn (cdr (assoc keyword type-map))))
(if type-fn
(funcall type-fn line i)
(error 'parser-error
(format nil "PARSE failed--~a is not a known keyword.~%" (keyword))))))
(defun extract-r-type (line i)
'r)
(defun extract-i-type (line i)
'i)
(defun extract-j-type (line i)
'j)
|