blob: ad386ba38c336a366464fe0830b1efe7497e2d82 (
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
|
(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))))
|