From 5eeb83d2b620e77000ab77269faa974007c9ff28 Mon Sep 17 00:00:00 2001 Message-Id: <5eeb83d2b620e77000ab77269faa974007c9ff28.1719152086.git.mdw@distorted.org.uk> From: Mark Wooding Date: Tue, 20 Aug 2019 02:26:17 +0100 Subject: [PATCH] src/pset-parse.lisp: Add a little vertical space and commentary. Organization: Straylight/Edgeware From: Mark Wooding --- src/pset-parse.lisp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/pset-parse.lisp b/src/pset-parse.lisp index 4dec565..e86be27 100644 --- a/src/pset-parse.lisp +++ b/src/pset-parse.lisp @@ -64,6 +64,12 @@ (defun parse-expression (scanner) ,@body)))))) (flet ((dispatch (name args &rest spec) + ;; Evaluate the ARGS to determine their types and values. Find + ;; the first SPEC, of the form (RETTY OP ARGTY*), where the + ;; ARGTYs match the argument types, in order, and apply OP to + ;; the argument values, return this as a result of type RETTY. + ;; If no SPEC matches, then report an error. + (oplambda (let ((args (mapcar (compose #'funcall #'cons) args))) (aif (find-if (lambda (item) @@ -81,13 +87,21 @@ (defun parse-expression (scanner) ;; Parse the expression, producing a thunk. (expr (:nestedp nestedp) + (lisp (case (token-type scanner) + ((:int :id :char :string) + ;; A simple literal. (let ((type (token-type scanner)) (value (token-value scanner))) (scanner-step scanner) (values (lambda () (values type value)) t t))) + (#\? + ;; A Lisp s-expression. Catch and report reader- + ;; errors (though the main parser will probably + ;; end up /very/ confused); delay evaluation for + ;; later. (handler-case (let* ((stream (make-scanner-stream scanner)) (sexp (read stream t))) @@ -100,12 +114,16 @@ (defun parse-expression (scanner) "Lisp `read' error: ~A" cond) (values #'continue t t)))) + (#\{ + ;; A code fragment. (let ((fragment (parse-delimited-fragment scanner #\{ #\}))) (values (lambda () (values :fragment fragment)) t t))) + (#\< + ;; A C type. (parse (seq (#\< (ds (parse-c-type scanner)) (dc (parse-declarator @@ -116,10 +134,13 @@ (defun parse-expression (scanner) #\>) (values (lambda () (values :type (car dc))) t t)))) + (t + ;; Anything else is an error. (values (list :int :id :char :string #\? #\{ #\<) nil nil)))) + ;; Binary operators. ((:op #\* binop "*" (x y 7) (dispatch "*" (list x y) (list :int #'* :int :int))) (:op #\/ binop "/" (x y 7) @@ -138,12 +159,14 @@ (defun parse-expression (scanner) (:op #\- binop "-" (x y 5) (dispatch "-" (list x y) (list :int #'- :int :int)))) + ;; Prefix operators. ((:op #\+ preop "+" (x 9) (dispatch "+" (list x) (list :int #'+ :int))) (:op #\- preop "-" (x 9) (dispatch "-" (list x) (list :int #'- :int))) (:op #\( lparen #\))) + ;; Postfix operators. ((:op (when nestedp #\)) rparen #\)))) ;; Do the delayed evaluation. Establish a restart so that we can -- [mdw]