summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-03-20 13:51:28 -0400
committerbd <bdunahu@operationnull.com>2025-03-20 13:51:28 -0400
commit6e338215192c26dfb16236398ca8e3762a8d4d0e (patch)
tree823d7102f43ea5a4b377d5c2cb04a5ec02fb20b7 /src
parent19d13c8339ee990fba358417a54aa6f1c94c7bca (diff)
Add logic to open file, lex single character symbols, tests
Diffstat (limited to 'src')
-rw-r--r--src/lex.lisp52
-rw-r--r--src/main.lisp15
-rw-r--r--src/package.lisp6
3 files changed, 68 insertions, 5 deletions
diff --git a/src/lex.lisp b/src/lex.lisp
new file mode 100644
index 0000000..ad386ba
--- /dev/null
+++ b/src/lex.lisp
@@ -0,0 +1,52 @@
+(in-package #:lex)
+
+(defun file->tokens (file)
+ "Opens FILE and parses returns a list of tokens, or
+NIL if the file could not be opened."
+
+ (defun read-tokens (tokens-so-far)
+ "Collects tokens in FILE into TOKENS-SO-FAR."
+ (let ((token (read-token)))
+ (if token
+ (read-tokens (cons token tokens-so-far))
+ (reverse tokens-so-far))))
+
+ (and (probe-file file)
+ (with-open-file (*standard-input* file :direction :input)
+ (read-tokens '()))))
+
+(defun read-token ()
+ "Reads *STANDARD-INPUT* and returns a token, or nil if the end
+of file has been reached.
+Whitespace, commas, colons, and parentheses are token delimiters.
+Comments start with a semi-colon ';' and all tokens after are ignored."
+ (let ((chr (read-char *standard-input* nil)))
+ (cond
+ ((null chr) chr)
+ ((whitespace-char-p chr)
+ (read-token))
+
+ ((char= chr #\;)
+ (progn (read-line *standard-input* nil)
+ (read-token)))
+
+ ((char= chr #\() 'left-paren)
+ ((char= chr #\)) 'right-paren)
+
+ ((digit-char-p chr)
+ (read-immediate chr))
+
+ ((alpha-char-p chr)
+ (read-identifier chr))
+
+ (t (error (format nil "~a is not a valid lexical symbol.~%" chr))))))
+
+(defun read-immediate (chr)
+ 'immediate)
+
+(defun read-identifier (chr)
+ 'id)
+
+(defun whitespace-char-p (x)
+ (or (char= #\space x)
+ (not (graphic-char-p x))))
diff --git a/src/main.lisp b/src/main.lisp
index c85e392..1f0afdd 100644
--- a/src/main.lisp
+++ b/src/main.lisp
@@ -35,14 +35,19 @@ _/_/ _/_/ "
(defun driver (cmd)
"Reads in a file and directs lexing, parsing, and binary emission."
(print-splash)
- (let ((args (clingon:command-arguments cmd))
- (parse? (not (clingon:getopt cmd :lex)))
- (emit? (not (clingon:getopt cmd :parse))))
+ (let* ((args (clingon:command-arguments cmd))
+ (file (car args))
+ (parse? (not (clingon:getopt cmd :lex)))
+ (emit? (not (clingon:getopt cmd :parse))))
(cond
;; complain about num arguments
((/= (length args) 1) (error "Wrong number of arguments."))
- ((not (util:asm-extension? (car args))) (error "The file is not an asm source code file."))))
- (error-cli "Nitimur in Vetitum"))
+ ((not (util:asm-extension? file))
+ (error "The file is not an asm source code file, or it could not be opened."))
+ (t (let ((tokens (lex:file->tokens file)))
+ (format t "~a" tokens)
+ (format t "Nitimur in Vetitum~%"))))))
+
(defun cli/command ()
"Returns a clingon command."
diff --git a/src/package.lisp b/src/package.lisp
index 9d21293..44399cb 100644
--- a/src/package.lisp
+++ b/src/package.lisp
@@ -5,3 +5,9 @@
(defpackage #:util
(:use #:cl)
(:export #:asm-extension?))
+
+(defpackage #:lex
+ (:use #:cl)
+ (:export #:file->tokens
+ ;; exported for testing only
+ #:read-token))