From 7a6f4586c2e83ffcdb5a8b7b2c5591f6e80e038f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Tom=C3=A1s?= Date: Sun, 13 Oct 2024 00:34:11 -0300 Subject: Change project file structure and api --- base.lisp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 base.lisp (limited to 'base.lisp') diff --git a/base.lisp b/base.lisp new file mode 100644 index 0000000..8206322 --- /dev/null +++ b/base.lisp @@ -0,0 +1,51 @@ +(in-package #:monparser) + +(defstruct parsing + tree + left + limit) + +(defstruct failure + place + message) + +(defun lazy-parsing-p (r) + (or (functionp r) + (parsing-p r))) + +(defun new (tree) + (lambda (input &key limit lazy) + (declare (ignore lazy)) + (if (and limit (> limit 0)) + (make-failure :place input + :message (format nil "Didn't reach expected limit: ~a." limit)) + (make-parsing :tree tree :left input)))) + +(defun bind (p f &key (greedy t)) + (lambda (input &key limit lazy) + (let (r) + (if greedy + (setf r (funcall p input :limit limit)) + (let ((next-parser (funcall f nil input)) + (limit -1)) + (do ((sweep-input input (advance sweep-input))) + ((or (not (has-data? sweep-input)) + (> limit -1)) nil) + (when (lazy-parsing-p (funcall next-parser sweep-input :lazy t)) + (setf limit (cursor-distance sweep-input input)))) + (if (< limit 0) + (setf r (make-failure :place input + :message "Reached end of input while sweeping.")) + (setf r (funcall p input :limit limit))))) + (if (parsing-p r) + (if lazy + (lambda (ignored-input &key lazy limit) + (declare (ignore ignored-input limit)) + (funcall (funcall f (parsing-tree r) input) + (parsing-left r) + :lazy lazy + :limit (if greedy (parsing-limit r)))) + (funcall (funcall f (parsing-tree r) input) + (parsing-left r) + :limit (if greedy (parsing-limit r)))) + r)))) -- cgit v1.2.3