From 6e338215192c26dfb16236398ca8e3762a8d4d0e Mon Sep 17 00:00:00 2001 From: bd Date: Thu, 20 Mar 2025 13:51:28 -0400 Subject: Add logic to open file, lex single character symbols, tests --- src/lex.lisp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/lex.lisp (limited to 'src/lex.lisp') 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)))) -- cgit v1.2.3