diff options
author | bd <bdunahu@operationnull.com> | 2025-03-20 13:51:28 -0400 |
---|---|---|
committer | bd <bdunahu@operationnull.com> | 2025-03-20 13:51:28 -0400 |
commit | 6e338215192c26dfb16236398ca8e3762a8d4d0e (patch) | |
tree | 823d7102f43ea5a4b377d5c2cb04a5ec02fb20b7 /src/lex.lisp | |
parent | 19d13c8339ee990fba358417a54aa6f1c94c7bca (diff) |
Add logic to open file, lex single character symbols, tests
Diffstat (limited to 'src/lex.lisp')
-rw-r--r-- | src/lex.lisp | 52 |
1 files changed, 52 insertions, 0 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)))) |