emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Initial GUD integration support.


From: Jan Nieuwenhuizen
Subject: [PATCH] Initial GUD integration support.
Date: Tue, 5 Aug 2014 15:21:45 +0200

        * examples/gud-break.scm: New example; showing initial GUD
        integration.

        * module/system/repl/debug.scm (debug-prompt): New procedure;
        gdb-like debug prompt.  Experimental!

        * module/system/repl/error-handling.scm (call-with-error-handling):
        * module/system/repl/command.scm (step, step-instruction, next)
        (next-instruction): Use it.
---
 examples/gud-break.scm                | 56 +++++++++++++++++++++++++++++++
 module/system/repl/command.scm        |  8 ++---
 module/system/repl/debug.scm          | 62 +++++++++++++++++++++++++++++++++++
 module/system/repl/error-handling.scm |  3 +-
 4 files changed, 124 insertions(+), 5 deletions(-)
 create mode 100644 examples/gud-break.scm

diff --git a/examples/gud-break.scm b/examples/gud-break.scm
new file mode 100644
index 0000000..8378a0c
--- /dev/null
+++ b/examples/gud-break.scm
@@ -0,0 +1,56 @@
+#! /bin/sh
+# -*-scheme-*-
+exec guile -e main -s "$0" "$@"
+!#
+;; Experimental GUD support for Guile REPL
+;; Find a gud.el that you want to patch, e.g.
+;;     zcat /usr/share/emacs/24.3/lisp/progmodes/gud.el.gz > ~/.emacs.d/gud.el
+;; or
+;;     M-x find-function gdb RET
+;;     C-x C-w ~/.emacs.d/gud.el RET
+;; Patch it
+;;     patch ~/.emacs.d/gud.el < 
0001-Initial-Guile-REPL-guiler-debugger-support-for-GUD.patch
+;; M-x load-library ~/.emacs.d/gud.el RET
+;; M-x guiler RET
+;; ,m gud-break
+;; ,br main
+;; ,r
+;; ,n
+;; ,n # no easy RET shortcut yet
+;;
+;; And see |> marker in Emac's left margin track the program's execution.
+
+(read-set! keywords 'prefix)
+
+(define (main . args)
+  (eval '(main (command-line)) (resolve-module '(gud-break))))
+
+(define-module (gud-break)
+  :export (main))
+
+(define (stderr fmt . args)
+  (apply format (cons (current-error-port) (cons* fmt args)))
+  (force-output (current-error-port)))
+
+(define (main . args) 
+  (stderr "~a:hello world\n" (current-source-location))
+  (let
+      ((a #f)
+       (b #f))
+    (set! a 1)
+    (stderr "set: a=~a\n" a)
+    (set! b 2)
+    (stderr "set: b=~a\n" b)
+    (let
+        ((c #f)
+         (d #f))
+      (set! c 3)
+      (stderr "set: c=~a\n" c)
+      (set! d 4)
+      (stderr "set: d=~a\n" d))
+    (stderr "~a:leaving...\n" (current-source-location)))
+  (stderr "~a:goodbye world\n" (current-source-location)))
+
+
+
+
diff --git a/module/system/repl/command.scm b/module/system/repl/command.scm
index 62bc297..3999c5e 100644
--- a/module/system/repl/command.scm
+++ b/module/system/repl/command.scm
@@ -740,7 +740,7 @@ Resume execution, breaking when the current frame finishes."
 Step until control reaches a different source location.
 
 Step until control reaches a different source location."
-  (let ((msg (format #f "Step into ~a" cur)))
+  (let ((msg (debug-prompt cur)))
     (add-ephemeral-stepping-trap! cur (repl-next-resumer msg)
                                   #:into? #t #:instruction? #f)
     (throw 'quit)))
@@ -750,7 +750,7 @@ Step until control reaches a different source location."
 Step until control reaches a different instruction.
 
 Step until control reaches a different VM instruction."
-  (let ((msg (format #f "Step into ~a" cur)))
+  (let ((msg (debug-prompt cur)))
     (add-ephemeral-stepping-trap! cur (repl-next-resumer msg)
                                   #:into? #t #:instruction? #t)
     (throw 'quit)))
@@ -760,7 +760,7 @@ Step until control reaches a different VM instruction."
 Step until control reaches a different source location in the current frame.
 
 Step until control reaches a different source location in the current frame."
-  (let ((msg (format #f "Step into ~a" cur)))
+  (let ((msg (debug-prompt cur)))
     (add-ephemeral-stepping-trap! cur (repl-next-resumer msg)
                                   #:into? #f #:instruction? #f)
     (throw 'quit)))
@@ -770,7 +770,7 @@ Step until control reaches a different source location in 
the current frame."
 Step until control reaches a different instruction in the current frame.
 
 Step until control reaches a different VM instruction in the current frame."
-  (let ((msg (format #f "Step into ~a" cur)))
+  (let ((msg (debug-prompt cur)))
     (add-ephemeral-stepping-trap! cur (repl-next-resumer msg)
                                   #:into? #f #:instruction? #t)
     (throw 'quit)))
diff --git a/module/system/repl/debug.scm b/module/system/repl/debug.scm
index 300145d..5e47d19 100644
--- a/module/system/repl/debug.scm
+++ b/module/system/repl/debug.scm
@@ -24,6 +24,7 @@
   #:use-module (system base language)
   #:use-module (system vm vm)
   #:use-module (system vm frame)
+  #:use-module (ice-9 and-let-star)
   #:use-module (ice-9 rdelim)
   #:use-module (ice-9 pretty-print)
   #:use-module (ice-9 format)
@@ -32,6 +33,7 @@
   #:export (<debug>
             make-debug debug?
             debug-frames debug-index debug-error-message
+            debug-prompt
             terminal-width
             print-registers print-locals print-frame print-frames frame->module
             stack->vector narrow-stack->vector
@@ -160,6 +162,66 @@
             (lp (+ i inc)
                 (frame-source frame)))))))
 
+(define *source-alist* '())
+(define (source-add file-name source)
+  (set! *source-alist* (assoc-set! *source-alist* file-name source))
+  source)
+
+(define* (gulp-port #:optional (port current-input-port)) 
+  (or (and-let* ((result (read-delimited "" port))
+                 ((string? result)))
+                result)
+      ""))
+
+(define (gulp-file file-name)
+  (gulp-port (open-input-file (format #f "~a" file-name))))
+
+(define (read-source-file file-name)
+  (or (assoc-ref *source-alist* file-name)
+      (and-let* ((source (gulp-file file-name))
+                 (lines (string-split source #\newline)))
+                (source-add file-name lines))))
+
+(define (fs-find-file file-name)
+  (let loop ((path (cons "." %load-path )))
+    (if (null? path)
+        #f
+        (let* ((dir (car path)) 
+               (fs-file-name (string-join (list dir file-name) "/")))
+          (if (file-exists? fs-file-name)
+              fs-file-name
+              (loop (cdr path)))))))
+
+(define (source-code file-name line-number)
+  (or (and-let* ((file-name file-name)
+                 (line-number line-number)
+                 (lines (read-source-file file-name)))
+                (list-ref lines line-number))
+      ""))
+
+(define *last-source* #f)
+(define* (debug-prompt frame #:optional (last-source *last-source*) (message 
""))
+  "A gdb,pydb-like debug prompt."
+  (define (source:pretty-file source)
+    (if source
+        (or (source:file source) "current input")
+        "unknown file"))
+  (let* ((source (frame-source frame))
+         (file (source:pretty-file source))
+         (file-name (fs-find-file file))
+         (line (and=> source source:line))
+         (col (and=> source source:column))
+         (code (source-code file-name line))
+         (line-column (format #f "~a~a" (if line (1+ line) "") 
+                              (if col (format #f ":~a" col) ""))))
+    (set! *last-source* source)
+    (string-append
+     (if (and file (not (equal? file (source:pretty-file last-source))))
+         (format #f "~&~a:~a:~a~&" file-name line-column message) ;;GNU 
standard!
+         ;;(format #f "~&In ~a:~a~&" file-name message) ;;or awkward Guile 
convention?
+         "")
+     (format #f "~&~10a~a" line-column code))))
+
 ;; Ideally here we would have something much more syntactic, in that a set! to 
a
 ;; local var that is not settable would raise an error, and export etc forms
 ;; would modify the module in question: but alack, this is what we have now.
diff --git a/module/system/repl/error-handling.scm 
b/module/system/repl/error-handling.scm
index 94a9f2a..1777854 100644
--- a/module/system/repl/error-handling.scm
+++ b/module/system/repl/error-handling.scm
@@ -80,7 +80,8 @@
                (begin
                  (format #t "~a~%" error-msg)
                  (format #t "Entering a new prompt.  ")
-                 (format #t "Type `,bt' for a backtrace or `,q' to 
continue.\n")))
+                 (format #t "Type `,bt' for a backtrace or `,q' to 
continue.\n")
+                 (format #t "~a~&" (debug-prompt frame #f))))
            ((@ (system repl repl) start-repl) #:debug debug)))))
 
     (define (null-trap-handler frame trap-idx trap-name)
-- 
Jan Nieuwenhuizen <address@hidden> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | AvatarĀ®  http://AvatarAcademy.nl  




reply via email to

[Prev in Thread] Current Thread [Next in Thread]