lib/sod-hosted.c (sod_makev): Use two statements rather than tricky expression.
[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;;;
e0808c47 10;;; This file is part of the Sensible Object Design, an object system for C.
dea4d055
MW
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
7702b7bc
MW
64 (string
65 &key (start 0) end filename
4b8e5c03
MW
66 &aux (%string string)
67 (index start)
dea4d055
MW
68 (limit (or end (length string))))))
69 "Scanner structure for a simple string scanner."
4b8e5c03 70 (%string "" :type string :read-only t)
f5992dc3 71 (filename "<string>" :type string :read-only t)
dea4d055 72 (index 0 :type (and fixnum unsigned-byte))
f5992dc3
MW
73 (limit nil :type (and fixnum unsigned-byte) :read-only t)
74 (line 1 :type fixnum)
75 (column 0 :type fixnum))
4b8e5c03
MW
76(define-access-wrapper string-scanner-string string-scanner-%string
77 :read-only t)
dea4d055
MW
78
79(defmethod scanner-at-eof-p ((scanner string-scanner))
80 (>= (string-scanner-index scanner) (string-scanner-limit scanner)))
81
82(defmethod scanner-current-char ((scanner string-scanner))
83 (char (string-scanner-string scanner) (string-scanner-index scanner)))
84
85(defmethod scanner-step ((scanner string-scanner))
f5992dc3
MW
86 (let ((index (string-scanner-index scanner)))
87 (setf (values (string-scanner-line scanner)
88 (string-scanner-column scanner))
89 (update-position (char (string-scanner-string scanner) index)
90 (string-scanner-line scanner)
91 (string-scanner-column scanner))
92 (string-scanner-index scanner) (1+ index))))
dea4d055 93
2392e488 94(defmethod scanner-unread ((scanner string-scanner) char)
f5992dc3
MW
95 (let ((index (1- (string-scanner-index scanner))))
96 (setf (values (string-scanner-line scanner)
97 (string-scanner-column scanner))
98 (backtrack-position (char (string-scanner-string scanner) index)
99 (string-scanner-line scanner)
100 (string-scanner-column scanner))
101 (string-scanner-index scanner) index)))
102
103(defmethod scanner-filename ((scanner string-scanner))
104 (string-scanner-filename scanner))
105(defmethod scanner-line ((scanner string-scanner))
106 (string-scanner-line scanner))
107(defmethod scanner-column ((scanner string-scanner))
108 (string-scanner-column scanner))
109(defmethod file-location ((scanner string-scanner))
110 (make-file-location (string-scanner-filename scanner)
111 (string-scanner-line scanner)
112 (string-scanner-column scanner)))
2392e488 113
dea4d055
MW
114(defmethod scanner-capture-place ((scanner string-scanner))
115 (string-scanner-index scanner))
116
117(defmethod scanner-restore-place ((scanner string-scanner) place)
118 (setf (string-scanner-index scanner) place))
119
120(defmethod scanner-interval
121 ((scanner string-scanner) place-a &optional place-b)
4b8e5c03 122 (with-slots ((string %string) index) scanner
dea4d055
MW
123 (subseq string place-a (or place-b index))))
124
9e41cce7
MW
125(defmethod make-scanner-stream ((scanner string-scanner))
126 (make-instance 'character-scanner-stream :scanner scanner))
127
dea4d055
MW
128;;;--------------------------------------------------------------------------
129;;; List scanner.
130
61c7351e 131(export '(list-scanner list-scanner-p make-list-scanner))
dea4d055 132(defstruct (list-scanner
4b8e5c03 133 (:constructor make-list-scanner (list &aux (%list list))))
dea4d055
MW
134 "Simple token scanner for lists.
135
136 The list elements are the token semantic values; the token types are the
137 names of the elements' classes. This is just about adequate for testing
138 purposes, but is far from ideal for real use."
4b8e5c03
MW
139 (%list nil :type list))
140(define-access-wrapper list-scanner-list list-scanner-%list)
dea4d055
MW
141
142(defmethod scanner-step ((scanner list-scanner))
143 (pop (list-scanner-list scanner)))
144
145(defmethod scanner-at-eof-p ((scanner list-scanner))
146 (null (list-scanner-list scanner)))
147
148(defmethod token-type ((scanner list-scanner))
149 (class-name (class-of (car (list-scanner-list scanner)))))
150
151(defmethod token-value ((scanner list-scanner))
152 (car (list-scanner-list scanner)))
153
154(defmethod scanner-capture-place ((scanner list-scanner))
155 (list-scanner-list scanner))
156
157(defmethod scanner-restore-place ((scanner list-scanner) place)
158 (setf (list-scanner-list scanner) place))
159
160;;;----- That's all, folks --------------------------------------------------