       (set-buffer (get-buffer-create zomp-symbol-buffer))
       (insert-file-contents zomp-symbol-file nil nil nil t))
     (process-send-string
-     (zomp-get-toplevel-buffer)
+     (zomp-get-shell-buffer)
      (concat "!silent !writeSymbols " zomp-symbol-file "
 "))))
 

  (interactive)
  (when (called-interactively-p)
    (message "Evaluating buffer"))
  (zomp-tl-do (buffer-substring (buffer-end -1) (buffer-end 1)) 'create "


")
  (zomp-tl-move-point-to-end))

(defun zomp-tl-discard-input ()
  (interactive)
  (zomp-tl-do "!"))

(defun zomp-tl-run-test ()
  (interactive)
  (when (called-interactively-p)
    (message "Running function test"))
  (zomp-tl-move-point-to-end)
  (zomp-tl-do "!run test"))

(defun zomp-run (&optional prefix)
"Will run test() after evaluating
- the current toplevel expression (function) if toplevel is running
- the current buffer of toplevel is not running
so you can use this as a quick way to start working on a project.

Run this with a prefix to start a toplevel specific to this buffer"
  (interactive "P")
  (when prefix
    (zomp-make-buffer-local-toplevel))
  (if (zomp-get-toplevel-buffer)
      (progn
        (zomp-request-execution-abort)
        (zomp-tl-eval-current))
    (zomp-start-or-show-toplevel prefix)
    (zomp-tl-eval-buffer))
  (zomp-tl-run-test))

(defun zomp-request-execution-abort ()
  "Send a signal to the toplevel to request it to abort the
current main() execution.

Will cause the zompRequestedPause() function to return true. Any
application honoring this will then return from main to allow the
editor to trigger recompilations etc. and possibly resume main()"
  (interactive)
  (when (zomp-get-toplevel-buffer)
    (with-current-buffer zomp-toplevel-buffer-name
      (comint-interrupt-subjob))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

      )))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; shell interaction

(defvar zomp-shell-buffer-name "*zomp-shell*"
  "The name of the buffer in which the zomp shell runs")

(define-derived-mode zomp-shell-mode shell-mode "ZompTL"
  "Major mode for a zomp shell in which you can interactively
  compile and run zomp code"
  (set (make-variable-buffer-local 'comint-use-prompt-regexp) t)
  (set (make-variable-buffer-local 'comint-prompt-regexp) "  # "))

(defun zomp-shell ()
  (interactive)
  (let ((zomp-new-tl-buffer-name zomp-shell-buffer-name) (oldwin (selected-window)))
    (shell zomp-shell-buffer-name)
    ;; in case zomp-shell-buffer-name is buffer local we need to be sure it
    ;; has the same value in the shell buffer as in the zomp buffer invoking
    ;; the shell
    (zomp-shell-mode)
    (set (make-local-variable 'zomp-shell-buffer-name) zomp-new-tl-buffer-name)
    (zomp-tl-do (concat "cd " zomp-basedir))
    (zomp-tl-do "./zomp_shell.native; exit")
    (message "Started zomp shell")
    (select-window oldwin)))

(defun zomp-get-shell-buffer (&optional create-if-not-existing)
  "Get the zomp shell interaction buffer. If `create-if-not-existing' is equal
 to 'create the shell will be started if it is not not running, yet"
  (or
   (get-buffer-process zomp-shell-buffer-name)
   (when (equal create-if-not-existing 'create)
     (zomp-shell)
     (get-buffer-process zomp-shell-buffer-name))))

(defun zomp-shell-move-point-to-end ()
  "Will move the point to the end of the shell buffer for all
windows displaying it"
  (let ((original-window (selected-window)))
    (dolist (wnd (get-buffer-window-list (get-buffer zomp-shell-buffer-name)))
      (select-window wnd)
      (goto-char (point-max)))
    (select-window original-window)))

(defun zomp-make-buffer-local-shell ()
  (make-variable-buffer-local 'zomp-shell-buffer-name)
  (setq zomp-shell-buffer-name (format "*zomp-shell<%s>*" (buffer-name))))

(defun zomp-start-or-show-shell (&optional prefix)
  "Shows the shell in a buffer and starts it if it wasn't
  running, yet. With a prefix this will start a buffer local zomp
  shell which you can use to run multiple zomp instances at
  once"
  (interactive "P")
  (cond ((null prefix)
         (if (not (zomp-get-shell-buffer))
             (zomp-shell)
           (let ((oldwin (selected-window)))
             (switch-to-buffer-other-window (get-buffer zomp-shell-buffer-name))
             (select-window oldwin))))
        (t
         (zomp-make-buffer-local-shell)
         (unless (zomp-get-shell-buffer)
           (zomp-shell)))))

(defun zomp-shell-do (code &optional create-if-not-existing append)
  "Send some text to the zomp toplevel. If
  `create-if-not-existing' is 'create then the toplevel will be
  started if it is not running, yet"
  (if (not (or create-if-not-existing (zomp-get-shell-buffer)))
      (message "Zomp shell is not running")
    (process-send-string (zomp-get-shell-buffer create-if-not-existing) "!prompt
")
    (process-send-string
     (zomp-get-shell-buffer create-if-not-existing)
     (concat code (or append "
")))
    (process-send-string (zomp-get-shell-buffer) "!prompt #
")))

(defun zomp-tl-run (funcname)
  (interactive "MName of function: ")
  (when (= 0 (length funcname))
    (setq funcname "main"))
  (zomp-shell-move-point-to-end)
  (zomp-shell-do (concat "!run " funcname)))

(defun zomp-tl-list-bindings (regexps)
  (interactive "MList bindings matching: ")
  (zomp-shell-do (concat "!bindings " regexps)))

(defun zomp-tl-eval-region ()
  (interactive)
  (when (called-interactively-p)
    (message "Evaluating region"))
  (zomp-request-execution-abort)
  (zomp-shell-do (buffer-substring (region-beginning) (region-end)) nil "


"))
