summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-04-08 01:56:18 -0400
committerbd <bdunahu@operationnull.com>2025-04-08 01:56:18 -0400
commitb85c10ba1c53f1b442fea6bde4c2a2f73cfe5d6b (patch)
tree643d37db692c19d1ef64223eadcac7a28dbbd7db /src
parent4c76966b49e8559f710013463dac04143c1f4e09 (diff)
Simplify lexer-error handling, skeletion parsing functions for types
Diffstat (limited to 'src')
-rw-r--r--src/lex.lisp30
-rw-r--r--src/package.lisp17
-rw-r--r--src/parse.lisp42
-rw-r--r--src/util.lisp32
4 files changed, 74 insertions, 47 deletions
diff --git a/src/lex.lisp b/src/lex.lisp
index d5c77a1..5b1457d 100644
--- a/src/lex.lisp
+++ b/src/lex.lisp
@@ -1,18 +1,12 @@
(in-package #:lex)
-(define-condition invalid-immediate-or-keyword (error)
- ((chr :initarg :chr
- :initform nil
- :reader chr)
- (instance :initarg :instance
- :initform nil
- :reader instance))
+(define-condition lexer-error (error)
+ ((message :initarg :message
+ :initform nil
+ :reader message))
(:report (lambda (condition stream)
- (format stream
- "LEX failed--encountered ~a while reading ~a."
- (chr condition) (instance condition))))
- (:documentation "Dedicated error for immediates/keywords which contain
-invalid characters."))
+ (format stream "~A" (message condition))))
+ (:documentation "Dedicated error for an invalid lex."))
(defun file->tokens (file)
"Opens FILE and parses returns a list of tokens, or
@@ -63,7 +57,9 @@ Comments start with a semi-colon ';' and all tokens after are ignored."
((alpha-char-p chr)
(read-keyword chr))
- (t (error (format nil "~a is not a valid lexical symbol.~%" chr))))))
+ (t (error 'lexer-error
+ :message
+ (format nil "LEX failled--~a is not a valid lexical symbol.~%" chr))))))
(defun read-immediate (chr)
"Reads a sequence of digits, in base 2, 8, 10, or 16.. Throws
@@ -74,7 +70,9 @@ Comments start with a semi-colon ';' and all tokens after are ignored."
(cond ((and (not (null chr)) (digit-char-p chr))
(read-immediate-helper (cons (read-char *standard-input* nil) chrs-so-far)))
((and (not (null chr)) (alpha-char-p chr))
- (error 'invalid-immediate-or-keyword :chr chr :instance "immediate"))
+ (error 'lexer-error
+ :message
+ (format nil "LEX failed--encountered ~a while reading immediate.~%" chr)))
(t (reverse chrs-so-far)))))
(let* ((next (peek-char nil *standard-input* nil))
@@ -99,7 +97,9 @@ error if a digit is encountered."
(cond ((and (not (null chr)) (alpha-char-p chr))
(read-keyword-helper (cons (read-char *standard-input* nil) chrs-so-far)))
((and (not (null chr)) (digit-char-p chr))
- (error 'invalid-immediate-or-keyword :chr chr :instance "keyword"))
+ (error 'lexer-error
+ :message
+ (format nil "LEX failed--encountered ~a while reading keyword.~%" chr)))
(t (reverse chrs-so-far)))))
(coerce (read-keyword-helper (list chr)) 'string))
diff --git a/src/package.lisp b/src/package.lisp
index d999783..3364856 100644
--- a/src/package.lisp
+++ b/src/package.lisp
@@ -1,4 +1,4 @@
-(defpackage #:rva
+helper(defpackage #:rva
(:use #:cl)
(:export #:main))
@@ -6,18 +6,21 @@
(:use #:cl)
(:export #:asm-extension?
#:format-as-binary
- #:label-loc
- #:mnemonic-loc))
+ #:type-r
+ #:type-i
+ #:type-j
+ #:label-loc))
(defpackage #:lex
(:use #:cl)
- (:export #:file->tokens
+ (:export #:lexer-error
+ #:file->tokens
;; exported for testing only
- #:read-token
- #:invalid-immediate-or-keyword))
+ #:read-token))
(defpackage #:parse
(:use #:cl)
- (:export #:tokens->ast
+ (:export #:parser-error
+ #:tokens->ast
;; exported for testing only
#:extract-label))
diff --git a/src/parse.lisp b/src/parse.lisp
index 8bd8c50..3052583 100644
--- a/src/parse.lisp
+++ b/src/parse.lisp
@@ -1,9 +1,20 @@
-(in-package #:parse)
+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)
- (let ((program (remove nil (mapcar #'extract-label program))))
- ;; TODO
- 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)
@@ -19,3 +30,26 @@ processing."
(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)
diff --git a/src/util.lisp b/src/util.lisp
index 1ea6dfc..5edee4a 100644
--- a/src/util.lisp
+++ b/src/util.lisp
@@ -11,27 +11,17 @@
(declare (type (integer 0 *) len))
(format nil "~V,'0b" len num))
-(defmacro generate-type-map (type opsize ops)
- "Generates an alist where the key corresponds to an element in
-OPS, while the value is the index of that key (padded to OPSIZE)
-concatenated with TYPE."
- `(let ((i 0))
- (mapcar (lambda (x)
- (incf i)
- (cons x (concatenate 'string ,type
- (format-as-binary i ,opsize))))
- ,ops)))
+(defparameter type-r
+ '(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)
+ "I-type instructions.")
+
+(defparameter type-j
+ '(JMP JRL JAL BEQ BGT BUF BOF PUSH POP)
+ "J-type instructions.")
(defparameter label-loc '()
"A symbol table mapping label names to line indices.")
-
-(defparameter mnemonic-loc
- `(,@(generate-type-map "00" 5
- '(ADD SUB MUL QUOT REM SFTR SFTL AND OR NOT
- XOR ADDV SUBV MULV DIVV CMP CEV))
- ,@(generate-type-map "01" 4
- '(LOAD LOADV ADDI SUBI SFTRI SFTLI ANDI ORI
- XORI STORE STOREV))
- ,@(generate-type-map "10" 4
- '(JMP JRL JAL BEQ BGT BUF BOF PUSH POP)))
- "An alist mapping known mnemonics to their binary representation.")