X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/aa14a4cddcb96b681d5c19a2ec8bad382f43b264..c3e28c92f639126436db713381309200eaba3ba2:/src/parser/scanner-proto.lisp diff --git a/src/parser/scanner-proto.lisp b/src/parser/scanner-proto.lisp index 966c77c..aed4c9f 100644 --- a/src/parser/scanner-proto.lisp +++ b/src/parser/scanner-proto.lisp @@ -7,7 +7,7 @@ ;;;----- Licensing notice --------------------------------------------------- ;;; -;;; This file is part of the Sensble Object Design, an object system for C. +;;; This file is part of the Sensible Object Design, an object system for C. ;;; ;;; SOD is free software; you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published by @@ -74,7 +74,7 @@ (:documentation "Capture the SCANNER's current place and return it.") (:method (scanner) - (error "Scanner ~S doesn't support rewinding." scanner))) + (error "Scanner ~S doesn't support rewinding" scanner))) (export 'scanner-restore-place) (defgeneric scanner-restore-place (scanner place) @@ -99,9 +99,12 @@ if you wanted to circumvent the cleanup then you should have used `with-parser-place', which does all of this in the meta-level." (once-only (scanner) - `(let ((,place (scanner-capture-place ,scanner))) - (unwind-protect (progn ,@body) - (scanner-release-place ,scanner ,place))))) + (multiple-value-bind (docs decls body) (parse-body body :docp nil) + (declare (ignore docs)) + `(let ((,place (scanner-capture-place ,scanner))) + ,@decls + (unwind-protect (progn ,@body) + (when ,place (scanner-release-place ,scanner ,place))))))) ;;;-------------------------------------------------------------------------- ;;; Character scanner protocol. @@ -154,6 +157,7 @@ (:documentation "Return the SCANNER's current column number.") (:method (scanner) nil)) +(export 'scanner-file-location) (defun scanner-file-location (scanner) "Capture the current location of the SCANNER. @@ -172,32 +176,11 @@ ;;;-------------------------------------------------------------------------- ;;; Token scanner protocol. -;; A place marker. - -(export '(token-scanner-place token-scanner-place-p)) -(defstruct token-scanner-place - "A link in the chain of lookahead tokens; capturable as a place. - - If the scanner's place is captured, it starts to maintain a list of - lookahead tokens. The list contains internal links -- it works out - slightly easier that way. This is basically a simpler version of the - charbuf scanner (q.v.); most significantly, the chain links here do double - duty as place markers. - - The details of this structure are not a defined part of the token scanner - protocol." - - (next nil :type (or token-scanner-place null)) - (type nil :read-only t) - (value nil :read-only t) - (line 1 :type (or fixnum null) :read-only t) - (column 0 :type (or fixnum null) :read-only t)) - ;; The token scanner base class and parser context. (export '(token-scanner token-type token-value)) (defclass token-scanner () - ((type :reader token-type) + ((%type :reader token-type) (value :reader token-value) (captures :initform 0 :type fixnum) (tail :initform nil :type (or token-scanner-place null)) @@ -212,11 +195,11 @@ scanner protocol, which explains the model. Subclasses must provide the detailed scanning behaviour -- most notably - the `scanner-token' generic function. This function should also update - the `line' and `column' slots to track the position in the underlying - source, if appropriate, and also implement a method on `file-location' to - return the location. This class will handle the remaining details, such - as dealing correctly with rewinding.")) + the `scanner-token' generic function -- and also implement a method on + `file-location' to return the location. The `scanner-token' method should + also update the `line' and `column' slots to track the position in the + underlying source, if appropriate. This class will handle the remaining + details, such as dealing correctly with rewinding.")) (export 'token-scanner-context) (defclass token-scanner-context (scanner-context token-parser-context) @@ -224,6 +207,33 @@ (:documentation "A parser context for a richer token-based scanners.")) +;; A place marker. + +(export '(token-scanner-place token-scanner-place-p)) +(defstruct (token-scanner-place + (:constructor make-token-scanner-place + (&key scanner next type value line column + &aux (%type type)))) + "A link in the chain of lookahead tokens; capturable as a place. + + If the scanner's place is captured, it starts to maintain a list of + lookahead tokens. The list contains internal links -- it works out + slightly easier that way. This is basically a simpler version of the + charbuf scanner (q.v.); most significantly, the chain links here do double + duty as place markers. + + The details of this structure are not a defined part of the token scanner + protocol." + + (scanner nil :type token-scanner :read-only t) + (next nil :type (or token-scanner-place null)) + (%type nil :read-only t) + (value nil :read-only t) + (line 1 :type (or fixnum null) :read-only t) + (column 0 :type (or fixnum null) :read-only t)) +(define-access-wrapper token-scanner-place-type token-scanner-place-%type + :read-only t) + ;; Protocol. (export 'scanner-token)