Print debugging statement: Difference between revisions
(→{{header|REXX}}: added the REXX computer programming language for this task.) |
m (→{{header|REXX}}: added a comment in the REXX section header.) |
||
Line 201: | Line 201: | ||
There are other options for the REXX's '''trace''' instruction, but the '''i''' is the most informative and |
There are other options for the REXX's '''trace''' instruction, but the '''i''' is the most informative and |
||
<br>shows intermediate results within a REXX statement as it's being evaluated. |
<br>shows intermediate results within a REXX statement as it's being evaluated. |
||
The first number (for the '''trace''' output) is the line number for the REXX program. |
|||
<br>Blank lines are not ''traced''. |
|||
<lang rexx>/*REXX program to demonstrate debugging (TRACE) information while executing a program*/ |
<lang rexx>/*REXX program to demonstrate debugging (TRACE) information while executing a program*/ |
||
/*────────────────────────────────────────────── (below) the I is for information. */ |
/*────────────────────────────────────────────── (below) the I is for information. */ |
Revision as of 23:57, 27 August 2019
From Wikipedia:
Print debugging (or tracing) is the act of watching (live or recorded) trace statements, or print statements, that indicate the flow of execution of a process. This is sometimes called printf debugging, due to the use of the printf function in C.
- Task
- Show the print debugging statements in the language.
- Demonstrate their ability to track provenance by displaying information about source code (e.g., code fragment, line and column number).
C
C doesn't have a built-in print debugging statement. However, it can be defined by users as a macro.
<lang C>#include <stdio.h>
- define DEBUG_INT(x) printf( #x " at line %d\nresult: %d\n\n", __LINE__, x)
int add(int x, int y) {
int result = x + y; DEBUG_INT(x); DEBUG_INT(y); DEBUG_INT(result); DEBUG_INT(result+1); return result;
}
int main() {
add(2, 7); return 0;
}</lang>
- Output:
x at line 7 result: 2 y at line 8 result: 7 result at line 9 result: 9 result+1 at line 10 result: 10
Go
Go doesn't have a built-in print debugging statement as such. Nor does it have macros.
However, as the following example shows, it is easy enough to mimic a C-like approach by writing a short 'debug' function which can show the value of an expression and its type at the appropriate line number in the program's source code.
Note that a label for the expression (whether it's a simple variable or not) must be passed to the 'debug' function as there is no way to deduce it otherwise. <lang go>package main
import (
"fmt" "runtime"
)
type point struct {
x, y float64
}
func add(x, y int) int {
result := x + y debug("x", x) debug("y", y) debug("result", result) debug("result+1", result+1) return result
}
func debug(s string, x interface{}) {
_, _, lineNo, _ := runtime.Caller(1) fmt.Printf("%q at line %d type '%T'\nvalue: %#v\n\n", s, lineNo, x, x)
}
func main() {
add(2, 7) b := true debug("b", b) s := "Hello" debug("s", s) p := point{2, 3} debug("p", p) q := &p debug("q", q)
}</lang>
- Output:
"x" at line 14 type 'int' value: 2 "y" at line 15 type 'int' value: 7 "result" at line 16 type 'int' value: 9 "result+1" at line 17 type 'int' value: 10 "b" at line 29 type 'bool' value: true "s" at line 31 type 'string' value: "Hello" "p" at line 33 type 'main.point' value: main.point{x:2, y:3} "q" at line 35 type '*main.point' value: &main.point{x:2, y:3}
Pyret
Pyret has the spy
expression. The expression can print the value of an identifier, using the identifier itself as a label if it's not already given. It could also print the value of an arbitrary expression, but it needs an explicit label in this case.
<lang pyret>fun add(x, y):
result = x + y spy "in add": x, y, result, result-plus-one: result + 1 end result
end
add(2, 7)</lang>
- Output:
Spying "in add" (at file:///spies.arr:3:2-8:5) x: 2 y: 7 result: 9 result-plus-one: 10 9
Racket
Racket doesn't have a built-in print debugging statement. However, it can be defined by users as a macro.
<lang racket>#lang racket
(require syntax/parse/define)
(define (debug:core line col code val #:label [label #f])
;; if label exists, use it instead of the code fragment (printf "~a at line ~a column ~a\n" (or label code) line col) (printf "result: ~a\n\n" val) ;; return the value itself, so that we can wrap macro around an expression ;; without restructuring any code val)
(define-simple-macro (debug <x> option ...)
#:with line (datum->syntax this-syntax (syntax-line #'<x>)) #:with col (datum->syntax this-syntax (syntax-column #'<x>)) (debug:core line col (quote <x>) <x> option ...))
(define (add x y)
(define result (+ x y)) (debug x) (debug y) (debug (if #t (+ x y) (error 'impossible))) (debug (add1 result) #:label "result plus one") (debug result))
(add 2 7)</lang>
- Output:
x at line 20 column 9 result: 2 y at line 21 column 9 result: 7 (if #t (+ x y) (error 'impossible)) at line 22 column 9 result: 9 result plus one at line 23 column 9 result: 10 result at line 24 column 9 result: 9 9
REXX
There are other options for the REXX's trace instruction, but the i is the most informative and
shows intermediate results within a REXX statement as it's being evaluated.
The first number (for the trace output) is the line number for the REXX program.
Blank lines are not traced.
<lang rexx>/*REXX program to demonstrate debugging (TRACE) information while executing a program*/
/*────────────────────────────────────────────── (below) the I is for information. */
trace i
parse arg maxDiv .
if maxDiv== | maxDiv=="," then maxDiv= 1000 /*obtain optional argument from the CL.*/
say 'maximum random divisor is:' maxDiv /*display the max divisor being used. */
total= 0
do j=1 to 100 total= total + j/random(maxDiv) end /*j*/
say 'total=' total /*stick a fork in it, we're all done. */</lang>
- output when using the input of: 9
4 *-* parse arg maxDiv . >>> "9" >.> "" 5 *-* if maxDiv=='' | maxDiv=="," then maxDiv= 1000 /*obtain optional argument from the CL.*/ >V> "9" >L> "," >O> "0" >V> "9" >L> "" >O> "0" >U> "0" 6 *-* say 'maximum random divisor is:' maxDiv /*display the max divisor being used. */ >L> "maximum random divisor is:" >V> "9" >O> "maximum random divisor is: 9" maximum random divisor is: 9 7 *-* total= 0 >L> "0" 8 *-* do j=1 to 100 >L> "1" >L> "100" >V> "1" 9 *-* total= total + j/random(maxDiv) >V> "0" >V> "1" >V> "9" >F> "8" >O> "0.125" >O> "0.125" 10 *-* end /*j*/ 8 *-* do j=1 to 100 >V> "1" >V> "2" 9 *-* total= total + j/random(maxDiv) >V> "0.125" >V> "2" >V> "9" >F> "6" >O> "0.333333333" >O> "0.458333333" 10 *-* end /*j*/ 8 *-* do j=1 to 100 >V> "2" >V> "3" 9 *-* total= total + j/random(maxDiv) >V> "0.458333333" >V> "3" >V> "9" >F> "0" 9 +++ total= total + j/random(maxDiv) Error 42 running "c:\debuggin.rex", line 9: Arithmetic overflow/underflow Error 42.3: Arithmetic overflow; divisor must not be zero