summaryrefslogtreecommitdiff
path: root/base.lisp
diff options
context:
space:
mode:
authorJuan Manuel Tomás <jtomas1815@gmail.com>2026-03-17 17:48:03 -0300
committerJuan Manuel Tomás <jtomas1815@gmail.com>2026-03-17 17:48:03 -0300
commitd08d5b232d74f3a75a833b231c4ef5e80870c993 (patch)
treec123d61d35a992f5ea460a96eb89d1550c646b25 /base.lisp
parentd78ef10ad3ffe0eeaee0cd2a8f6b58e403085d48 (diff)
downloadmonparser-d08d5b232d74f3a75a833b231c4ef5e80870c993.tar.gz
monparser-d08d5b232d74f3a75a833b231c4ef5e80870c993.zip
Unify cursor start and endHEADmain
Diffstat (limited to 'base.lisp')
-rw-r--r--base.lisp63
1 files changed, 25 insertions, 38 deletions
diff --git a/base.lisp b/base.lisp
index 0599a3c..7c72501 100644
--- a/base.lisp
+++ b/base.lisp
@@ -1,61 +1,48 @@
(in-package #:monparser)
-(defstruct result)
+(defstruct result
+ (place (make-instance 'cursor) :type cursor))
(defstruct (parsing (:include result))
- tree
- (start (make-instance 'cursor) :type cursor)
- (end (make-instance 'cursor) :type cursor))
+ tree)
(defstruct (failure (:include result))
- (place (make-instance 'cursor) :type cursor)
(message "" :type string)
(priority 0 :type integer))
+(defmethod print-object ((obj failure) stream)
+ (let ((linecol (line-and-column (result-place obj))))
+ (format stream "~a:~a: ~a~&~a~&"
+ (car linecol) (cdr linecol) (failure-message obj) (result-place obj))))
+
(deftype parser ()
- `(function (cursor cursor) result))
+ `(function (cursor) result))
(defmacro lazy (parser &rest args)
- (let ((start (gensym))
- (input (gensym)))
+ (let ((input (gensym)))
`(the parser
- (lambda (,start ,input)
- (funcall (,parser ,@args) ,start ,input)))))
-
-(defun line-and-column (str index)
- (let ((line 1) (column 1))
- (dotimes (i index)
- (let ((c (char str i)))
- (case c
- (#\Newline
- (incf line)
- (setf column 1))
- (t (incf column)))))
- (cons line column)))
-
-(defmethod print-object ((obj failure) stream)
- (let ((linecol (line-and-column (data (failure-place obj))
- (index (failure-place obj)))))
- (format stream "~a:~a: ~a~&~a~&"
- (car linecol) (cdr linecol) (failure-message obj) (failure-place obj))))
+ (lambda (,input)
+ (funcall (,parser ,@args) ,input)))))
(declaim (ftype (function (t &key (:priority integer)) parser) fail))
(defun fail (message &key (priority 1))
- (lambda (start input)
- (declare (ignore start))
+ (lambda (input)
(make-failure :place input :message message :priority priority)))
(declaim (ftype (function (t) parser) new))
(defun new (tree)
- (lambda (start input)
- (make-parsing :tree tree :start start :end input)))
+ (lambda (input)
+ (make-parsing :place input :tree tree)))
+
+(deftype parser-continuation ()
+ `(function (t) parser))
-(declaim (ftype (function (parser (function (result) parser)) parser) bind))
+(declaim (ftype (function (parser parser-continuation) parser) bind))
(defun bind (parser f)
- (lambda (start input)
- (let ((r (funcall parser input input)))
+ (lambda (input)
+ (let ((r (funcall parser (cursor-rebase input))))
(cond ((parsing-p r)
- (funcall (funcall f r) start (parsing-end r)))
+ (funcall (funcall f r) (cursor-merge input (result-place r))))
((failure-p r) r)
(t (error (format nil "Invalid return value: ~a" r)))))))
@@ -67,18 +54,18 @@
(cond ((symbolp var)
(if (string= (symbol-name var) "_")
`(bind ,parser
- (the (function (result) parser)
+ (the parser-continuation
(lambda (,var)
(declare (ignore ,var))
(comp ,(cdr bindings) ,@body))))
`(bind ,parser
- (the (function (result) parser)
+ (the parser-continuation
(lambda (,var)
(let ((,var (parsing-tree ,var)))
(comp ,(cdr bindings) ,@body)))))))
((and (listp var) (= (length var) 1) (symbolp (car var)))
`(bind ,parser
- (the (function (result) parser)
+ (the parser-continuation
(lambda (,(first var))
(comp ,(cdr bindings) ,@body)))))
(t (error "Binding must be either a symbol or a list of one symbol."))))))