chiark / gitweb /
src/parser/parse-expr-{proto,impl}.lisp: Fully hide the parser state.
[sod] / src / parser / parser-expr-impl.lisp
index 16e0c5331864f9ab1d6fe1ebb19fe63d48fbe0e4..d4bc3a09ca0059e101d84a5369e72a0cd902eb3b 100644 (file)
@@ -26,7 +26,7 @@
 (cl:in-package #:sod-parser)
 
 ;;;--------------------------------------------------------------------------
-;;; Basic protocol implementation.
+;;; Basic protocol.
 
 (defclass expression-parse-state ()
   ((opstack :initform nil :type list)
@@ -35,9 +35,18 @@ (defclass expression-parse-state ()
   (:documentation
    "State for the expression parser.  Largely passive."))
 
-(defmethod push-value (value (state expression-parse-state))
-  (with-slots (valstack) state
-    (push value valstack)))
+(defgeneric push-operator (operator state)
+  (:documentation
+   "Push an OPERATOR onto the STATE's operator stack.
+
+   This should apply existing stacked operators as necessary to obey the
+   language's precedence rules."))
+
+(defgeneric apply-operator (operator state)
+  (:documentation
+   "Apply the OPERATOR to arguments on the STATE's value stack.
+
+   This should pop any necessary arguments, and push the result."))
 
 (defmethod push-operator (operator (state expression-parse-state))
   (with-slots (opstack) state
@@ -204,7 +213,7 @@ (defun parse-expression (p-operand p-binop p-preop p-postop)
                       (push-operator value state)))
               (multiple-value-bind (value winp) (parse p-operand)
                 (unless winp (fail value))
-                (push-value value state))
+                (push value (slot-value state 'valstack)))
               (loop (multiple-value-bind (value winp) (parse p-postop)
                       (unless winp (return))
                       (push-operator value state)))))