Expressions in debugger commands
A limited expression syntax can be used in debugger commands.
Some debugger commands such as display, print and call take expressions as arguments. The Genero debugger supports a reduced
syntax for command expressions described in this section. For a detailed description of comparison
operators, constant values and operands, see Expressions.
Syntax
[[package-path.]module.]variable
| char-const
| int-const
| dec-const
| NULL
| TRUE
| FALSE
| expression IS [NOT] NULL
| expression = expression
| expression == expression
| expression <= expression
| expression => expression
| expression < expression
| expression > expression
| expression + expression
| expression - expression
| expression * expression
| expression / expression
| expression OR expression
| expression AND expression
| NOT expression
| - expression
| ( expression )
- variable is a program variable name, of any type (primitive type, record, array, ...)
- module is a module name, if the variable is defined in this imported module.
- package-path is the package path, if the variable is defined in an imported module that belongs to this package.
- char-const is a character string literal delimited by single or double quotes.
- int-const is an integer literal.
- dec-const is a decimal number literal.
- expression is a combination of:
- one of the above listed syntax elements,
- an imported symbol (variable, function, ...),
- a build-in function such as
length(expression), - a class method such as
base.Application.getArgument(nnn), - a type function,
- a user-defined C extension function,
- chaining method calls is supported:
s.subString(2,3).getLength()
Function calls in expressions
When calling a function in an expression, the debugger requires the exact number of parameters.
If a parameter is a RECORD, the function must be called with a
RECORD variable without the .* notation: It is not possible to
pass simple values as parameter to a function expecting a RECORD, even if the
number of simple values is same as the number of record fields.
Example 1
Source code main1.4gl:
IMPORT util
TYPE t_rec RECORD pkey INT, name VARCHAR(50) END RECORD
MAIN
VAR rec t_rec
LET rec.pkey = 124
LET rec.name = "aaaaaa"
DISPLAY util.JSON.stringify(rec)
CALL myfunc(rec)
END MAIN
FUNCTION myfunc(prec t_rec) RETURNS ()
DISPLAY "record: ", prec.*
END FUNCTION
Using the debugger:
$ fglcomp main1.4gl
$ fglrun -d main1.42m
(fgldb) break 7
Breakpoint 1 at 0x00000000: file main1.4gl, line 7.
(fgldb) run
Breakpoint 1, main() at main1.4gl:7
4 VAR rec t_rec
5 LET rec.pkey = 124
6 LET rec.name = "aaaaaa"
-> 7 DISPLAY util.JSON.stringify(rec)
8 CALL myfunc(rec)
9 END MAIN
10 FUNCTION myfunc(prec t_rec) RETURNS ()
(fgldb) print base.Application.getArgument(0)
$1 = "main1.42m"
(fgldb) print rec.pkey * 100
$2 = 12400
(fgldb) print rec
$2 = {pkey = 124, name = "aaaaaa"}
(fgldb) call util.JSON.parse('"eee"',rec.name)
(fgldb) print rec
$3 = {pkey = 124, name = "eee"}
(fgldb) call myfunc(rec)
record: 124eee
(fgldb) quitExample main2.4gl:
MAIN
VAR arr DYNAMIC ARRAY OF STRING
LET arr[3] = "zzzzzz"
DISPLAY arr.getLength()
END MAINDebugging session:
$ fglcomp main2.4gl
$ fglrun -d main2.42m
(fgldb) break 3
Breakpoint 1 at 0x00000000: file main2.4gl, line 3.
(fgldb) run
Breakpoint 1, main() at main2.4gl:3
1 MAIN
2 VAR arr DYNAMIC ARRAY OF STRING
-> 3 LET arr[3] = "zzzzzz"
4 DISPLAY arr.getLength()
5 END MAIN
6
(fgldb) print arr
$1 = {}
(fgldb) next
1 MAIN
2 VAR arr DYNAMIC ARRAY OF STRING
3 LET arr[3] = "zzzzzz"
-> 4 DISPLAY arr.getLength()
5 END MAIN
6
(fgldb) print arr
$2 = {(null), (null), "zzzzzz"}
(fgldb) print arr.getLength()
$3 = 3
(fgldb) quit