                         "Unknown Push instruction:'" token "'"))))
 
 
+(defn- throw-unknown-push-item-error
+  [item]
+  (throw (Exception. (str 
+                        "Push Parsing Error: Cannot interpret '"
+                        item
+                        "' as a Push item."))))
+
+
 (defn- add-instruction
   "Takes an Interpreter and an Instruction (record), and adds the
   instruction to the :instructions registry of the interpreter,



(defn boolean?
  "a checker that returns true if the argument is the literal `true` or the literal `false`"
  [item]
  (or (false? item) (true? item)))


(defn instruction?
  "takes an Interpreter and a keyword, and returns true if the keyword is a key of the :instructions registry in that Interpreter instance"
  [interpreter token]
  (contains? (:instructions interpreter) token))


(defn handle-item
  "Takes an Interpreter and an item, and either recognizes and invokes a keyword registered in that Interpreter as an instruction, or sends the item to the correct stack (if it exists). Throws an exception if the Clojure expression is not recognized explicitly as a registered instruction or some other kind of Push literal."
  [interpreter item]
  (cond
    (instruction? interpreter item) (execute-instruction interpreter item)
    (integer? item) (push-item interpreter :integer item)
    (boolean? item) (push-item interpreter :boolean item)
    (char? item) (push-item interpreter :char item)
    (float? item) (push-item interpreter :float item)
    (string? item) (push-item interpreter :string item)
    (list? item) (load-items interpreter :exec item)
    :else (throw
      (Exception. (str "Push Parsing Error: Cannot interpret '" item "' as a Push item.")))))


(defn clear-all-stacks
  "removes all items from all stacks in an Interpreter"
  [interpreter]
  (let [stacklist (keys (:stacks interpreter))]
    (assoc interpreter :stacks (reduce #(assoc %1 %2 '()) {} stacklist))))



(defn reset-interpreter

    :else interpreter)))


(defn get-stack
  "A convenience function which returns the named stack from the
  interpreter"
  [interpreter stack]
  (get-in interpreter [:stacks stack]))


(defn set-stack
  "A convenience function which replaces the named stack with the
  indicated list"
  [interpreter stack new-value]
  (assoc-in interpreter [:stacks stack] new-value))


(defn push-item
  "Takes an Interpreter, a stack name and a Clojure expression, and
  returns the Interpreter with the item pushed onto the specified
  stack. If the stack doesn't already exist, it is created."
  [interpreter stack item]
  (let [old-stack (get-in interpreter [:stacks stack])]
    (assoc-in interpreter [:stacks stack] (conj old-stack item))))


(defn load-items
  "Takes an Interpreter, a stack name, and a collection of items. Puts
  all the items onto the named stack, one at time (probably reversing
  them along the way."
  [interpreter stackname item-list]
  (let [old-stack (get-in interpreter [:stacks stackname])
        new-stack (into old-stack (reverse item-list))]
    (set-stack interpreter stackname new-stack)))


(defn clear-stack
