An actual running implementation, which makes code that compiles.
[sod] / src / parser / scanner-impl.lisp
CommitLineData
dea4d055
MW
1;;; -*-lisp-*-
2;;;
3;;; Basic scanner interface
4;;;
5;;; (c) 2009 Straylight/Edgeware
6;;;
7
8;;;----- Licensing notice ---------------------------------------------------
9;;;
10;;; This file is part of the Sensble Object Design, an object system for C.
11;;;
12;;; SOD is free software; you can redistribute it and/or modify
13;;; it under the terms of the GNU General Public License as published by
14;;; the Free Software Foundation; either version 2 of the License, or
15;;; (at your option) any later version.
16;;;
17;;; SOD is distributed in the hope that it will be useful,
18;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;;; GNU General Public License for more details.
21;;;
22;;; You should have received a copy of the GNU General Public License
23;;; along with SOD; if not, write to the Free Software Foundation,
24;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26(cl:in-package #:sod-parser)
27
28;;;--------------------------------------------------------------------------
29;;; Common scanner implementation..
30
31(defmethod file-location ((scanner character-scanner))
32 (scanner-file-location scanner))
9ec578d9
MW
33
34(defmethod file-location ((scanner token-scanner))
35 (scanner-file-location scanner))
dea4d055
MW
36
37;;;--------------------------------------------------------------------------
38;;; Streams on character scanners.
39
40(defmethod stream-read-char ((stream character-scanner-stream))
41 (with-slots (scanner) stream
42 (if (scanner-at-eof-p scanner)
43 :eof
44 (prog1 (scanner-current-char scanner)
45 (scanner-step scanner)))))
46
47(defmethod stream-unread-char ((stream character-scanner-stream) char)
48 (with-slots (scanner) stream
49 (scanner-unread scanner char)))
50
51(defmethod stream-peek-char ((stream character-scanner-stream))
52 (with-slots (scanner) stream
53 (scanner-current-char scanner)))
54
55;;;--------------------------------------------------------------------------
56;;; String scanner.
57
58;; This is much more convenient for testing lexers than the full character
59;; buffer scanner.
60
61(export '(string-scanner make-string-scanner string-scanner-p))
62(defstruct (string-scanner
63 (:constructor make-string-scanner
64 (string &key (start 0) end
65 &aux (index start)
66 (limit (or end (length string))))))
67 "Scanner structure for a simple string scanner."
68 (string "" :type string :read-only t)
69 (index 0 :type (and fixnum unsigned-byte))
70 (limit nil :type (and fixnum unsigned-byte) :read-only t))
71
72(defmethod scanner-at-eof-p ((scanner string-scanner))
73 (>= (string-scanner-index scanner) (string-scanner-limit scanner)))
74
75(defmethod scanner-current-char ((scanner string-scanner))
76 (char (string-scanner-string scanner) (string-scanner-index scanner)))
77
78(defmethod scanner-step ((scanner string-scanner))
79 (incf (string-scanner-index scanner)))
80
81(defmethod scanner-capture-place ((scanner string-scanner))
82 (string-scanner-index scanner))
83
84(defmethod scanner-restore-place ((scanner string-scanner) place)
85 (setf (string-scanner-index scanner) place))
86
87(defmethod scanner-interval
88 ((scanner string-scanner) place-a &optional place-b)
89 (with-slots (string index) scanner
90 (subseq string place-a (or place-b index))))
91
92;;;--------------------------------------------------------------------------
93;;; List scanner.
94
95(export 'list-scanner)
96(defstruct (list-scanner
97 (:constructor make-list-scanner (list)))
98 "Simple token scanner for lists.
99
100 The list elements are the token semantic values; the token types are the
101 names of the elements' classes. This is just about adequate for testing
102 purposes, but is far from ideal for real use."
103 (list nil :type list))
104
105(defmethod scanner-step ((scanner list-scanner))
106 (pop (list-scanner-list scanner)))
107
108(defmethod scanner-at-eof-p ((scanner list-scanner))
109 (null (list-scanner-list scanner)))
110
111(defmethod token-type ((scanner list-scanner))
112 (class-name (class-of (car (list-scanner-list scanner)))))
113
114(defmethod token-value ((scanner list-scanner))
115 (car (list-scanner-list scanner)))
116
117(defmethod scanner-capture-place ((scanner list-scanner))
118 (list-scanner-list scanner))
119
120(defmethod scanner-restore-place ((scanner list-scanner) place)
121 (setf (list-scanner-list scanner) place))
122
123;;;----- That's all, folks --------------------------------------------------