From aa378b3568b7dbb05de0de9f17abaae03863058a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Tom=C3=A1s?= Date: Mon, 1 May 2023 23:03:53 -0300 Subject: Improve flexibility This will make it easier to run the parser in a multi-stage setup without sacrificing the standalone setups. Modified comp to extract the location of parsed things. I expose the parts of the Input, Parsing and Failure objects to customize error handling. Parsing and Failure objects have a default printer now. --- input.lisp | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'input.lisp') diff --git a/input.lisp b/input.lisp index 8b031fd..a96888f 100644 --- a/input.lisp +++ b/input.lisp @@ -1,43 +1,43 @@ (in-package #:input) -(defstruct input - (cursor 0) - (file nil :read-only t) - (data nil :read-only t)) +(defclass input () + ((cursor :initarg :cursor :accessor cursor :initform 0) + (file :initarg :file :reader file :initform nil) + (data :initarg :data :reader data :initform nil))) -(defun has-data? (input &optional (window-size 1)) - (<= (+ window-size (input-cursor input)) - (length (input-data input)))) +(defun has-data? (input) + (< (cursor input) (length (data input)))) (defun prefix? (target input) - (string= target (input-data input) :start2 (input-cursor input) :end2 (+ (input-cursor input) (length target)))) + (string= target + (data input) + :start2 (cursor input) + :end2 (min (+ (cursor input) (length target)) + (length (data input))))) (defun peek (input) - (char (input-data input) - (input-cursor input))) + (char (data input) + (cursor input))) (defun advance (input &optional (amount 1)) - (let ((new-input (copy-structure input))) - (incf (input-cursor new-input) amount) - new-input)) + (make-instance 'input + :data (data input) + :file (file input) + :cursor (1+ (cursor input)))) -(declaim (ftype (function (simple-string) (values input &optional)) from-string)) (defun from-string (str) - (make-input :data str)) + (make-instance 'input :data str)) -(declaim (ftype (function (simple-string) (values input &optional)) from-file)) (defun from-file (filename) - (make-input :file filename :data (str:read-file filename))) + (make-instance 'input :file filename :data (str:read-file filename))) -(defun generate-report (input message) +(defun line-and-column (input) (let ((line 1) (column 1)) - (dotimes (i (input-cursor input)) - (let ((c (char (input-data input) i))) + (dotimes (i (cursor input)) + (let ((c (char (data input) i))) (case c (#\Newline (incf line) (setf column 1)) (t (incf column))))) - (if (input-file input) - (format nil "~a:~a:~a: ~a" (input-file input) line column message) - (format nil "~a:~a: ~a" line column message)))) + (values line column))) -- cgit v1.2.3