lib/sod-hosted.c (sod_makev): Use two statements rather than tricky expression.
[sod] / src / parser / scanner-impl.lisp
... / ...
CommitLineData
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 Sensible 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))
33
34(defmethod file-location ((scanner token-scanner))
35 (scanner-file-location scanner))
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
65 &key (start 0) end filename
66 &aux (%string string)
67 (index start)
68 (limit (or end (length string))))))
69 "Scanner structure for a simple string scanner."
70 (%string "" :type string :read-only t)
71 (filename "<string>" :type string :read-only t)
72 (index 0 :type (and fixnum unsigned-byte))
73 (limit nil :type (and fixnum unsigned-byte) :read-only t)
74 (line 1 :type fixnum)
75 (column 0 :type fixnum))
76(define-access-wrapper string-scanner-string string-scanner-%string
77 :read-only t)
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))
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))))
93
94(defmethod scanner-unread ((scanner string-scanner) char)
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)))
113
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)
122 (with-slots ((string %string) index) scanner
123 (subseq string place-a (or place-b index))))
124
125(defmethod make-scanner-stream ((scanner string-scanner))
126 (make-instance 'character-scanner-stream :scanner scanner))
127
128;;;--------------------------------------------------------------------------
129;;; List scanner.
130
131(export '(list-scanner list-scanner-p make-list-scanner))
132(defstruct (list-scanner
133 (:constructor make-list-scanner (list &aux (%list list))))
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."
139 (%list nil :type list))
140(define-access-wrapper list-scanner-list list-scanner-%list)
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 --------------------------------------------------