home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-01-23 | 51.6 KB | 1,247 lines |
- Newsgroups: alt.sources
- Path: sparky!uunet!cs.utexas.edu!qt.cs.utexas.edu!yale.edu!newsserver.jvnc.net!princeton!csservices!tyrolia!mg
- From: mg@tyrolia (Michael Golan)
- Subject: Duel - a language for debugging C programs part 1/6
- Message-ID: <1993Jan22.034007.20953@csservices.Princeton.EDU>
- Followup-To: alt.sources.d
- Summary: great add-on to gdb!
- Keywords: debugging gdb debugger duel C bug
- Sender: news@csservices.Princeton.EDU (USENET News System)
- Organization: Department of Computer Science, Princeton University
- Date: Fri, 22 Jan 1993 03:40:07 GMT
- Lines: 1233
-
- Submitted-by: mg@cs.princeton.edu
- Archive-name: duel/part01
-
- -----------------------------------------------------------------------------
- DUEL - A high level language for debugging C programs.
- -----------------------------------------------------------------------------
-
- Duel is a special purpose language designed for concise state
- exploration of debugged C programs under existing debuggers.
- It allows you to explore your program's state better than either
- the debugger's commands, a C interpreter, or print statements
- added to your programs. The debugger is extended with the new
- 'dl' command for Duel expressions:
-
- gdb> dl x[1..10] >? 5
- x[3] = 14
- x[8] = 6
-
- prints the array elements x[1] to x[10] that are greater than 5.
- The output includes the values 14 and 6, as well as their
- symbolic representation "x[3]" and "x[8]".
-
- Duel is debugger-independent, but the current distribution interface only
- with gdb. You will need the source for gdb-4.6, or 4.7. Duel is public
- domain code. Do whatever you like with it - add it to commercial debuggers,
- to dbx/sdb or even make it part of the GNU project.
- No part of this distribution contains any copyright or derived code,
- (i.e. no GPL code, either). Free and public domain code need no disclaimer,
- which is obvious to anyone in the software business.
-
- Even if you don't normally use debuggers, but you are programming in C, give
- Duel a try! The man page & help even include summary of useful gdb commands.
-
- Duel is available for anonymous ftp from ftp.cs.princeton.edu, in
- /duel/duel.tar.Z. "tar.Z" format means you should use the command
- "zcat duel.tar.Z | tar xf -" to unpack the files.
- The Usenix Jan/93 paper about Duel is also available as tech report 399,
- in /reports/1992/399.ps.Z on ftp.cs.princeton.edu
-
- DUEL is "Debugging U (might) Even Like" or "Don't Use this Exotic Language"
- you should judge which is better!
-
- Michael Golan
- mg@cs.princeton.edu
- -----------------------------------------------------------------------------
- The tutorial part from the manual page follows:
-
- Duel is based on expressions which return multiple values. The x..y
- operator returns the integers from x to y; the x,y operator returns x
- and then y, e.g.
-
- gdb> dl (1,9,12..15,22)
-
- prints 1, 9, 12, 13, 14, 15 and 22. Such expressions can be used wher-
- ever a single value is used, e.g.
-
- gdb> dl x[0..99]=0 ;
-
- assigns zero to the first 100 elements of array x. The semantics of x[i]
- are the same as in C. They are applied for each of the values returned
- by 0..99, which can be thought of as an implied external loop. The
- trailing semicolon indicates evaluation for side-effects only, with no
- output. Duel incorporates C operators, casts C statements as expres-
- sions, and supports limited variable declaration:
-
- gdb> dl int i;for(i=0;i<100;i++)
- if(x[i]<0) printf("x[%d]=%d\n",i,x[i]);
- x[7] = -4
-
- The semicolon prevents Duel output; only output from printf is printed.
- Aliases are defined with x:=y and provide an alternative to variable
- declaration. We could also return x[i] instead of using printf:
-
- gdb> dl if(x[i:=0..99]<0) x[i]
- x[i] = -4
-
- The symbolic output "x[i]" can be fixed by surrounding i with {}, i.e.
-
- gdb> dl if(x[i:=0..99]<0) x[{i}]
- x[7] = -4
-
- The {} are like (), but force the symbolic evaluation to use i's value,
- instead of "i". You can usually avoid this altogether with direct Duel
- operators:
-
- gdb> dl x[..100] <? 0
- x[7] = -4
-
- The ..n operator is a shorthand for 0..n-1, i.e. ..100 is the same as
- 0..99. The x<?y, x==?y, x>=?y, etc., operators compare their left side
- operand to their right side operand as in C, but return the left side
- value if the comparison result is true. Otherwise, they look for the
- next values to compare, without returning anything.
-
- Duel's x.y and x->y allow an expression y, evaluated under x's scope:
-
- gdb> dl emp[..100].(if(code>400) (code,name))
- emp[46].code = 682
- emp[46].name = "Ela"
-
- The if() expression is evaluated under the scope of each element of
- emp[], an array of structures. In C terms, we had to write:
-
- gdb> dl int i; for(i=0; i<100 ; i++)
- if(emp[i].code>400) emp[{i}].code,emp[{i}].name
-
- A useful alternative to loops is the x=>y operator. It returns y for
- each value of x, setting `_' to reference x's value, e.g.
-
- gdb> ..100 => if(emp[_].code>400) emp[_].code,emp[_].name
-
- Using `_' instead of `i' also avoids the need for {i}. Finally, the
- x-->y operator expands lists and other data structures. If head points
- to a linked list threaded through the next field, then:
-
- gdb> dl head-->next->data
- head->data = 12
- head->next->data = 14
- head-->next[[2]]->data = 20
- head-->next[[3]]->data = 26
-
- produce the data field for each node in the list. x-->y returns x, x->y,
- x->y->y, x->y->y->y, ... until a NULL is found. The symbolic output
- "x-->y[[n]]" indicates that ->y was applied n times. x[[y]] is also the
- selection operator:
-
- gdb> dl head-->next[[50..60]]->data
-
- return the 50th through the 60th elements in the list. The #/x operator
- counts the number of values, so
-
- gdb> dl #/( head-->next->data >? 50 )
-
- counts the number of data elements over 50 on the list.
-
-
-
- #!/bin/sh
- # This is duel, a shell archive (shar 3.32)
- # made 01/22/1993 03:34 UTC by mg@cs.princeton.edu
- # Source directory /tmp_mnt/n/fs/grad2/mg/duel/distr
- #
- # existing files WILL be overwritten
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 2443 -rw-r--r-- README
- # 7232 -rw-r--r-- INSTALL
- # 22468 -rw-r--r-- duel.1
- # 5550 -rw-r--r-- internals.doc
- # 5186 -rw-r--r-- wishlist.doc
- # 7719 -rw-r--r-- gnu-vs-duel.doc
- # 20549 -rw-r--r-- duelgdb.c
- # 993 -rw-r--r-- src/Makefile
- # 21 -rw-r--r-- src/patchlevel.h
- # 1162 -rw-r--r-- src/duel.h
- # 15898 -rw-r--r-- src/global.h
- # 3352 -rw-r--r-- src/proto.h
- # 6871 -rw-r--r-- src/duel.c
- # 29171 -rw-r--r-- src/parse.y
- # 27680 -rw-r--r-- src/eval.c
- # 45286 -rw-r--r-- src/evalops.c
- # 2715 -rw-r--r-- src/error.c
- # 7498 -rw-r--r-- src/print.c
- # 5857 -rw-r--r-- src/types.c
- # 3378 -rw-r--r-- src/misc.c
- # 5695 -rw-r--r-- src/duelself.c
- # 262 -rw-r--r-- src/tsuite.c
- # 1206 -rw-r--r-- src/tsuite.gdb
- # 1095 -rw-r--r-- src/tsuite.self
- # 3214 -rw-r--r-- src/tsuite.gdb.out
- # 4576 -rw-r--r-- src/tsuite.self.out
- #
- if touch 2>&1 | fgrep 'amc' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= README ==============
- echo "x - extracting README (Text)"
- sed 's/^X//' << 'SHAR_EOF' > README &&
- X-------------------------------------------------------------------------------
- XREADME for DUEL 1.00.0 distribution mg@cs.princeton.edu (M. Golan) January 93
- X-------------------------------------------------------------------------------
- X
- XDUEL - A high level language for debugging C programs.
- X
- XEven if you don't normally use debuggers, but you are programming in C, give
- XDuel a try! The man page & help even include summary of useful gdb commands.
- XTo show positive elements of array x, index 0 to 1023, in Duel: x[..1024]>?0
- X
- XDuel is debugger-independent, but the current distribution interface only
- Xwith gdb. You will need the source for gdb-4.6, or 4.7. Duel is public
- Xdomain code. Do whatever you like with it - add it to commercial debuggers,
- Xto dbx/sdb or even make it part of the GNU project.
- XNo part of this distribution contains any copyright or derived code,
- X(i.e. no GPL code, either). Free and public domain code need no disclaimer,
- Xwhich is obvious to anyone in the software business.
- X
- X
- XDuel is available for anonymous ftp from ftp.cs.princeton.edu, in
- X/duel/duel.tar.Z. "tar.Z" format means you should use the command
- X "zcat duel.tar.Z | tar xf -" to unpack the files.
- XThe Usenix Jan/93 paper about Duel is also available as tech report 399,
- Xin /reports/1992/399.ps.Z on ftp.cs.princeton.edu
- X
- XThe distribution contains:
- X
- XREADME - this file
- XINSTALL - how to install duel (you need gdb4.6 or later first!)
- Xduel.1 - man page
- Xinternals.doc - documents internals
- Xwishlist.doc - things that could be added/improved/hacked
- Xgnu-vs-duel.doc - explains why Duel is not GNU and why you should release
- X public domain code and not GNUish code.
- Xduelgdb.c - module linked in with gdb (sets 'dl' command, etc)
- X
- XIn ./src directory:
- X
- X*.h - include files: duel.h proto.h global.h patchlevel.h
- X*.c - source: duel.c eval.c evalops.c print.c error.c misc.c types.c
- Xparse.y - yacc/bison parser & lexer.
- Xduelself.c - stand alone link module (for testing only)
- XMakefile - vanilla make file
- X
- Xtsuite.self - a test suite for duelself (includes intentional errors!)
- Xtsuite.gdb - a test suite for duelgdb -"-
- Xtsuite.c - file being "debug" by tsuite.gdb (cc -g tsuite.c -o tsuite)
- Xtsuite.self.out - expected test suite self output
- Xtsuite.gdb.out - expected test suite gdb output
- X (note different machines will have different addresses)
- X
- X
- XMichael Golan
- Xmg@cs.princeton.edu
- X
- SHAR_EOF
- $TOUCH -am 0121222593 README &&
- chmod 0644 README ||
- echo "restore of README failed"
- set `wc -c README`;Wc_c=$1
- if test "$Wc_c" != "2443"; then
- echo original size 2443, current size $Wc_c
- fi
- # ============= INSTALL ==============
- echo "x - extracting INSTALL (Text)"
- sed 's/^X//' << 'SHAR_EOF' > INSTALL &&
- X-------------------------------------------------------------------------------
- XINSTALLING DUEL 1.00.0 distribution mg@cs.princeton.edu (M. Golan) January 93
- X-------------------------------------------------------------------------------
- X
- XAll files in the distribution are public domain (not gnuish!) code.
- X
- X
- XBASICS
- XDuel is a library, normally linked with a debugger. Currently only gdb
- Xis supported. However, the code in the distribution contains a self-link
- Xmodule which can be used to test duel expressions w/o gdb (useful only
- Xto verify duel, or if you plan to port or use as a portable debugging tool).
- X
- XNormally, Duel runs on top of the GNU debugger gdb(1). In order to use it,
- Xyou must first install gdb. Duel should work with gdb version 4.6 and
- Xlater. For older versions, some minor changes might be needed to
- Xthe interface module duelgdb.c. Before duel is installed, unpack
- Xand compile the regular gdb distribution. The Duel distribution
- Xfiles should be unpacked in subdirectory 'duel' of
- Xgdb. Duel is then compiled into the library duel.a. Then, you
- Xmodify the gdb Makefile to include the module duel/duelgdb.c and
- Xto link with duel/src/duel.a. You also need to modify one source line
- Xin gdb's code, to change comments to start with '##' instead of '#'.
- XIf everything goes well, after another 'make' the new gdb executable
- Xshould support the 'duel' command (alias 'dl'). You can test it by
- Xrunning gdb and giving a command like "dl 1..10". There is also
- Xa test suite.
- X
- XSUN EXAMPLE
- X
- X% mkdir ~/duelgdb
- X% cd ~/duelgdb
- X% ftp ftp.cs.princeton.edu
- X ftp cd /pub/duel
- X ftp> get gdb-4.7.tar.Z
- X ftp> get duel.tar.Z
- X% zcat gdb-4.7.tar | tar xvf -
- X% cd gdb-4.7
- X% ./configure sparc
- X% cd gdb
- X% vi Makefile - modifiy "GCC=gcc" to "CC=gcc"
- X% cd ..
- X% make
- X% cd gdb
- X% gdb - check gdb works. try "print 1+2"
- X% mkdir duel
- X% cd duel
- X% zcat ~/duelgdb/duel.tar | tar xvf -
- X% cd src
- X% make
- X% vi y.tab.c - SUN yacc add "char *malloc" which is wrong. remove it
- X% make - try again
- X% selftest < tsuite.self > self.out
- X% diff tsuite.self.out self.out - see diffs. @xxxx diffs are ok
- X% cd .. - back to duel
- X% cd .. - up to gdb's src
- X% mv duel/duelgdb.c .
- X% vi Makefile - add SFILES_MAINDIR=duelgdb.c OBS=duelgdb.o
- X CLIBS=duel/src/duel.a CDEPS=duel/src/duel.a
- X% vi main.c - "else if (c == '#')" --> "else if (c=='#' && *p1=='#')"
- X% make
- X% gdb - test new gdb, with duel
- X gdb> dl 1..4 - should print 1 2 3 4
- X
- X% cd duel/src
- X% cc -g tsuite.c -o tsuite - prepare program tsuite.gdb use
- X% ../../gdb <tsuite.gdb >gdb.out - run test suite
- X% diff gdb.out tsuite.gdb.out gdb.out - see diffs @xxx diffs are ok
- X
- X
- XDETAILS
- X1. Get the gdb distribution, install, configure, compile and test it.
- X The configure script works pretty well, but watch out for weird
- X utilities in your path (e.g. GNU sed was in my PATH before the
- X standard sed. It was incompatible and caused lots of trouble).
- X Most common use is ./configure sparc or ./configure decstation
- X and then just "make".
- X
- X SUN sparc: use gcc on SUN, since duel uses prototypes and SUN's cc
- X can't handle them. Change gdb/Makefile: from GCC=gdb to CC=gdb, but note
- X the warnings about the ioctrl in the makefile (I had no problems with
- X gcc 2.1; I am not sure what these warnings imply).
- X
- X SGI iris machines: use ./configure iris4. Note that gdb is broken on
- X the irises (can't write to the target), so it cripples the use of duel
- X as well (no declared variables (use aliases), no strings).
- X
- X DEC mips machines: This is what duel was developed on, should work fine.
- X use straight cc, shouldn't have any problems.
- X
- X Other machines: you should test gdb's ability to allocate and write into
- X the target's memory. Compile tsuite.c and start it under gdb (single step
- X twice). Now, enter the command
- X gdb> print "test"
- X If it fails, gdb can not find "malloc", can't call it, or can't write
- X to the target's memory; duel will be limited in functionality.
- X
- X
- X2. Unpack the duel source code into a subdirectory duel of gdb.
- X DO NOT unpack it in the gdb directory, since duel source files
- X like eval.c will clash with gdb source files. The gdb directory
- X is the one that contains files like 'values.c', 'valops.c'.
- X
- X3. In gdb/duel/src, run make. This compiles the Duel source code into
- X duel.a, to be later linked with gdb. The makefile is pretty
- X simple. You can used either cc or gcc, but it must support ANSI
- X prototypes. All system include files are in duel.h.
- X On SUN machines, you must use gcc (cc doesn't support prototypes)
- X you will need to modify y.tab.c, because it declares malloc
- X incorrectly (first line in the file, delete it)
- X
- X The program duelself will also be created (A stand-alone duel code
- X for testing)
- X
- X4. Verify that duel is compiled ok by running duelself and giving
- X a command like (1..4)*(4,2.5). You can also run the whole
- X test suite with "duelself <tsuite.self >self.out" and compare
- X the tsuite.self.out and self.out files. Note that memory
- X references are likely to be different. Also, beware that the
- X test suite has intentional errors (not all marked clearly).
- X
- X5. Add a link from gdb/duel/duelgdb.c to gdb/duelgdb.c, or just
- X move the duel/duelgdb.c file to gdb's main dir.
- X
- X6. Edit gdb's Makefile. The Makefile is produced automatically,
- X so any changes you made will be undone if you reconfigure gdb.
- X You may change either the Makefile, or the Makefile.in (in
- X which case gdb should re-configure itself automatically,
- X and might require a total recompile). If you only going to
- X compile duel once, and you already compiled gdb, I suggest
- X you just modify the Makefile.
- X
- X A. Locate the SFILES_MAINDIR = macro. add duelgdb.c
- X B. Locate OBS = macro. add duelgdb.o
- X C. Locate CLIBS = macro. add duel/src/duel.a
- X D. You can also add duel/src/duel.a to CDEPS = if you want to
- X rebuild gdb automatically each time duel.a changes.
- X
- X7. Modify gdb's comments to start with '##' instead of '#', since
- X duel uses '#' as an operator. This step is optional -- you could
- X use %/ and %% for #/ and # (see duel/parse.y).
- X in file main.c line 1529 or near by, "else if (c == '#')"
- X modify to "else if (c == '#' && *p1 == '#')"
- X
- X8. run make in gdb's directory. The new gdb binary should support
- X the duel (alias dl) commands. You can test it by running gdb
- X and trying 'dl 1..10' which should print the numbers from 1 to 10.
- X A test suite tsuite.gdb is in duel/src. to use, first compile
- X tsuite.c, cc -g tsuite.c -o tsuite, then run gdb <tsuite.gdb >gdb.out
- X and compare the output to tsuite.gdb.out. Again, beware that there
- X are intentional errors in the test suite, and that output of
- X addresses/pointer is likely to differ.
- X Possible problems: duel uses assert.h. If you use gcc, you could
- X end up with an undefined __eprintf from gdb's assert.h. Either use
- X cc, point to the standard assert.h, or use gcc -U__GNU__.
- X
- X9. Install the new gdb as "duel" instead of "gdb". Also install the
- X manual page duel/duel.1
- X
- XWHY SO MANY STEPS?
- XBecause I don't want to distribute a modified version of any GNU stuff.
- Xthis protects you from being GNU-ized if you only want the duel code.
- X
- X
- XMichael Golan
- Xmg@cs.princeton.edu
- X
- SHAR_EOF
- $TOUCH -am 0121201193 INSTALL &&
- chmod 0644 INSTALL ||
- echo "restore of INSTALL failed"
- set `wc -c INSTALL`;Wc_c=$1
- if test "$Wc_c" != "7232"; then
- echo original size 7232, current size $Wc_c
- fi
- # ============= duel.1 ==============
- echo "x - extracting duel.1 (Text)"
- sed 's/^X//' << 'SHAR_EOF' > duel.1 &&
- X'\" t
- X.\" This document and the Duel source code are in the public domain.
- X.\" Note that the duel executable contains GNU code and is not public domain.
- X.TH Duel 1 "Jan 93" "Version 1.0"
- X.SH NAME
- Xduel \- A high level C debugging language extension to gdb
- X.SH SYNOPSIS
- X.B duel
- X[gdb options]
- X.RB "[\|" \c
- X.I prog\c
- X.RB "[\|" \c
- X.IR core \||\| procID\c
- X\&\|]\&\|]
- X.ad b
- X.SH DESCRIPTION
- XDuel is a special purpose language designed for concise state exploration
- Xof debugged C programs, currently implemented under the GNU debugger
- X.IR gdb (1).
- XDuel is invoked by entering the shell command
- X.I duel
- Xinstead of
- X.I gdb.
- XIt is identical to gdb except for
- Xcomments, which begin with `##' instead of `#', and the new
- X.I dl
- Xcommand for Duel expressions:
- X.nf
- X
- X\f2gdb>\f1 dl x[1..10] >? 5
- Xx[3] = 14
- Xx[8] = 6
- X
- X.fi
- Xprints the array elements x[1] to x[10] that are greater than 5.
- XThe output includes the values 14 and 6, as well as their
- Xsymbolic representation "x[3]" and "x[8]".
- X.SH IF YOU NEVER USED GDB
- XThe improved functionality added by Duel merits a fresh look
- Xeven by debugger shunners.
- XGdb is a powerful debugger with many commands, a thick manual and
- Xvarious interfaces including
- X.IR emacs (1)
- Xand
- X.IR xxgdb (1).
- XThese gdb commands should help you get started:
- X
- X.TS
- Xl l.
- X\f2b line\f1 set a breakpoint at the line (b func to break at a function)
- X\f2d n\f1 delete breakpoint number n (gdb prints n when bp occurs)
- X\f2l line\f1 list the source beginning at line (l file.c:line for module)
- X\f2r parm\f1 run/restart the program with the given parameters
- X\f2s\f1 single-step to the next statement (steps into function calls)
- X\f2n\f1 single-step to the next line, skipping over function calls
- X\f2c\f1 continue execution
- X\f2bt\f1 show a stack trace
- X\f2p exp\f1 evaluate a symbolic expression
- X\f2dl exp\f1 evaluate a Duel expression
- X\f2dl gdb\f1 give a gdb command summary
- X.TE
- X
- XThe most common use is `b func' followed by `r' followed by several
- X`n' and `s', evaluating expressions in between.
- X.SH DUEL QUICK START
- XDuel is implemented by adding the
- X.I dl
- Xcommand to gdb. All gdb commands
- Xwork as before. The dl command, however, is interpreted by duel.
- XGdb concepts (such as the value history) do not work in the dl command,
- Xand duel concepts are not understood by other gdb command.
- X
- XDuel is based on expressions which return multiple values.
- XThe x..y operator returns
- Xthe integers from x to y; the x,y operator returns x and then y, e.g.
- X.sp
- X\f2gdb>\f1 dl (1,9,12..15,22)
- X.sp
- Xprints 1, 9, 12, 13, 14, 15 and 22. Such expressions can
- Xbe used wherever a single value is used, e.g.
- X.sp
- X\f2gdb>\f1 dl x[0..99]=0 ;
- X.sp
- Xassigns zero to the first 100 elements of array x. The semantics of x[i]
- Xare the same as in C. They are applied for each of the values
- Xreturned by 0..99, which can be thought of as an implied external loop.
- XThe trailing semicolon indicates evaluation for side-effects only, with no
- Xoutput.
- XDuel incorporates C operators, casts C statements as
- Xexpressions, and supports limited variable declaration:
- X.sp
- X.br
- X\f2gdb>\f1 dl int i;for(i=0;i<100;i++)
- X.br
- X if(x[i]<0) printf("x[%d]=%d\\n",i,x[i]);
- X.br
- Xx[7] = -4
- X.sp
- XThe semicolon prevents Duel output;
- Xonly output from printf is printed.
- XAliases are defined with x:=y and provide an alternative to variable
- Xdeclaration. We could also return x[i] instead of using printf:
- X.sp
- X\f2gdb>\f1 dl if(x[i:=0..99]<0) x[i]
- X.br
- Xx[i] = -4
- X.sp
- XThe symbolic output "x[i]" can be fixed by surrounding i with {}, i.e.
- X.sp
- X\f2gdb>\f1 dl if(x[i:=0..99]<0) x[{i}]
- X.br
- Xx[7] = -4
- X.sp
- XThe {} are like (), but force the symbolic evaluation to use i's value,
- Xinstead of "i". You can usually avoid this altogether
- Xwith direct Duel operators:
- X.sp
- X\f2gdb>\f1 dl x[..100] <? 0
- X.br
- Xx[7] = -4
- X.sp
- XThe ..n operator is a shorthand for 0..n-1, i.e. ..100 is the same as 0..99.
- XThe x<?y, x==?y, x>=?y, etc., operators compare their left side operand to
- Xtheir right side operand as in C, but return the left side value if
- Xthe comparison result is true. Otherwise, they look for the next
- Xvalues to compare, without returning anything.
- X
- XDuel's x.y and x->y allow an expression y, evaluated under x's scope:
- X.sp
- X\f2gdb>\f1 dl emp[..100].(if(code>400) (code,name))
- X.br
- Xemp[46].code = 682
- X.br
- Xemp[46].name = "Ela"
- X.sp
- XThe if() expression is evaluated under the scope of each element
- Xof emp[], an array of structures. In C terms, we had to write:
- X.sp
- X\f2gdb>\f1 dl int i; for(i=0; i<100 ; i++)
- X.br
- X if(emp[i].code>400) emp[{i}].code,emp[{i}].name
- X.sp
- XA useful alternative to loops is the x=>y operator. It returns y for each
- Xvalue of x, setting `_' to reference x's value, e.g.
- X.sp
- X\f2gdb>\f1 ..100 => if(emp[_].code>400) emp[_].code,emp[_].name
- X.sp
- XUsing `_' instead of `i' also avoids the need for {i}. Finally,
- Xthe x\-\->y operator expands lists and other data structures. If head points
- Xto a linked list threaded through the next field, then:
- X.sp
- X\f2gdb>\f1 dl head-->next->data
- X.br
- Xhead->data = 12
- X.br
- Xhead->next->data = 14
- X.br
- Xhead-->next[[2]]->data = 20
- X.br
- Xhead-->next[[3]]->data = 26
- X.sp
- Xproduce the data field for each node in the list. x\-\->y
- Xreturns x, x->y, x->y->y, x->y->y->y, ... until a NULL is found.
- XThe symbolic output "x\-\->y[[n]]"
- Xindicates that ->y was applied n times. x[[y]] is also the selection
- Xoperator:
- X.sp
- X\f2gdb>\f1 dl head-->next[[50..60]]->data
- X.sp
- Xreturn the 50th through the 60th elements in the list. The #/x operator
- Xcounts the number of values, so
- X.sp
- X\f2gdb>\f1 dl #/( head-->next->data >? 50 )
- X.sp
- Xcounts the number of data elements over 50 on the list.
- XSeveral other operators, including x@y, x#y and
- Xactive call stack access are described in the operators section.
- X.SH OPERATORS SUMMARY
- X.\"All the C operators have the same precedence and associativity as in C. C
- X.\"statements have precedence just below `,' and `;' has the lowest precedence.
- X.\"Most Duel operators have the same precedence as their C counterparts. The
- X.\"following table is in decreasing precedence:
- X.TS
- Xl l l.
- XAssoc Operators Details
- Xleft {} () [] -> . f() --> x-->y expands x->y x->y->y ...
- X x[[y]] x#y x@y generate x; select, index or stop-at y
- Xright #/ - * & ! ~ ++ -- (cast) #/x number of x values
- X frame(n) sizeof reference to call stack level n
- Xleft x/y x*y x%y multiply, divide, reminder
- Xleft x-y x+y add, subtract
- Xleft x<<y x>>y shift left/right
- Xnone x..y ..y x.. ..y = 0..y-1. x..y return x, x+1...y
- Xleft < > <= >= <? >? <=? >=? x>?y return x if x>y
- Xleft == != ==? !=? x==?y return x if x==y
- Xleft x&y bit-and
- Xleft x^y bit-xor
- Xleft x|y bit-or
- Xleft x&&y &&/x &&/x are all x values non-zero?
- Xleft x||y ||/x ||/x is any x value non-zero?
- Xright x? y:z foreach x, if(x) y else z
- Xright x:=y x=y x+=y ... x:=y set x as an alias to y
- Xleft x,y return x, then y
- Xright x=>y foreach x, evaluate y with x value `_'
- Xright if() else while() for() C statements cast as operators
- Xleft x;y evaluate and ignore x, return y
- X.TE
- X
- X.SH EXAMPLES
- X.TS
- Xl l.
- Xdl (0xff-0x12)*3 compute simple expression
- Xdl (1..10)*(1..10) display multiplication table
- Xdl x[10..20,22,24,40..60] display x[i] for the selected indexes
- Xdl x[9..0] display x[i] backwards
- Xdl x[..100] >? 5 display x[i] that are greater than 5
- Xdl x[..100] >? 5 <? 10 display x[i] if 5<x[i]<10
- Xdl x[..100] ==? (6..9) same
- Xdl x[0..99]=>if(_>5 && _<10) _ same
- Xdl y[x[..100] !=? 0] display y[x[i]] for each non-zero x[i]
- Xdl emp[..50].code display emp[i].code for i=0 to 49
- Xdl emp[..50].(code,name) display emp[i].code & emp[i].name
- Xdl val[..50].(is_dbl? x:y) display val[i].x or val[i].y depending
- X on val[i].is_dbl.
- Xdl val[..50].if(is_dbl) x else y same as above
- Xdl x[..100]=0 ; assign 0 to x[i]
- Xdl x[i:=..100]=y[i] ; assign y[i] to x[i]
- Xdl x[..100]=y[..100] *ERR* assign y[99] to each x[j]
- Xdl x[i:=..3]=(4,5,9)[[i]] assign x[0]=4 x[1]=5 x[2]=9
- Xdl x[..3]=(4,5,9) *ERR* assign 9 to each element
- Xdl if(x[i:=..100]<0) x[i]=0 ; assign 0 to negative x[i]
- Xdl (hash[..1024]!=?0)->scope hash[i].scope for non-null hash[i]
- Xdl x[i:=..100] >? x[i+1] check if x[i] is not sorted
- Xdl x[i:=..100] ==? x[j:=..100]=> checks if x has non-unique elements
- X if(i<j) x[{i,j}]
- Xdl if(x[i:=..99] == same
- X x[j:=i+1..99]) x[{i,j}]
- Xdl (x[..100] >? 0)[[0]] the 1st (0th element) positive x[i]
- Xdl (x[..100] >? 0)[[2]] return the 3rd positive x[i]
- Xdl (x[..100] >? 0)[[..5]] return the first 5 positive x[i]
- Xdl (x[0..] >? 6)[[0]] return the first x[i]>6, no limit on i
- Xdl argv[0..]@0 argv[0] argv[1] .. until first null
- Xdl x[0..]@-1 >? 9 x[0..n]>9 where n is first x[n]== -1
- Xdl emp[0..]@(code==0) emp[0]..emp[n-1] where emp[n].code==0
- X
- Xdl head-->next->val val of each element in a linked list
- Xdl head-->next[[20]] the 21st element of a linked list
- Xdl *head-->next[[20]] display above as a struct
- Xdl #/head-->next count elements on a linked list
- Xdl x-->y[[#/x-->y - 1]] last element of a linked list
- Xdl x-->y[[#/x-->y - 10..1]] last 10 elements of a linked list
- Xdl head-->next-> check if the list is sorted by val
- X if(next) val >? next->val
- X
- Xdl head-->(next!=?head) expand cyclic linked list (tail->head)
- Xdl head-->(next!=?_) handle termination with p->next==p
- Xdl root-->(left,right)->key expand binary tree, show keys
- X
- Xdl (T mytype) x convert x to a user defined type mytype
- Xdl (struct s*) x convert x to struct s pointer
- Xdl if(x) y; else z *ERR* ';' must be followed by an expression
- Xdl {x} y *ERR* '}' requires ';' if followed by exp
- X.TE
- X.SH SEMANTICS
- XDuel's semantics are modeled after the Icon programming language.
- XThe input consists of expressions which return sequences of values.
- XC statements are cast as expressions, too.
- XExpressions are parsed into abstract syntax trees, which are
- Xtraversed during evaluation. The evaluation of most nodes (operators)
- Xrecursively evaluates the next value for each operand, and then applies the
- Xoperator to produce the next result. Only one value is produced each time,
- Xand Duel's eval function keeps a `state' for each node
- X(backtracking, co-routines, consumer-producer or threads are good metaphors
- Xfor the evaluation mechanism.)
- X
- XFor example, in (5,3)+6..8, the
- Xevaluation of `+' first retrieves the operands 5 and 6, to compute and
- Xreturn 5+6. Then 7, the next right operand is retrieved
- Xand 5+7 is returned, followed by 5+8.
- XSince there are no other right operand value, the next left operand, 3
- Xis fetched. The right operand's computation is restarted returning
- X6, and 3+6 is returned. The final return values are 3+7 and 3+8.
- X
- XThe computation for operators like x>?y is similar, but when x<=y,
- Xthe next values are fetched instead of returning a value,
- Xforming the basis for an implicit search. Operators like `..' return a
- Xsequence of values for each pair of operands. For a better understanding
- Xof the evaluation mechanism, see the USENIX Winter/93 conference paper
- X"DUEL - A Very High Level Debugging Language".
- X
- XDuel values follow the C semantics. A value is either an
- X"lvalue" (can be used as the left hand side of assignment), or an "rvalue".
- XTherefor, objects like arrays can not be directly manipulated (However,
- Xoperators like x..y can accomplish such tasks.)
- X
- XDuel types also follow the C semantics, but there are important
- Xdifferences. C types are checked statically. In Duel, types are checked
- Xwhen an operator is applied, e.g. (1,1.0)/2 return the integer zero and
- Xthe double 0.5, and (x,y).z returns x.z and y.z even if
- Xx and y are of different types, as long as they both have a field z.
- XValues and types of symbols are looked up at run-time (using gdb's lookup
- Xrules), to allow dynamic scoping and types. This results in a parsing
- Xproblem, where operators must be well defined: (x)(y) can be parsed as
- Xeither a function call x(y) or a cast (x)y. To avoid this ambiguity, the
- Xcapital T keyword is required before a user defined type.
- XFor example,
- Xif value is a typedef, C's (value *) x is written in Duel as:
- X(T value *) x. Types that begin with a reserved keyword don't
- Xneed T, e.g. (struct value*) x and (long *[5]) y are accepted.
- X.SH OPERATORS
- X.sp
- X.I "x+y x-y x*y x/y x%y x^y x|y x&y x<<y x>>y "
- X.br
- X.I "x>y x<y x>=y x<=y x==y x!=y x=y x[y]"
- X.sp
- XThese binary operators follow their C semantics. For each value of x,
- Xthey are evaluated for every value of y, .e.g. (5,2)>(4,1)
- Xevaluates as 5>4, 5>1, 2>4, 2>1 returning 1, 1, 0, 1.
- XThe y values are re-evaluated for each new value of x, e.g.
- Xi=4; (4,5)>i++ evaluates as 4>4 and 5>5.
- XBeware of multiple y values in assignment, e.g. x[..3]=(4,6,9) does not
- Xset x[0]=4, x[1]=6 and x[2]=9. It assigns 4, 6 and 9 to each element, having
- Xthe same effect as x[..3]=9. Use x[i:=..3]=(4,6,9)[[i]] to achieve the
- Xdesired effect.
- X.sp
- X.I "-x ~x &x *x !x ++x --x x++ x-- sizeof(x) (type)x"
- X.sp
- XThese unary operators follow their C semantics. They are applied
- Xto each value of x. The increment and decrement operators require an
- Xlvalue, so i:=0 ; i++ produces an error because i is an alias to 0,
- Xan rvalue. Cast to user defined type must begin with T, e.g. (T val*) x.
- XSee variable declaration for more details.
- X.sp
- X.I "x&&y x||y"
- X.sp
- XThese logical operators also follow their C semantics, but have non-intuitive
- Xresults for multi-valued x and y, e.g. (1,0,0) || (1,0) returns 1,1,0,1,0 --
- Xthe right hand-side (1,0) is returned for each left-hand side 0. It is best
- Xto use these operators only in single value expressions.
- X.sp
- X.I "x? y:z if(x)y if(x)y else z"
- X.sp
- XThese expressions return the values of y for each non-zero value
- Xreturned by x, and the values of z for each zero value returned by x, e.g.
- Xif(x[..100]==0) y returns y for every x[i]==0, not if all x[i] are zero
- X(if(&&/(x[..100]==0)) y does that).
- XAlso, "if(x) y; else z" is illegal. Duel's semicolon is
- Xan expression separator, not a terminator.
- X.sp
- X.I "while(x)y for(w;x;y)z"
- X.sp
- XThe while(x)y expression returns y as long as all values of x are non-zero.
- XThe for() expression is similar and both have the expected C semantics. For
- Xexample, "for(i=0 ; i<100 ; i++) x[i]" is the same as x[..100]. Unlike
- Xthe if() expression, while(x[..100]==0) continue to execute only if all
- Xelements of x are zero, i.e. the condition is evaluated into a single value
- Xusing an implicit &&/x.
- X.sp
- X.BI "Variable declaration: " "type name [,name ...] ; ..."
- X.sp
- XExpressions can begin with variables declaration (but not initialization).
- XInternally, a declaration sets an alias to space allocated
- Xin the target by calling malloc(), e.g. `int x' is the same as
- X"x:= *(int *) malloc(sizeof(int))". This is oblivious to the user.
- XThe allocated memory is not claimed when a variable is redeclared.
- XDeclared variables addresses can be passed to functions and used in other
- Xdata structures. The keyword `T' must precede user defined types (typedef),
- Xe.g. if val is a user defined type, The C code "val *p=(val*) x" becomes
- X"T val *p; p=(T val *) x" in Duel.
- X.sp
- X.BI "Function calls: " "func(parm,...)"
- X.sp
- XFunction calls to the debugged program can be intermixed with Duel
- Xcode. Multi-valued parameters are handled as with binary operators.
- XThe call value can have multiple values, e.g. (x,y)() calls x()
- Xand y(). Currently, struct/union parameters and return values are not
- Xsupported.
- X.sp
- X.I "x,y x..y ..x x.."
- X.sp
- XThese operators produce multiple values for single value operands.
- Xx,y returns x, then y. x..y returns the integers from x to y.
- XWhen x>y the sequence is returned in descending order, i.e. 5..3
- Xreturns 5, 4, 3.
- XThe operator ..x is a shorthand for 0..x-1, e.g. ..3 returns 0, 1, 2.
- XThe x.. operator is a shorthand for x..maxint. It returns increasing
- Xinteger values starting at x indefinitely, and should be bounded
- Xby [[n]] or @n operators.
- X`,' retains its precedence level in C. The precedence of `..'
- Xis above `<' and below arithmetic operators, so 0..n-1 and x==1..9 work
- Xas expected.
- X.sp
- X.I "x<?y x>?y x>=?y x<=?y x!=?y x==?y"
- X.sp
- XThese operators work like their C counterparts but return x if the comparison
- Xis true. If the comparison is false, the next (x,y) value is tried, forming
- Xthe basis of an implicit search.
- X.sp
- X.I "(x) {x} x;y x=>y"
- X.sp
- XBoth () and {} act as C parenthesis.
- XThe curly braces set the returned symbolic value
- Xas the actual value, e.g. if i=5 and x[5]=3, then
- Xx[i] produces the output "x[i] = 3", x[{i}] produces
- X"x[5] = 3" and {x[i]} produces just "3".
- XThe semicolon is an operator. x;y evaluates x, ignoring the results,
- Xthen evaluate and return y, e.g. (i:=1..3 ; i+5) sets i to 3 and return 8.
- XThe x=>y operator evaluate and return y for each value of x,
- Xe.g. (i:=1..3 => i+5) returns 6, 7 and 8. The value returned by x is
- Xalso stored implicitly in `_' which can be used in y, e.g. 1..5 => z[_][_]
- Xwill output z[1][1], z[2][2] etc. The symbolic value for _ is that of the
- Xleft side value, hence {_} is not needed.
- X.br
- XSemicolon has the lowest precedence, so it must be used inside () or {}
- Xfor compound expressions. The precedence of `=>' is just below `,'.
- XBeware that "if(a) x; else {y;} z" is illegal; a semicolon is not allowed
- Xbefore '}' or 'else' and must be inserted before z.
- X.sp
- X.IB "x->y x.y"
- X.sp
- XThese expression work as in C for a symbol y. If y is an expression, it
- Xis evaluated under the scope of x. e.g. x.(a+b) is the same as x.a+x.b,
- Xif a and b are field of x (if they are not, they are looked up as local
- Xor global variables). x may return multiple values of different types,
- Xe.g. (u,v).a returns u.a and v.a, even if u and v are different structures.
- XAlso, the value of x is available as `_' inside y, e.g. x[..100].(if(a) _)
- Xproduces x[i] for each x[i].a!=0. Nested x.y are allowed, e.g.
- Xu.(v.(a+b)) would lookup a and b first under v, then under u.
- X.sp
- X.BI Aliases: " x:=y"
- X.sp
- XAliases store a reference to y in x. Any reference to x is
- Xthen replaced by y. If y is a constant or an rvalue, its
- Xvalue is replaced for x. If y is an lvalue (e.g. a variable), a reference
- Xto same lvalue is returned. for example, x:=emp[5] ; x=9 assigns 9 to
- Xemp[5].
- XAliases retain their values across invocation of the "dl" command. An alias
- Xto a local variable will reference a stray address when the variable
- Xgoes out of scope.
- XThe special command "dl clear" delete all the aliases, and "dl alias"
- Xshow all current aliases. Symbols are looked up
- Xas aliases first, so an alias x will hide a local x.
- X.sp
- X.I x-->y
- X.sp
- XThe expansion operator x-->y expands a data structure x following the y links.
- XIt returns x, x->y, x->y->y, until a null is found. If x is null, no values
- Xare produced. If y returns multiple values, they are stacked and each is
- Xfurther expanded in a depth-first notion. For example, if r is the root of
- Xa tree with children u->childs[..u->nchilds], then
- Xu-->(childs[..nchilds]) expands the whole tree. y is an arbitrary
- Xexpression, evaluated exactly like x->y (this includes `_'.)
- X.sp
- X.I x@y
- X.sp
- XThe expression x@y produces the values of x until x.y is non-zero, e.g.
- Xfor(i=0 ; x[i].code!= -1 && i<100 ; i++) x[i] can be written as
- Xx[..100]@(code==-1).
- XThe evaluation of x is stopped as soon as y evaluates to true.
- Xx->y or x=>y are used to evaluate y when x is not a struct or a union. If
- Xy is a constant,(_==y) is used. e.g. s[0..]@0 produces the characters in
- Xstring s up to but not including the terminating null.
- X.sp
- X.IB "#/x &&/x ||/x"
- X.sp
- XThese operator return a single "summary" value for all the values returned by
- Xx. #/x returns the number of values returned by x, e.g.
- X#/(x[..100]>?0) counts the number of positive x[i]. &&/x returns 1 if all
- Xthe values produced by x are non-zero, and ||/x returns 1 if any of x's values
- Xare non-zero. Like in C, the evaluation stops as soon as possible.
- XFor example, ||/(x[..100]==0) and &&/(x[..100]==0) check if one or all of
- Xx[i] are zero, respectively.
- X.sp
- X.IB "x#y x[[y]]"
- X.sp
- XThe operator x#y produces the values of x and arranges for y to be an alias
- Xfor the index of each value in x. It is commonly used with x-->y to produce
- Xthe element's index, e.g. head-->next->val#i=i assigns each val field
- Xits element number in the list.
- X.br
- XThe selection operator x[[y]] produces the yth result of x. If y returns
- Xmultiple value, each select a value of x, e.g. (5,7,11,13)[3,0,2]
- Xreturns 13, 5 and 11 (13 is the 3rd element, 5 is the 0th element).
- XDon't use side effects in x, since its evaluation can be restarted depending
- Xon y, e.g. after (x[0..i++])[[3,5]] the value of i is unpredictable.
- X.sp
- X.IB "frame(n) frames_no func.x"
- X.sp
- Xframe(n) for an integer n returns a reference to the nth frame
- Xon the stack (0 is the inner most function and frame(frames_no-1) is main()).
- XFrame values can be compared to function pointers,
- Xe.g. frame(3)==myfunc is true if the 4th frame is a call to myfunc, and in
- Xscope resolution, e.g. frame(3).x return the local variable x of the 4th frame.
- Xframes_no is the number of active frames on the stack, e.g.
- X(frames(..frames_no) ==? myfunc).x displays x for all active
- Xinvocations of myfunc. As a special case, (frames(..frames_no)==?f)[[0]].x
- Xcan be written as f.x (x can be an expression).
- X.sp
- X.SH BUGS
- XBoth `{}' and `;' are operators, not statements or expression separators;
- X"if(x) y; else {z;} u" is illegal; use "if(x) y else {z} ; u".
- X.br
- Xuser-defined types (typedef) must be preceded by the keyword T, e.g. if
- Xvalue is a user type, C's "(value *)x" must be written as "(T value *)x".
- X.br
- XNot all C idiom are implemented, including: modified-assignment operators
- X(x+=y), switch, break, continue, do, goto, scopes, and function declarations.
- X.br
- XYou can not call a function with a struct/union parameter or return value.
- X.br
- XValues stored in registers are fetched as rvalues and can not be assigned to.
- X.br
- XAssignment to bit-fields is not supported.
- X.br
- XDeclared variables can not be initialized. Use assignment instead.
- X.br
- Xgdb does not store function prototypes, so parameters are not checked.
- X
- XGdb itself is buggy, which shows up, especially in symbol tables and
- Xcalling target functions. Before you report bug, try to do the closest
- Xthing under gdb's "print". Send bug reports, fixes, improvements, etc.
- Xto: mg@cs.princeton.edu.
- X.SH AUTHOR
- XDuel is public domain code -- no copy left or right. See the internals
- Xdocumentation for details on porting Duel and using its code.
- XDuel was designed and written by Michael Golan as part of a PhD thesis
- Xin the Computer Science Department of Princeton University.
- XI would like to thank my advisor, David R. Hanson, who helped in all phases
- Xof this project and to Matt Blaze for his support and useful insight.
- X.sp
- XDuel stands for Debugging U (might) Even Like, or Don't Use this Exotic
- XLanguage. Judge for yourself!
- X
- X
- SHAR_EOF
- $TOUCH -am 0121191893 duel.1 &&
- chmod 0644 duel.1 ||
- echo "restore of duel.1 failed"
- set `wc -c duel.1`;Wc_c=$1
- if test "$Wc_c" != "22468"; then
- echo original size 22468, current size $Wc_c
- fi
- # ============= internals.doc ==============
- echo "x - extracting internals.doc (Text)"
- sed 's/^X//' << 'SHAR_EOF' > internals.doc &&
- XDUEL 1.0 INTERNALS
- XThis documents some of the basics internal info, and might help porting
- Xduel. Incomplete and probably badly written. sorry.
- X
- XEntry points and modules
- X--------------------------
- Xduel_eval_and_parse is entry point into duel, in duel.c
- Xduel_parse in parse.y does all parsing
- Xduel_eval in eval.y makes the evaluation
- Xevalop.c contains low-level evaluation
- Xmisc.c contains misc stuff
- Xtypes.c type create/manage
- X
- Xstart reading the code from duel.c, then global.h, then eval.c.
- Xeval.c is hairy, especially the state-keeping code. The goto's are
- Xintentional, they convey control better than other constructs.
- X
- XTypes
- X------
- XA relatively straight-forward system, if you have read code of real C
- Xcompilers. A type is a "graph" with each node being a base type or
- Xa composition of other types. see global.h and types.c
- X
- XValue system
- X-------------
- Xalso pretty simple, either an LVALUE, which have u.lvalue point to it,
- Xor an RVALUE, so u.rval_type contains the actual value. There is also
- Xa special BVALUE hack to hold lvalued bitfields, which is only useful
- Xis someone implements modifying a bitfield. and there is an FVALUE, which
- Xis just stored in u.rval_int but has the special value type (it was either
- Xthis or add a new TYPE, i preferred a new value).
- XNote the there is no "register" type support. You must read register variables
- Xas rvalues (duelgdb.c does that). I don't think it is essential, since
- Xgdb can be used directly to modify such values (this might be a
- Xproblem in watchpoint/cond.breaks however). Also cc -g don't usually keep
- Xstuff in registers. We could add "SVALUE" for these.
- XBitfields are a pain, but bvalue is really needed, eg for x[..100].bitfield=0
- X
- XMemory allocation
- X-----------------
- Xgo through duel_malloc/duel_free.
- XMemory is allocated only for (a) a new node, while parsing, (b) a value pushed
- Xon stack for x-->y operator (c) duel aliases.
- XIt is always safe to call duel_free_nodes which free everything except
- Xfor aliases.
- XMemory spill can occur in asynchronous interrupts (^C), but they at most
- Xreflect items moved from one list to another. This isn't too bad.
- X
- XInterrupts
- X----------
- XDuel ignores the issues of interrupts, but is written so it can be
- Xinterrupted at any time. Naturally, some memory could be lost if an
- Xoperation is interrupted, since Duel does not setup critical sections.
- XHowever, interrupts will no result in bad internal structures, so it is
- Xsafe to call duel_free_nodes after an interrupt.
- Xduelgdb.c implements exactly that - interrupts at all times, and cleanup
- Xusing duel_free_nodes.
- X
- XParsing
- X--------
- Xyacc is pretty weak, especially when I tried complex ops like x\y#z
- X(as a single, 3 val op!). I have up on such things and the syntax is
- Xpretty clean. Things to watch for are the semicolon nonsense,
- Xespecially with optional-expressions (as in for(a;b;c);), the T hack
- Xfor user types (only fix is to delay decision on (x)(y) till runtime
- Xor make clearer rules (consider something; (x)(y), do you parse x as a type
- Xand ignore the possible x:=printf in "something", etc), and the use of ","
- Xregular op and nodes for function parameters (the parser knows only about
- Xa single parameter, an exp!).
- X
- XSearch ops
- X-----------
- XStraight forward stacking in dfs_... in eval.c
- XNote things are put in reversed, so root-->(left,right) does what you
- Xexpect. Also linked-lists could be greatly optimized.
- XThe functionality for ->> (BFS) is already in, all you need is to
- Xmake the stack into a queue by pushing from the other side (really append)
- X
- XMulti-expressions
- X--------------------
- XAs far as I know, you could save root (in duel.h) and use it to evaluate
- Xas often as needed (e.g for breakpoints/watchpoints), the internals
- Xof the nodes hold all eval info. You must reset the expression
- Xwith eval_stop, if u dont eval it to the last value. Also make sure you
- Xcleanup the dot stack. Aliases (in misc.c) could become scoped, of course.
- X
- XInterface to the debugger
- X-------------------------
- X
- XWhat DUEL needs:
- X1. A way to access the symbol table for variable names, types, etc.
- X2. A way to access the value of a variable, both for read and writes.
- X3. A way to call debuggee functions.
- X4. A way to get locals of frame n
- X5. misc functions, eg memory alloc, entery/exit code
- X
- XIn practice, you will probably take duelgdb.c and modify it until you
- Xget the "right thing" for your debugger.
- XNOTE: duelgdb.c was written from scratch and has *no* GNU code in it.
- X
- XThe most complex issue is types - you must pass names in a tvalue,
- Xwhich include a tctype (the C reminds one of a "C" type, not just 'type'
- Xwhich is ambiguous). The code to convert gdb types into duel types is
- Xtypical. Watch out for recursive struct pointers (the hash table handles
- Xthese problems), and for partial types, e.g. pointer to struct which
- Xcontains no fields (size zero!).
- X
- XYou can return a BVALUE an LVALUE (preferred) or an RVALUE for a name
- Xlookup. use RVALUE for names found in registers, and return the actual
- Xvalue.
- X
- Xif a frame number is given for symbol lookup, only local variables
- Xallocated in that frame should be returned. (else return none. don't
- Xreturn a global if it exist with the same name, this will make the dot
- Xstack compute things wrong).
- X
- XNode that this doesnt help with scoping problems (for duel)- e.g.
- Xyou can't do myfunc.x if x is a static variable in myfunc. There needs to
- Xbe a more complex & general way in the language to specify this (i.e.
- Xspecify a source location in which the variable is visible, AND a frame
- Xto use if the value is kept on a frame) frame(n).(scope(file,line).x)?
- X
- SHAR_EOF
- $TOUCH -am 0115021793 internals.doc &&
- chmod 0644 internals.doc ||
- echo "restore of internals.doc failed"
- set `wc -c internals.doc`;Wc_c=$1
- if test "$Wc_c" != "5550"; then
- echo original size 5550, current size $Wc_c
- fi
- # ============= wishlist.doc ==============
- echo "x - extracting wishlist.doc (Text)"
- sed 's/^X//' << 'SHAR_EOF' > wishlist.doc &&
- X += -= etc operators
- X initialize variables e.g. int x=0 , maybe even scopes
- X +/ */ &/ |/ ^/ ==/ !=/ </ >/ <=/ >=/
- X src(location) as scope
- X istype(type,x) to check type of x
- X ?x to check for x in current scope
- X conditional break points, watchpoints
- X better type checking of structs.
- X bitfield assignment
- X better builtin commands, help
- X output formatting, duel/xodus, more general out(v)
- X duel macros/functions
- X \x and \\x
- X check array bounds
- X x->>y x->-y x>--y
- X check cycles in --> expansion
- X ..:+ ..:-
- X print types, do so better
- X
- X
- XChecking for cycles in --> expansion
- X------------------------------------
- XOne can easily add code to handle head-->(next!=?head), as well as
- Xhead-->(next!=?_). If you don't know what these do, you should RTFM again :-)
- X
- XYou can also keep all pointers that have been expanded already,
- Xhence detecting any kind of cycle. However, what to do in
- Xsuch cases is debatable. Some users would like to see
- Xcycles terminate expansion quietly, while others will want a fatal error
- Xto be produced. This could be handled by an operator like x-->?y which
- Xwould indicate that cycles are ok and expansion should terminate quietly,
- Xwhile x-->y produce an error on cycles.
- X
- XIf you have a strong opinion on this subject, or a better idea, lemme know!
- X
- XOther expansions: x->>y x->-y x>--y
- X------------------------------------
- Xx-->y applies DFS (Depth First Search). Another useful expansion would be
- XBFS (Breath First Search). It is simple to implement - y's values should
- Xbe put on a queue instead of a stack, and the code in place has been written
- Xwith this in mind (eval.c).
- XOthers will probably want a post-order or in-order search instead of preorder
- Xsearch as done by x-->y. I am not sure this is important enough to merit
- Xnew operators, but ->- for inorder and >-- for post order are reserved.
- XThese, too, should be easy to implement, but it is very unclear that the
- Xadded complexity to the language is worth it. If you really need such
- Xoperators, lemme know.
- X
- XIncrement count for x..y (x..y:+z and x..y:-z)
- X------------------------------------------------
- XThe x..y operator could be extended to support an increment or decrement
- Xvalue. This would allow 1..n to be written as 1..n:+1 so when n==0 it
- Xwill not produce the surprising 1,0 results.
- XHowever, 0..10:+2 could also be written as (0..5)*2, so it is unclear
- Xthat such operators are really needed (maybe just x..+y, x..-y to force
- Xthe direction).
- X
- X
- XDuel functions / print procedures
- X-------------------------------------
- Xthe command: dl define x expr
- Xwill define x to be duel procedure for expression expr.
- Xx can then be used like an alias (indeed, it will probably be kept in
- Xthe alias table with a special value). x evaluation returns multiple
- Xvalues.
- XThere is no need parameters, since emp.x would call "x" using the implicit
- Xparameter "_" set as emp. the expression for x is essentially put into
- Xthe code for the execution. Having no parameters (except implicit ones)
- Xmake it easier to document, use etc.
- X
- XSuch functions (macros?) are most useful for output. e.g.
- Xdl define empout val_type,a, u.if(val_type==0) code*6,name else code,z
- Xdl emp.empout
- Xwill produce output for
- X struct {
- X int val_type,code ;
- X char a;
- X union { char *name ; double z ; } u
- X } emp ;
- X
- Xthe empout procedure can be defined just once, and used to output such
- Xunions as needed.
- X
- XThe next step is to call such functions automatically for output and
- Xfor expansion. We add syntax like dl define out(type) expr
- X
- Xthen whenever an expression of the given type is to be printed, this
- Xcode is evaluated instead, e.g.:
- Xdl define out(struct emp) ...
- Xdl emp ## this calls the above out code for the output.
- X
- XWe can also expand expressions by calling the right function, e.g.
- XThe operator "\" calls a function to expand a specific type:
- Xdl define \(struct list *) (_-->next)
- Xdl if(\head#i == \head#j && i<j) \head[[i,j]]
- X
- Xinstead of writing this code (find non unique elements of linked list):
- X if(head-->next#i == head-->next#j && i<j) head-->next[[i,j]]
- X
- XBoth printing and expansion occurs automatically based on TYPE.
- XIt is unclear if the an array is allowed to be expanded by a pointer
- Xtype expansion or not (i.e. is \(int *) to expand "int x[40]").
- Xthis might require an extension to types allowing \(int [n]) which matches
- Xany int array and set n for the specific bound. Types could be extended
- Xin a similar way, e.g. \(type **) _[0..]@0
- Xwhich expands any array of pointers (e.g. argv).
- XThis can quickly require scope-nesting for local aliases/variables.
- X
- XAs before, it is unclear what of these is useful. Unless people depends on
- Xduel heavily, and write such "output/expansion" functions for the project,
- Xthe features are useless (who is going to use this interactively?)
- X
- XRegular expressions for names. $xxx and `xxx`
- X----------------------------------------------
- Xthis allows things like emp.`value_*` to return all the value_something
- Xfields. it is really useful with structs, especially if a grep-style hat (^)
- Xis supported. Obviously extends to func.rexp, to show all locals, etc,
- Xwhich will make it possible to write a stack-trace display in duel.
- X
- Xexact semantics (e.g. what is matched and how) unclear.
- SHAR_EOF
- $TOUCH -am 0121191493 wishlist.doc &&
- chmod 0644 wishlist.doc ||
- echo "restore of wishlist.doc failed"
- set `wc -c wishlist.doc`;Wc_c=$1
- if test "$Wc_c" != "5186"; then
- echo original size 5186, current size $Wc_c
- fi
- echo "End of part 1, continue with part 2"
- exit 0
-