Print debugging statement: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|REXX}}: added more information in the REXX section header.)
m (→‎{{header|REXX}}: used a shorter output.)
Line 247: Line 247:
>V> "1"
>V> "1"
>V> "9"
>V> "9"
>F> "6"
>F> "3"
>O> "0.166666667"
>O> "0.333333333"
>O> "0.166666667"
>O> "0.333333333"
11 *-* end /*j*/
11 *-* end /*j*/
9 *-* do j=1 to 100
9 *-* do j=1 to 100
Line 255: Line 255:
>V> "2"
>V> "2"
10 *-* total= total + j/random(maxDiv)
10 *-* total= total + j/random(maxDiv)
>V> "0.166666667"
>V> "0.333333333"
>V> "2"
>V> "2"
>V> "9"
>F> "8"
>O> "0.25"
>O> "0.416666667"
11 *-* end /*j*/
9 *-* do j=1 to 100
>V> "2"
>V> "3"
10 *-* total= total + j/random(maxDiv)
>V> "0.416666667"
>V> "3"
>V> "9"
>V> "9"
>F> "0"
>F> "0"
10 +++ total= total + j/random(maxDiv)
10 +++ total= total + j/random(maxDiv)
Error 42 running "c:\debuggin.rex", line 10: Arithmetic overflow/underflow
Error 42 running "c:\debuggin.rex", line 10: Arithmetic overflow/underflow
Error 42.3: Arithmetic overflow; divisor must not be zero
Error 42.3: Arithmetic overflow; divisor must not be zero
</pre>
</pre>

Revision as of 00:05, 28 August 2019

Print debugging statement is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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>

  1. 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.

This particular output is from the Regina REXX interpreter. <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"
     9 *-* do j=1  to 100
       >L>   "1"
       >L>   "100"
       >V>   "1"
    10 *-*  total= total + j/random(maxDiv)
       >V>    "0"
       >V>    "1"
       >V>    "9"
       >F>    "3"
       >O>    "0.333333333"
       >O>    "0.333333333"
    11 *-* end   /*j*/
     9 *-* do j=1  to 100
       >V>   "1"
       >V>   "2"
    10 *-*  total= total + j/random(maxDiv)
       >V>    "0.333333333"
       >V>    "2"
       >V>    "9"
       >F>    "0"
    10 +++    total= total + j/random(maxDiv)
Error 42 running "c:\debuggin.rex", line 10: Arithmetic overflow/underflow
Error 42.3: Arithmetic overflow; divisor must not be zero