src/parser/parse-expr-{proto,impl}.lisp: Fully hide the parser state.
[sod] / src / parser / parser-expr-impl.lisp
index 5ae4035..d4bc3a0 100644 (file)
@@ -7,7 +7,7 @@
 
 ;;;----- Licensing notice ---------------------------------------------------
 ;;;
-;;; This file is part of the Sensble Object Design, an object system for C.
+;;; This file is part of the Sensible Object Design, an object system for C.
 ;;;
 ;;; SOD is free software; you can redistribute it and/or modify
 ;;; it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@
 (cl:in-package #:sod-parser)
 
 ;;;--------------------------------------------------------------------------
-;;; Basic protocol implementation.
+;;; Basic protocol.
 
 (defclass expression-parse-state ()
   ((opstack :initform nil :type list)
   (: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
          (let ((head (car opstack)))
            (cond ((not (typep head 'open-parenthesis))
                   (apply-operator head state))
-                 ((not (eq (slot-value head 'tag) tag))
+                 ((not (eql (slot-value head 'tag) tag))
                   (fail))
                  (t
                   (return)))
                       (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)))))