⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debugger.scm

📁 MSYS在windows下模拟了一个类unix的终端
💻 SCM
📖 第 1 页 / 共 2 页
字号:
(define state? (record-predicate state-rtd))(define make-state (record-constructor state-rtd '(stack index)))(define state-stack (record-accessor state-rtd 'stack))(define state-index (record-accessor state-rtd 'index))(define (new-state-index state index)  (make-state (state-stack state) index));;;; Character parsing(define (read-token port)  (letrec      ((loop	(lambda (chars)	  (let ((char (peek-char port)))	    (cond ((eof-object? char)		   (do-eof char chars))		  ((char=? #\newline char)		   (do-eot chars))		  ((char-whitespace? char)		   (do-eot chars))		  ((char=? #\# char)		   (read-char port)		   (let ((terminator (skip-comment port)))		     (if (eof-object? char)			 (do-eof char chars)			 (do-eot chars))))		  (else		   (read-char port)		   (loop (cons char chars)))))))       (do-eof	(lambda (eof chars)	  (if (null? chars)	      eof	      (do-eot chars))))       (do-eot	(lambda (chars)	  (if (null? chars)	      #f	      (list->string (reverse! chars))))))    (skip-whitespace port)    (loop '())))(define (skip-whitespace port)  (let ((char (peek-char port)))    (cond ((or (eof-object? char)	       (char=? #\newline char))	   char)	  ((char-whitespace? char)	   (read-char port)	   (skip-whitespace port))	  ((char=? #\# char)	   (read-char port)	   (skip-comment port))	  (else char))))(define (skip-comment port)  (let ((char (peek-char port)))    (if (or (eof-object? char)	    (char=? #\newline char))	char	(begin	  (read-char port)	  (skip-comment port)))))(define (read-rest-of-line port)  (let loop ((chars '()))    (let ((char (read-char port)))      (if (or (eof-object? char)	      (char=? #\newline char))	  (list->string (reverse! chars))	  (loop (cons char chars))))))(define (discard-rest-of-line port)  (let loop ()    (if (not (let ((char (read-char port)))	       (or (eof-object? char)		   (char=? #\newline char))))	(loop))));;;; Commands(define command-table (make-command-table '()))(define-command "help" 'tokens  "Type \"help\" followed by a command name for full documentation."  (lambda (state tokens)    (let loop ((name (if (null? tokens) '("help") tokens)))      (let ((value (lookup-command name)))	(cond ((not value)	       (write-command-name name)	       (display " is not a known command name.")	       (newline))	      ((command? value)	       (display (command-documentation value))	       (newline)	       (if (equal? '("help") (command-name value))		   (begin		     (display "Available commands are:")		     (newline)		     (for-each (lambda (entry)				 (if (not (list? (caddr entry)))				     (begin				       (display "  ")				       (display (car entry))				       (newline))))			       (command-table-entries command-table)))))	      ((command-table? value)	       (display "The \"")	       (write-command-name name)	       (display "\" command requires a subcommand.")	       (newline)	       (display "Available subcommands are:")	       (newline)	       (for-each (lambda (entry)			   (if (not (list? (caddr entry)))			       (begin				 (display "  ")				 (write-command-name name)				 (write-char #\space)				 (display (car entry))				 (newline))))			 (command-table-entries value)))	      ((list? value)	       (loop value))	      (else	       (error "Unknown value from lookup-command:" value)))))    state))(define-command "frame" '('optional exact-nonnegative-integer)  "Select and print a stack frame.With no argument, print the selected stack frame.  (See also \"info frame\").An argument specifies the frame to select; it must be a stack-frame number."  (lambda (state n)    (let ((state (if n (select-frame-absolute state n) state)))      (write-state-short state)      state)))(define-command "position" '()  "Display the position of the current expression."  (lambda (state)    (let* ((frame (stack-ref (state-stack state) (state-index state)))	   (source (frame-source frame)))      (if (not source)	  (display "No source available for this frame.")	  (let ((position (source-position source)))	    (if (not position)		(display "No position information available for this frame.")		(display-position position)))))    (newline)    state))(define-command "up" '('optional exact-integer)  "Move N frames up the stack.  For positive numbers N, this advancestoward the outermost frame, to higher frame numbers, to framesthat have existed longer.  N defaults to one."  (lambda (state n)    (let ((state (select-frame-relative state (or n 1))))      (write-state-short state)      state)))(define-command "down" '('optional exact-integer)  "Move N frames down the stack.  For positive numbers N, thisadvances toward the innermost frame, to lower frame numbers, toframes that were created more recently.  N defaults to one."  (lambda (state n)    (let ((state (select-frame-relative state (- (or n 1)))))      (write-state-short state)      state)))(define (eval-handler key . args)  (let ((stack (make-stack #t eval-handler)))    (if (= (length args) 4)	(apply display-error stack (current-error-port) args)	;; We want display-error to be the "final common pathway"	(catch #t	       (lambda ()		 (apply bad-throw key args))	       (lambda (key . args)		 (apply display-error stack (current-error-port) args)))))  (throw 'continue))(define-command "evaluate" '(object)  "Evaluate an expression.The expression must appear on the same line as the command,however it may be continued over multiple lines."  (lambda (state expression)    (let ((source (frame-source (stack-ref (state-stack state)					   (state-index state)))))      (if (not source)	  (display "No environment for this frame.\n")	  (catch 'continue		 (lambda ()		   (lazy-catch #t			       (lambda ()				 (let* ((env (memoized-environment source))					(value (local-eval expression env)))				   (display ";value: ")				   (write value)				   (newline)))			       eval-handler))		 (lambda args args)))      state)))(define-command "backtrace" '('optional exact-integer)  "Print backtrace of all stack frames, or innermost COUNT frames.With a negative argument, print outermost -COUNT frames.If the number of frames aren't explicitly given, the debug option`depth' determines the maximum number of frames printed."  (lambda (state n-frames)    (let ((stack (state-stack state)))      ;; Kludge around lack of call-with-values.      (let ((values	     (lambda (start end)	       ;;(do ((index start (+ index 1)))	       ;;    ((= index end))	       ;;(write-state-short* stack index))	       ;;	       ;; Use builtin backtrace instead:	       (display-backtrace stack				  (current-output-port)				  (if (memq 'backwards (debug-options))				      start				      (- end 1))				  (- end start))	       )))	(let ((end (stack-length stack)))	  (cond ((not n-frames) ;(>= (abs n-frames) end))		 (values 0 (min end (cadr (memq 'depth (debug-options))))))		((>= n-frames 0)		 (values 0 n-frames))		(else		 (values (+ end n-frames) end))))))    state))(define-command "quit" '()  "Exit the debugger."  (lambda (state)    (throw 'exit-debugger)))(define-command '("info" "frame") '()  "All about selected stack frame."  (lambda (state)    (write-state-long state)    state))(define-command '("info" "args") '()  "Argument variables of current stack frame."  (lambda (state)    (let ((index (state-index state)))      (let ((frame (stack-ref (state-stack state) index)))	(write-frame-index-long frame)	(write-frame-args-long frame)))    state))(define-command-alias "f" "frame")(define-command-alias '("info" "f") '("info" "frame"))(define-command-alias "bt" "backtrace")(define-command-alias "where" "backtrace")(define-command-alias "p" "evaluate")(define-command-alias '("info" "stack") "backtrace");;;; Command Support(define (select-frame-absolute state number)  (new-state-index state		   (frame-number->index		    (let ((end (stack-length (state-stack state))))		      (if (>= number end)			  (- end 1)			  number))		    (state-stack state))))(define (select-frame-relative state delta)  (new-state-index state		   (let ((index (+ (state-index state) delta))			 (end (stack-length (state-stack state))))		     (cond ((< index 0) 0)			   ((>= index end) (- end 1))			   (else index)))))(define (write-state-short state)  (display "Frame ")  (write-state-short* (state-stack state) (state-index state)))(define (write-state-short* stack index)  (write-frame-index-short stack index)  (write-char #\space)  (write-frame-short (stack-ref stack index))  (newline))(define (write-frame-index-short stack index)  (let ((s (number->string (frame-number (stack-ref stack index)))))    (display s)    (write-char #\:)    (write-chars #\space (- 4 (string-length s)))))(define (write-frame-short frame)  (if (frame-procedure? frame)      (write-frame-short/application frame)      (write-frame-short/expression frame)))(define (write-frame-short/application frame)  (write-char #\[)  (write (let ((procedure (frame-procedure frame)))	   (or (and (procedure? procedure)		    (procedure-name procedure))	       procedure)))  (if (frame-evaluating-args? frame)      (display " ...")      (begin	(for-each (lambda (argument)		    (write-char #\space)		    (write argument))		  (frame-arguments frame))	(write-char #\]))));;; Use builtin function instead:(set! write-frame-short/application      (lambda (frame)	(display-application frame (current-output-port) 12)))(define (write-frame-short/expression frame)  (write (let* ((source (frame-source frame))		(copy (source-property source 'copy)))	   (if (pair? copy)	       copy	       (unmemoize source)))))(define (write-state-long state)  (let ((index (state-index state)))    (let ((frame (stack-ref (state-stack state) index)))      (write-frame-index-long frame)      (write-frame-long frame))))(define (write-frame-index-long frame)  (display "Stack frame: ")  (write (frame-number frame))  (if (frame-real? frame)      (display " (real)"))  (newline))(define (write-frame-long frame)  (if (frame-procedure? frame)      (write-frame-long/application frame)      (write-frame-long/expression frame)))(define (write-frame-long/application frame)  (display "This frame is an application.")  (newline)  (if (frame-source frame)      (begin	(display "The corresponding expression is:")	(newline)	(display-source frame)	(newline)))  (display "The procedure being applied is: ")  (write (let ((procedure (frame-procedure frame)))	   (or (and (procedure? procedure)		    (procedure-name procedure))	       procedure)))  (newline)  (display "The procedure's arguments are")  (if (frame-evaluating-args? frame)      (display " being evaluated.")      (begin	(display ": ")	(write (frame-arguments frame))))  (newline))(define (display-source frame)  (let* ((source (frame-source frame))	 (copy (source-property source 'copy)))    (cond ((source-position source)	   => (lambda (p) (display-position p) (display ":\n"))))    (display "  ")    (write (or copy (unmemoize source)))))(define (source-position source)  (let ((fname (source-property source 'filename))	(line (source-property source 'line))	(column (source-property source 'column)))    (and fname	 (list fname line column))))(define (display-position pos)  (format #t "~A:~D:~D" (car pos) (+ 1 (cadr pos)) (+ 1 (caddr pos))))(define (write-frame-long/expression frame)  (display "This frame is an evaluation.")  (newline)  (display "The expression being evaluated is:")  (newline)  (display-source frame)  (newline))(define (write-frame-args-long frame)  (if (frame-procedure? frame)      (let ((arguments (frame-arguments frame)))	(let ((n (length arguments)))	  (display "This frame has ")	  (write n)	  (display " argument")	  (if (not (= n 1))	      (display "s"))	  (write-char (if (null? arguments) #\. #\:))	  (newline))	(for-each (lambda (argument)		    (display "  ")		    (write argument)		    (newline))		  arguments))      (begin	(display "This frame is an evaluation frame; it has no arguments.")	(newline))))(define (write-chars char n)  (do ((i 0 (+ i 1)))      ((>= i n))    (write-char char)))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -