summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2008-04-07 23:00:12 +0000
committerMike Frysinger <vapier@gentoo.org>2008-04-07 23:00:12 +0000
commit38454e6310c6e9e679b6171d2007e40b46cd513c (patch)
treefd9587c8d8aca71c85a0903a4313f62a6ed29969 /src/patchsets/gdb
parentmake sure stupid cvs keywords dont screw up our patches (diff)
downloadgentoo-38454e6310c6e9e679b6171d2007e40b46cd513c.tar.gz
gentoo-38454e6310c6e9e679b6171d2007e40b46cd513c.tar.bz2
gentoo-38454e6310c6e9e679b6171d2007e40b46cd513c.zip
punt to readd with -kb
Diffstat (limited to 'src/patchsets/gdb')
-rw-r--r--src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch12130
-rw-r--r--src/patchsets/gdb/6.8/11_all_gdb-6.6-duel-integrate.patch59
2 files changed, 0 insertions, 12189 deletions
diff --git a/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch b/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch
deleted file mode 100644
index 1abd30b0c9..0000000000
--- a/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch
+++ /dev/null
@@ -1,12130 +0,0 @@
-Add support for DUEL to gdb.
-ftp://ftp.cs.princeton.edu/pub/duel/
-
-To make changes:
- - patch -p0 < gdb-duel.patch
- - cd gdb/duel
- - <make changes>
- - ./create-patch.sh
-
-Diffstat:
- duel/MANUAL | 501 +++++++
- duel/Makefile | 32
- duel/README | 57
- duel/WHATNEW | 38
- duel/create-patch.sh | 34
- duel/duel.1 | 547 ++++++++
- duel/duel.c | 682 ++++++++++
- duel/duel.h | 35
- duel/duel.pipe | 107 +
- duel/duelself.c | 209 +++
- duel/error.c | 112 +
- duel/eval.c | 832 ++++++++++++
- duel/evalops.c | 1273 +++++++++++++++++++
- duel/global.h | 450 ++++++
- duel/internals.doc | 129 +
- duel/misc.c | 142 ++
- duel/output.c | 53
- duel/output2.c | 141 ++
- duel/parse.c | 3326 +++++++++++++++++++++++++++++++++++++++++++++++++++
- duel/parse.y | 940 ++++++++++++++
- duel/patchlevel.h | 7
- duel/print.c | 299 ++++
- duel/proto.h | 101 +
- duel/tsuite.c | 64
- duel/tsuite.gdb | 126 +
- duel/tsuite.gdb.out | 293 ++++
- duel/tsuite.self | 111 +
- duel/tsuite.self.out | 263 ++++
- duel/types.c | 200 +++
- duel/wishlist.doc | 160 ++
- duelgdb.c | 694 ++++++++++
- 31 files changed, 11958 insertions(+)
-
---- gdb/duel/MANUAL
-+++ gdb/duel/MANUAL
-@@ -0,0 +1,501 @@
-+
-+
-+
-+ DDDDuuuueeeellll((((1111)))) VVVVeeeerrrrssssiiiioooonnnn 1111....11110000 ((((MMMMaaaarrrr 99993333)))) DDDDuuuueeeellll((((1111))))
-+
-+
-+
-+ NNNNAAAAMMMMEEEE
-+ duel - A high level C debugging language extension to gdb
-+
-+ SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
-+ dddduuuueeeellll [gdb options] [_p_r_o_g[_c_o_r_e|_p_r_o_c_I_D]]
-+
-+ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
-+ Duel is a special purpose language designed for concise state
-+ exploration of debugged C programs, currently implemented under the
-+ GNU debugger _g_d_b(1). Duel is invoked by entering the shell command
-+ _d_u_e_l instead of _g_d_b. It is identical to gdb except for comments, which
-+ begin with `##' instead of `#', and the new _d_l command for Duel
-+ expressions:
-+
-+ _g_d_b> 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]".
-+
-+ IIIIFFFF YYYYOOOOUUUU NNNNEEEEVVVVEEEERRRR UUUUSSSSEEEEDDDD GGGGDDDDBBBB
-+ The improved functionality added by Duel merits a fresh look even by
-+ debugger shunners. Gdb is a powerful debugger with many commands, a
-+ thick manual and various interfaces including _e_m_a_c_s(1) and _x_x_g_d_b(1).
-+ These gdb commands should help you get started:
-+
-+ _b _l_i_n_e set a breakpoint at the line (b func to break at a function)
-+ _d _n delete breakpoint number n (gdb prints n when bp occurs)
-+ _l _l_i_n_e list the source beginning at line (l file.c:line for module)
-+ _r _p_a_r_m run/restart the program with the given parameters
-+ _s single-step to the next statement (steps into function calls)
-+ _n single-step to the next line, skipping over function calls
-+ _c continue execution
-+ _b_t show a stack trace
-+ _p _e_x_p evaluate a symbolic expression
-+ _d_l _e_x_p evaluate a Duel expression
-+ _d_l _g_d_b give a gdb command summary
-+
-+ The most common use is `b func' followed by `r' followed by several
-+ `n' and `s', evaluating expressions in between.
-+
-+ DDDDUUUUEEEELLLL QQQQUUUUIIIICCCCKKKK SSSSTTTTAAAARRRRTTTT
-+ Duel is implemented by adding the _d_l command to gdb. All gdb commands
-+ work as before. The dl command, however, is interpreted by duel. Gdb
-+ concepts (such as the value history) do not work in the dl command,
-+ and duel concepts are not understood by other gdb command.
-+
-+ 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.
-+
-+ _g_d_b> dl (1,9,12..15,22)
-+
-+ prints 1, 9, 12, 13, 14, 15 and 22. Such expressions can be used
-+ wherever a single value is used, e.g.
-+
-+ _g_d_b> 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 expressions, and supports limited variable declaration:
-+
-+ _g_d_b> 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:
-+
-+ _g_d_b> 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.
-+
-+ _g_d_b> 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:
-+
-+ _g_d_b> 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:
-+
-+ _g_d_b> 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:
-+
-+ _g_d_b> 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.
-+
-+ _g_d_b> ..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:
-+
-+ _g_d_b> 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:
-+
-+ _g_d_b> 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
-+
-+ _g_d_b> dl #/( head-->next->data >? 50 )
-+
-+ counts the number of data elements over 50 on the list. Several other
-+ operators, including x@y, x#y and active call stack access are
-+ described in the operators section.
-+
-+ OOOOPPPPEEEERRRRAAAATTTTOOOORRRRSSSS SSSSUUUUMMMMMMMMAAAARRRRYYYY
-+ Assoc Operators Details
-+ left {} () [] -> . f() --> x-->y expands x->y x->y->y ...
-+ x[[y]] x#y x@y generate x; select, index or stop-at y
-+ right #/ - * & ! ~ ++ -- (cast) #/x number of x values
-+ frame(n) sizeof(x) reference to call stack level n
-+ left x/y x*y x%y multiply, divide, reminder
-+ left x-y x+y add, subtract
-+ left x<<y x>>y shift left/right
-+ none x..y ..y x.. ..y = 0..y-1. x..y return x, x+1...y
-+ left < > <= >= <? >? <=? >=? x>?y return x if x>y
-+ left == != ==? !=? x==?y return x if x==y
-+ left x&y bit-and
-+ left x^y bit-xor
-+ left x|y bit-or
-+ left x&&y &&/x &&/x are all x values non-zero?
-+ left x||y ||/x ||/x is any x value non-zero?
-+ right x? y:z foreach x, if(x) y else z
-+ right x:=y x=y x+=y ... x:=y set x as an alias to y
-+ left x,y return x, then y
-+ right x=>y foreach x, evaluate y with x value `_'
-+ right if() else while() for() C statements cast as operators
-+ left x;y evaluate and ignore x, return y
-+
-+
-+ EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
-+ dl (0xff-0x12)*3 compute simple expression
-+ dl (1..10)*(1..10) display multiplication table
-+ dl x[10..20,22,24,40..60] display x[i] for the selected indexes
-+ dl x[9..0] display x[i] backwards
-+ dl x[..100] >? 5 display x[i] that are greater than 5
-+ dl x[..100] >? 5 <? 10 display x[i] if 5<x[i]<10
-+ dl x[..100] ==? (6..9) same
-+ dl x[0..99]=>if(_>5 && _<10) _ same
-+ dl y[x[..100] !=? 0] display y[x[i]] for each non-zero x[i]
-+ dl emp[..50].code display emp[i].code for i=0 to 49
-+ dl emp[..50].(code,name) display emp[i].code & emp[i].name
-+ dl val[..50].(is_dbl? x:y) display val[i].x or val[i].y depending
-+ on val[i].is_dbl.
-+ dl val[..50].if(is_dbl) x else y same as above
-+ dl x[..100]=0 ; assign 0 to x[i]
-+ dl x[i:=..100]=y[i] ; assign y[i] to x[i]
-+ dl x[..100]=y[..100] *ERR* assign y[99] to each x[j]
-+ dl x[i:=..3]=(4,5,9)[[i]] assign x[0]=4 x[1]=5 x[2]=9
-+ dl x[..3]=(4,5,9) *ERR* assign 9 to each element
-+ dl if(x[i:=..100]<0) x[i]=0 ; assign 0 to negative x[i]
-+ dl (hash[..1024]!=?0)->scope hash[i].scope for non-null hash[i]
-+ dl x[i:=..100] >? x[i+1] check if x[i] is not sorted
-+ dl x[i:=..100] ==? x[j:=..100]=> checks if x has non-unique elements
-+ if(i<j) x[{i,j}]
-+ dl if(x[i:=..99] == same
-+ x[j:=i+1..99]) x[{i,j}]
-+ dl (x[..100] >? 0)[[0]] the 1st (0th element) positive x[i]
-+ dl (x[..100] >? 0)[[2]] return the 3rd positive x[i]
-+ dl (x[..100] >? 0)[[..5]] return the first 5 positive x[i]
-+ dl (x[0..] >? 6)[[0]] return the first x[i]>6, no limit on i
-+ dl argv[0..]@0 argv[0] argv[1] .. until first null
-+ dl x[0..]@-1 >? 9 x[0..n]>9 where n is first x[n]== -1
-+ dl emp[0..]@(code==0) emp[0]..emp[n-1] where emp[n].code==0
-+
-+ dl head-->next->val val of each element in a linked list
-+ dl head-->next[[20]] the 21st element of a linked list
-+ dl *head-->next[[20]] display above as a struct
-+ dl strcmp(head-->next->msg, search linked list for a string
-+ "testing") ==? 0
-+ dl #/head-->next count elements on a linked list
-+ dl x-->y[[#/x-->y - 1]] last element of a linked list
-+ dl x-->y[[#/x-->y - 10..1]] last 10 elements of a linked list
-+ dl head-->next-> check if the list is sorted by val
-+ if(next) val >? next->val
-+
-+ dl head-->(next!=?head) expand cyclic linked list (tail->head)
-+ dl head-->(next!=?_) handle termination with p->next==p
-+ dl root-->(left,right)->key expand binary tree, show keys
-+ dl root-->(left,right)->( check bin tree sorted by key
-+ (left!=?0)->key>=?key, (right !=?0 )->key<=?key)
-+
-+ dl (1000..=>if(&&/(2,3.._-1=>__%_ find first 10 primes over 1000
-+ ) _)[[..10]]
-+ dl (T mytype) x convert x to user defined type mytype
-+ dl (struct s*) x convert x to struct s pointer
-+ dl if(x) y; else z *ERR* ';' must be followed by an expression
-+ dl {x} y *ERR* '}' requires ';' if followed by exp
-+
-+ SSSSEEEEMMMMAAAANNNNTTTTIIIICCCCSSSS
-+ Duel's semantics are modeled after the Icon programming language. The
-+ input consists of expressions which return sequences of values. C
-+ statements are cast as expressions, too. Expressions are parsed into
-+ abstract syntax trees, which are traversed during evaluation. The
-+ evaluation of most nodes (operators) recursively evaluates the next
-+ value for each operand, and then applies the operator to produce the
-+ next result. Only one value is produced each time, and Duel's eval
-+ function keeps a `state' for each node (backtracking, co-routines,
-+ consumer-producer or threads are good metaphors for the evaluation
-+ mechanism.)
-+
-+ For example, in (5,3)+6..8, the evaluation of `+' first retrieves the
-+ operands 5 and 6, to compute and return 5+6. Then 7, the next right
-+ operand is retrieved and 5+7 is returned, followed by 5+8. Since
-+ there are no other right operand value, the next left operand, 3 is
-+ fetched. The right operand's computation is restarted returning 6, and
-+ 3+6 is returned. The final return values are 3+7 and 3+8.
-+
-+ The computation for operators like x>?y is similar, but when x<=y, the
-+ next values are fetched instead of returning a value, forming the
-+ basis for an implicit search. Operators like `..' return a sequence of
-+ values for each pair of operands. For a better understanding of the
-+ evaluation mechanism, see the USENIX Winter/93 conference paper "DUEL
-+ - A Very High Level Debugging Language".
-+
-+ Duel values follow the C semantics. A value is either an "lvalue" (can
-+ be used as the left hand side of assignment), or an "rvalue".
-+ Therefor, objects like arrays can not be directly manipulated
-+ (However, operators like x..y can accomplish such tasks.)
-+
-+ Duel types also follow the C semantics, with some important
-+ differences. C types are checked statically; Duel types are checked
-+ when operators are applied, e.g., (1,1.0)/2 returns 0 (int) and 0.5
-+ (double); (x,y).z returns x.z and y.z even if x and y are of different
-+ types, as long as they both have a field z.
-+
-+ Values and types of symbols are looked up at run-time (using gdb's
-+ lookup rules), allowing dynamic scoping and types, but causing a
-+ parsing problem: (x)(y) can be parsed as either a function call x(y)
-+ or a cast (x)y; x*y can be parsed as a declaration of y as (x*) or as
-+ multiplication.
-+
-+ To avoid this ambiguity, the keyword T must precede a user defined
-+ type. For example, if value is a typedef, C's (value (*)()) x is
-+ written in Duel as: (T value (*)()) x. Types that begin with a
-+ reserved keyword don't need T, e.g. (struct value*) x and (long *[5])
-+ y are accepted. As special cases, (type)x and (type*)x are accepted
-+ but discouraged (it causes (printf)("hi"), which is valid in C, to
-+ fail). A side effect is that "sizeof x" must be written as sizeof(x).
-+
-+ OOOOPPPPEEEERRRRAAAATTTTOOOORRRRSSSS
-+ _x+_y _x-_y _x*_y _x/_y _x%_y _x^_y _x|_y _x&_y _x<<_y _x>>_y
-+ _x>_y _x<_y _x>=_y _x<=_y _x==_y _x!=_y _x=_y _x[_y]
-+
-+ These binary operators follow their C semantics. For each value of x,
-+ they are evaluated for every value of y, .e.g. (5,2)>(4,1) evaluates
-+ as 5>4, 5>1, 2>4, 2>1 returning 1, 1, 0, 1. The y values are re-
-+ evaluated for each new value of x, e.g. i=4; (4,5)>i++ evaluates as
-+ 4>4 and 5>5. Beware of multiple y values in assignment, e.g.
-+ x[..3]=(4,6,9) does not set x[0]=4, x[1]=6 and x[2]=9. It assigns 4, 6
-+ and 9 to each element, having the same effect as x[..3]=9. Use
-+ x[i:=..3]=(4,6,9)[[i]] to achieve the desired effect.
-+
-+ -_x ~_x &_x *_x !_x ++_x --_x _x++ _x-- _s_i_z_e_o_f(_x) (_t_y_p_e)_x
-+
-+ These unary operators follow their C semantics. They are applied to
-+ each value of x. The increment and decrement operators require an
-+ lvalue, so i:=0 ; i++ produces an error because i is an alias to 0, an
-+ rvalue. Parenthesis must be used with sizeof(x), "sizeof x" is not
-+ allowed. Cast to user defined type requires generally requires T,
-+ e.g.,
-+ (T val(*)())x, but (val)x and (val*)x are accepted as special cases.
-+
-+ _x&&_y _x||_y
-+
-+ These logical operators also follow their C semantics, but have non-
-+ intuitive results for multi-valued x and y, e.g. (1,0,0) || (1,0)
-+ returns 1,1,0,1,0 -- the right hand-side (1,0) is returned for each
-+ left-hand side 0. It is best to use these operators only in single
-+ value expressions.
-+
-+ _x? _y:_z _i_f(_x)_y _i_f(_x)_y _e_l_s_e _z
-+
-+ These expressions return the values of y for each non-zero value
-+ returned by x, and the values of z for each zero value returned by x,
-+ e.g. if(x[..100]==0) y returns y for every x[i]==0, not if all x[i]
-+ are zero (if(&&/(x[..100]==0)) y does that). Also, "if(x) y; else z"
-+ is illegal. Duel's semicolon is an expression separator, not a
-+ terminator.
-+
-+ _w_h_i_l_e(_x)_y _f_o_r(_w;_x;_y)_z
-+
-+ The while(x)y expression returns y as long as all values of x are
-+ non-zero. The for() expression is similar and both have the expected
-+ C semantics. For example, "for(i=0 ; i<100 ; i++) x[i]" is the same as
-+ x[..100]. Unlike the if() expression, while(x[..100]==0) continue to
-+ execute only if all elements of x are zero, i.e. the condition is
-+ evaluated into a single value using an implicit &&/x.
-+
-+ VVVVaaaarrrriiiiaaaabbbblllleeee ddddeeeeccccllllaaaarrrraaaattttiiiioooonnnn:::: _t_y_p_e _n_a_m_e [,_n_a_m_e ...] ; ...
-+
-+ Expressions can begin with variables declaration (but not
-+ initialization). Internally, a declaration sets an alias to space
-+ allocated in the target by calling malloc(), e.g. `int x' is the same
-+ as "x:= *(int *) malloc(sizeof(int))". This is oblivious to the user.
-+ The allocated memory is not claimed when a variable is redeclared.
-+ Declared variables addresses can be passed to functions and used in
-+ other data structures. The keyword `T' must precede user defined types
-+ (typedef), e.g. if val is a user defined type, The C code "val
-+ *p=(val*) x" becomes "T val *p; p=(T val *) x" in Duel.
-+
-+ FFFFuuuunnnnccccttttiiiioooonnnn ccccaaaallllllllssss:::: _f_u_n_c(_p_a_r_m,...)
-+
-+ Function calls to the debugged program can be intermixed with Duel
-+ code. Multi-valued parameters are handled as with binary operators.
-+ The call value can have multiple values, e.g. (x,y)() calls x() and
-+ y(). Currently, struct/union parameters and return values are not
-+ supported.
-+
-+ _x,_y _x.._y .._x _x..
-+
-+ These operators produce multiple values for single value operands. x,y
-+ returns x, then y. x..y returns the integers from x to y. When x>y the
-+ sequence is returned in descending order, i.e. 5..3 returns 5, 4, 3.
-+ The operator ..x is a shorthand for 0..x-1, e.g. ..3 returns 0, 1, 2.
-+ The x.. operator is a shorthand for x..maxint. It returns increasing
-+ integer values starting at x indefinitely, and should be bounded by
-+ [[n]] or @n operators. `,' retains its precedence level in C. The
-+ precedence of `..' is above `<' and below arithmetic operators, so
-+ 0..n-1 and x==1..9 work as expected.
-+
-+ _x<?_y _x>?_y _x>=?_y _x<=?_y _x!=?_y _x==?_y
-+
-+ These operators work like their C counterparts but return x if the
-+ comparison is true. If the comparison is false, the next (x,y) value
-+ is tried, forming the basis of an implicit search.
-+
-+ (_x) {_x} _x;_y _x=>_y
-+
-+ Both () and {} act as C parenthesis. The curly braces set the returned
-+ symbolic value as the actual value, e.g. if i=5 and x[5]=3, then x[i]
-+ produces the output "x[i] = 3", x[{i}] produces "x[5] = 3" and {x[i]}
-+ produces just "3". The semicolon is an operator. x;y evaluates x,
-+ ignoring the results, then evaluate and return y, e.g. (i:=1..3 ; i+5)
-+ sets i to 3 and return 8. The x=>y operator evaluate and return y for
-+ each value of x, e.g. (i:=1..3 => i+5) returns 6, 7 and 8. The value
-+ returned by x is also stored implicitly in `_' which can be used in y,
-+ e.g. 1..5 => z[_][_] will output z[1][1], z[2][2] etc. The symbolic
-+ value for _ is that of the left side value, hence {_} is not needed.
-+ Semicolon has the lowest precedence, so it must be used inside () or
-+ {} for compound expressions. The precedence of `=>' is just below `,'.
-+ Beware that "if(a) x; else {y;} z" is illegal; a semicolon is not
-+ allowed before '}' or 'else' and must be inserted before z.
-+
-+ _x->_y _x._y
-+
-+ These expression work as in C for a symbol y. If y is an expression,
-+ it is evaluated under the scope of x. e.g. x.(a+b) is the same as
-+ x.a+x.b, if a and b are field of x (if they are not, they are looked
-+ up as local or global variables). x may return multiple values of
-+ different types, e.g. (u,v).a returns u.a and v.a, even if u and v are
-+ different structures. Also, the value of x is available as `_' inside
-+ y, e.g. x[..100].(if(a) _) produces x[i] for each x[i].a!=0. Nested
-+ x.y are allowed, e.g. u.(v.(a+b)) would lookup a and b first under v,
-+ then under u.
-+
-+ AAAAlllliiiiaaaasssseeeessss:::: _x:=_y
-+
-+ Aliases store a reference to y in x. Any reference to x is then
-+ replaced by y. If y is a constant or an rvalue, its value is replaced
-+ for x. If y is an lvalue (e.g. a variable), a reference to same lvalue
-+ is returned. for example, x:=emp[5] ; x=9 assigns 9 to emp[5].
-+ Aliases retain their values across invocation of the "dl" command. An
-+ alias to a local variable will reference a stray address when the
-+ variable goes out of scope. The special command "dl clear" delete all
-+ the aliases, and "dl alias" show all current aliases. Symbols are
-+ looked up as aliases first, so an alias x will hide a local x.
-+
-+ _x-->_y
-+
-+ The expansion operator x-->y expands a data structure x following the
-+ y links. It returns x, x->y, x->y->y, until a null is found. If x is
-+ null, no values are produced. If y returns multiple values, they are
-+ stacked and each is further expanded in a depth-first notion. For
-+ example, if r is the root of a tree with children u->childs[..u-
-+ >nchilds], then u-->(childs[..nchilds]) expands the whole tree. y is
-+ an arbitrary expression, evaluated exactly like x->y (this includes
-+ `_'.)
-+
-+ _x@_y
-+
-+ The expression x@y produces the values of x until x.y is non-zero,
-+ e.g. for(i=0 ; x[i].code!= -1 && i<100 ; i++) x[i] can be written as
-+ x[..100]@(code==-1). The evaluation of x is stopped as soon as y
-+ evaluates to true. x->y or x=>y are used to evaluate y when x is not a
-+ struct or a union. If y is a constant,(_==y) is used. e.g. s[0..]@0
-+ produces the characters in string s up to but not including the
-+ terminating null.
-+
-+ #/_x &&/_x ||/_x
-+
-+ These operator return a single "summary" value for all the values
-+ returned by x. #/x returns the number of values returned by x, e.g.
-+ #/(x[..100]>?0) counts the number of positive x[i]. &&/x returns 1 if
-+ all the values produced by x are non-zero, and ||/x returns 1 if any
-+ of x's values are non-zero. Like in C, the evaluation stops as soon as
-+ possible. For example, ||/(x[..100]==0) and &&/(x[..100]==0) check if
-+ one or all of x[i] are zero, respectively.
-+
-+ _x#_y _x[[_y]]
-+
-+ The operator x#y produces the values of x and arranges for y to be an
-+ alias for the index of each value in x. It is commonly used with x-->y
-+ to produce the element's index, e.g. head-->next->val#i=i assigns
-+ each val field its element number in the list.
-+ The selection operator x[[y]] produces the yth result of x. If y
-+ returns multiple value, each select a value of x, e.g.
-+ (5,7,11,13)[3,0,2] returns 13, 5 and 11 (13 is the 3rd element, 5 is
-+ the 0th element). Don't use side effects in x, since its evaluation
-+ can be restarted depending on y, e.g. after (x[0..i++])[[3,5]] the
-+ value of i is unpredictable.
-+
-+ _f_r_a_m_e(_n) _f_r_a_m_e_s__n_o _f_u_n_c._x
-+
-+ frame(n) for an integer n returns a reference to the nth frame on the
-+ stack (0 is the inner most function and frame(frames_no-1) is main()).
-+ Frame values can be compared to function pointers, e.g.
-+ frame(3)==myfunc is true if the 4th frame is a call to myfunc, and in
-+ scope resolution, e.g. frame(3).x return the local variable x of the
-+ 4th frame. frames_no is the number of active frames on the stack,
-+ e.g. (frames(..frames_no) ==? myfunc).x displays x for all active
-+ invocations of myfunc. As a special case,
-+ (frames(..frames_no)==?f)[[0]].x can be written as f.x (x can be an
-+ expression).
-+
-+
-+ BBBBUUUUGGGGSSSS
-+ Both `{}' and `;' are operators, not statements or expression
-+ separators; "if(x) y; else {z;} u" is illegal; use "if(x) y else {z} ;
-+ u". Ambiguities require preceding user-defined types (typedef) with
-+ the keyword T, e.g., if value is a user type, C's "sizeof(value*)" is
-+ written "sizeof(T value*)", except for the casts "(t)x" and "(t*)x";
-+ sizeof(x) requires parenthesis for variable x.
-+
-+ Unimplemented C idiom include: modified-assignment (x+=y), switch,
-+ break, continue, do, goto, scopes, function declarations, initializing
-+ declared variables, assignment to bit-fields and register variables,
-+ and calling functions with a struct/union parameter or return value.
-+ gdb does not store function prototypes, so parameters are not checked.
-+
-+ Gdb itself is buggy, which shows up, especially in symbol tables and
-+ calling target functions. Before you report bug, try to do the closest
-+ thing under gdb's "print". Send bug to: mg@cs.princeton.edu.
-+
-+ FFFFIIIILLLLEEEESSSS
-+ duel.out tracks duel commands usage. Help analyze duel's use by
-+ mailing a copy to mg@cs.princeton.edu.
-+ Duel is available by anonymous ftp at ftp.cs.princeton.edu:/duel.
-+
-+ AAAAUUUUTTTTHHHHOOOORRRR
-+ Duel is public domain code -- no copy left or right. See the internals
-+ documentation for details on porting Duel and using its code. Duel
-+ was designed and written by Michael Golan as part of a PhD thesis in
-+ the Computer Science Department of Princeton University. I would like
-+ to thank my advisor, Dave Hanson, who helped in all phases of this
-+ project and to Matt Blaze for his support and useful insight.
-+
-+ Duel stands for Debugging U (might) Even Like, or Don't Use this
-+ Exotic Language. Judge for yourself!
---- gdb/duel/Makefile
-+++ gdb/duel/Makefile
-@@ -0,0 +1,32 @@
-+#
-+# generic makefile for Duel 1.10
-+# nothing fancy is required: yacc/bison of parse.y, compile all other modules,
-+# and put all of the OBJ= modules into duel.a library.
-+# gdb is compiled with its own makefile (you add duel.a and duelgdb.c)
-+# selfduel, for testing, is compiled and linked with duel.a
-+
-+AR ?= ar
-+RANLIB ?= ranlib
-+
-+OBJ = duel.o types.o eval.o misc.o parse.o error.o evalops.o print.o
-+
-+all: duel.a duelself
-+
-+duelself: duel.a output.o
-+
-+duel.a: $(OBJ)
-+ $(AR) rc $@ $^
-+ $(RANLIB) $@
-+
-+parse.c: parse.y
-+ bison -o $@ $^
-+
-+clean distclean:
-+ rm -f $(OBJ) y.tab.c parse.c duelself.o duelself duel.a
-+
-+install:
-+
-+test: duelself
-+ duelself <tsuite.self >self.out
-+ @echo NOTE: diffs of the @xxxx values are ok
-+ diff tsuite.self.out self.out
---- gdb/duel/README
-+++ gdb/duel/README
-@@ -0,0 +1,57 @@
-+-------------------------------------------------------------------------------
-+README for DUEL 1.10 distribution mg@cs.princeton.edu (M. Golan) Mar 93
-+-------------------------------------------------------------------------------
-+see WHATNEW for what's new in version 1.10.
-+
-+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, e.g.,
-+
-+ gdb> dl x[0..10].level >? 5
-+ x[3].level = 14
-+ x[8].level = 6
-+
-+ prints the "level" fields of array elements x[0] to x[10] that are greater
-+ than 5. The output includes the values 14 and 6, as well as their
-+ symbolic representation "x[3].level" and "x[8].level". Linked list and
-+ other complex data structures are just as easy. Most of C (e.g. for, if)
-+ is also supported, e.g., int i; for(i=0; i<11; i++) if(x[i].level>5) x[i].
-+
-+Even if you don't normally use debuggers, but you are programming in C, give
-+Duel a try! The man page & help even include a summary of useful gdb commands.
-+The man page (duel.1) contains an introduction & many examples.
-+
-+Duel is debugger-independent, but the current distribution interface only
-+with gdb. You will need the source for gdb-4.6, 4.7 or 4.8. 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.
-+
-+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, or, in it Usenix
-+formatting, as /duel/usenix.paper.ps.Z. The software & man page are more
-+up-to-date though.
-+
-+See MANIFEST for a list of files in the distribution. The file INSTALL
-+explains how to install duel. MANUAL is a formatted version of the manual
-+duel.1.
-+
-+If you are using duel and find it useful, or have any comments or suggestion,
-+please drop me a line! duel.out is automatically produced to contain
-+the dl commands you have used, I would appreciate it if you email it to
-+me so that I could collect usage information. Thanks!
-+
-+Michael Golan
-+mg@cs.princeton.edu
---- gdb/duel/WHATNEW
-+++ gdb/duel/WHATNEW
-@@ -0,0 +1,38 @@
-+-------------------------------------------------------------------------------
-+WHATNEW for DUEL 1.10 distribution mg@cs.princeton.edu (M. Golan) Mar 93
-+-------------------------------------------------------------------------------
-+patch 1.10.4 fix use of system("date") to support OS/2
-+patch 1.10.3 bug fix left->left bad symbolic, long symbolics caused crash
-+patch 1.10.2 bug fix (type*) casting was wrong
-+patch 1.10.1 bug fix frame(0).bad_name crashed duel. enum size zero,
-+ sometimes possible in symbol tables, now allowed.
-+
-+What's New in version 1.10
-+--------------------------
-+Previously, all typedefs had to be preceded with 'T', e.g. (T uint) x.
-+The parsing is now hacked, so that the most common cases don't require T:
-+(type)x and (type*)x, e.g., (uint)x, *(value *)p. T is still required in
-+complex casts like (T value (*)())p, in variable declaration "T uint x ;"
-+and with sizeof(T uint). Side effects of this change: (printf)("hi\n")
-+won't work, since (printf) is recognized as a cast. This shouldn't be a
-+problem - you can use {x} for (x). Also, "sizeof x" is no longer supported,
-+you must use sizeof(x) instead.
-+
-+An experimental output control through a pipe has been added. To try it,
-+you should change duel/src/Makefile to compile output2.o instead of output.o
-+(delete duel.a to make sure it won't have both output.o and output2.o).
-+When output2.o is linked into duelself and/or gdb, duel fork and execute
-+the command duel.pipe in the current directory. All the output from expression
-+evaluation is sent to this program and its output is displayed. An example
-+duel.pipe, a Perl script, is provided. A lot that can be done with duel.pipe
-+to process the results symbolically, e.g., display integers in decimal,
-+place values on the same line, fork and execute xgraph, check
-+for unique values, etc. I would appreciate any comments on its use.
-+
-+A few minor bugs have been fixed. duel.man now contains a nicely formatted
-+version of duel.1. Portability was improved. #/(x) provide a better symbolic
-+expression.
-+
-+What's new in version 1.02
-+--------------------------
-+a few bug fixed, improved portability, gdb4.8 support.
---- gdb/duel/create-patch.sh
-+++ gdb/duel/create-patch.sh
-@@ -0,0 +1,34 @@
-+#!/bin/sh
-+
-+export LC_ALL=C # make sure order/sort is consistent
-+
-+make -s clean
-+make -s parse.c
-+
-+cd ../..
-+mkdir -p empty/gdb/duel
-+
-+diff -Nur empty/gdb gdb | \
-+ sed -r \
-+ -e '/^diff -Nur/d' \
-+ -e 's:^--- empty/gdb:--- gdb:' \
-+ -e '/^(---|\+\+\+) /s:\t.*::' \
-+ > gdb-duel.patch.bulk
-+cat <<EOF > gdb-duel.patch
-+Add support for DUEL to gdb.
-+ftp://ftp.cs.princeton.edu/pub/duel/
-+
-+To make changes:
-+ - patch -p0 < gdb-duel.patch
-+ - cd gdb/duel
-+ - <make changes>
-+ - ./create-patch.sh
-+
-+Diffstat:
-+$(diffstat gdb-duel.patch.bulk)
-+
-+$(cat gdb-duel.patch.bulk)
-+EOF
-+rm -r gdb-duel.patch.bulk empty
-+
-+echo "updated patch now ready:" $(du -b gdb-duel.patch)
---- gdb/duel/duel.1
-+++ gdb/duel/duel.1
-@@ -0,0 +1,547 @@
-+'\" t
-+.\" This document and the Duel source code are in the public domain.
-+.\" Note that the duel executable contains GNU code and is not public domain.
-+.TH Duel 1 "Mar 93" "Version 1.10"
-+.SH NAME
-+duel \- A high level C debugging language extension to gdb
-+.SH SYNOPSIS
-+.B duel
-+[gdb options]
-+.RB "[\|" \c
-+.I prog\c
-+.RB "[\|" \c
-+.IR core \||\| procID\c
-+\&\|]\&\|]
-+.ad b
-+.SH DESCRIPTION
-+Duel is a special purpose language designed for concise state exploration
-+of debugged C programs, currently implemented under the GNU debugger
-+.IR gdb (1).
-+Duel is invoked by entering the shell command
-+.I duel
-+instead of
-+.I gdb.
-+It is identical to gdb except for
-+comments, which begin with `##' instead of `#', and the new
-+.I dl
-+command for Duel expressions:
-+.nf
-+
-+\f2gdb>\f1 dl x[1..10] >? 5
-+x[3] = 14
-+x[8] = 6
-+
-+.fi
-+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]".
-+.SH IF YOU NEVER USED GDB
-+The improved functionality added by Duel merits a fresh look
-+even by debugger shunners.
-+Gdb is a powerful debugger with many commands, a thick manual and
-+various interfaces including
-+.IR emacs (1)
-+and
-+.IR xxgdb (1).
-+These gdb commands should help you get started:
-+
-+.TS
-+l l.
-+\f2b line\f1 set a breakpoint at the line (b func to break at a function)
-+\f2d n\f1 delete breakpoint number n (gdb prints n when bp occurs)
-+\f2l line\f1 list the source beginning at line (l file.c:line for module)
-+\f2r parm\f1 run/restart the program with the given parameters
-+\f2s\f1 single-step to the next statement (steps into function calls)
-+\f2n\f1 single-step to the next line, skipping over function calls
-+\f2c\f1 continue execution
-+\f2bt\f1 show a stack trace
-+\f2p exp\f1 evaluate a symbolic expression
-+\f2dl exp\f1 evaluate a Duel expression
-+\f2dl gdb\f1 give a gdb command summary
-+.TE
-+
-+The most common use is `b func' followed by `r' followed by several
-+`n' and `s', evaluating expressions in between.
-+.SH DUEL QUICK START
-+Duel is implemented by adding the
-+.I dl
-+command to gdb. All gdb commands
-+work as before. The dl command, however, is interpreted by duel.
-+Gdb concepts (such as the value history) do not work in the dl command,
-+and duel concepts are not understood by other gdb command.
-+
-+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.
-+.sp
-+\f2gdb>\f1 dl (1,9,12..15,22)
-+.sp
-+prints 1, 9, 12, 13, 14, 15 and 22. Such expressions can
-+be used wherever a single value is used, e.g.
-+.sp
-+\f2gdb>\f1 dl x[0..99]=0 ;
-+.sp
-+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
-+expressions, and supports limited variable declaration:
-+.sp
-+.br
-+\f2gdb>\f1 dl int i;for(i=0;i<100;i++)
-+.br
-+ if(x[i]<0) printf("x[%d]=%d\\n",i,x[i]);
-+.br
-+x[7] = -4
-+.sp
-+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:
-+.sp
-+\f2gdb>\f1 dl if(x[i:=0..99]<0) x[i]
-+.br
-+x[i] = -4
-+.sp
-+The symbolic output "x[i]" can be fixed by surrounding i with {}, i.e.
-+.sp
-+\f2gdb>\f1 dl if(x[i:=0..99]<0) x[{i}]
-+.br
-+x[7] = -4
-+.sp
-+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:
-+.sp
-+\f2gdb>\f1 dl x[..100] <? 0
-+.br
-+x[7] = -4
-+.sp
-+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:
-+.sp
-+\f2gdb>\f1 dl emp[..100].(if(code>400) (code,name))
-+.br
-+emp[46].code = 682
-+.br
-+emp[46].name = "Ela"
-+.sp
-+The if() expression is evaluated under the scope of each element
-+of emp[], an array of structures. In C terms, we had to write:
-+.sp
-+\f2gdb>\f1 dl int i; for(i=0; i<100 ; i++)
-+.br
-+ if(emp[i].code>400) emp[{i}].code,emp[{i}].name
-+.sp
-+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.
-+.sp
-+\f2gdb>\f1 ..100 => if(emp[_].code>400) emp[_].code,emp[_].name
-+.sp
-+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:
-+.sp
-+\f2gdb>\f1 dl head-->next->data
-+.br
-+head->data = 12
-+.br
-+head->next->data = 14
-+.br
-+head-->next[[2]]->data = 20
-+.br
-+head-->next[[3]]->data = 26
-+.sp
-+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:
-+.sp
-+\f2gdb>\f1 dl head-->next[[50..60]]->data
-+.sp
-+return the 50th through the 60th elements in the list. The #/x operator
-+counts the number of values, so
-+.sp
-+\f2gdb>\f1 dl #/( head-->next->data >? 50 )
-+.sp
-+counts the number of data elements over 50 on the list.
-+Several other operators, including x@y, x#y and
-+active call stack access are described in the operators section.
-+.SH OPERATORS SUMMARY
-+.\"All the C operators have the same precedence and associativity as in C. C
-+.\"statements have precedence just below `,' and `;' has the lowest precedence.
-+.\"Most Duel operators have the same precedence as their C counterparts. The
-+.\"following table is in decreasing precedence:
-+.TS
-+l l l.
-+Assoc Operators Details
-+left {} () [] -> . f() --> x-->y expands x->y x->y->y ...
-+ x[[y]] x#y x@y generate x; select, index or stop-at y
-+right #/ - * & ! ~ ++ -- (cast) #/x number of x values
-+ frame(n) sizeof(x) reference to call stack level n
-+left x/y x*y x%y multiply, divide, reminder
-+left x-y x+y add, subtract
-+left x<<y x>>y shift left/right
-+none x..y ..y x.. ..y = 0..y-1. x..y return x, x+1...y
-+left < > <= >= <? >? <=? >=? x>?y return x if x>y
-+left == != ==? !=? x==?y return x if x==y
-+left x&y bit-and
-+left x^y bit-xor
-+left x|y bit-or
-+left x&&y &&/x &&/x are all x values non-zero?
-+left x||y ||/x ||/x is any x value non-zero?
-+right x? y:z foreach x, if(x) y else z
-+right x:=y x=y x+=y ... x:=y set x as an alias to y
-+left x,y return x, then y
-+right x=>y foreach x, evaluate y with x value `_'
-+right if() else while() for() C statements cast as operators
-+left x;y evaluate and ignore x, return y
-+.TE
-+
-+.SH EXAMPLES
-+.TS
-+l l.
-+dl (0xff-0x12)*3 compute simple expression
-+dl (1..10)*(1..10) display multiplication table
-+dl x[10..20,22,24,40..60] display x[i] for the selected indexes
-+dl x[9..0] display x[i] backwards
-+dl x[..100] >? 5 display x[i] that are greater than 5
-+dl x[..100] >? 5 <? 10 display x[i] if 5<x[i]<10
-+dl x[..100] ==? (6..9) same
-+dl x[0..99]=>if(_>5 && _<10) _ same
-+dl y[x[..100] !=? 0] display y[x[i]] for each non-zero x[i]
-+dl emp[..50].code display emp[i].code for i=0 to 49
-+dl emp[..50].(code,name) display emp[i].code & emp[i].name
-+dl val[..50].(is_dbl? x:y) display val[i].x or val[i].y depending
-+ on val[i].is_dbl.
-+dl val[..50].if(is_dbl) x else y same as above
-+dl x[..100]=0 ; assign 0 to x[i]
-+dl x[i:=..100]=y[i] ; assign y[i] to x[i]
-+dl x[..100]=y[..100] *ERR* assign y[99] to each x[j]
-+dl x[i:=..3]=(4,5,9)[[i]] assign x[0]=4 x[1]=5 x[2]=9
-+dl x[..3]=(4,5,9) *ERR* assign 9 to each element
-+dl if(x[i:=..100]<0) x[i]=0 ; assign 0 to negative x[i]
-+dl (hash[..1024]!=?0)->scope hash[i].scope for non-null hash[i]
-+dl x[i:=..100] >? x[i+1] check if x[i] is not sorted
-+dl x[i:=..100] ==? x[j:=..100]=> checks if x has non-unique elements
-+ if(i<j) x[{i,j}]
-+dl if(x[i:=..99] == same
-+ x[j:=i+1..99]) x[{i,j}]
-+dl (x[..100] >? 0)[[0]] the 1st (0th element) positive x[i]
-+dl (x[..100] >? 0)[[2]] return the 3rd positive x[i]
-+dl (x[..100] >? 0)[[..5]] return the first 5 positive x[i]
-+dl (x[0..] >? 6)[[0]] return the first x[i]>6, no limit on i
-+dl argv[0..]@0 argv[0] argv[1] .. until first null
-+dl x[0..]@-1 >? 9 x[0..n]>9 where n is first x[n]== -1
-+dl emp[0..]@(code==0) emp[0]..emp[n-1] where emp[n].code==0
-+
-+dl head-->next->val val of each element in a linked list
-+dl head-->next[[20]] the 21st element of a linked list
-+dl *head-->next[[20]] display above as a struct
-+dl strcmp(head-->next->msg, search linked list for a string
-+ "testing") ==? 0
-+dl #/head-->next count elements on a linked list
-+dl x-->y[[#/x-->y - 1]] last element of a linked list
-+dl x-->y[[#/x-->y - 10..1]] last 10 elements of a linked list
-+dl head-->next-> check if the list is sorted by val
-+ if(next) val >? next->val
-+
-+dl head-->(next!=?head) expand cyclic linked list (tail->head)
-+dl head-->(next!=?_) handle termination with p->next==p
-+dl root-->(left,right)->key expand binary tree, show keys
-+dl root-->(left,right)->( check bin tree sorted by key
-+ (left!=?0)->key>=?key, (right !=?0 )->key<=?key)
-+
-+dl (1000..=>if(&&/(2,3.._-1=>__%_ find first 10 primes over 1000
-+ ) _)[[..10]]
-+dl (T mytype) x convert x to user defined type mytype
-+dl (struct s*) x convert x to struct s pointer
-+dl if(x) y; else z *ERR* ';' must be followed by an expression
-+dl {x} y *ERR* '}' requires ';' if followed by exp
-+.TE
-+.SH SEMANTICS
-+Duel's semantics are modeled after the Icon programming language.
-+The input consists of expressions which return sequences of values.
-+C statements are cast as expressions, too.
-+Expressions are parsed into abstract syntax trees, which are
-+traversed during evaluation. The evaluation of most nodes (operators)
-+recursively evaluates the next value for each operand, and then applies the
-+operator to produce the next result. Only one value is produced each time,
-+and Duel's eval function keeps a `state' for each node
-+(backtracking, co-routines, consumer-producer or threads are good metaphors
-+for the evaluation mechanism.)
-+
-+For example, in (5,3)+6..8, the
-+evaluation of `+' first retrieves the operands 5 and 6, to compute and
-+return 5+6. Then 7, the next right operand is retrieved
-+and 5+7 is returned, followed by 5+8.
-+Since there are no other right operand value, the next left operand, 3
-+is fetched. The right operand's computation is restarted returning
-+6, and 3+6 is returned. The final return values are 3+7 and 3+8.
-+
-+The computation for operators like x>?y is similar, but when x<=y,
-+the next values are fetched instead of returning a value,
-+forming the basis for an implicit search. Operators like `..' return a
-+sequence of values for each pair of operands. For a better understanding
-+of the evaluation mechanism, see the USENIX Winter/93 conference paper
-+"DUEL - A Very High Level Debugging Language".
-+
-+Duel values follow the C semantics. A value is either an
-+"lvalue" (can be used as the left hand side of assignment), or an "rvalue".
-+Therefor, objects like arrays can not be directly manipulated (However,
-+operators like x..y can accomplish such tasks.)
-+
-+Duel types also follow the C semantics, with some important
-+differences. C types are checked statically; Duel types are checked
-+when operators are applied, e.g., (1,1.0)/2 returns 0 (int) and
-+0.5 (double); (x,y).z returns x.z and y.z even if
-+x and y are of different types, as long as they both have a field z.
-+
-+Values and types of symbols are looked up at run-time (using gdb's lookup
-+rules), allowing dynamic scoping and types, but causing a parsing
-+problem: (x)(y) can be parsed as either a function call x(y) or a
-+cast (x)y; x*y can be parsed as a declaration of y as (x*) or as
-+multiplication.
-+
-+To avoid this ambiguity, the
-+keyword T must precede a user defined type. For example,
-+if value is a typedef, C's (value (*)()) x is written in Duel as:
-+(T value (*)()) x. Types that begin with a reserved keyword don't
-+need T, e.g. (struct value*) x and (long *[5]) y are accepted.
-+As special cases, (type)x and (type*)x are accepted but
-+discouraged (it causes (printf)("hi"), which is valid in C, to fail).
-+A side effect is that "sizeof x" must be written as sizeof(x).
-+.SH OPERATORS
-+.sp
-+.I "x+y x-y x*y x/y x%y x^y x|y x&y x<<y x>>y "
-+.br
-+.I "x>y x<y x>=y x<=y x==y x!=y x=y x[y]"
-+.sp
-+These binary operators follow their C semantics. For each value of x,
-+they are evaluated for every value of y, .e.g. (5,2)>(4,1)
-+evaluates as 5>4, 5>1, 2>4, 2>1 returning 1, 1, 0, 1.
-+The y values are re-evaluated for each new value of x, e.g.
-+i=4; (4,5)>i++ evaluates as 4>4 and 5>5.
-+Beware of multiple y values in assignment, e.g. x[..3]=(4,6,9) does not
-+set x[0]=4, x[1]=6 and x[2]=9. It assigns 4, 6 and 9 to each element, having
-+the same effect as x[..3]=9. Use x[i:=..3]=(4,6,9)[[i]] to achieve the
-+desired effect.
-+.sp
-+.I "-x ~x &x *x !x ++x --x x++ x-- sizeof(x) (type)x"
-+.sp
-+These unary operators follow their C semantics. They are applied
-+to each value of x. The increment and decrement operators require an
-+lvalue, so i:=0 ; i++ produces an error because i is an alias to 0,
-+an rvalue. Parenthesis must be used with sizeof(x), "sizeof x" is not
-+allowed. Cast to user defined type requires generally requires T, e.g.,
-+ (T val(*)())x, but (val)x and (val*)x are accepted as special cases.
-+.sp
-+.I "x&&y x||y"
-+.sp
-+These logical operators also follow their C semantics, but have non-intuitive
-+results for multi-valued x and y, e.g. (1,0,0) || (1,0) returns 1,1,0,1,0 --
-+the right hand-side (1,0) is returned for each left-hand side 0. It is best
-+to use these operators only in single value expressions.
-+.sp
-+.I "x? y:z if(x)y if(x)y else z"
-+.sp
-+These expressions return the values of y for each non-zero value
-+returned by x, and the values of z for each zero value returned by x, e.g.
-+if(x[..100]==0) y returns y for every x[i]==0, not if all x[i] are zero
-+(if(&&/(x[..100]==0)) y does that).
-+Also, "if(x) y; else z" is illegal. Duel's semicolon is
-+an expression separator, not a terminator.
-+.sp
-+.I "while(x)y for(w;x;y)z"
-+.sp
-+The while(x)y expression returns y as long as all values of x are non-zero.
-+The for() expression is similar and both have the expected C semantics. For
-+example, "for(i=0 ; i<100 ; i++) x[i]" is the same as x[..100]. Unlike
-+the if() expression, while(x[..100]==0) continue to execute only if all
-+elements of x are zero, i.e. the condition is evaluated into a single value
-+using an implicit &&/x.
-+.sp
-+.BI "Variable declaration: " "type name [,name ...] ; ..."
-+.sp
-+Expressions can begin with variables declaration (but not initialization).
-+Internally, a declaration sets an alias to space allocated
-+in the target by calling malloc(), e.g. `int x' is the same as
-+"x:= *(int *) malloc(sizeof(int))". This is oblivious to the user.
-+The allocated memory is not claimed when a variable is redeclared.
-+Declared variables addresses can be passed to functions and used in other
-+data structures. The keyword `T' must precede user defined types (typedef),
-+e.g. if val is a user defined type, The C code "val *p=(val*) x" becomes
-+"T val *p; p=(T val *) x" in Duel.
-+.sp
-+.BI "Function calls: " "func(parm,...)"
-+.sp
-+Function calls to the debugged program can be intermixed with Duel
-+code. Multi-valued parameters are handled as with binary operators.
-+The call value can have multiple values, e.g. (x,y)() calls x()
-+and y(). Currently, struct/union parameters and return values are not
-+supported.
-+.sp
-+.I "x,y x..y ..x x.."
-+.sp
-+These operators produce multiple values for single value operands.
-+x,y returns x, then y. x..y returns the integers from x to y.
-+When x>y the sequence is returned in descending order, i.e. 5..3
-+returns 5, 4, 3.
-+The operator ..x is a shorthand for 0..x-1, e.g. ..3 returns 0, 1, 2.
-+The x.. operator is a shorthand for x..maxint. It returns increasing
-+integer values starting at x indefinitely, and should be bounded
-+by [[n]] or @n operators.
-+`,' retains its precedence level in C. The precedence of `..'
-+is above `<' and below arithmetic operators, so 0..n-1 and x==1..9 work
-+as expected.
-+.sp
-+.I "x<?y x>?y x>=?y x<=?y x!=?y x==?y"
-+.sp
-+These operators work like their C counterparts but return x if the comparison
-+is true. If the comparison is false, the next (x,y) value is tried, forming
-+the basis of an implicit search.
-+.sp
-+.I "(x) {x} x;y x=>y"
-+.sp
-+Both () and {} act as C parenthesis.
-+The curly braces set the returned symbolic value
-+as the actual value, e.g. if i=5 and x[5]=3, then
-+x[i] produces the output "x[i] = 3", x[{i}] produces
-+"x[5] = 3" and {x[i]} produces just "3".
-+The semicolon is an operator. x;y evaluates x, ignoring the results,
-+then evaluate and return y, e.g. (i:=1..3 ; i+5) sets i to 3 and return 8.
-+The x=>y operator evaluate and return y for each value of x,
-+e.g. (i:=1..3 => i+5) returns 6, 7 and 8. The value returned by x is
-+also stored implicitly in `_' which can be used in y, e.g. 1..5 => z[_][_]
-+will output z[1][1], z[2][2] etc. The symbolic value for _ is that of the
-+left side value, hence {_} is not needed.
-+.br
-+Semicolon has the lowest precedence, so it must be used inside () or {}
-+for compound expressions. The precedence of `=>' is just below `,'.
-+Beware that "if(a) x; else {y;} z" is illegal; a semicolon is not allowed
-+before '}' or 'else' and must be inserted before z.
-+.sp
-+.IB "x->y x.y"
-+.sp
-+These expression work as in C for a symbol y. If y is an expression, it
-+is evaluated under the scope of x. e.g. x.(a+b) is the same as x.a+x.b,
-+if a and b are field of x (if they are not, they are looked up as local
-+or global variables). x may return multiple values of different types,
-+e.g. (u,v).a returns u.a and v.a, even if u and v are different structures.
-+Also, the value of x is available as `_' inside y, e.g. x[..100].(if(a) _)
-+produces x[i] for each x[i].a!=0. Nested x.y are allowed, e.g.
-+u.(v.(a+b)) would lookup a and b first under v, then under u.
-+.sp
-+.BI Aliases: " x:=y"
-+.sp
-+Aliases store a reference to y in x. Any reference to x is
-+then replaced by y. If y is a constant or an rvalue, its
-+value is replaced for x. If y is an lvalue (e.g. a variable), a reference
-+to same lvalue is returned. for example, x:=emp[5] ; x=9 assigns 9 to
-+emp[5].
-+Aliases retain their values across invocation of the "dl" command. An alias
-+to a local variable will reference a stray address when the variable
-+goes out of scope.
-+The special command "dl clear" delete all the aliases, and "dl alias"
-+show all current aliases. Symbols are looked up
-+as aliases first, so an alias x will hide a local x.
-+.sp
-+.I x-->y
-+.sp
-+The expansion operator x-->y expands a data structure x following the y links.
-+It returns x, x->y, x->y->y, until a null is found. If x is null, no values
-+are produced. If y returns multiple values, they are stacked and each is
-+further expanded in a depth-first notion. For example, if r is the root of
-+a tree with children u->childs[..u->nchilds], then
-+u-->(childs[..nchilds]) expands the whole tree. y is an arbitrary
-+expression, evaluated exactly like x->y (this includes `_'.)
-+.sp
-+.I x@y
-+.sp
-+The expression x@y produces the values of x until x.y is non-zero, e.g.
-+for(i=0 ; x[i].code!= -1 && i<100 ; i++) x[i] can be written as
-+x[..100]@(code==-1).
-+The evaluation of x is stopped as soon as y evaluates to true.
-+x->y or x=>y are used to evaluate y when x is not a struct or a union. If
-+y is a constant,(_==y) is used. e.g. s[0..]@0 produces the characters in
-+string s up to but not including the terminating null.
-+.sp
-+.IB "#/x &&/x ||/x"
-+.sp
-+These operator return a single "summary" value for all the values returned by
-+x. #/x returns the number of values returned by x, e.g.
-+#/(x[..100]>?0) counts the number of positive x[i]. &&/x returns 1 if all
-+the values produced by x are non-zero, and ||/x returns 1 if any of x's values
-+are non-zero. Like in C, the evaluation stops as soon as possible.
-+For example, ||/(x[..100]==0) and &&/(x[..100]==0) check if one or all of
-+x[i] are zero, respectively.
-+.sp
-+.IB "x#y x[[y]]"
-+.sp
-+The operator x#y produces the values of x and arranges for y to be an alias
-+for the index of each value in x. It is commonly used with x-->y to produce
-+the element's index, e.g. head-->next->val#i=i assigns each val field
-+its element number in the list.
-+.br
-+The selection operator x[[y]] produces the yth result of x. If y returns
-+multiple value, each select a value of x, e.g. (5,7,11,13)[3,0,2]
-+returns 13, 5 and 11 (13 is the 3rd element, 5 is the 0th element).
-+Don't use side effects in x, since its evaluation can be restarted depending
-+on y, e.g. after (x[0..i++])[[3,5]] the value of i is unpredictable.
-+.sp
-+.IB "frame(n) frames_no func.x"
-+.sp
-+frame(n) for an integer n returns a reference to the nth frame
-+on the stack (0 is the inner most function and frame(frames_no-1) is main()).
-+Frame values can be compared to function pointers,
-+e.g. frame(3)==myfunc is true if the 4th frame is a call to myfunc, and in
-+scope resolution, e.g. frame(3).x return the local variable x of the 4th frame.
-+frames_no is the number of active frames on the stack, e.g.
-+(frames(..frames_no) ==? myfunc).x displays x for all active
-+invocations of myfunc. As a special case, (frames(..frames_no)==?f)[[0]].x
-+can be written as f.x (x can be an expression).
-+.sp
-+.SH BUGS
-+Both `{}' and `;' are operators, not statements or expression separators;
-+"if(x) y; else {z;} u" is illegal; use "if(x) y else {z} ; u". Ambiguities
-+require preceding
-+user-defined types (typedef) with the keyword T, e.g., if
-+value is a user type, C's "sizeof(value*)" is written
-+"sizeof(T value*)", except for the casts "(t)x" and "(t*)x"; sizeof(x)
-+requires parenthesis for variable x.
-+
-+Unimplemented C idiom include: modified-assignment
-+(x+=y), switch, break, continue, do, goto, scopes, function declarations,
-+initializing declared variables,
-+assignment to bit-fields and register variables, and
-+calling functions with a struct/union parameter or return value.
-+gdb does not store function prototypes, so parameters are not checked.
-+
-+Gdb itself is buggy, which shows up, especially in symbol tables and
-+calling target functions. Before you report bug, try to do the closest
-+thing under gdb's "print". Send bug to: mg@cs.princeton.edu.
-+.SH FILES
-+duel.out tracks duel commands usage. Help analyze duel's use by mailing a
-+copy to mg@cs.princeton.edu.
-+.br
-+Duel is available by anonymous ftp at ftp.cs.princeton.edu:/duel.
-+.SH AUTHOR
-+Duel is public domain code -- no copy left or right. See the internals
-+documentation for details on porting Duel and using its code.
-+Duel was designed and written by Michael Golan as part of a PhD thesis
-+in the Computer Science Department of Princeton University.
-+I would like to thank my advisor, Dave Hanson, who helped in all phases
-+of this project and to Matt Blaze for his support and useful insight.
-+.sp
-+Duel stands for Debugging U (might) Even Like, or Don't Use this Exotic
-+Language. Judge for yourself!
-+
-+
---- gdb/duel/duel.c
-+++ gdb/duel/duel.c
-@@ -0,0 +1,682 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* this module contains the entery point to duel - duel_eval_and_pasre.
-+ */
-+
-+/*
-+ * $Log: 10_all_gdb-6.6-duel.patch,v $
-+ * Revision 1.1 2008/04/06 23:59:05 vapier
-+ * initial 6.8 patchset based on last 6.7.1 patchset
-+ *
-+ * Revision 1.11 93/03/13 04:03:07 mg
-+ * moved VERSION to patchlevel.h
-+ *
-+ * Revision 1.10 93/03/12 05:41:54 mg
-+ * Version 1.10 - support (x)y cast, piped output.
-+ *
-+ * Revision 1.9 93/02/23 19:09:35 mg
-+ * new version 1.02 release (support gdb4.8)
-+ *
-+ * Revision 1.8 93/02/03 21:56:33 mg
-+ * version 1.01
-+ *
-+ * Revision 1.7 93/01/12 21:28:44 mg
-+ * cleanup and set for release
-+ *
-+ * Revision 1.6 93/01/06 23:57:10 mg
-+ * added alias, clear commands, new memory alloc/release
-+ *
-+ * Revision 1.5 93/01/03 07:26:47 mg
-+ * new printing setup
-+ *
-+ * Revision 1.4 92/12/24 23:32:38 mg
-+ * better struct support, misc changes
-+ *
-+ * Revision 1.3 92/10/19 15:02:04 mg
-+ * lcc happy, size zero arrays
-+ *
-+ * Revision 1.2 92/10/14 02:03:15 mg
-+ * misc
-+ *
-+ */
-+
-+#include <setjmp.h>
-+#define DEF /* define global variables */
-+#include "duel.h"
-+#include "patchlevel.h"
-+
-+static jmp_buf duel_abort_jmp ; /* abort current execution */
-+static tnode *root ; /* root of current eval node */
-+
-+
-+/* abort evaluation of current expression */
-+
-+PROC duel_abort(void)
-+{
-+ longjmp(duel_abort_jmp,1);
-+}
-+
-+PROC duel_cleanup(void *unused) /* cleanup malloc, etc, when duel eval ends*/
-+{
-+ duel_redirectable_output_abort();
-+ duel_free_nodes(root);
-+ root=NULL ;
-+}
-+
-+LPROC longhelp(void)
-+{
-+ duel_printf(
-+"Duel(1) Duel(1)\n\
-+\n\
-+NAME\n\
-+ duel - A high level C debugging language extension to gdb\n\
-+\n\
-+DESCRIPTION\n\
-+ Duel is a special purpose language designed for concise state explo-\n\
-+ ration of debugged C programs, currently implemented under the GNU\n\
-+ debugger gdb(1). Duel is invoked by entering the shell command duel\n\
-+ instead of gdb. It is identical to gdb except for comments, which\n\
-+ begin with `##' instead of `#', and the new dl command for Duel expres-\n\
-+ sions:\n\
-+\n\
-+ gdb> dl x[1..10] >? 5\n\
-+ x[3] = 14\n\
-+ x[8] = 6\n\
-+\n\
-+ prints the array elements x[1] to x[10] that are greater than 5. The\n\
-+ output includes the values 14 and 6, as well as their symbolic repre-\n\
-+ sentation \"x[3]\" and \"x[8]\".\n\
-+\n\
-+DUEL QUICK START\n\
-+ Duel is implemented by adding the dl command to gdb. All gdb commands\n\
-+ work as before. The dl command, however, is interpreted by duel. Gdb\n\
-+ concepts (such as the value history) do not work in the dl command, and\n\
-+ duel concepts are not understood by other gdb command.\n\
-+\n\
-+ Duel is based on expressions which return multiple values. The x..y\n\
-+ operator returns the integers from x to y; the x,y operator returns x\n\
-+ and then y, e.g.\n\
-+\n\
-+ gdb> dl (1,9,12..15,22)\n\
-+\n\
-+ prints 1, 9, 12, 13, 14, 15 and 22. Such expressions can be used wher-\n\
-+ ever a single value is used, e.g.\n\
-+\n\
-+ gdb> dl x[0..99]=0 ;\n\
-+\n\
-+ assigns zero to the first 100 elements of array x. The semantics of\n\
-+ x[i] are the same as in C. They are applied for each of the values\n\
-+ returned by 0..99, which can be thought of as an implied external loop.\n\
-+ The trailing semicolon indicates evaluation for side-effects only, with\n\
-+ no output. Duel incorporates C operators, casts C statements as\n\
-+ expressions, and supports limited variable declaration:\n\
-+\n\
-+ gdb> dl int i;for(i=0;i<100;i++)\n\
-+ if(x[i]<0) printf(\"x[%%d]=%%d\\n\",i,x[i]);\n\
-+ x[7] = -4\n\
-+\n\
-+ The semicolon prevents Duel output; only output from printf is printed.\n\
-+ Aliases are defined with x:=y and provide an alternative to variable\n\
-+ declaration. We could also return x[i] instead of using printf:\n\
-+\n\
-+ gdb> dl if(x[i:=0..99]<0) x[i]\n\
-+ x[i] = -4\n\
-+\n\
-+ The symbolic output \"x[i]\" can be fixed by surrounding i with {}, i.e.\n\
-+\n\
-+ gdb> dl if(x[i:=0..99]<0) x[{i}]\n\
-+ x[7] = -4\n\
-+\n\
-+ The {} are like (), but force the symbolic evaluation to use i's value,\n\
-+ instead of \"i\". You can usually avoid this altogether with direct Duel\n\
-+ operators:\n\
-+\n\
-+ gdb> dl x[..100] <? 0\n\
-+ x[7] = -4\n\
-+\n\
-+ The ..n operator is a shorthand for 0..n-1, i.e. ..100 is the same as\n\
-+ 0..99. The x<?y, x==?y, x>=?y, etc., operators compare their left side\n\
-+ operand to their right side operand as in C, but return the left side\n\
-+ value if the comparison result is true. Otherwise, they look for the\n\
-+ next values to compare, without returning anything.\n\
-+\n\
-+ Duel's x.y and x->y allow an expression y, evaluated under x's scope:\n\
-+\n\
-+ gdb> dl emp[..100].(if(code>400) (code,name))\n\
-+ emp[46].code = 682\n\
-+ emp[46].name = \"Ela\"\n\
-+\n\
-+ The if() expression is evaluated under the scope of each element of\n\
-+ emp[], an array of structures. In C terms, we had to write:\n\
-+\n\
-+ gdb> dl int i; for(i=0; i<100 ; i++)\n\
-+ if(emp[i].code>400) emp[{i}].code,emp[{i}].name\n\
-+\n\
-+ A useful alternative to loops is the x=>y operator. It returns y for\n\
-+ each value of x, setting `_' to reference x's value, e.g.\n\
-+\n\
-+ gdb> ..100 => if(emp[_].code>400) emp[_].code,emp[_].name\n\
-+\n\
-+ Using `_' instead of `i' also avoids the need for {i}. Finally, the\n\
-+ x-->y operator expands lists and other data structures. If head points\n\
-+ to a linked list threaded through the next field, then:\n\
-+\n\
-+ gdb> dl head-->next->data\n\
-+ head->data = 12\n\
-+ head->next->data = 14\n\
-+ head-->next[[2]]->data = 20\n\
-+ head-->next[[3]]->data = 26\n\
-+\n\
-+ produce the data field for each node in the list. x-->y returns x,\n\
-+ x->y, x->y->y, x->y->y->y, ... until a NULL is found. The symbolic\n\
-+ output \"x-->y[[n]]\" indicates that ->y was applied n times. x[[y]] is\n\
-+ also the selection operator:\n\
-+\n\
-+ gdb> dl head-->next[[50..60]]->data\n\
-+\n\
-+ return the 50th through the 60th elements in the list. The #/x operator\n\
-+ counts the number of values, so\n\
-+\n\
-+ gdb> dl #/( head-->next->data >? 50 )\n\
-+\n\
-+ counts the number of data elements over 50 on the list. Several other\n\
-+ operators, including x@y, x#y and active call stack access are\n\
-+ described in the operators section.\n\
-+\n\
-+OPERATORS SUMMARY\n\
-+ Assoc Operators Details\n\
-+ left {} () [] -> . f() --> x-->y expands x->y x->y->y ...\n\
-+ x[[y]] x#y x@y generate x; select, index or stop-at y\n\
-+ right #/ - * & ! ~ ++ -- (cast) #/x number of x values\n\
-+ frame(n) sizeof(x) reference to call stack level n\n\
-+ left x/y x*y x%%y multiply, divide, reminder\n\
-+ left x-y x+y add, subtract\n\
-+ left x<<y x>>y shift left/right\n\
-+ none x..y ..y x.. ..y = 0..y-1. x..y return x, x+1...y\n\
-+ left < > <= >= <? >? <=? >=? x>?y return x if x>y\n\
-+ left == != ==? !=? x==?y return x if x==y\n\
-+ left x&y bit-and\n\
-+ left x^y bit-xor\n\
-+ left x|y bit-or\n\
-+ left x&&y &&/x &&/x are all x values non-zero?\n\
-+ left x||y ||/x ||/x is any x value non-zero?\n\
-+ right x? y:z foreach x, if(x) y else z\n\
-+ right x:=y x=y x+=y ... x:=y set x as an alias to y\n\
-+ left x,y return x, then y\n\
-+ right x=>y foreach x, evaluate y with x value `_'\n\
-+ right if() else while() for() C statements cast as operators\n\
-+ left x;y evaluate and ignore x, return y\n\
-+\n\
-+\n\
-+EXAMPLES\n\
-+ dl (0xff-0x12)*3 compute simple expression\n\
-+ dl (1..10)*(1..10) display multiplication table\n\
-+ dl x[10..20,22,24,40..60] display x[i] for the selected indexes\n\
-+ dl x[9..0] display x[i] backwards\n\
-+ dl x[..100] >? 5 display x[i] that are greater than 5\n\
-+ dl x[..100] >? 5 <? 10 display x[i] if 5<x[i]<10\n\
-+ dl x[..100] ==? (6..9) same\n\
-+ dl x[0..99]=>if(_>5 && _<10) _ same\n\
-+ dl y[x[..100] !=? 0] display y[x[i]] for each non-zero x[i]\n\
-+ dl emp[..50].code display emp[i].code for i=0 to 49\n\
-+ dl emp[..50].(code,name) display emp[i].code & emp[i].name\n\
-+ dl val[..50].(is_dbl? x:y) display val[i].x or val[i].y depending\n\
-+ on val[i].is_dbl.\n\
-+ dl val[..50].if(is_dbl) x else y same as above\n\
-+ dl x[..100]=0 ; assign 0 to x[i]\n\
-+ dl x[i:=..100]=y[i] ; assign y[i] to x[i]\n\
-+ dl x[..100]=y[..100] *ERR* assign y[99] to each x[j]\n\
-+ dl x[i:=..3]=(4,5,9)[[i]] assign x[0]=4 x[1]=5 x[2]=9\n\
-+ dl x[..3]=(4,5,9) *ERR* assign 9 to each element\n\
-+ dl if(x[i:=..100]<0) x[i]=0 ; assign 0 to negative x[i]\n\
-+ dl (hash[..1024]!=?0)->scope hash[i].scope for non-null hash[i]\n\
-+ dl x[i:=..100] >? x[i+1] check if x[i] is not sorted\n\
-+ dl x[i:=..100] ==? x[j:=..100]=> checks if x has non-unique elements\n\
-+ if(i<j) x[{i,j}]\n\
-+ dl if(x[i:=..99] == same\n\
-+ x[j:=i+1..99]) x[{i,j}]\n\
-+ dl (x[..100] >? 0)[[0]] the 1st (0th element) positive x[i]\n\
-+\n\
-+ dl (x[..100] >? 0)[[2]] return the 3rd positive x[i]\n\
-+ dl (x[..100] >? 0)[[..5]] return the first 5 positive x[i]\n\
-+ dl (x[0..] >? 6)[[0]] return the first x[i]>6, no limit on i\n\
-+ dl argv[0..]@0 argv[0] argv[1] .. until first null\n\
-+ dl x[0..]@-1 >? 9 x[0..n]>9 where n is first x[n]== -1\n\
-+ dl emp[0..]@(code==0) emp[0]..emp[n-1] where emp[n].code==0\n\
-+\n\
-+ dl head-->next->val val of each element in a linked list\n\
-+ dl head-->next[[20]] the 21st element of a linked list\n\
-+ dl *head-->next[[20]] display above as a struct\n\
-+ dl strcmp(head-->next->msg, search linked list for a string\n\
-+ \"testing\") ==? 0\n\
-+ dl #/head-->next count elements on a linked list\n\
-+ dl x-->y[[#/x-->y - 1]] last element of a linked list\n\
-+ dl x-->y[[#/x-->y - 10..1]] last 10 elements of a linked list\n\
-+ dl head-->next-> check if the list is sorted by val\n\
-+ if(next) val >? next->val\n\
-+\n\
-+ dl head-->(next!=?head) expand cyclic linked list (tail->head)\n\
-+ dl head-->(next!=?_) handle termination with p->next==p\n\
-+ dl root-->(left,right)->key expand binary tree, show keys\n\
-+ dl root-->(left,right)->( check bin tree sorted by key\n\
-+ (left!=?0)->key>=?key, (right !=?0 )->key<=?key)\n\
-+\n\
-+ dl (1000..=>if(&&/(2,3.._-1=>__%%_ find first 10 primes over 1000\n\
-+ ) _)[[..10]]\n\
-+ dl (T mytype) x convert x to user defined type mytype\n\
-+ dl (struct s*) x convert x to struct s pointer\n\
-+ dl if(x) y; else z *ERR* ';' must be followed by an expression\n\
-+ dl {x} y *ERR* '}' requires ';' if followed by exp\n\
-+\n\
-+SEMANTICS\n\
-+ Duel's semantics are modeled after the Icon programming language. The\n\
-+ input consists of expressions which return sequences of values. C\n\
-+ statements are cast as expressions, too. Expressions are parsed into\n\
-+ abstract syntax trees, which are traversed during evaluation. The eval-\n\
-+ uation of most nodes (operators) recursively evaluates the next value\n\
-+ for each operand, and then applies the operator to produce the next\n\
-+ result. Only one value is produced each time, and Duel's eval function\n\
-+ keeps a `state' for each node (backtracking, co-routines, consumer-pro-\n\
-+ ducer or threads are good metaphors for the evaluation mechanism.)\n\
-+\n\
-+ For example, in (5,3)+6..8, the evaluation of `+' first retrieves the\n\
-+ operands 5 and 6, to compute and return 5+6. Then 7, the next right op-\n\
-+ erand is retrieved and 5+7 is returned, followed by 5+8. Since there\n\
-+ are no other right operand value, the next left operand, 3 is fetched.\n\
-+ The right operand's computation is restarted returning 6, and 3+6 is\n\
-+ returned. The final return values are 3+7 and 3+8.\n\
-+\n\
-+ The computation for operators like x>?y is similar, but when x<=y, the\n\
-+ next values are fetched instead of returning a value, forming the basis\n\
-+ for an implicit search. Operators like `..' return a sequence of values\n\
-+ for each pair of operands. For a better understanding of the evaluation\n\
-+ mechanism, see the USENIX Winter/93 conference paper \"DUEL - A Very\n\
-+ High Level Debugging Language\".\n\
-+\n\
-+ Duel values follow the C semantics. A value is either an \"lvalue\" (can\n\
-+ be used as the left hand side of assignment), or an \"rvalue\". There-\n\
-+ for, objects like arrays can not be directly manipulated (However,\n\
-+ operators like x..y can accomplish such tasks.)\n\
-+\n\
-+ Duel types also follow the C semantics, with some important differ-\n\
-+ ences. C types are checked statically; Duel types are checked when\n\
-+ operators are applied, e.g., (1,1.0)/2 returns 0 (int) and 0.5 (dou-\n\
-+ ble); (x,y).z returns x.z and y.z even if x and y are of different\n\
-+ types, as long as they both have a field z.\n\
-+\n\
-+ Values and types of symbols are looked up at run-time (using gdb's\n\
-+ lookup rules), allowing dynamic scoping and types, but causing a pars-\n\
-+ ing problem: (x)(y) can be parsed as either a function call x(y) or a\n\
-+ cast (x)y; x*y can be parsed as a declaration of y as (x*) or as multi-\n\
-+ plication.\n\
-+\n\
-+ To avoid this ambiguity, the keyword T must precede a user defined\n\
-+ type. For example, if value is a typedef, C's (value (*)()) x is writ-\n\
-+ ten in Duel as: (T value (*)()) x. Types that begin with a reserved\n\
-+ keyword don't need T, e.g. (struct value*) x and (long *[5]) y are\n\
-+ accepted. As special cases, (type)x and (type*)x are accepted but dis-\n\
-+ couraged (it causes (printf)(\"hi\"), which is valid in C, to fail). A\n\
-+ side effect is that \"sizeof x\" must be written as sizeof(x).\n\
-+\n\
-+OPERATORS\n\
-+ x+y x-y x*y x/y x%%y x^y x|y x&y x<<y x>>y\n\
-+ x>y x<y x>=y x<=y x==y x!=y x=y x[y]\n\
-+\n\
-+ These binary operators follow their C semantics. For each value of x,\n\
-+ they are evaluated for every value of y, .e.g. (5,2)>(4,1) evaluates as\n\
-+ 5>4, 5>1, 2>4, 2>1 returning 1, 1, 0, 1. The y values are re-evalu-\n\
-+ ated for each new value of x, e.g. i=4; (4,5)>i++ evaluates as 4>4 and\n\
-+ 5>5. Beware of multiple y values in assignment, e.g. x[..3]=(4,6,9)\n\
-+ does not set x[0]=4, x[1]=6 and x[2]=9. It assigns 4, 6 and 9 to each\n\
-+ element, having the same effect as x[..3]=9. Use x[i:=..3]=(4,6,9)[[i]]\n\
-+ to achieve the desired effect.\n\
-+\n\
-+ -x ~x &x *x !x ++x --x x++ x-- sizeof(x) (type)x\n\
-+\n\
-+ These unary operators follow their C semantics. They are applied to\n\
-+ each value of x. The increment and decrement operators require an\n\
-+ lvalue, so i:=0 ; i++ produces an error because i is an alias to 0, an\n\
-+ rvalue. Parenthesis must be used with sizeof(x), \"sizeof x\" is not\n\
-+ allowed. Cast to user defined type requires generally requires T, e.g.,\n\
-+ (T val(*)())x, but (val)x and (val*)x are accepted as special cases.\n\
-+\n\
-+ x&&y x||y\n\
-+\n\
-+ These logical operators also follow their C semantics, but have non-\n\
-+ intuitive results for multi-valued x and y, e.g. (1,0,0) || (1,0)\n\
-+ returns 1,1,0,1,0 -- the right hand-side (1,0) is returned for each\n\
-+ left-hand side 0. It is best to use these operators only in single\n\
-+ value expressions.\n\
-+\n\
-+ x? y:z if(x)y if(x)y else z\n\
-+\n\
-+ These expressions return the values of y for each non-zero value\n\
-+ returned by x, and the values of z for each zero value returned by x,\n\
-+ e.g. if(x[..100]==0) y returns y for every x[i]==0, not if all x[i]\n\
-+ are zero (if(&&/(x[..100]==0)) y does that). Also, \"if(x) y; else z\"\n\
-+ is illegal. Duel's semicolon is an expression separator, not a termina-\n\
-+ tor.\n\
-+\n\
-+ while(x)y for(w;x;y)z\n\
-+\n\
-+ The while(x)y expression returns y as long as all values of x are non-\n\
-+ zero. The for() expression is similar and both have the expected C\n\
-+ semantics. For example, \"for(i=0 ; i<100 ; i++) x[i]\" is the same as\n\
-+ x[..100]. Unlike the if() expression, while(x[..100]==0) continue to\n\
-+ execute only if all elements of x are zero, i.e. the condition is eval-\n\
-+ uated into a single value using an implicit &&/x.\n\
-+\n\
-+ Variable declaration: type name [,name ...] ; ...\n\
-+\n\
-+ Expressions can begin with variables declaration (but not initializa-\n\
-+ tion). Internally, a declaration sets an alias to space allocated in\n\
-+ the target by calling malloc(), e.g. `int x' is the same as \"x:= *(int\n\
-+ *) malloc(sizeof(int))\". This is oblivious to the user. The allocated\n\
-+ memory is not claimed when a variable is redeclared. Declared vari-\n\
-+ ables addresses can be passed to functions and used in other data\n\
-+ structures. The keyword `T' must precede user defined types (typedef),\n\
-+ e.g. if val is a user defined type, The C code \"val *p=(val*) x\"\n\
-+ becomes \"T val *p; p=(T val *) x\" in Duel.\n\
-+\n\
-+ Function calls: func(parm,...)\n\
-+\n\
-+ Function calls to the debugged program can be intermixed with Duel\n\
-+ code. Multi-valued parameters are handled as with binary operators.\n\
-+ The call value can have multiple values, e.g. (x,y)() calls x() and\n\
-+ y(). Currently, struct/union parameters and return values are not sup-\n\
-+ ported.\n\
-+\n\
-+ x,y x..y ..x x..\n\
-+\n\
-+ These operators produce multiple values for single value operands. x,y\n\
-+ returns x, then y. x..y returns the integers from x to y. When x>y the\n\
-+ sequence is returned in descending order, i.e. 5..3 returns 5, 4, 3.\n\
-+ The operator ..x is a shorthand for 0..x-1, e.g. ..3 returns 0, 1, 2.\n\
-+ The x.. operator is a shorthand for x..maxint. It returns increasing\n\
-+ integer values starting at x indefinitely, and should be bounded by\n\
-+ [[n]] or @n operators. `,' retains its precedence level in C. The\n\
-+ precedence of `..' is above `<' and below arithmetic operators, so\n\
-+ 0..n-1 and x==1..9 work as expected.\n\
-+\n\
-+ x<?y x>?y x>=?y x<=?y x!=?y x==?y\n\
-+\n\
-+ These operators work like their C counterparts but return x if the com-\n\
-+ parison is true. If the comparison is false, the next (x,y) value is\n\
-+ tried, forming the basis of an implicit search.\n\
-+\n\
-+ (x) {x} x;y x=>y\n\
-+\n\
-+ Both () and {} act as C parenthesis. The curly braces set the returned\n\
-+ symbolic value as the actual value, e.g. if i=5 and x[5]=3, then x[i]\n\
-+ produces the output \"x[i] = 3\", x[{i}] produces \"x[5] = 3\" and {x[i]}\n\
-+ produces just \"3\". The semicolon is an operator. x;y evaluates x,\n\
-+ ignoring the results, then evaluate and return y, e.g. (i:=1..3 ; i+5)\n\
-+ sets i to 3 and return 8. The x=>y operator evaluate and return y for\n\
-+ each value of x, e.g. (i:=1..3 => i+5) returns 6, 7 and 8. The value\n\
-+ returned by x is also stored implicitly in `_' which can be used in y,\n\
-+ e.g. 1..5 => z[_][_] will output z[1][1], z[2][2] etc. The symbolic\n\
-+ value for _ is that of the left side value, hence {_} is not needed.\n\
-+ Semicolon has the lowest precedence, so it must be used inside () or {}\n\
-+ for compound expressions. The precedence of `=>' is just below `,'.\n\
-+ Beware that \"if(a) x; else {y;} z\" is illegal; a semicolon is not\n\
-+ allowed before '}' or 'else' and must be inserted before z.\n\
-+\n\
-+ x->y x.y\n\
-+\n\
-+ These expression work as in C for a symbol y. If y is an expression, it\n\
-+ is evaluated under the scope of x. e.g. x.(a+b) is the same as x.a+x.b,\n\
-+ if a and b are field of x (if they are not, they are looked up as local\n\
-+ or global variables). x may return multiple values of different types,\n\
-+ e.g. (u,v).a returns u.a and v.a, even if u and v are different struc-\n\
-+ tures. Also, the value of x is available as `_' inside y, e.g.\n\
-+ x[..100].(if(a) _) produces x[i] for each x[i].a!=0. Nested x.y are\n\
-+ allowed, e.g. u.(v.(a+b)) would lookup a and b first under v, then\n\
-+ under u.\n\
-+\n\
-+ Aliases: x:=y\n\
-+\n\
-+ Aliases store a reference to y in x. Any reference to x is then\n\
-+ replaced by y. If y is a constant or an rvalue, its value is replaced\n\
-+ for x. If y is an lvalue (e.g. a variable), a reference to same lvalue\n\
-+ is returned. for example, x:=emp[5] ; x=9 assigns 9 to emp[5]. Aliases\n\
-+ retain their values across invocation of the \"dl\" command. An alias to\n\
-+ a local variable will reference a stray address when the variable goes\n\
-+ out of scope. The special command \"dl clear\" delete all the aliases,\n\
-+ and \"dl alias\" show all current aliases. Symbols are looked up as\n\
-+ aliases first, so an alias x will hide a local x.\n\
-+\n\
-+ x-->y\n\
-+\n\
-+ The expansion operator x-->y expands a data structure x following the y\n\
-+ links. It returns x, x->y, x->y->y, until a null is found. If x is\n\
-+ null, no values are produced. If y returns multiple values, they are\n\
-+ stacked and each is further expanded in a depth-first notion. For exam-\n\
-+ ple, if r is the root of a tree with children u->childs[..u->nchilds],\n\
-+ then u-->(childs[..nchilds]) expands the whole tree. y is an arbitrary\n\
-+ expression, evaluated exactly like x->y (this includes `_'.)\n\
-+\n\
-+ x@y\n\
-+\n\
-+ The expression x@y produces the values of x until x.y is non-zero, e.g.\n\
-+ for(i=0 ; x[i].code!= -1 && i<100 ; i++) x[i] can be written as\n\
-+ x[..100]@(code==-1). The evaluation of x is stopped as soon as y eval-\n\
-+ uates to true. x->y or x=>y are used to evaluate y when x is not a\n\
-+ struct or a union. If y is a constant,(_==y) is used. e.g. s[0..]@0\n\
-+ produces the characters in string s up to but not including the termi-\n\
-+ nating null.\n\
-+\n\
-+ #/x &&/x ||/x\n\
-+\n\
-+ These operator return a single \"summary\" value for all the values\n\
-+ returned by x. #/x returns the number of values returned by x, e.g.\n\
-+ #/(x[..100]>?0) counts the number of positive x[i]. &&/x returns 1 if\n\
-+ all the values produced by x are non-zero, and ||/x returns 1 if any of\n\
-+ x's values are non-zero. Like in C, the evaluation stops as soon as\n\
-+ possible. For example, ||/(x[..100]==0) and &&/(x[..100]==0) check if\n\
-+ one or all of x[i] are zero, respectively.\n\
-+\n\
-+ x#y x[[y]]\n\
-+\n\
-+ The operator x#y produces the values of x and arranges for y to be an\n\
-+ alias for the index of each value in x. It is commonly used with x-->y\n\
-+ to produce the element's index, e.g. head-->next->val#i=i assigns each\n\
-+ val field its element number in the list.\n\
-+ The selection operator x[[y]] produces the yth result of x. If y\n\
-+ returns multiple value, each select a value of x, e.g.\n\
-+ (5,7,11,13)[3,0,2] returns 13, 5 and 11 (13 is the 3rd element, 5 is\n\
-+ the 0th element). Don't use side effects in x, since its evaluation\n\
-+ can be restarted depending on y, e.g. after (x[0..i++])[[3,5]] the\n\
-+ value of i is unpredictable.\n\
-+\n\
-+ frame(n) frames_no func.x\n\
-+\n\
-+ frame(n) for an integer n returns a reference to the nth frame on the\n\
-+ stack (0 is the inner most function and frame(frames_no-1) is main()).\n\
-+ Frame values can be compared to function pointers, e.g.\n\
-+ frame(3)==myfunc is true if the 4th frame is a call to myfunc, and in\n\
-+ scope resolution, e.g. frame(3).x return the local variable x of the\n\
-+ 4th frame. frames_no is the number of active frames on the stack, e.g.\n\
-+ (frames(..frames_no) ==? myfunc).x displays x for all active invoca-\n\
-+ tions of myfunc. As a special case, (frames(..frames_no)==?f)[[0]].x\n\
-+ can be written as f.x (x can be an expression).\n\
-+\n\
-+\n\
-+BUGS\n\
-+ Both `{}' and `;' are operators, not statements or expression separa-\n\
-+ tors; \"if(x) y; else {z;} u\" is illegal; use \"if(x) y else {z} ; u\".\n\
-+ Ambiguities require preceding user-defined types (typedef) with the\n\
-+ keyword T, e.g., if value is a user type, C's \"sizeof(value*)\" is\n\
-+ written \"sizeof(T value*)\", except for the casts \"(t)x\" and \"(t*)x\";\n\
-+ sizeof(x) requires parenthesis for variable x.\n\
-+\n\
-+ Unimplemented C idiom include: modified-assignment (x+=y), switch,\n\
-+ break, continue, do, goto, scopes, function declarations, initializing\n\
-+ declared variables, assignment to bit-fields and register variables,\n\
-+ and calling functions with a struct/union parameter or return value.\n\
-+ gdb does not store function prototypes, so parameters are not checked.\n\
-+\n\
-+ Gdb itself is buggy, which shows up, especially in symbol tables and\n\
-+ calling target functions. Before you report bug, try to do the closest\n\
-+ thing under gdb's \"print\". Send bug to: mg@cs.princeton.edu.\n\
-+\n\
-+FILES\n\
-+ duel.out tracks duel commands usage. Help analyze duel's use by mailing\n\
-+ a copy to mg@cs.princeton.edu.\n\
-+ Duel is available by anonymous ftp at ftp.cs.princeton.edu:/duel.\n\
-+\n\
-+AUTHOR\n\
-+ Duel is public domain code -- no copy left or right. See the internals\n\
-+ documentation for details on porting Duel and using its code. Duel was\n\
-+ designed and written by Michael Golan as part of a PhD thesis in the\n\
-+ Computer Science Department of Princeton University. I would like to\n\
-+ thank my advisor, Dave Hanson, who helped in all phases of this project\n\
-+ and to Matt Blaze for his support and useful insight.\n\
-+\n\
-+ Duel stands for Debugging U (might) Even Like, or Don't Use this Exotic\n\
-+ Language. Judge for yourself!\n\
-+\n\
-+Version 1.10 Mar 93 Duel(1)\n\n");
-+}
-+
-+LPROC help(void)
-+{
-+ duel_printf(
-+"Duel - Debugging U (might) Even Like -- A high level debugging language\n\n\
-+Duel was designed to overcome problems with traditional debuggers' print\n\
-+statement. It supports the C operators, many C constructs, and many new\n\
-+operators for easy exploration of the program's space, e.g.\n\
-+x[..100] >? 0 show positive x[i] for i=0 to 99\n\
-+y[10..20].code !=? 0 show non-zero y[i].code for i=10 to 20\n\
-+h-->next->code expand linked list h->next, h->next->next ...\n\
-+head-->next.if(code>0) name show name for each element with code>0\n\
-+x[i:=..100]=y[i]; array copy. i is an alias to vals 0..99\n\
-+head-->next[[10..15]] the 10th to 15th element of a linked list\n\
-+#/(head-->next->val==?4) count elements with val==4\n\
-+head-->next->if(next) val >? next->val check if list is sorted by val\n\
-+\n\
-+Duel was written by Michael Golan at Princeton University. Send email to\n\
-+mg@cs.princeton.edu. Duel is public domain code. No copy left or right.\n\
-+all but 500 lines are independent of gdb. Port it! Make it Commercial!\n\
-+\n\
-+Try \"dl ops\" for op summary; \"dl\" alone lists all commands\n");
-+}
-+
-+LPROC examples(void)
-+{
-+ duel_printf("\
-+x[10..20,22,24,40..60] display x[i] for the selected indexes\n\
-+x[9..0] display x[i] backwards\n\
-+x[..100] >? 5 <? 10 display x[i] if 5<x[i]<10\n\
-+x[0..99]=>if(_>5 && _<10) _ same\n\
-+val[..50].if(is_dx) x else y \
-+val[i].x or val[i].y depending on val[i].is_dx\n\
-+emp[..50].if(is_m) _ return emp[i] if emp[i].is_m.\n\
-+x[i:=..100]=y[i] ; assign y[i] to x[i]\n\
-+x[i:=..100] >? x[i+1] check if x[i] is not sorted\n\
-+(x[..100] >? 0)[[2]] return the 3rd positive x[i]\n\
-+argv[0..]@0 argv[0] argv[1] .. until first null\n\
-+emp[0..]@(code==0) emp[0]..emp[n-1] where emp[n].code==0\n\
-+head-->next->val val of each element in a linked list\n\
-+*head-->next[[20]] element 20 of list, '*' display struct w/fields\n\
-+#/head-->next count elements on a linked list\n\
-+#/(head-->next-val>?5) count those over 5\n\
-+head-->(next!=?head) expand cyclic linked list (tail->head)\n\
-+T mytype x ; declare var for user defined type (need 'T')\n\
-+int i ; for(i=0 ;i<5 .. declare variable, use C construct.\n");
-+}
-+
-+LPROC operators(void)
-+{
-+ duel_printf("\
-+DUEL operators in decreasing precedence. All C operators are accepted!\n\
-+note: precede typedefs by 'T', eg \"sizeof(T uint)\"\n\n\
-+{x} same as (x) but x's value is used for symbol emp[{i}]\n\
-+x-->y expands data structure from x, using y root-->(left,right)->key\n\
-+x.y eval y under x's scope, like pascal \"with\". x is accesible as '_'\n\
-+x->y same as (*x).y. hash[..50]->if(_!=0) key\n\
-+x[[y]] select the y'th elements of x head-->next[[..6]]\n\
-+x@y eval x, stop as soon as y true (_==y if y const). argv[0..]@0\n\
-+x#y eval x, set alias y as values counter (x-->next#n)->level==?n");
-+ duel_printf("\n\
-+#/x count number of values from x #/head-->next\n\
-+frame(n) use with '.' to reference stack frames. frame(3).val\n\
-+x..y x, x+1, x+2 .. y. (if x>y, return them backwards) x[10..20]\n\
-+..y like 0..y-1 x[..1024]\n\
-+x.. like x..maxint. Caution: use only with x@y or x[[y]] name[0..]@0\n\
-+x>?y x if x>y else nothing. also <? <=? >=? ==? and !=? x[..10]<?0\n\
-+&&/x 1 or 0 if x!=0 for all x values. ||/x similar &&/x[..100]>=0\n\
-+x,y x, then y. head-->next->(val,key)\n\
-+x=>y eval y for each x, setting '_' to x's values x[..50]=>_*_\n\
-+if(x) y C statements are operators. Also for(), while(), if() else\n\
-+x;y Evaluate and ignore x's value, then return y\n");
-+}
-+
-+/* entry point into duel. s is the expression to evaluate */
-+
-+void duel_parse_and_eval(char *s)
-+{
-+ static first=1 ;
-+ if(first) { /* init stuff */
-+ duel_init_basic_ctypes();
-+ duel_printf("%s.%d, public domain debugging language. \"dl\" for help\n",
-+ VERSION,PATCHLEVEL);
-+ duel_redirectable_output_init();
-+ first=0 ;
-+ }
-+ if(!s || *s==0) { /* no input, give some help */
-+ duel_printf("\
-+Supported DUEL commands:\n\
-+duel help - give basic help (shortcut: dl ?)\n\
-+duel longhelp - give a longer help (dl ?\?)\n\
-+duel examples - show useful usage examples (dl ex)\n\
-+duel operators - operators summary (dl ops)\n\
-+duel aliases - show current aliases (dl alias)\n\
-+duel clear - clear all aliases\n\
-+duel debug - toggle duel debug mode\n");
-+ return ;
-+ }
-+ if(strcmp(s,"?")==0 || strcmp(s,"help")==0) {
-+ help();
-+ return ;
-+ }
-+ if(strcmp(s,"?\?")==0 || strcmp(s,"longhelp")==0) {
-+ longhelp();
-+ return ;
-+ }
-+ if(strcmp(s,"examples")==0 || strcmp(s,"ex")==0 ) {
-+ examples();
-+ return ;
-+ }
-+ if(strcmp(s,"operators")==0 || strcmp(s,"ops")==0) {
-+ operators();
-+ return ;
-+ }
-+ if(strcmp(s,"debug")==0) { /* turn debugging of duel itself */
-+ duel_debug= !duel_debug ;
-+ duel_printf("duel debug mode %d\n",duel_debug);
-+ return ;
-+ }
-+ if(strcmp(s,"clear")==0) {
-+ duel_clear_aliases();
-+ duel_printf("Aliases table cleared\n");
-+ return ;
-+ }
-+ if(strcmp(s,"alias")==0 || strcmp(s,"aliases")==0) {
-+ duel_show_aliases();
-+ return ;
-+ }
-+ if(setjmp(duel_abort_jmp)==0) { /* set abort point */
-+ if((root=duel_parse(s))!=NULL) {
-+ tvalue v ;
-+ duel_set_input_string(s); /* for src-location err management */
-+ duel_reset_eval();
-+ duel_redirectable_output_start(s); /* allow eval output to go to pipe */
-+ while(duel_eval(root,&v)) {
-+ duel_print_value(&v);
-+ duel_flush();
-+ }
-+ duel_redirectable_output_end();
-+ }
-+ }
-+ duel_cleanup(0);
-+}
---- gdb/duel/duel.h
-+++ gdb/duel/duel.h
-@@ -0,0 +1,35 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* duel.h - include file to be used with all duel source code.
-+ * it defines important global constants & data types, as well as some
-+ * global variables. prototypes should go in the duelprot.h file
-+ */
-+
-+
-+/* common duel include files. I dunno why people don't like recursive
-+ * includes, as long as it is consistent. Note only one level of recursion.
-+ * the debugger module itself dont use this file, instead it includes what
-+ * it needs directly.
-+ * as for including "everything", unless one redefine some standard lib func,
-+ * I feel safer including most standard lib files. It seems to prevent errors
-+ * even if it garble the name space a bit.
-+ */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <stddef.h>
-+#include <string.h>
-+#include <assert.h>
-+#include <ctype.h>
-+#include <limits.h>
-+#include <math.h>
-+/* global data and types */
-+
-+#include "global.h"
-+
-+/* prototypes for all global functions follows */
-+
-+#include "proto.h"
---- gdb/duel/duel.pipe
-+++ gdb/duel/duel.pipe
-@@ -0,0 +1,107 @@
-+#!/usr/local/bin/perl
-+# perl script opened as a pipe by duel
-+#
-+# duel(gdb), fork this program and feed it as stdin, the output from
-+# evaluating expressions. the input is
-+# $$$START: expr where expr is the expression being evaluted
-+# $$$DONE end of results
-+# $$$ABORT end of results due to error or interrupt
-+# $$$SYM: s symbolic output 's'
-+# $$$VAL: v value for previous symbolic output
-+#
-+# the output from this program is fed back into duel, which simply display
-+# it. After DONE/ABORT, duel wait for a $$$DONE to get back, so it can
-+# return to gdb's prompt.
-+#
-+# Duel expressions terminates after '|>', the text after which should be
-+# processed by the pipe (a "pipe command" if you will).
-+# There is no limit to what this program can do. Currently all it does
-+# is provide all hex/ all decimal display of integers (|>hex and |>dec),
-+# and provide "smart" output, on the same line, when the symbolic output
-+# is the same as the values.
-+#
-+# Some examples of what can be done here:
-+# |> sort -- will sort the output
-+# |> sort? -- display a message if it was/wasnt sorted
-+# |> uniq -- display only uniq values in output
-+# |> uniq? -- display message if all output was uniq.
-+# |> vals -- only display vals, ignore symbolic
-+# |> syms -- only display symbolics, ignore vals
-+# |> matrix -- Attempt to display in a matrix format
-+# |> compress -- compress into single lines, eg
-+# x[i].val=1\n x[i].name="me"\n
-+# becomes: x[i] = { val=1, name="me" }
-+# |> vector -- attempt to display as vector, eg
-+# x[1]=5\bx[4]=3\nx[9]=2\nx[12]=8\n becomes:
-+# i 1 4 9 12
-+# x[i] 5 3 2 8
-+# |> smart -- try to figure out one of the above formats...
-+# |> plotxy -- plot (sym,val) using xgraph. can convert x[5]
-+# symbol into '5' for the x-coord, etc.
-+# |> stack -- output of frame(..frames_no).`*`,
-+# which hasnt been implemented yet (* is regex),
-+# to be formatted as a stack trace...
-+#
-+# the code below is very simple. A better organization will support
-+# adding "functions" (commands) and specify for each command if the
-+# function is called only after all values have been collected, or
-+# for every value, if the command is active until unset, or just for
-+# the specific line it was given on, what flags it set/reset, etc.
-+
-+
-+$|=1 ; # flush output on every write to the pipe
-+
-+%cmds = ("norm",1,"smart",1,"dec",1,"hex",1) ;
-+$smart=0;
-+$base=0 ;
-+
-+while(<>) {
-+ chop; study ;
-+ if(/^\$\$\$START: /) {
-+ if(/\|\>\s*([^"']*)$/) { # |> pipe-command
-+ $_ = $1 ;
-+ s/\s+$// ; # clean trailing spaces
-+ if($cmds{$_}) {
-+ printf "Pipe command '$_'\n" ;
-+ $smart=0 if /norm/ ;
-+ $smart=1 if /smart/ ;
-+ $base=0 if /norm/ ;
-+ $base=10 if /dec/ ;
-+ $base=16 if /hex/ ;
-+ }
-+ else { printf "BAD PIP COMMAND '$_'\n" ; }
-+ }
-+ $same=0 ;
-+ }
-+ elsif(/^\$\$\$DONE$/) {
-+ print "\n" if $same ; # go to next line if not on same
-+ print "\$\$\$DONE\n" ;
-+ }
-+ elsif(/^\$\$\$ABORT$/) {
-+ print "\n" if $same ; # go to next line if not on same
-+ print "\$\$\$DONE\n" ;
-+ }
-+ elsif(/^\$\$\$SYM: (.*)$/) {
-+ $sym = $1 ;
-+ }
-+ elsif(/^\$\$\$VAL: (.*)$/) {
-+ $_ = $val = $1 ;
-+ $_ = oct if($base==10 && /^0x[0-9a-z]*$/) ;
-+ $_ = sprintf("0x%2.2x",$_) if($base==16 && /^[1-9]\d*$/) ;
-+ if($smart && ( $sym eq $_ || $sym eq $val)) {
-+ $sz= 3 + length ;
-+ if($same+$sz > 75) { print "\n" ; $same=0 ; }
-+ $same+=$sz ;
-+ print "$_, " ;
-+ }
-+ else {
-+ print "\n" if $same ; # go to next line if not on same
-+ if($sym == $val) { print "$_\n" ; }
-+ else { print "$sym = $_\n" ; }
-+ $same=0 ;
-+ }
-+ }
-+ else {
-+ print "bad duel input to duel.pipe ignored: $_\n" ;
-+ }
-+}
---- gdb/duel/duelself.c
-+++ gdb/duel/duelself.c
-@@ -0,0 +1,209 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* self-debugger module, it contains all of duel's access to
-+ * the outside world (like duelgdb.c), but is intended to work when duel
-+ * is linked with the debuggee directly (not with the debugger!)
-+ * if you link this with duel.a, you get a test suite of duel
-+ * for the C program: (tsuite.c)
-+ *
-+ * int gint ;
-+ * typedef unsigned int uint ;
-+ * int main() {
-+ * printf ; malloc ; / * include them in bin * /
-+ * char *s="main string" ;
-+ * }
-+ *
-+ * You could link this module with your own program and call it at
-+ * "appropriate places", then ship the program with this code, and
-+ * use duel at client's site when a crash occurs. However, reading in
-+ * the symbol table and figuring out the active frames remains a problem.
-+ */
-+
-+/*
-+ * $Log: 10_all_gdb-6.6-duel.patch,v $
-+ * Revision 1.1 2008/04/06 23:59:05 vapier
-+ * initial 6.8 patchset based on last 6.7.1 patchset
-+ *
-+ * Revision 1.6 93/03/19 16:55:35 mg
-+ * allow execution from within make
-+ *
-+ * Revision 1.5 93/03/12 05:47:29 mg
-+ * *** empty log message ***
-+ *
-+ * Revision 1.4 93/02/04 00:05:10 mg
-+ * avoid Header problems in self.out
-+ *
-+ * Revision 1.3 93/01/13 16:21:40 mg
-+ * made sure printf is declared
-+ *
-+ * Revision 1.2 93/01/12 21:31:01 mg
-+ * brought uptodate with duelgdb.c
-+ * cleanup and set for release
-+ *
-+ */
-+/* include system dependent stuff here */
-+
-+#include "duel.h"
-+
-+int main(int argc,char **argv);
-+
-+FUNC void* duel_malloc(size_t size)
-+{
-+ void *p=malloc(size);
-+ if(p==0) duel_fatal("out of memory.");
-+ return p;
-+}
-+
-+PROC duel_free(void *p)
-+{
-+ free(p);
-+}
-+/* fetch n bytes from the target at the given memory address.
-+ * the address to fetch from is given by (from).
-+ * the value is stored at the 'to' location, which points to space for
-+ * n bytes in the debugger.
-+ * if the address can not be accessed, false is returned (if all ok, ret true)
-+ */
-+
-+FUNC bool duel_get_target_bytes(ttarget_ptr from,void *to,size_t n)
-+{
-+ duel_bcopy(to,from,n);
-+ return TRUE ;
-+}
-+
-+/* store n bytes to the debuggee. reverse parms from above */
-+FUNC bool duel_put_target_bytes(ttarget_ptr to,void *from,size_t n)
-+{
-+ duel_bcopy(to,from,n);
-+ return TRUE ;
-+}
-+
-+/* fetch the value of a bitfield of a given structure. */
-+
-+FUNC bool duel_get_target_bitfield(ttarget_ptr struct_at,int bitpos,
-+ int bitlen,void *to,tctype_kind tkind)
-+{
-+ return FALSE ; /* not supported in duelself */
-+}
-+
-+/* make a function call to the target. */
-+/* support only passing/returing sizeof(int) upto 5 paramaters */
-+PROC duel_target_func_call(tvalue *func, tvalue *parms[],
-+ int parms_no,tvalue *rval)
-+{
-+ int (*f)();
-+ int i ;
-+ if(parms_no>5) duel_fatal("too many parms");
-+ if(sizeof(func->ctype->u.kid)!=sizeof(int) &&
-+ func->ctype->u.kid!=ctype_void ) duel_fatal("unsupported func parm");
-+ for(i=0 ; i<parms_no ; i++) {
-+ if(parms[i]->val_kind!=VK_RVALUE || parms[i]->ctype->size!=sizeof(int))
-+ duel_fatal("unsupported paramater");
-+ }
-+ f=(int (*)()) func->u.lvalue ;
-+ switch(parms_no) {
-+ case 0:
-+ rval->u.rval_int= (*f)();
-+ break ;
-+ case 1:
-+ rval->u.rval_int= (*f)(parms[0]->u.rval_int);
-+ break ;
-+ case 2:
-+ rval->u.rval_int= (*f)(parms[0]->u.rval_int,parms[1]->u.rval_int);
-+ break ;
-+ case 3:
-+ rval->u.rval_int= (*f)(parms[0]->u.rval_int,parms[1]->u.rval_int,
-+ parms[2]->u.rval_int);
-+ break ;
-+ case 4:
-+ rval->u.rval_int= (*f)(parms[0]->u.rval_int,parms[1]->u.rval_int,
-+ parms[2]->u.rval_int,parms[3]->u.rval_int);
-+ break ;
-+ case 5:
-+ rval->u.rval_int= (*f)(parms[0]->u.rval_int,parms[1]->u.rval_int,
-+ parms[2]->u.rval_int,parms[3]->u.rval_int,parms[4]->u.rval_int);
-+ break ;
-+ }
-+ rval->val_kind=VK_RVALUE ;
-+ rval->ctype=func->ctype->u.kid ;
-+}
-+
-+/* find debuggee variable.
-+ * recognize main.s, gint, malloc, printf
-+ */
-+
-+int gint ; /* global variable recognized */
-+char **main_s ; /* point to main's 's' */
-+
-+FUNC bool duel_get_target_variable(char *name, int frame_no, tvalue *v)
-+{
-+ v->val_kind=VK_LVALUE ;
-+ if(frame_no<=0 && strcmp(name,"s")==0) {
-+ v->ctype=duel_mkctype_ptr(ctype_char);
-+ v->u.lvalue = (void*) main_s ;
-+ return TRUE ;
-+ }
-+ if(frame_no != -1) return FALSE ;
-+ if(strcmp(name,"main")==0) {
-+ v->ctype=duel_mkctype_func(ctype_void);
-+ v->u.lvalue = (void*) main ;
-+ return TRUE ;
-+ }
-+ if(strcmp(name,"malloc")==0) {
-+ v->ctype=duel_mkctype_func(duel_mkctype_ptr(ctype_void));
-+ v->u.lvalue = (void*) malloc ;
-+ return TRUE ;
-+ }
-+ if(strcmp(name,"printf")==0) {
-+ if(0) printf(""); /* "declare" print */
-+ v->ctype=duel_mkctype_func(ctype_int);
-+ v->u.lvalue = (void*) printf ;
-+ return TRUE ;
-+ }
-+ if(strcmp(name,"gint")!=0) return FALSE ;
-+ v->ctype= ctype_int ; /* type of this variable */
-+ v->u.lvalue= (void*) &gint ; /* address of variable */
-+ return TRUE ;
-+}
-+
-+
-+FUNC int duel_get_frames_number(void)
-+{
-+ return 1 ; /* main */
-+}
-+
-+
-+FUNC ttarget_ptr duel_get_function_for_frame(int frame_no)
-+{
-+ if(frame_no==0) return (void*) main ;
-+ else duel_fatal("bad frame number - internal err");
-+}
-+
-+FUNC tctype* duel_get_target_typedef(char *name)
-+{
-+ if(strcmp(name,"uint")==0) return ctype_uint ;
-+ return NULL ;
-+}
-+
-+FUNC tctype* duel_get_target_struct_tag(char *name) { return 0 ; }
-+FUNC tctype* duel_get_target_union_tag(char *name) { return 0 ; }
-+FUNC tctype* duel_get_target_enum_tag(char *name) { return 0 ; }
-+
-+int main(int argc,char **argv)
-+{
-+ char *s="main string" ;
-+ main_s = &s ; /* put s into the "symbol tbl" */
-+
-+ while(1) {
-+ char in[120] ;
-+ gets(in);
-+ if(feof(stdin)) break ;
-+ /* output & input are RCS'ed. avoid $Header in self.out, which is
-+ * the input header, which RCS fix... which create mis matches */
-+ if(strncmp(in,"## $Header",10)==0) continue ;
-+ printf("dl> %s\n",in);
-+ if(in[0]==0 || in[0]=='#' && in[1]=='#') continue ; /* comments */
-+ duel_parse_and_eval(in);
-+ }
-+ return 0 ; /* to run in make */
-+}
---- gdb/duel/error.c
-+++ gdb/duel/error.c
-@@ -0,0 +1,112 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* display errors in a neat way */
-+
-+/*
-+ * $Log: 10_all_gdb-6.6-duel.patch,v $
-+ * Revision 1.1 2008/04/06 23:59:05 vapier
-+ * initial 6.8 patchset based on last 6.7.1 patchset
-+ *
-+ * Revision 1.5 93/03/12 05:48:27 mg
-+ * support output redirection
-+ *
-+ * Revision 1.4 93/01/12 21:35:31 mg
-+ * cleanup and set for release
-+ *
-+ */
-+
-+#include "duel.h"
-+
-+static tnode *curr_eval_node ; /* current node being evaluated */
-+static char *curr_inputstr ; /* current input string being eval */
-+
-+/* indicate the active node where an operator is now evaluated.
-+ * if an error occurs, this marker is used to tell the user where
-+ * the error is located.
-+ * return previous setup to caller, so it can be restored.
-+ */
-+
-+FUNC tnode* duel_set_eval_loc(tnode *n)
-+{
-+ tnode *prev=curr_eval_node ;
-+ curr_eval_node=n ;
-+ return prev ;
-+}
-+
-+/* indicate the current input string which is evaluated
-+ * (intended for future versions with multiple input strings)
-+ */
-+
-+FUNC char* duel_set_input_string(char *s)
-+{
-+ char *prev=curr_inputstr ;
-+ curr_inputstr=s ;
-+ return prev ;
-+}
-+/* display source position for errors, based on current node being eval'ed */
-+
-+LPROC print_src_pos(void)
-+{
-+ int src_pos=0 ;
-+ int i ;
-+ if(curr_eval_node) src_pos=curr_eval_node->src_pos ;
-+ duel_printf("Error: %s\n",curr_inputstr) ;
-+ duel_printf(" ") ;
-+ for(i=0 ; i<src_pos ; i++) duel_printf("-");
-+ duel_printf("^-- ");
-+}
-+
-+/* called for errors that are results of bad user input (syntax/sematics),
-+ * e.g. an illegal variable name, etc
-+ * the message is printed as a format string for 'op'.
-+ * the error location in the source is printed based on the current eval node,
-+ * and the value of the given operands are displayed.
-+ */
-+
-+PROC duel_op_error(char *mesg,char *op,tvalue *v1,tvalue *v2)
-+{
-+ char s[160] ;
-+
-+ duel_redirectable_output_abort();
-+ print_src_pos();
-+ duel_printf(mesg,op);
-+ duel_printf("\n");
-+ if(v1) {
-+ duel_printf("operand%s ``%s'' ",(v2!=0)? "1":"",v1->symb_val);
-+ duel_printf("\t-- type: ");
-+ duel_print_type(v1->ctype,1);
-+ duel_sprint_scalar_value(s,v1);
-+ duel_printf("\n\t\t-- value: %s\n",s);
-+ }
-+ if(v2) {
-+ duel_printf("operand%s ``%s'' ",(v1!=0)? "2":"",v2->symb_val);
-+ duel_printf("\t-- type: ");
-+ duel_print_type(v2->ctype,1);
-+ duel_sprint_scalar_value(s,v2);
-+ duel_printf("\n\t\t-- value: %s\n",s);
-+ }
-+
-+ duel_abort();
-+}
-+
-+/* handle a genral error, no value (operand) is involved.
-+ * location (node) is still displayed
-+ */
-+
-+PROC duel_gen_error(char *mesg,char *arg1)
-+{
-+ duel_redirectable_output_abort();
-+ print_src_pos();
-+ duel_printf(mesg,arg1);
-+ duel_printf("\n");
-+ duel_abort();
-+}
-+
-+/* handle fatal messages */
-+
-+PROC duel_fatal(char *msg)
-+{
-+ duel_redirectable_output_abort();
-+ duel_printf("Fatal Duel error: %s\n",msg);
-+ duel_abort();
-+}
---- gdb/duel/eval.c
-+++ gdb/duel/eval.c
-@@ -0,0 +1,832 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* this module is the most critical code, the recursive evaluation
-+ */
-+
-+/*
-+ * $Log: 10_all_gdb-6.6-duel.patch,v $
-+ * Revision 1.1 2008/04/06 23:59:05 vapier
-+ * initial 6.8 patchset based on last 6.7.1 patchset
-+ *
-+ * Revision 1.13 93/03/19 15:39:34 mg
-+ * fixed bug in left->left symbolic, and long symbolics which caused crashes
-+ *
-+ * Revision 1.12 93/03/12 05:48:45 mg
-+ * fixed sizeof(type) symbolic
-+ *
-+ * Revision 1.11 93/02/26 04:59:51 mg
-+ * improved symbolic debugging of #/
-+ *
-+ * Revision 1.10 93/02/03 21:47:41 mg
-+ * fixed dot stack bug; fixed func-call last parm eval bug
-+ *
-+ * Revision 1.9 93/01/12 21:50:26 mg
-+ * cleanup and set for release
-+ *
-+ * Revision 1.8 93/01/07 00:09:34 mg
-+ * scope stack changes a bit.
-+ * clear/aliases commands.
-+ * func.x support, x.y etc force existance if y field of x., x=>y w/'_'
-+ * allow fields in y for x@y, x pointer.
-+ * fixed eval_node setup
-+ * added &&/ ||/
-+ *
-+ *
-+ * Revision 1.7 93/01/03 07:29:23 mg
-+ * function calls, error reporting, printing.
-+ *
-+ * Revision 1.6 92/12/24 23:33:48 mg
-+ * frames support
-+ *
-+ * Revision 1.5 92/10/19 15:06:35 mg
-+ * *** empty log message ***
-+ *
-+ * Revision 1.4 92/10/14 02:04:35 mg
-+ * misc
-+ *
-+ * Revision 1.3 92/09/16 11:04:16 mg
-+ * *** empty log message ***
-+ *
-+ * Revision 1.2 92/09/15 05:54:56 mg
-+ * cosmetics and new ops:
-+ * generic '.' and '_' support. x@y. '..x' and 'x..'. while(), for(), ?:
-+ *
-+ */
-+
-+#include "duel.h"
-+
-+
-+
-+#define DOT_STACK_SIZE 100 /* dot stack size, maximum no. of dots in stmt */
-+
-+/* the scope eval stack.
-+ * used for several purposes: to push _'s values (=>), to push structs
-+ * and unions for x.y and x->y, and to push func/frame values fro frame(i).x
-+ * and func.x/
-+ * realv is the real value for the left side operand. It is used for '_'.
-+ * fieldv is the one to be used to fetch actual names. either:
-+ * fieldv=realv (for x.y, frame(i).y), fieldv=*realv (for x->y),
-+ * fieldv=func_frame(realv) (for func.x), or fieldv=0 (x=>y).
-+ */
-+struct {
-+ tvalue *realv ; /* actual value for x in x.y or x->y etc. used for _ */
-+ tvalue *fieldv; /* value to use for fetching fields, *realv for x->y */
-+ } dot_stack[DOT_STACK_SIZE] ;
-+int dot_stack_top= -1 ;
-+
-+PROC duel_reset_eval(void) /* reset evaluation states from previous eval */
-+{
-+ dot_stack_top= -1 ; /* reset stack */
-+}
-+
-+/* try to find the given name on the dot_stack of structures.
-+ * if found, return true and value in(v) else return false.
-+ * the symbolic value is not set.
-+ * if top_only, looks only at the top of the stack.
-+ */
-+LFUNC bool find_dot_name(char *name,tvalue *v,bool top_only)
-+{
-+ int i,j ;
-+ tctype_field *f ;
-+ tctype *t ;
-+ tvalue *x;
-+
-+ for(i=dot_stack_top ; i>=0 ; i--) { /* look at the stack[i] */
-+ if(top_only && i!=dot_stack_top) break ; /* consider only top of stk*/
-+ x=dot_stack[i].realv ;
-+ if(name[0]=='_' && name[1]==0 || /* _ */
-+ name[1]=='_' && i==dot_stack_top-1 && name[2]==0 || /* __ */
-+ name[1]=='0'+dot_stack_top-i && name[2]==0) { /* _[0-9] */
-+ *v = *x ;
-+ return TRUE ;
-+ }
-+ x=dot_stack[i].fieldv;
-+ if(!x) continue ;
-+ if(x->val_kind==VK_FVALUE) {
-+ if(!duel_get_target_variable(name,x->u.fvalue,v)) continue ;
-+ strcpy(v->symb_val,name);
-+ return TRUE ;
-+ }
-+ t=x->ctype ;
-+ if(!ctype_kind_struct_like(t)) continue ;
-+ duel_assert(x->val_kind==VK_LVALUE);
-+ for(j=0 ; j<t->u.f.fields_no ; j++) { /* look at field[j] of struct*/
-+ f= &t->u.f.fields[j] ;
-+ if(strcmp(f->name,name)==0) goto found ;
-+ }
-+ }
-+ return FALSE ;
-+found:
-+ v->ctype=f->ctype ;
-+ strcpy(v->symb_val,name);
-+ if(f->bitlen==0) {
-+ v->u.lvalue=x->u.lvalue+f->bitpos/BITS_PER_BYTE ;
-+ v->val_kind=VK_LVALUE ;
-+ return TRUE ;
-+ }
-+ /* special care for a bitfield */
-+ if(f->ctype->type_kind!=CTK_INT && f->ctype->type_kind!=CTK_UINT)
-+ duel_gen_error("bitfield '%s' must be int or unsigned",name);
-+ v->val_kind=VK_BVALUE ;
-+ v->u.bvalue.lvalue=x->u.lvalue ;
-+ v->u.bvalue.bitpos=f->bitpos ;
-+ v->u.bvalue.bitlen=f->bitlen ;
-+ return TRUE ;
-+}
-+
-+/* find the value of a given symbolic name and
-+ * return in in v
-+ * if name is not found, aborts with an error
-+ */
-+
-+LPROC duel_eval_name(char *name,tvalue *v)
-+{
-+ tvalue *aval=duel_find_alias(name) ; /* find internal alias */
-+ if(aval!=NULL) *v= *aval ;
-+ else
-+ if(find_dot_name(name,v,FALSE)) return ; /* setup name itself */
-+ else
-+ if(duel_get_target_variable(name,-1,v));
-+ else
-+ if(strcmp(name,"frames_no")==0) { /* check special variables */
-+ v->val_kind=VK_RVALUE ;
-+ v->ctype=ctype_int ;
-+ v->u.rval_int=duel_get_frames_number();
-+ }
-+ else duel_gen_error("variable '%s' not found",name);
-+ strcpy(v->symb_val,name);
-+}
-+
-+
-+LPROC push_val(tval_list *l,tvalue *v)
-+{
-+ tval_lcell *e = duel_malloc(sizeof(tval_lcell));
-+ e->val = *v ;
-+ e->next=l->head ;
-+ l->head=e ;
-+ if(l->tail==0) l->tail=e ;
-+}
-+
-+LPROC append_val(tval_list *l,tvalue *v)
-+{
-+ tval_lcell *e=duel_malloc(sizeof(tval_lcell)) ;
-+ e->val = *v ;
-+ e->next=0 ;
-+ if(l->head==0) l->head=l->tail=e ;
-+ else l->tail=l->tail->next=e ;
-+}
-+
-+/* push a whole val-list(ins) into (l) i.e. insert (ins) at the head of(l)
-+ */
-+
-+LPROC push_val_list(tval_list *l,tval_list *ins)
-+{
-+ if(ins->head==NULL) return ; /* inserted list is empty */
-+ if(l->head==NULL) { *l= *ins ; return ; } /* insert-into is empty */
-+ ins->tail->next=l->head ;
-+ l->head=ins->head ;
-+}
-+
-+
-+/* remove first(top) element */
-+LFUNC bool pop_val(tval_list *l,tvalue *v)
-+{
-+ tval_lcell *e=l->head ;
-+ if(e==0) return(FALSE);
-+ *v=e->val ;
-+ l->head=e->next ;
-+ return(TRUE);
-+}
-+/* compute the symbolic value of one iteration of a search (eg -->) operator.
-+ * Normally, for (x) and (y) the result x->y is returned.
-+ * But, if x === a-->next[[n]] and y === next, then we
-+ * return a-->next[[m]] where m=n+1.
-+ * Also, instead of returning x->y we return x-->y[[1]]
-+ *
-+ * note: this was not written for speed! I don't know if it takes
-+ * a significant amount of time or not.
-+ */
-+
-+LPROC set_search_symb_val(char *opcode,tvalue *xval,tvalue *yval)
-+{
-+ char *x = xval->symb_val ;
-+ char *y = yval->symb_val ;
-+ int i,opl=strlen(opcode),xl=strlen(x),yl=strlen(y) ;
-+ char s[3*VALUE_MAX_SYMBOLIC_SIZE];
-+
-+ if(yl+2<xl && strcmp(x+xl-yl,y)==0 && x[xl-yl-2]=='-' && x[xl-yl-1]=='>')
-+ sprintf(s,"%-.*s%s%s[[2]]",xl-yl-2,x,opcode,y);
-+ else {
-+ for(i=xl-1 ; i>0 ; i--) /* see if we have op in x */
-+ if(strncmp(&x[i],opcode,opl)==0) break ;
-+ if(i>0 && strncmp(&x[i+opl],y,yl)==0 &&
-+ x[i+opl+yl]=='[' && x[i+opl+yl+1]=='[' && x[xl-2]==']' && x[xl-1]==']'){
-+ /* x seems to be something like head-->next[1] */
-+ int j,val=0 ;
-+ for(j=i+opl+yl+2 ; j<xl-2 ; j++) {
-+ if(x[j]<'0' || x[j]>'9') goto simple ;
-+ val=10*val+x[j]-'0' ; /* compute index */
-+ }
-+ sprintf(s,"%-.*s[[%d]]",i+opl+yl,x,val+1); /* and re-create it */
-+ }
-+ else {
-+simple: /* we failed to find a x-->y[z] pattern, make new one */
-+ sprintf(s,"%s->%s",x,y);
-+ }
-+ }
-+ s[VALUE_MAX_SYMBOLIC_SIZE-1]=0 ; /* chop as needed */
-+ strcpy(y,s);
-+}
-+
-+LPROC push_dot_stack(tvalue *realv,tvalue *fieldv)
-+{
-+ if(dot_stack_top==DOT_STACK_SIZE)
-+ duel_gen_error("expression too complex ('.' and '->' levels)",0);
-+ dot_stack[++dot_stack_top].realv=realv ;
-+ dot_stack[dot_stack_top].fieldv=fieldv ;
-+}
-+
-+LPROC pop_dot_stack(void)
-+{
-+ duel_assert(dot_stack_top>=0);
-+ dot_stack_top-- ;
-+}
-+
-+/* a simple fetch of a field. used mainly when printing
-+ * v must be a struct with the given name field. value is returned in ret.
-+ * return false if name not found.
-+ */
-+
-+FUNC bool duel_get_dot_name(tvalue *v,char *name,tvalue *ret)
-+{
-+ bool ok ;
-+ push_dot_stack(v,v);
-+ ok=find_dot_name(name,ret,TRUE);
-+ pop_dot_stack();
-+ return ok ;
-+}
-+
-+/* evaluate x.y and similar "with" operators. Special care when y is a
-+ * name and not an expression -- force y to be a direct field of x.
-+ * y is the 'y' node. v is value to return. op is opcode for error reports
-+ * (rv,fv) are values to push on the dot stack. rv is the real 'x' value,
-+ * fv is the value of x to use for field lookup (fv= *rv for '->')
-+ */
-+
-+LFUNC bool eval_dot(tnode *y,tvalue *v,char *op,tvalue *rv,tvalue *fv)
-+{
-+ bool ok ;
-+ push_dot_stack(rv,fv);
-+ if(y->node_kind!=NK_NAME) ok=duel_eval(y,v); /* "with" style */
-+ else { /* x.y y simply name */
-+ if(++y->eval.level>1) { y->eval.level=0 ; ok=FALSE ; }
-+ else {
-+ ok=find_dot_name(y->name,v,TRUE);
-+ if(!ok) duel_op_error("field not found in operator '%s'",op,rv,0);
-+ }
-+ }
-+ pop_dot_stack();
-+ return ok ;
-+}
-+
-+
-+/* evaluate special operators like '-->' '?:' etc */
-+
-+/* get the next result of an sop val:
-+ * DFS: init by pushing(x)
-+ * Iterate: pop x, compute all x->y, push (reversed)
-+ * out: x
-+
-+ * POS: init by pushing(x), unmarked.
-+ * Iterate: pop x, if marked return it. else push back, marked.
-+ * compute all x->y, push (reversed)
-+ * repeat until marked x is popped.
-+ * out: poped x which is marked.
-+
-+ * BFS: init by pushing(x)
-+ * Iterate: get first(x),
-+ * compute all x->y and put into queue.
-+ * return x.
-+ */
-+
-+/* fetch the next value in a DFS search on x-->y. y is given as a node
-+ * and x is popped of the given list. Value is returned in v.
-+ * note: the results from x->y are reversed when pushed on the list,
-+ * this is so x-->(left,right) would return the left first (put last on
-+ * the stack, even though it is computed first!)
-+ * malloc problem: newl is kept locally, so in case of ^C while here, mem
-+ * it points to will be lost. Normally only a few values
-+ */
-+
-+LFUNC bool get_next_dfs_val(tval_list *l, tnode *y,tvalue *v)
-+{
-+ tvalue child,x ;
-+ tval_list newl ;
-+ newl.head=0 ;
-+ do {
-+ if(!pop_val(l,v)) return(FALSE) ;
-+ x= *v ;
-+ duel_get_struct_ptr_val(&x,"x-->y");
-+ } while(x.u.lvalue==0) ; /* ignore null pointers */
-+ while(eval_dot(y,&child,"-->",v,&x)) {
-+ set_search_symb_val("-->",&x,&child); /* makes x-->y[n] neatly */
-+ append_val(&newl,&child); /* append to childs list */
-+ }
-+ push_val_list(l,&newl); /* append new childs to stack */
-+ return(TRUE); /* returns the popped value in v */
-+}
-+
-+
-+/* stop the evaluation of the expression at node n.
-+ * useful with operators like first().
-+ * each node keeps an internal state allowing it to produce the next value.
-+ * this function resets those states.
-+ *
-+ * How: the internal state is kept in n->eval.level. we reset level to zero
-+ * for the node and the subnodes. if the level is already zero,
-+ * the node has already gone to the 'initial state', so the subnodes
-+ * are not visited.
-+ */
-+
-+LPROC stop_eval(tnode *n)
-+{
-+ int i;
-+ if(n==NULL || n->eval.level==0) return ; /* done! subnodes are also ok */
-+ n->eval.level=0 ;
-+ for(i=0 ; i<NODE_MAX_KIDS ; i++) stop_eval(n->kids[i]);
-+}
-+
-+/* evaluate function paramaters. This recursive function should be called
-+ * with the top node for the parms. Parms are parsed as "," operators.
-+ * the function leaves the computed values "hanging" on v1 of each "," node.
-+ * the last paramater is left at v2 of the function call itself (there isnt
-+ * any other reasonable place!).
-+ * 2nd paramater is the function call node, used for the last paramater.
-+ */
-+
-+LFUNC bool eval_func_parms(tnode *n,tnode *fn)
-+{
-+ tvalue *p= &n->eval.v1 ;
-+ if(n->node_kind==NK_OP && n->op_kind==OPK_SBIN && n->op==',') {
-+ while(n->eval.level==2 || duel_eval(n->kids[0],p)) {
-+ n->eval.level=2 ; /* left side active parm in p */
-+ if(eval_func_parms(n->kids[1],fn)) goto ok;
-+ n->eval.level=1 ; /*re-eval */
-+ }
-+ return FALSE ;
-+ }
-+ else if(!duel_eval(n,p = &fn->eval.v2)) return FALSE; /* last paramater */
-+ok:
-+ duel_standardize_func_parm(p);
-+ return TRUE ;
-+}
-+
-+LFUNC bool eval_func_call(tnode *n,tvalue *v)
-+{
-+
-+ tvalue *f= &n->eval.v1 ;
-+ tvalue *parms[21];
-+ int i,parms_no ;
-+ tnode *p ;
-+
-+again:
-+ if(n->kids[1]==NULL) { /* no parms */
-+ n->eval.level=1 ;
-+ if(!duel_eval(n->kids[0],f)) return FALSE ;
-+ }
-+ else {
-+ while(n->eval.level==2 || duel_eval(n->kids[0],f)) {
-+ n->eval.level=2 ; /* function in f */
-+ if(eval_func_parms(n->kids[1],n)) goto ok;
-+ n->eval.level=1 ; /*re-eval func */
-+ }
-+ return FALSE ;
-+ ok: ;
-+ }
-+
-+ if(f->ctype->type_kind!=CTK_FUNC) duel_op_error("bad function call",0,f,0);
-+
-+ p=n->kids[1] ; /* collect paramaters now */
-+ parms_no=0 ;
-+ while(p && p->node_kind==NK_OP && p->op_kind==OPK_SBIN && p->op==',') {
-+ parms[parms_no++]= &p->eval.v1 ;
-+ p=p->kids[1] ;
-+ if(parms_no>=20) duel_op_error("too many paramaters",0,0,0);
-+ }
-+ if(p) parms[parms_no++]= &n->eval.v2 ; /* last paramater */
-+
-+ duel_target_func_call(f,parms,parms_no,v);
-+ if(f->ctype->u.kid->type_kind==CTK_VOID) goto again ; /* no return vals */
-+ duel_set_symb_val(v,"%s(",f,0);
-+ for(i=0 ; i<parms_no ; i++)
-+ duel_set_symb_val(v,"%s%s,",v,parms[i]);
-+ if(parms_no>0) v->symb_val[strlen(v->symb_val)-1]='\0' ; /*chop ',' tail*/
-+ strcat(v->symb_val,")");
-+ return TRUE ;
-+}
-+
-+
-+/* evaluate for special operators: those the produce more than one value,
-+ * binary ones. ',' '..' etc
-+ */
-+
-+LFUNC bool duel_eval_sbin(tnode *n,tvalue *v)
-+{
-+ tval_list *vl = &n->eval.vlist ;
-+ tvalue y,*v1= &n->eval.v1, *v2= &n->eval.v2 ;
-+ tnode *kid0 = n->kids[0], *kid1 = n->kids[1] ;
-+ int vi ;
-+ bool ok ;
-+#define lev n->eval.level
-+
-+ duel_assert(n->node_kind==NK_OP && n->op_kind==OPK_SBIN);
-+ switch(n->op) {
-+ case OP_DECL:
-+ duel_assert(kid0->node_kind==NK_NAME && kid1->node_kind==NK_CTYPE);
-+ if(kid1->ctype->size<=0) duel_gen_error("illegal type size",0);
-+ v->val_kind=VK_LVALUE ;
-+ v->ctype=kid1->ctype ;
-+ v->u.lvalue=duel_alloc_target_space(kid1->ctype->size);
-+ strcpy(v->symb_val,kid0->name);
-+ duel_set_alias(kid0->name,v);
-+ break ;
-+ case OP_DEF:
-+ if(kid0->node_kind!=NK_NAME)
-+ duel_gen_error("left side of := must be a simple var",0);
-+ if(!duel_eval(kid1,v)) return FALSE ;
-+ duel_set_alias(kid0->name,v);
-+ return TRUE ;
-+ case ',':
-+ if(lev==1 && duel_eval(kid0,v)) return TRUE ;
-+ lev=2 ;
-+ return duel_eval(kid1,v);
-+ case ';':
-+ /*note: (x;) is not allowed in syntax, but is allowed here and
-+ *means eval x, return nothing. used by parser, e.g. terminating ';'
-+ *produces no side effects
-+ */
-+
-+ if(lev==1) while(duel_eval(kid0,v)) ; /* eval all left size */
-+ lev=2 ;
-+ return duel_eval(kid1,v);
-+ break ;
-+ case OP_IMP: /* a=>b for each _=eval(a) return eval(b) (with _ set) */
-+ if(lev>1) goto im2 ;
-+ for(;;) {
-+ if(!duel_eval(kid0,v1)) return FALSE ;
-+ lev=2 ;
-+ im2: push_dot_stack(v1,0);
-+ ok=duel_eval(kid1,v);
-+ pop_dot_stack();
-+ if(ok) return TRUE ;
-+ }
-+ case OP_IF: /* if(a) b return eval(b) for each eval(a)!=0 */
-+ if(lev>1) goto if2 ;
-+ for(;;) {
-+ if(!duel_eval(kid0,v)) return FALSE ;
-+ if(!duel_mk_logical(v,"if(x)y")) continue ;
-+ lev=2 ;
-+ if2: if(duel_eval(kid1,v)) return TRUE ;
-+ }
-+ case OP_OR: /* a||b normal 'C' logical or */
-+ if(lev>1) goto or2 ;
-+ for(;;) {
-+ if(!duel_eval(kid0,v)) return FALSE ;
-+ if(duel_mk_logical(v,"x||y")) {lev=1 ; return TRUE ;}
-+ or2: if(duel_eval(kid1,v)) {
-+ lev=2 ;
-+ duel_mk_logical(v,"y||x");
-+ return TRUE ;
-+ }
-+ }
-+ case OP_AND: /* a&&b normal 'C' logical and */
-+ if(lev>1) goto an2 ;
-+ for(;;) {
-+ if(!duel_eval(kid0,v)) return FALSE ;
-+ if(!duel_mk_logical(v,"x&&y")) {lev=1 ; return TRUE ;}
-+ an2: if(duel_eval(kid1,v)) {
-+ lev=2 ;
-+ duel_mk_logical(v,"y&&x");
-+ return TRUE ;
-+ }
-+ }
-+ case '.':
-+ if(lev>1) goto dt2 ;
-+ for(;;) {
-+ if(!duel_eval(kid0,v1)) return FALSE ;
-+ *v2 = * v1 ; /* copy value for the lookup */
-+ if(ctype_kind_func_ptr_like(v1->ctype)) /* func.x */
-+ duel_find_func_frame(v2,"x.y");
-+ else
-+ if(v1->val_kind!=VK_FVALUE) /* type check frame or struct*/
-+ duel_get_struct_val(v1,"x.y");
-+ lev=2 ;
-+ dt2: if(!eval_dot(kid1,v,".",v1,v2)) continue ;
-+ if(v->ctype!=v1->ctype || v->val_kind!=v1->val_kind ||
-+ v->u.lvalue != v1->u.lvalue ||
-+ strcmp(v->symb_val,v1->symb_val)!=0) /* check for x._ */
-+ duel_set_symb_val(v,"%s.%s",v1,v);
-+ return TRUE ;
-+ }
-+ case OP_ARR:
-+ if(lev>1) goto ar2 ;
-+ for(;;) {
-+ if(!duel_eval(kid0,v1)) return FALSE ;
-+ *v2 = *v1 ; /* copy value for dereferencing */
-+ duel_get_struct_ptr_val(v2,"x->y");
-+ lev=2 ;
-+ ar2: if(!eval_dot(kid1,v,"->",v1,v2)) continue ;
-+ if(v->ctype!=v1->ctype || v->val_kind!=v1->val_kind ||
-+ v->u.lvalue != v1->u.lvalue ||
-+ strcmp(v->symb_val,v1->symb_val)!=0) /* check for x->_ */
-+ duel_set_symb_val(v,"%s->%s",v1,v);
-+ return TRUE ;
-+ }
-+ case OP_TO: /* a..b Is it legal to have 1..(5,6) sure! */
-+ if(lev>1) goto to2 ;
-+ do {
-+ if(kid0 && !duel_eval(kid0,v1)) break ;
-+ do {
-+ if(kid1 && !duel_eval(kid1,v2)) break ;
-+ to2: if(duel_do_op_to(kid0? v1:0,kid1? v2:0,++lev-2,v)) return TRUE;
-+ } while(kid1);
-+ } while(kid0) ; /* either one (kid0 null) or infinite iterations*/
-+ break ;
-+ case OP_SEL: /* x[[y]] */
-+ if(lev==1) { lev=2 ; n->eval.counter= -1 ; }
-+ if(!duel_eval(kid1,v1)) {
-+ stop_eval(kid0);
-+ return FALSE ;
-+ }
-+ vi=duel_get_posint_val(v1,"y[[x]]");
-+ if(vi<=n->eval.counter) {
-+ /* v is smaller than previous v value, so reset x and
-+ * start over. Example: \x[1,5,3] after \x[1],
-+ * we continue to get [5]. but to get [3] we reset
-+ * Alternatively, we could have kept a list of old
-+ * generated values.
-+ */
-+ stop_eval(kid0) ;
-+ n->eval.counter= -1 ;
-+ }
-+ for( ; n->eval.counter<vi ; n->eval.counter++)
-+ if(!duel_eval(kid0,v))
-+ duel_op_error("operator x of y[[x]] too large",0,v1,0);
-+ return TRUE ; /* value is the last (v) computed */
-+ break ;
-+ case '@': /* x@y - generate x stops when y true */
-+ if(!duel_eval(kid0,v)) return FALSE ;
-+ if(kid1->node_kind==NK_CONST) { /* special case y constant */
-+ *v2=kid1->cnst ;
-+ *v1= *v ; /* because 'apply_bin_op' destroy its args */
-+ duel_apply_bin_op(OP_EQ,v1,v2,&y);
-+ if(y.u.rval_int) { stop_eval(kid0); return FALSE ; }
-+ return TRUE ;
-+ }
-+ *v1 = *v ; /* allow fields in y of x@y for x struct ptr */
-+ if(ctype_kind_ptr_like(v->ctype) &&
-+ ctype_kind_struct_like(v->ctype->u.kid))
-+ duel_get_struct_ptr_val(v1,"x@y");
-+
-+ while(eval_dot(kid1,v2,"@",v,v1)) /* check &&/y */
-+ if(!duel_mk_logical(v2,"y@x")) { /* y==0, so dont stop x */
-+ stop_eval(kid1);
-+ return TRUE ;
-+ }
-+ stop_eval(kid0);
-+ break ;
-+ case '#': /* x#i define variable i as counter for gen. x*/
-+ if(kid1->node_kind!=NK_NAME)
-+ duel_gen_error("x#y 2rd operand must be a name",0);
-+ if(!duel_eval(kid0,v)) return FALSE ;
-+ if(lev==1) { lev=2 ; n->eval.counter= -1 ; } /* first time */
-+ y.val_kind=VK_RVALUE ;
-+ y.ctype=ctype_int ;
-+ y.u.rval_int= ++n->eval.counter ;
-+ sprintf(y.symb_val,"%d",n->eval.counter);
-+ duel_set_alias(kid1->name,&y);
-+ return TRUE ;
-+ break ;
-+ case OP_DFS: /* x-->y */
-+ if(lev>1) goto df2 ;
-+ for(;;) {
-+ if(!duel_eval(kid0,v)) return FALSE ;
-+ duel_free_val_list(vl);
-+ push_val(vl,v);
-+ lev=2 ;
-+ df2: if(get_next_dfs_val(vl,kid1,v)) return TRUE ;
-+ }
-+ break ;
-+ case OP_WHILE: /* while(a) b */
-+ if(lev==2) goto wh2 ;
-+ for(;;) {
-+ while(duel_eval(kid0,v)) /* check &&/a */
-+ if(!duel_mk_logical(v,"while(x)y")) {
-+ stop_eval(kid0);
-+ return FALSE ;
-+ }
-+ lev=2 ;
-+ wh2: if(duel_eval(kid1,v)) return TRUE ;
-+ }
-+ default: duel_assert(0);
-+ }
-+ return FALSE ;
-+#undef lev
-+}
-+
-+
-+
-+LFUNC bool duel_eval_tri(tnode *n,tvalue *v)
-+{
-+#define lev n->eval.level
-+ duel_assert(n->node_kind==NK_OP && n->op_kind==OPK_TRI);
-+ switch(n->op) {
-+ case OP_IF: /* if(a) b else c return eval(b) for each eval(a)!=0
-+ * and eval(c) for each eval(a)==0 (usu. (a) is one result*/
-+ if(lev>1) goto if2;
-+ for(;;) {
-+ if(!duel_eval(n->kids[0],v)) return FALSE ;
-+ lev=(duel_mk_logical(v,"if(x) y else z")? 2:3) ;
-+ if2: if(duel_eval(n->kids[lev-1],v)) return TRUE ;
-+ }
-+ case '?': /* a? b:c has the same semantics as if(a) b else c */
-+ if(lev>1) goto qm2;
-+ for(;;) {
-+ if(!duel_eval(n->kids[0],v)) return FALSE ;
-+ lev=(duel_mk_logical(v,"x? y:z")? 2:3) ;
-+ qm2: if(duel_eval(n->kids[lev-1],v)) return TRUE ;
-+ }
-+ default: duel_assert(0);
-+ }
-+ return FALSE ;
-+#undef lev
-+}
-+
-+LFUNC bool duel_eval_quad(tnode *n,tvalue *v)
-+{
-+#define lev n->eval.level
-+ duel_assert(n->node_kind==NK_OP && n->op_kind==OPK_QUAD);
-+ switch(n->op) {
-+ case OP_FOR: /* for(a;b;c) d ; */
-+ if(lev==1) { lev=2 ; while(duel_eval(n->kids[0],v)); }
-+ if(lev==3) goto fr3 ;
-+ for(;;) {
-+ while(duel_eval(n->kids[1],v)) /* check &&/b */
-+ if(!duel_mk_logical(v,"for(a;x;y)z")) {
-+ stop_eval(n->kids[1]);
-+ return FALSE ;
-+ }
-+ lev=3 ;
-+ fr3: if(duel_eval(n->kids[3],v)) return TRUE ;
-+ while(duel_eval(n->kids[2],v));
-+ }
-+ default: duel_assert(0);
-+ }
-+ return FALSE ;
-+#undef lev
-+}
-+
-+FUNC bool duel_eval(tnode *n,tvalue *v)
-+{
-+ tvalue u,tmp ;
-+ bool ok=FALSE ;
-+ tnode *prev_loc ;
-+
-+ if(!n) return FALSE ;
-+ prev_loc=duel_set_eval_loc(n); /* set current eval node, save prev */
-+ if(n->eval.level==0) n->eval.level=1 ; /* indicate node is 'active' */
-+
-+ switch(n->node_kind) {
-+ case NK_CONST: /* return a 'value' node made of this constant */
-+ if(n->eval.level==1) {
-+ n->eval.level=2 ;
-+ *v=n->cnst ;
-+ ok=TRUE ;
-+ }
-+ break ;
-+ case NK_NAME:
-+ if(n->eval.level==1) {
-+ n->eval.level=2 ;
-+ duel_eval_name(n->name,v);
-+ ok=TRUE ;
-+ }
-+ break ;
-+ case NK_OP:
-+ switch(n->op_kind) {
-+ case OPK_SUNARY: /* special unary ops */
-+ if(n->op=='#') {
-+ int count=0 ;
-+ if(n->eval.level==1) {
-+ while(duel_eval(n->kids[0],&u))
-+ if(count++ == 0) duel_set_symb_val(v,"#/(%s ...)",&u,0);
-+ if(count == 0) duel_set_symb_val(v,"#/(empty)",0,0);
-+ v->val_kind=VK_RVALUE ;
-+ v->ctype=ctype_int ;
-+ v->u.rval_int=count ;
-+ n->eval.level=2 ;
-+ ok=TRUE ;
-+ }
-+ }
-+ else
-+ if(n->op==OP_AND) {
-+ if(n->eval.level==1) { int result=1 ;
-+ while(duel_eval(n->kids[0],v)) {
-+ if(!duel_mk_logical(v,"&&/x")) {
-+ stop_eval(n->kids[0]);
-+ result=0 ;
-+ break ;
-+ }
-+ }
-+ v->val_kind=VK_RVALUE ;
-+ v->ctype=ctype_int ;
-+ v->u.rval_int=result ;
-+ sprintf(v->symb_val,"%d",result);
-+ n->eval.level=2 ;
-+ ok=TRUE ;
-+ }
-+ }
-+ else
-+ if(n->op==OP_OR) {
-+ if(n->eval.level==1) { int result=0 ;
-+ while(duel_eval(n->kids[0],v)) {
-+ if(duel_mk_logical(v,"||/x")) {
-+ stop_eval(n->kids[0]);
-+ result=1 ;
-+ break ;
-+ }
-+ }
-+ v->val_kind=VK_RVALUE ;
-+ v->ctype=ctype_int ;
-+ v->u.rval_int=result ;
-+ sprintf(v->symb_val,"%d",result);
-+ n->eval.level=2 ;
-+ ok=TRUE ;
-+ }
-+ }
-+ else
-+ if(n->op==OP_SIZ) {
-+ if(n->eval.level==1) {
-+ char *tname=n->kids[0]->ctype->name ;
-+ duel_assert(n->kids[0]->node_kind==NK_CTYPE);
-+ v->val_kind=VK_RVALUE ;
-+ v->ctype=ctype_size_t ;
-+ v->u.rval_size_t=n->kids[0]->ctype->size ;
-+ n->eval.level=2 ;
-+ if(tname==NULL || *tname=='\0') tname="T" ; /* cheating */
-+ sprintf(v->symb_val,"sizeof(%s)",tname);
-+ ok=TRUE ;
-+ }
-+ }
-+ else duel_assert(0);
-+ break ;
-+ case OPK_UNARY:
-+ if(!duel_eval(n->kids[0],v)) break ;
-+ duel_apply_unary_op(n->op,v);
-+ ok=TRUE ;
-+ break ;
-+ case OPK_POST_UNARY:
-+ if(!duel_eval(n->kids[0],v)) break ;
-+ duel_apply_post_unary_op(n->op,v);
-+ ok=TRUE ;
-+ break ;
-+ case OPK_BIN: /* a+b, compute and hold a, iterate on b, redo a */
-+ while(n->eval.level==2 || duel_eval(n->kids[0],&n->eval.v1)) {
-+ n->eval.level=2 ; /* left side active op in vals[0] */
-+ while(duel_eval(n->kids[1],&u)) {
-+ tmp= n->eval.v1 ; /* copy left val, it is destoryed*/
-+ ok=duel_apply_bin_op(n->op,&tmp,&u,v);
-+ if(ok) goto done;
-+ }
-+ n->eval.level=1 ; /*left side val no longer valid, re-eval*/
-+ }
-+ break ;
-+ case OPK_SBIN: /* a,b etc, special ops */
-+ ok=duel_eval_sbin(n,v) ;
-+ break ;
-+ case OPK_TRI:
-+ ok=duel_eval_tri(n,v) ;
-+ break ;
-+ case OPK_QUAD:
-+ ok=duel_eval_quad(n,v) ;
-+ break ;
-+ case OPK_CAST:
-+ duel_assert(n->kids[0]->node_kind==NK_CTYPE);
-+ if(!duel_eval(n->kids[1],v)) break ;
-+ duel_do_cast(n->kids[0]->ctype,v);
-+ ok=TRUE ;
-+ break ;
-+ case OPK_ASSIGN:
-+ duel_gen_error("modified assignment is not supported yet",0);
-+ case OPK_FUNC:
-+ ok=eval_func_call(n,v) ;
-+ break ;
-+ default: duel_assert(0);
-+ }
-+ break ;
-+ default: duel_assert(0);
-+ }
-+done:
-+ if(!ok) n->eval.level=0 ; /* no other val available */
-+ duel_set_eval_loc(prev_loc);
-+ return ok ;
-+}
---- gdb/duel/evalops.c
-+++ gdb/duel/evalops.c
-@@ -0,0 +1,1273 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* this module contains evalauation code for many standard operators, eg '+'
-+ */
-+
-+/*
-+ * $Log: 10_all_gdb-6.6-duel.patch,v $
-+ * Revision 1.1 2008/04/06 23:59:05 vapier
-+ * initial 6.8 patchset based on last 6.7.1 patchset
-+ *
-+ * Revision 1.14 93/03/19 15:40:17 mg
-+ * fixed bug long symbolics handling
-+ *
-+ * Revision 1.13 93/03/12 05:50:01 mg
-+ * uses tuint instead of uint, etc.
-+ *
-+ * Revision 1.12 93/02/26 05:00:13 mg
-+ * fixed void pointers compare. ctype_voidptr is not unique!
-+ *
-+ * Revision 1.11 93/02/04 02:09:55 mg
-+ * typo
-+ *
-+ * Revision 1.10 93/02/04 01:24:51 mg
-+ * better error reports for "="
-+ *
-+ * Revision 1.9 93/02/03 21:47:43 mg
-+ * support "signed char"
-+ *
-+ * Revision 1.8 93/01/12 21:51:29 mg
-+ * cleanup and set for release
-+ *
-+ * Revision 1.7 93/01/07 00:10:51 mg
-+ * auto convert func to &func
-+ * find a frame for a func
-+ *
-+ *
-+ * Revision 1.6 93/01/03 07:30:02 mg
-+ * function calls, error reporting, printing.
-+ *
-+ * Revision 1.5 92/12/24 23:34:47 mg
-+ * frames support
-+ *
-+ * Revision 1.4 92/10/19 15:07:46 mg
-+ * fvalue added (not ready yet), svalues dropped
-+ *
-+ * Revision 1.3 92/10/14 02:05:10 mg
-+ * add print/{x} support
-+ *
-+ * Revision 1.2 92/09/15 05:48:57 mg
-+ * support '..' new formats
-+ *
-+ */
-+
-+#include "duel.h"
-+
-+/*
-+ * This file is made up of three parts:
-+ * (1) low-level functions that interact with the debugger/type system directly
-+ * (2) mid-level functions that compute the result of simple operators like '+'
-+ * (3) high-level functions that compute any binary/unary op.
-+ * Only some of the functions in (1) are global, and all of the (3) are.
-+ * this collection is in one file to allow a minimal of global symbols
-+ * (for minimum collision with the debugger)
-+ */
-+
-+
-+
-+/****************************************************************************
-+ A low-level set of functions follows. They interact with the type system
-+ and the debugger/target's space directly:
-+ get_storage_type_kind - retrieve ctype_kind, with special conversion for enums
-+ get_rvalue - retrieve the rvalue of a variable/lvalue.
-+ set_symb_val - set the symbolic value of a tvalue.
-+ upgrade_small_int_types - figure out the type to upgrade to from char etc.
-+ find_numeric_result_type - figure type of x+y where + is generic C op
-+ convert_scalar_type - convert one scalar type to another
-+ get_numeric_val - retrieve rvalue, making sure it is numeric
-+ get_scalar_val - retrieve rvalue, making sure it is numeric or pointer
-+ get_integral_val- retrieve rvalue, making sure it is an integer
-+ get_int_val - retrieve rvalue, make sure it's an integer, return int val
-+ get_pointer_val - retrieve rvalue, make sure it's a pointer.
-+ ****************************************************************************/
-+
-+/* give the storage-type kind of a given type.
-+ * this is the same type-kind as the type itslef, except in the case of enums
-+ * where the type-kind of the storage will be CTK_INT etc (integral type)
-+ * the storage type kind is set when the enum is created.
-+ */
-+
-+LFUNC tctype_kind get_storage_type_kind(tctype *t)
-+{
-+ if(t->type_kind!=CTK_ENUM) return t->type_kind ;
-+ return t->u.e.real_type_kind ;
-+}
-+
-+/* try_get_rvalue -- make an rvalue of v. if v is already an rvalue,
-+ * nothing is done. Else v is an b/lvalue, so its rvalue is fetched.
-+ * special care:
-+ * (1) Enums are fetched as int of same size. type stay enum!
-+ * (2) Arrays and functions are made into pointers
-+ * (3) Bitfields are converted to ints (debugger dependent)
-+ * there are no rvalues of 'bitfield' type!
-+ * return succ/fail for bad mem ref. the "real" function everyone calls is
-+ * get_rvalue (this function is used only by printing functions to avoid
-+ * chicken&egg problem of error reporting.)
-+ */
-+
-+FUNC duel_try_get_rvalue(tvalue *v,char *op)
-+{
-+ void *p ;
-+ int n ;
-+ bool ok;
-+ if(v->val_kind == VK_RVALUE) return TRUE;
-+ if(v->val_kind == VK_FVALUE)
-+ duel_op_error("illegal type 'frame' for operand x of '%s'",op,v,0);
-+ switch(get_storage_type_kind(v->ctype)) {
-+ case CTK_CHAR: p= &v->u.rval_char ; n=sizeof(char) ;break ;
-+ case CTK_SCHAR: p= &v->u.rval_schar ; n=sizeof(tschar) ;break ;
-+ case CTK_UCHAR: p= &v->u.rval_uchar ; n=sizeof(tuchar) ;break ;
-+ case CTK_USHORT: p= &v->u.rval_ushort ; n=sizeof(tushort) ;break ;
-+ case CTK_SHORT: p= &v->u.rval_short ; n=sizeof(short) ;break ;
-+ case CTK_INT: p= &v->u.rval_int ; n=sizeof(int) ;break ;
-+ case CTK_UINT: p= &v->u.rval_uint ; n=sizeof(tuint) ;break ;
-+ case CTK_LONG: p= &v->u.rval_long ; n=sizeof(long) ;break ;
-+ case CTK_ULONG: p= &v->u.rval_ulong ; n=sizeof(tulong) ;break ;
-+ case CTK_LONGLONG:p= &v->u.rval_longlong ; n=sizeof(long long) ;break ;
-+ case CTK_ULONGLONG:p= &v->u.rval_ulonglong;n=sizeof(tulonglong) ;break ;
-+ case CTK_FLOAT: p= &v->u.rval_float ; n=sizeof(float) ;break ;
-+ case CTK_DOUBLE: p= &v->u.rval_double ; n=sizeof(double) ;break ;
-+ case CTK_PTR: p= &v->u.rval_ptr ; n=sizeof(ttarget_ptr) ;break ;
-+ case CTK_ARRAY: /* the lvalue becomes an rvalue, a real pointer! */
-+ duel_assert(v->val_kind==VK_LVALUE); /* duel exp rules */
-+ v->val_kind=VK_RVALUE ;
-+ v->ctype=duel_mkctype_ptr(v->ctype->u.kid) ;
-+ v->u.rval_ptr=v->u.lvalue ;
-+ return TRUE;
-+ case CTK_FUNC: /* makes it a pointer to a func*/
-+ duel_assert(v->val_kind==VK_LVALUE); /* duel exp rules */
-+ v->val_kind=VK_RVALUE ;
-+ v->ctype=duel_mkctype_ptr(v->ctype) ;
-+ v->u.rval_ptr=v->u.lvalue ;
-+ return TRUE;
-+
-+ case CTK_STRUCT: /* can't have an rval from struct? */
-+ case CTK_UNION:
-+ /* enums were eliminated above */
-+ default: duel_assert(0);
-+ }
-+ if(v->val_kind == VK_BVALUE) { /* bitfield: lvalue+bitpos/len */
-+ tbvalue_info bv;
-+ bv=v->u.bvalue ;
-+ ok=duel_get_target_bitfield(bv.lvalue, bv.bitpos, bv.bitlen, p,
-+ v->ctype->type_kind);
-+ if(!ok) { v->u.bvalue=bv ; return FALSE ; }
-+ }
-+ else {
-+ ttarget_ptr lv=v->u.lvalue ;
-+ ok=duel_get_target_bytes(lv,p,n); /*fetch n debuggee bytes*/
-+ if(!ok) { v->u.lvalue=lv ; return FALSE ; }
-+ }
-+
-+ v->val_kind=VK_RVALUE ;
-+ /* in remote debugging, one might need to swap byte order at this
-+ * point. [remote debugging is not supported by duel v1.0]
-+ */
-+ return TRUE ;
-+}
-+
-+
-+/*
-+ * safe get_rvalue - produce error messages on memory access failer.
-+ */
-+
-+LPROC get_rvalue(tvalue *v,char *op)
-+{
-+ bool ok=duel_try_get_rvalue(v,op);
-+ if(!ok) duel_op_error("illegal address for operand x of '%s'",op,v,0);
-+}
-+
-+/* put_rvalue: put the rvalue of v2 into the location in v1.
-+ * types are assumed to be the same.
-+ */
-+
-+LPROC put_rvalue(tvalue *v1,tvalue *v2,char *op)
-+{
-+ void *p ;
-+ int n ;
-+ duel_assert(v1->val_kind!=VK_RVALUE);
-+ duel_assert(v1->val_kind!=VK_FVALUE);
-+ duel_assert(v2->val_kind==VK_RVALUE);
-+ duel_assert(v1->ctype->size == v2->ctype->size);
-+ switch(get_storage_type_kind(v2->ctype)) {
-+ case CTK_CHAR: p= &v2->u.rval_char ; n=sizeof(char) ;break ;
-+ case CTK_SCHAR: p= &v2->u.rval_schar ; n=sizeof(tschar) ;break ;
-+ case CTK_UCHAR: p= &v2->u.rval_uchar ; n=sizeof(tuchar) ;break ;
-+ case CTK_USHORT: p= &v2->u.rval_ushort ; n=sizeof(tushort) ;break ;
-+ case CTK_SHORT: p= &v2->u.rval_short ; n=sizeof(short) ;break ;
-+ case CTK_INT: p= &v2->u.rval_int ; n=sizeof(int) ;break ;
-+ case CTK_UINT: p= &v2->u.rval_uint ; n=sizeof(tuint) ;break ;
-+ case CTK_LONG: p= &v2->u.rval_long ; n=sizeof(long) ;break ;
-+ case CTK_ULONG: p= &v2->u.rval_ulong ; n=sizeof(tulong) ;break ;
-+ case CTK_LONGLONG: p= &v2->u.rval_longlong ; n=sizeof(long long);break ;
-+ case CTK_ULONGLONG: p= &v2->u.rval_ulonglong ; n=sizeof(tulonglong);break ;
-+ case CTK_FLOAT: p= &v2->u.rval_float ; n=sizeof(float) ;break ;
-+ case CTK_DOUBLE: p= &v2->u.rval_double ; n=sizeof(double) ;break ;
-+ case CTK_PTR: p= &v2->u.rval_ptr ; n=sizeof(ttarget_ptr) ;break ;
-+ default: duel_assert(0); /* other types not supported as rvalues */
-+ }
-+ if(v1->val_kind == VK_BVALUE)
-+ duel_gen_error("assignment to bitfields is not yet supported",0);
-+ else
-+ if(!duel_put_target_bytes(v1->u.lvalue,p,n)) /*store n debuggee bytes*/
-+ duel_op_error("cant write memory for operand x of '%s'",op,v1,0);
-+}
-+
-+/* set the symbolic val for tvalue. input format is a sprintf,
-+ * with v1,v2 being other values that show as '%s' in the format.
-+ * v1,v2 can be zero if they are unused by the format.
-+ */
-+PROC duel_set_symb_val(tvalue *r,char *format,tvalue *v1,tvalue *v2)
-+{
-+ char s[3*VALUE_MAX_SYMBOLIC_SIZE];
-+ sprintf(s,format,v1->symb_val,v2->symb_val);
-+ s[VALUE_MAX_SYMBOLIC_SIZE-1]=0 ; /* chop as needed */
-+ strcpy(r->symb_val,s);
-+}
-+
-+/* given a small int type (short,char,enum) return the upgraded (int or
-+ * uint) type. Else return the original type
-+ */
-+LFUNC tctype* upgrade_small_int_types(tctype *t)
-+{
-+ switch(t->type_kind) {
-+ case CTK_ENUM:
-+ case CTK_CHAR:
-+ case CTK_SCHAR:
-+ case CTK_UCHAR:
-+ case CTK_SHORT:
-+ return ctype_int ;
-+ case CTK_USHORT:
-+ if(sizeof(tushort)==sizeof(int)) return ctype_uint ;
-+ else return ctype_int ;
-+ default:
-+ return t ;
-+ }
-+}
-+
-+/* find the type of the result of a generic numeric operation on
-+ * v1,v2. This applies the standard C type upgrade rules.
-+ * The type of the result is returned.
-+ * r is setup so it can receive the result: an RVALUE of the specified
-+ * type. Its symbolic value is also setup based on the symbolic value
-+ * of v1 v2 and the operation op.
-+ * Note: op is not used to figure out the numeric result, only
-+ * the types of v1 and v2. As a side effect, the answer for x|y where
-+ * y is a double will be given as double. it is up to the caller to
-+ * verify that v1,v2 have meaningful types of this operation
-+ *
-+ */
-+
-+LFUNC tctype* find_numeric_result_type(tvalue *v1,tvalue *v2,
-+ tvalue *r,char *op)
-+{
-+ tctype *t1=upgrade_small_int_types(v1->ctype); /* upgrade to int etc */
-+ tctype *t2=upgrade_small_int_types(v2->ctype);
-+ char s[80] ;
-+ r->val_kind=VK_RVALUE ;
-+ sprintf(s,"%%s%s%%s",op) ; /* eg, if op=">>" then s becomes "%s>>%s" */
-+ duel_set_symb_val(r,s,v1,v2);
-+
-+ if(t1==ctype_double || t2==ctype_double) return r->ctype=ctype_double ;
-+ if(t1==ctype_float || t2==ctype_float) return r->ctype=ctype_float ;
-+ if(t1==ctype_ulonglong || t2==ctype_ulonglong) return r->ctype=ctype_ulonglong ;
-+ if(t1==ctype_longlong || t2==ctype_longlong) return r->ctype=ctype_longlong ;
-+ if(t1==ctype_ulong || t2==ctype_ulong) return r->ctype=ctype_ulong ;
-+ if(sizeof(unsigned)==sizeof(long) &&
-+ (t1==ctype_long && t2==ctype_uint ||
-+ t1==ctype_uint && t2==ctype_long)) return r->ctype=ctype_ulong ;
-+ if(t1==ctype_long || t2==ctype_long) return r->ctype=ctype_long ;
-+ if(t1==ctype_uint || t2==ctype_uint) return r->ctype=ctype_uint ;
-+ return r->ctype=ctype_int ;
-+}
-+
-+/* convert_to_fix assisting-macro: takes the val stored in v and put it
-+ * into w. w is an lvalue with a 'fixed' type (t).
-+ */
-+
-+#define convert_to_fix(v,w) \
-+ switch(get_storage_type_kind(v->ctype)) { \
-+ case CTK_CHAR: w (v->u.rval_char) ; break ; \
-+ case CTK_SCHAR: w (v->u.rval_schar) ; break ; \
-+ case CTK_UCHAR: w (v->u.rval_uchar) ; break ; \
-+ case CTK_USHORT: w (v->u.rval_ushort) ; break ; \
-+ case CTK_SHORT: w (v->u.rval_short) ; break ; \
-+ case CTK_INT: w (v->u.rval_int) ; break ; \
-+ case CTK_UINT: w (v->u.rval_uint) ; break ; \
-+ case CTK_LONG: w (v->u.rval_long) ; break ; \
-+ case CTK_ULONG: w (v->u.rval_ulong) ; break ; \
-+ case CTK_LONGLONG: w (v->u.rval_longlong) ; break ; \
-+ case CTK_ULONGLONG: w (v->u.rval_ulonglong) ; break ; \
-+ case CTK_FLOAT: w (v->u.rval_float) ; break ; \
-+ case CTK_DOUBLE: w (v->u.rval_double) ; break ; \
-+ case CTK_PTR: w (tptrsize_int) (v->u.rval_ptr) ; break ; \
-+ default: duel_assert(0); \
-+ }
-+
-+
-+/* convert_scalar_type -- convert rvalue v to type t.
-+ * uses convert_to_fix macro. In effect, this is a huge switch for
-+ * all possible combinations of basic C types.
-+ */
-+
-+LPROC convert_scalar_type(tvalue *v,tctype *t,char *op)
-+{
-+ get_rvalue(v,op);
-+ switch(get_storage_type_kind(t)) {
-+ case CTK_CHAR: convert_to_fix(v,v->u.rval_char=(char)) ; break ;
-+ case CTK_SCHAR: convert_to_fix(v,v->u.rval_schar=(tschar)) ; break ;
-+ case CTK_UCHAR: convert_to_fix(v,v->u.rval_uchar=(tuchar)) ; break ;
-+ case CTK_SHORT: convert_to_fix(v,v->u.rval_short=(short)) ; break ;
-+ case CTK_USHORT: convert_to_fix(v,v->u.rval_ushort=(tushort)) ; break ;
-+ case CTK_INT: convert_to_fix(v,v->u.rval_int=(int)) ; break ;
-+ case CTK_UINT: convert_to_fix(v,v->u.rval_uint=(tuint)) ; break ;
-+ case CTK_LONG: convert_to_fix(v,v->u.rval_long=(long)) ; break ;
-+ case CTK_ULONG: convert_to_fix(v,v->u.rval_ulong=(tulong)) ; break ;
-+ case CTK_LONGLONG: convert_to_fix(v,v->u.rval_longlong=(long long)) ; break ;
-+ case CTK_ULONGLONG: convert_to_fix(v,v->u.rval_ulonglong=(tulonglong)) ; break ;
-+ case CTK_FLOAT: convert_to_fix(v,v->u.rval_float=(float)) ; break ;
-+ case CTK_DOUBLE: convert_to_fix(v,v->u.rval_double=(double)) ; break ;
-+ case CTK_PTR: convert_to_fix(v,
-+ v->u.rval_ptr=(ttarget_ptr)(tptrsize_int)) ; break ;
-+ default: duel_assert(0);
-+ }
-+ v->ctype=t ;
-+}
-+
-+
-+/* verify v is numeric, get its rvalue converted to type tout or at least int*/
-+LPROC get_numeric_val(tvalue *v,char *op,tctype *tout)
-+{
-+ if(!ctype_kind_numeric(v->ctype))
-+ duel_op_error("operand x of '%s' is not numeric",op,v,0);
-+ if(!tout) tout=upgrade_small_int_types(v->ctype); /* upgrade to int etc */
-+ convert_scalar_type(v,tout,op);
-+}
-+
-+/*verify v is integral, get its rvalue converted to type tout or at least int*/
-+LPROC get_integral_val(tvalue *v,char *op,tctype *tout)
-+{
-+ if(!ctype_kind_integral(v->ctype))
-+ duel_op_error("operand x of '%s' is not integral",op,v,0);
-+ if(!tout) tout=upgrade_small_int_types(v->ctype); /* upgrade to int etc */
-+ convert_scalar_type(v,tout,op);
-+}
-+
-+/* verify v is integral, return its actual value as 'int' */
-+FUNC int duel_get_int_val(tvalue *v,char *op)
-+{
-+ get_integral_val(v,op,ctype_int);
-+ return v->u.rval_int ;
-+}
-+
-+/* verify v is numeric or pointer/array, upgrade type to at least int or ptr
-+ and get the rvalue */
-+LPROC get_scalar_val(tvalue *v,char *op)
-+{
-+ if(ctype_kind_ptr_like(v->ctype)) get_rvalue(v,op);
-+ else {
-+ tctype *t=upgrade_small_int_types(v->ctype); /* upgrade to int */
-+ if(!ctype_kind_numeric(v->ctype))
-+ duel_op_error("operand x of '%s' is not a scalar",op,v,0);
-+ convert_scalar_type(v,t,op);
-+ }
-+}
-+
-+LPROC get_pointer_val(tvalue *v,char *op,bool zero_ok)
-+{
-+ if(ctype_kind_ptr_like(v->ctype)) get_rvalue(v,op);
-+ else
-+ if(zero_ok && v->ctype->type_kind==CTK_INT &&
-+ v->val_kind==VK_RVALUE && v->u.rval_int==0) {
-+ v->ctype=ctype_voidptr ;
-+ v->u.rval_ptr=0 ;
-+ }
-+ else duel_op_error("operand x of '%s' is not a pointer",op,v,0);
-+}
-+
-+/* copy one lvalue over the other. This copy is used for assignment,
-+ * including the assignment of structures and unions.
-+ * supports unlimited size and error reports when memory access fails.
-+ */
-+
-+LPROC copy_lvalues(tvalue *v1,tvalue *v2,char *op)
-+{
-+ size_t size ;
-+ ttarget_ptr to=v1->u.lvalue,from=v2->u.lvalue ;
-+ char buf[BUFSIZ] ;
-+ duel_assert(v1->val_kind==VK_LVALUE && v2->val_kind==VK_LVALUE);
-+ size=v1->ctype->size ;
-+ duel_assert(v2->ctype->size==size);
-+ while(size!=0) {
-+ size_t chunk_size=((size>BUFSIZ)? BUFSIZ:size) ;
-+ if(!duel_get_target_bytes(from,buf,chunk_size))
-+ duel_op_error("error reading memory (copy) in '%s'",op,v1,v2);
-+ if(!duel_put_target_bytes(to,buf,chunk_size))
-+ duel_op_error("error writing memory (copy) in '%s'",op,v1,v2);
-+ size-=chunk_size ;
-+ to+=chunk_size ;
-+ from+=chunk_size ;
-+ }
-+}
-+
-+/*
-+ * check that two values have "compatible" types.
-+ * since structs compiled in different modules are each unique,
-+ * we settle for comparing the number of references (array/ptr)
-+ * and then make sure the same type-kind is used, with the same
-+ * physical size.
-+ * this allows, e.g. struct {short x,y } and struct {int x}
-+ * to be considered equal. Possibly one could compare struct/union
-+ * for member sizes (but not names?!). this however requires to keep
-+ * track of self references and is not implemented here.
-+ */
-+
-+LPROC duel_check_type_eq(tvalue *v1,tvalue *v2,char *op)
-+{
-+ tctype *t1=v1->ctype, *t2=v2->ctype ;
-+ if(ctype_kind_ptr_like(t1) && ctype_kind_ptr_like(t2) && /*(void*) match*/
-+ (t1->u.kid==ctype_void || t2->u.kid==ctype_void)) return;
-+
-+ while(ctype_kind_ptr_like(t1) && ctype_kind_ptr_like(t2))
-+ t1=t1->u.kid, t2=t2->u.kid ;
-+ if(t1==t2) return ; /* exact same type */
-+ if(t1->type_kind != t2->type_kind || t1->size != t2->size)
-+ duel_op_error("incompatible types for op %s",op,v1,v2);
-+}
-+
-+
-+/**************************************************************************
-+ a set of mid-level functions follow. These actually apply duel/C
-+ operators to values
-+ **************************************************************************/
-+
-+/* these do pointer+int addition/subtraction of v1,v2 and store result in r.
-+ * NOTE: r's symbolic value is not set.
-+ */
-+
-+LPROC add_offset_to_ptr(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ size_t len ;
-+ get_pointer_val(v1,"x+y (ptr add)",FALSE);
-+ get_integral_val(v2,"y+x (ptr add)",NULL);
-+ r->val_kind=VK_RVALUE ;
-+ r->ctype=v1->ctype ;
-+ len=v1->ctype->u.kid->size ;
-+ if(len==0) duel_op_error("unknown pointer object size for '+' op",0,v1,0);
-+ switch(v2->ctype->type_kind) {
-+ case CTK_INT: r->u.rval_ptr =v1->u.rval_ptr +len*v2->u.rval_int ;break ;
-+ case CTK_UINT: r->u.rval_ptr =v1->u.rval_ptr +len*v2->u.rval_uint ;break ;
-+ case CTK_LONG: r->u.rval_ptr =v1->u.rval_ptr +len*v2->u.rval_long ;break ;
-+ case CTK_ULONG: r->u.rval_ptr =v1->u.rval_ptr +len*v2->u.rval_ulong;break ;
-+ case CTK_LONGLONG: r->u.rval_ptr =v1->u.rval_ptr +len*v2->u.rval_longlong ;break ;
-+ case CTK_ULONGLONG: r->u.rval_ptr =v1->u.rval_ptr +len*v2->u.rval_ulonglong;break ;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+LPROC sub_offset_from_ptr(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ size_t len ;
-+ get_pointer_val(v1,"x-y (ptr sub)",FALSE);
-+ get_integral_val(v2,"y-x (ptr sub)",NULL);
-+ r->val_kind=VK_RVALUE ;
-+ r->ctype=v1->ctype ;
-+ len=v1->ctype->u.kid->size ;
-+ if(len==0) duel_op_error("unknown pointer object size for '-' op",0,v1,0);
-+ switch(v2->ctype->type_kind) {
-+ case CTK_INT: r->u.rval_ptr =v1->u.rval_ptr -len*v2->u.rval_int ;break ;
-+ case CTK_UINT: r->u.rval_ptr =v1->u.rval_ptr -len*v2->u.rval_uint ;break ;
-+ case CTK_LONG: r->u.rval_ptr =v1->u.rval_ptr -len*v2->u.rval_long ;break ;
-+ case CTK_ULONG: r->u.rval_ptr =v1->u.rval_ptr -len*v2->u.rval_ulong;break ;
-+ case CTK_LONGLONG: r->u.rval_ptr =v1->u.rval_ptr -len*v2->u.rval_longlong ;break ;
-+ case CTK_ULONGLONG: r->u.rval_ptr =v1->u.rval_ptr -len*v2->u.rval_ulonglong;break ;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+
-+/* do addition of v1,v2 and store result in r.
-+ * NOTE: v1, v2 are destroyed!
-+ */
-+LPROC do_op_add(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ tctype *t=find_numeric_result_type(v1,v2,r,"+");
-+ if(ctype_kind_ptr_like(v1->ctype)) {
-+ get_integral_val(v2,"pointer+x",NULL);
-+ add_offset_to_ptr(v1,v2,r);
-+ return ;
-+ }
-+ if(ctype_kind_ptr_like(v2->ctype)) {
-+ get_integral_val(v1,"x+pointer",NULL);
-+ add_offset_to_ptr(v2,v1,r);
-+ return ;
-+ }
-+ get_numeric_val(v1,"x+y",t);
-+ get_numeric_val(v2,"y+x",t);
-+ r->val_kind=VK_RVALUE ;
-+ r->ctype=t ;
-+ duel_set_symb_val(r,"%s+%s",v1,v2);
-+ switch(t->type_kind) {
-+ case CTK_INT: r->u.rval_int =v1->u.rval_int +v2->u.rval_int ;break ;
-+ case CTK_UINT: r->u.rval_uint =v1->u.rval_uint +v2->u.rval_uint ;break ;
-+ case CTK_LONG: r->u.rval_long =v1->u.rval_long +v2->u.rval_long ;break ;
-+ case CTK_ULONG: r->u.rval_ulong=v1->u.rval_ulong +v2->u.rval_ulong ;break ;
-+ case CTK_LONGLONG: r->u.rval_longlong =v1->u.rval_longlong +v2->u.rval_longlong ;break ;
-+ case CTK_ULONGLONG: r->u.rval_ulonglong=v1->u.rval_ulonglong +v2->u.rval_ulonglong ;break ;
-+ case CTK_FLOAT: r->u.rval_float=v1->u.rval_float +v2->u.rval_float ;break ;
-+ case CTK_DOUBLE:r->u.rval_double=v1->u.rval_double+v2->u.rval_double;break;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+/* do arithmeric subtraction of v1,v2 and store result in r.
-+ * v1 and v2 should be of numeric type to begin with.
-+ * NOTE: v1, v2 are destroyed!
-+ */
-+LPROC do_op_subtract(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ tctype *t=find_numeric_result_type(v1,v2,r,"-");
-+ if(ctype_kind_ptr_like(v1->ctype)) {
-+ if(ctype_kind_ptr_like(v2->ctype)) {
-+ long len ; /* length must be signed to allow signed p-q result*/
-+ get_pointer_val(v1,"x-y",FALSE);
-+ get_pointer_val(v2,"x-y",FALSE);
-+ duel_check_type_eq(v1,v2,"- (ptr)");
-+ /* should compare pointer types */
-+ len=v1->ctype->u.kid->size ;
-+ if(len<=0)
-+ duel_op_error("illegal object size for op %s","- (ptr)",v1,v2);
-+ r->ctype=ctype_ptrdiff_t ;
-+ r->u.rval_ptrdiff_t= (v1->u.rval_ptr - v2->u.rval_ptr)/len ;
-+ return ;
-+ }
-+ get_integral_val(v2,"pointer-x",NULL);
-+ sub_offset_from_ptr(v1,v2,r);
-+ return ;
-+ }
-+ get_numeric_val(v1,"x-y",t);
-+ get_numeric_val(v2,"y-x",t);
-+ switch(t->type_kind) {
-+ case CTK_INT: r->u.rval_int =v1->u.rval_int - v2->u.rval_int ;break;
-+ case CTK_UINT: r->u.rval_uint =v1->u.rval_uint - v2->u.rval_uint ;break;
-+ case CTK_LONG: r->u.rval_long =v1->u.rval_long - v2->u.rval_long ;break;
-+ case CTK_ULONG: r->u.rval_ulong=v1->u.rval_ulong - v2->u.rval_ulong ;break;
-+ case CTK_LONGLONG: r->u.rval_longlong =v1->u.rval_longlong - v2->u.rval_longlong ;break;
-+ case CTK_ULONGLONG: r->u.rval_ulonglong=v1->u.rval_ulonglong - v2->u.rval_ulonglong ;break;
-+ case CTK_FLOAT: r->u.rval_float=v1->u.rval_float - v2->u.rval_float ;break;
-+ case CTK_DOUBLE:r->u.rval_double=v1->u.rval_double-v2->u.rval_double;break;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+/* compare values of v1 and v2, knowing that at least one is a frame-value
-+ * type. Allows two fvals to be compared, or an fval to be compared
-+ * to a func (this compares the func at the frame to the given func)
-+ */
-+
-+LFUNC bool comp_bin_op_eq_fvals(tvalue *v1,tvalue *v2)
-+{
-+ bool v1f=v1->val_kind == VK_FVALUE ;
-+ bool v2f=v2->val_kind == VK_FVALUE ;
-+ int frame_no ;
-+ ttarget_ptr frame_func,p ;
-+ if(v1f && v2f) return v1->u.fvalue == v2->u.fvalue ; /*cmp frames */
-+ if(v1f) {
-+ frame_no = v1->u.fvalue ;
-+ get_pointer_val(v2,"frame==x",FALSE) ;
-+ if(v2->ctype->u.kid->type_kind!=CTK_FUNC)
-+ duel_op_error("operand x of 'frame=x' not a func pointer",0,v2,0);
-+ p=v2->u.rval_ptr ;
-+ }
-+ else {
-+ frame_no = v2->u.fvalue ;
-+ get_pointer_val(v1,"x==frame",FALSE) ;
-+ if(v1->ctype->u.kid->type_kind!=CTK_FUNC)
-+ duel_op_error("operand x of 'x==frame' not a func pointer",0,v1,0);
-+ p=v1->u.rval_ptr ;
-+ }
-+ frame_func = duel_get_function_for_frame(frame_no);
-+ return frame_func == p ;
-+}
-+
-+
-+/* compares of v1,v2 and store result in r.
-+ * v1 and v2 should be of numeric/pointer type to begin with.
-+ * NOTE: v1, v2 are destroyed!
-+ */
-+
-+LPROC do_op_eq(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ tctype *t=find_numeric_result_type(v1,v2,r,"==");
-+ r->ctype=ctype_int ;
-+ if(v1->val_kind==VK_FVALUE || v2->val_kind==VK_FVALUE) {
-+ r->u.rval_int = comp_bin_op_eq_fvals(v1,v2);
-+ return ;
-+ }
-+ if(ctype_kind_ptr_like(v1->ctype) || ctype_kind_ptr_like(v2->ctype)) {
-+ get_pointer_val(v1,"x==y",TRUE);
-+ get_pointer_val(v2,"y==x",TRUE);
-+ duel_check_type_eq(v1,v2,"==");
-+ r->u.rval_int = v1->u.rval_ptr == v2->u.rval_ptr ;
-+ return ;
-+ }
-+ get_numeric_val(v1,"x==y",t);
-+ get_numeric_val(v2,"y==x",t);
-+ switch(t->type_kind) {
-+ case CTK_INT: r->u.rval_int=v1->u.rval_int == v2->u.rval_int ;break;
-+ case CTK_UINT: r->u.rval_int=v1->u.rval_uint == v2->u.rval_uint ;break;
-+ case CTK_LONG: r->u.rval_int=v1->u.rval_long == v2->u.rval_long ;break;
-+ case CTK_ULONG: r->u.rval_int=v1->u.rval_ulong == v2->u.rval_ulong ;break;
-+ case CTK_LONGLONG: r->u.rval_int=v1->u.rval_longlong == v2->u.rval_longlong ;break;
-+ case CTK_ULONGLONG: r->u.rval_int=v1->u.rval_ulonglong == v2->u.rval_ulonglong ;break;
-+ case CTK_FLOAT: r->u.rval_int=v1->u.rval_float == v2->u.rval_float ;break;
-+ case CTK_DOUBLE:r->u.rval_int=v1->u.rval_double == v2->u.rval_double;break;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+
-+/* compares of v1,v2 and store result in r.
-+ * v1 and v2 should be of numeric/pointer type to begin with.
-+ * NOTE: v1, v2 are destroyed!
-+ */
-+#define mk_func_compare(func,op,sop,xysop,yxsop,nullok) \
-+LPROC func(tvalue *v1,tvalue *v2,tvalue *r) \
-+{ \
-+ tctype *t=find_numeric_result_type(v1,v2,r,sop); \
-+ r->ctype=ctype_int ; \
-+ \
-+ if(ctype_kind_ptr_like(v1->ctype) || ctype_kind_ptr_like(v2->ctype)) { \
-+ get_pointer_val(v1,xysop,nullok); \
-+ get_pointer_val(v2,yxsop,nullok); \
-+ duel_check_type_eq(v1,v2,sop); \
-+ r->u.rval_int = v1->u.rval_ptr op v2->u.rval_ptr ; \
-+ return ; \
-+ } \
-+ get_numeric_val(v1,xysop,t); \
-+ get_numeric_val(v2,yxsop,t); \
-+ switch(t->type_kind) { \
-+ case CTK_INT: r->u.rval_int=v1->u.rval_int op v2->u.rval_int ;break;\
-+ case CTK_UINT: r->u.rval_int=v1->u.rval_uint op v2->u.rval_uint ;break;\
-+ case CTK_LONG: r->u.rval_int=v1->u.rval_long op v2->u.rval_long ;break;\
-+ case CTK_ULONG: r->u.rval_int=v1->u.rval_ulong op v2->u.rval_ulong ;break;\
-+ case CTK_LONGLONG: r->u.rval_int=v1->u.rval_longlong op v2->u.rval_longlong ;break;\
-+ case CTK_ULONGLONG: r->u.rval_int=v1->u.rval_ulonglong op v2->u.rval_ulonglong ;break;\
-+ case CTK_FLOAT: r->u.rval_int=v1->u.rval_float op v2->u.rval_float ;break;\
-+ case CTK_DOUBLE:r->u.rval_int=v1->u.rval_double op v2->u.rval_double;break;\
-+ default: duel_assert(0); \
-+ } \
-+}
-+
-+mk_func_compare(do_op_ne,!=,"!=","x!=y","y!=x",TRUE)
-+mk_func_compare(do_op_ge,>=,">=","x>=y","y>=x",FALSE)
-+mk_func_compare(do_op_le,<=,"<=","x<=y","y<=x",FALSE)
-+mk_func_compare(do_op_ls,<, "<", "x<y", "y<x",FALSE)
-+mk_func_compare(do_op_gt,>, ">", "x>y", "y>x",FALSE)
-+#undef mk_func_compare
-+
-+
-+/* do_compare_questionmark -- handle the <? >? etc ops */
-+
-+LFUNC bool do_compare_questionmark(topcode op,tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ tvalue tmp ;
-+ tmp= *v1 ;
-+ switch(op) {
-+ case OP_EQQ: do_op_eq(v1,v2,r); break ;
-+ case OP_NEQ: do_op_ne(v1,v2,r); break ;
-+ case OP_GEQ: do_op_ge(v1,v2,r); break ;
-+ case OP_LEQ: do_op_le(v1,v2,r); break ;
-+ case OP_LSQ: do_op_ls(v1,v2,r); break ;
-+ case OP_GTQ: do_op_gt(v1,v2,r); break ;
-+ }
-+ if(r->u.rval_int==0) return FALSE ;
-+ *r=tmp ;
-+ return TRUE ;
-+}
-+
-+
-+
-+/* apply indirection of a pointer.
-+ * this is easy, you just force the value to be an rvalue pointer, then
-+ * make it into an lvalue with the pointed-to type.
-+ * useful for (*x x[y] x->y etc)
-+ * does not setup a symbolic value!
-+ */
-+
-+
-+LPROC follow_pointer(tvalue *v,char *op,bool nonull)
-+{
-+ get_pointer_val(v,op,FALSE);
-+ if(nonull && v->u.rval_ptr == NULL)
-+ duel_op_error("dereference NULL pointer x in '%s'",op,v,0);
-+ v->val_kind=VK_LVALUE ;
-+ v->u.lvalue=v->u.rval_ptr ;
-+ v->ctype=v->ctype->u.kid ;
-+}
-+
-+PROC duel_get_struct_val(tvalue *v,char *op)
-+{
-+ if(!ctype_kind_struct_like(v->ctype))
-+ duel_op_error("operand x of '%s' not a sturct/union",op,v,0);
-+ duel_assert(v->val_kind==VK_LVALUE);
-+}
-+
-+PROC duel_get_struct_ptr_val(tvalue *v,char *op)
-+{
-+ follow_pointer(v,op,FALSE);
-+ if(!ctype_kind_struct_like(v->ctype))
-+ duel_op_error("operand x of '%s' not a pointer to sturct/union",op,v,0);
-+}
-+
-+FUNC int duel_get_posint_val(tvalue *v,char *op)
-+{
-+ int x ;
-+ x=duel_get_int_val(v,op);
-+ if(x<0) duel_op_error("operand x of '%s' can not be negative",op,v,0);
-+ return x ;
-+}
-+
-+/* indirection operator (*x) */
-+
-+LPROC do_op_indirection(tvalue *v)
-+{
-+ follow_pointer(v,"*x",TRUE);
-+ duel_set_symb_val(v,"*%s",v,0);
-+}
-+
-+/* address operator (&x)
-+ * x must be an lvalue. it is converted into a pointer to the given type,
-+ * an rvalue.
-+ */
-+
-+LPROC do_op_address(tvalue *v)
-+{
-+ if(v->val_kind != VK_LVALUE)
-+ duel_op_error("operand x of '&x' is not a lvalue",0,v,0);
-+ v->val_kind=VK_RVALUE ;
-+ v->u.rval_ptr=v->u.lvalue ;
-+ v->ctype=duel_mkctype_ptr(v->ctype);
-+ duel_set_symb_val(v,"&%s",v,0);
-+}
-+
-+LPROC do_op_index(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ get_pointer_val(v1,"x[y]",FALSE);
-+ get_integral_val(v2,"y[x]",NULL);
-+ add_offset_to_ptr(v1,v2,r);
-+ follow_pointer(r,"[]",TRUE);
-+ duel_set_symb_val(r,"%s[%s]",v1,v2);
-+}
-+
-+
-+/* do arithmeric multiply of v1,v2 and store result in r.
-+ * NOTE: v1, v2 are destroyed!
-+ */
-+LPROC do_op_multiply(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ tctype *t=find_numeric_result_type(v1,v2,r,"*");
-+ get_numeric_val(v1,"x*y",t);
-+ get_numeric_val(v2,"y*x",t);
-+ r->val_kind=VK_RVALUE ;
-+ r->ctype=t ;
-+ duel_set_symb_val(r,"%s*%s",v1,v2);
-+ switch(t->type_kind) {
-+ case CTK_INT: r->u.rval_int =v1->u.rval_int * v2->u.rval_int ;break;
-+ case CTK_UINT: r->u.rval_uint =v1->u.rval_uint * v2->u.rval_uint ;break;
-+ case CTK_LONG: r->u.rval_long =v1->u.rval_long * v2->u.rval_long ;break;
-+ case CTK_ULONG: r->u.rval_ulong =v1->u.rval_ulong * v2->u.rval_ulong;break;
-+ case CTK_LONGLONG: r->u.rval_longlong =v1->u.rval_longlong * v2->u.rval_longlong ;break;
-+ case CTK_ULONGLONG: r->u.rval_ulonglong =v1->u.rval_ulonglong * v2->u.rval_ulonglong;break;
-+ case CTK_FLOAT: r->u.rval_float =v1->u.rval_float * v2->u.rval_float;break;
-+ case CTK_DOUBLE:r->u.rval_double=v1->u.rval_double*v2->u.rval_double;break;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+/* do numeric divide of v1,v2 and store result in r.
-+ * v1 and v2 should be of numeric type to begin with.
-+ * NOTE: v1, v2 are destroyed!
-+ */
-+LPROC do_op_divide(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ tctype *t=find_numeric_result_type(v1,v2,r,"/");
-+ get_numeric_val(v1,"x/y",t);
-+ get_numeric_val(v2,"y/x",t);
-+ switch(t->type_kind) {
-+ case CTK_INT: if(v2->u.rval_int==0) goto div_err;
-+ r->u.rval_int =v1->u.rval_int / v2->u.rval_int ;break;
-+ case CTK_UINT: if(v2->u.rval_uint==0) goto div_err;
-+ r->u.rval_uint =v1->u.rval_uint / v2->u.rval_uint ;break;
-+ case CTK_LONG: if(v2->u.rval_long==0) goto div_err;
-+ r->u.rval_long =v1->u.rval_long / v2->u.rval_long ;break;
-+ case CTK_ULONG: if(v2->u.rval_ulong==0) goto div_err;
-+ r->u.rval_ulong =v1->u.rval_ulong/ v2->u.rval_ulong ;break;
-+ case CTK_LONGLONG: if(v2->u.rval_longlong==0) goto div_err;
-+ r->u.rval_longlong =v1->u.rval_longlong / v2->u.rval_longlong ;break;
-+ case CTK_ULONGLONG: if(v2->u.rval_ulonglong==0) goto div_err;
-+ r->u.rval_ulonglong =v1->u.rval_ulonglong/ v2->u.rval_ulonglong ;break;
-+ case CTK_FLOAT: if(v2->u.rval_float==0.0) goto div_err;
-+ r->u.rval_float =v1->u.rval_float/ v2->u.rval_float ;break;
-+ case CTK_DOUBLE:if(v2->u.rval_double==0.0) goto div_err;
-+ r->u.rval_double=v1->u.rval_double/v2->u.rval_double;break;
-+ default: duel_assert(0);
-+ }
-+ return ;
-+div_err: duel_op_error("division by zero",0,v1,v2);
-+}
-+
-+
-+/* do arithmeric reminder of v1,v2 and store result in r.
-+ * NOTE: v1, v2 are destroyed!
-+ */
-+LPROC do_op_reminder(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ tctype *t=find_numeric_result_type(v1,v2,r,"%");
-+ get_integral_val(v1,"x%y",t);
-+ get_integral_val(v2,"y%x",t);
-+ switch(t->type_kind) {
-+ case CTK_INT: if(v2->u.rval_int==0) goto div_err;
-+ r->u.rval_int = v1->u.rval_int % v2->u.rval_int ; break ;
-+ case CTK_UINT: if(v2->u.rval_uint==0) goto div_err;
-+ r->u.rval_uint = v1->u.rval_uint % v2->u.rval_uint ; break ;
-+ case CTK_LONG: if(v2->u.rval_long==0) goto div_err;
-+ r->u.rval_long = v1->u.rval_long % v2->u.rval_long ; break ;
-+ case CTK_ULONG: if(v2->u.rval_ulong==0) goto div_err;
-+ r->u.rval_ulong = v1->u.rval_ulong % v2->u.rval_ulong ; break ;
-+ case CTK_LONGLONG: if(v2->u.rval_longlong==0) goto div_err;
-+ r->u.rval_longlong = v1->u.rval_longlong % v2->u.rval_longlong ; break ;
-+ case CTK_ULONGLONG: if(v2->u.rval_ulonglong==0) goto div_err;
-+ r->u.rval_ulonglong = v1->u.rval_ulonglong % v2->u.rval_ulonglong ; break ;
-+ default: duel_assert(0);
-+ }
-+ return ;
-+div_err: duel_op_error("reminder modulo zero",0,v1,v2);
-+}
-+
-+/* do arithmeric or (bitwise) of v1,v2 and store result in r.
-+ * NOTE: v1, v2 are destroyed!
-+ */
-+LPROC do_op_or(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ tctype *t=find_numeric_result_type(v1,v2,r,"|");
-+ get_integral_val(v1,"x|y",t);
-+ get_integral_val(v2,"y|x",t);
-+ switch(t->type_kind) {
-+ case CTK_INT: r->u.rval_int = v1->u.rval_int | v2->u.rval_int ; break;
-+ case CTK_UINT: r->u.rval_uint = v1->u.rval_uint | v2->u.rval_uint ; break;
-+ case CTK_LONG: r->u.rval_long = v1->u.rval_long | v2->u.rval_long ; break;
-+ case CTK_ULONG:r->u.rval_ulong= v1->u.rval_ulong | v2->u.rval_ulong; break;
-+ case CTK_LONGLONG: r->u.rval_longlong = v1->u.rval_longlong | v2->u.rval_longlong ; break;
-+ case CTK_ULONGLONG:r->u.rval_ulonglong= v1->u.rval_ulonglong | v2->u.rval_ulonglong; break;
-+ default: duel_assert(0);
-+ }
-+ return ;
-+}
-+
-+/* do arithmeric and (bitwise) of v1,v2 and store result in r.
-+ * NOTE: v1, v2 are destroyed!
-+ */
-+LPROC do_op_and(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ tctype *t=find_numeric_result_type(v1,v2,r,"&");
-+ get_integral_val(v1,"x&y",t);
-+ get_integral_val(v2,"y&x",t);
-+ switch(t->type_kind) {
-+ case CTK_INT: r->u.rval_int = v1->u.rval_int & v2->u.rval_int ; break;
-+ case CTK_UINT: r->u.rval_uint = v1->u.rval_uint & v2->u.rval_uint ; break;
-+ case CTK_LONG: r->u.rval_long = v1->u.rval_long & v2->u.rval_long ; break;
-+ case CTK_ULONG:r->u.rval_ulong= v1->u.rval_ulong & v2->u.rval_ulong; break;
-+ case CTK_LONGLONG: r->u.rval_longlong = v1->u.rval_longlong & v2->u.rval_longlong ; break;
-+ case CTK_ULONGLONG:r->u.rval_ulonglong= v1->u.rval_ulonglong & v2->u.rval_ulonglong; break;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+/* do arithmeric xor (bitwise) of v1,v2 and store result in r.
-+ * NOTE: v1, v2 are destroyed!
-+ */
-+LPROC do_op_xor(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+
-+ tctype *t=find_numeric_result_type(v1,v2,r,"^");
-+ get_integral_val(v1,"x^y",t);
-+ get_integral_val(v2,"y^x",t);
-+ switch(t->type_kind) {
-+ case CTK_INT: r->u.rval_int = v1->u.rval_int ^ v2->u.rval_int ; break ;
-+ case CTK_UINT: r->u.rval_uint = v1->u.rval_uint ^ v2->u.rval_uint ; break ;
-+ case CTK_LONG: r->u.rval_long = v1->u.rval_long ^ v2->u.rval_long ; break ;
-+ case CTK_ULONG:r->u.rval_ulong= v1->u.rval_ulong^ v2->u.rval_ulong; break ;
-+ case CTK_LONGLONG: r->u.rval_longlong = v1->u.rval_longlong ^ v2->u.rval_longlong ; break ;
-+ case CTK_ULONGLONG:r->u.rval_ulonglong= v1->u.rval_ulonglong ^ v2->u.rval_ulonglong; break ;
-+ default: duel_assert(0);
-+ }
-+ return ;
-+}
-+
-+/* do arithmeric leftshift of v1,v2 and store result in r.
-+ * v1 and v2 should be of numeric type to begin with.
-+ * NOTE: v1, v2 are destroyed!
-+ */
-+LPROC do_op_leftshift(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ int by;
-+ get_integral_val(v1,"x<<y",NULL);
-+ by=duel_get_int_val(v2,"y<<x");
-+ r->val_kind=VK_RVALUE ;
-+ r->ctype=v1->ctype ;
-+ duel_set_symb_val(r,"%s<<%s",v1,v2);
-+ switch(v1->ctype->type_kind) {
-+ case CTK_INT: r->u.rval_int = v1->u.rval_int << by ; break ;
-+ case CTK_UINT: r->u.rval_uint = v1->u.rval_uint << by ; break ;
-+ case CTK_LONG: r->u.rval_long = v1->u.rval_long << by ; break ;
-+ case CTK_ULONG: r->u.rval_ulong = v1->u.rval_ulong << by ; break ;
-+ case CTK_LONGLONG: r->u.rval_longlong = v1->u.rval_longlong << by ; break ;
-+ case CTK_ULONGLONG: r->u.rval_ulonglong = v1->u.rval_ulonglong << by ; break ;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+/* do arithmeric rightshift of v1,v2 and store result in r.
-+ * v1 and v2 should be of numeric type to begin with.
-+ * NOTE: v1, v2 are destroyed!
-+ */
-+LPROC do_op_rightshift(tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ int by ;
-+ get_integral_val(v1,"x>>y",NULL);
-+ by=duel_get_int_val(v2,"y>>x");
-+ r->val_kind=VK_RVALUE ;
-+ r->ctype=v1->ctype ;
-+ duel_set_symb_val(r,"%s>>%s",v1,v2);
-+ switch(v1->ctype->type_kind) {
-+ case CTK_INT: r->u.rval_int = v1->u.rval_int >> by ; break ;
-+ case CTK_UINT: r->u.rval_uint = v1->u.rval_uint >> by ; break ;
-+ case CTK_LONG: r->u.rval_long = v1->u.rval_long >> by ; break ;
-+ case CTK_ULONG: r->u.rval_ulong = v1->u.rval_ulong >> by ; break ;
-+ case CTK_LONGLONG: r->u.rval_longlong = v1->u.rval_longlong >> by ; break ;
-+ case CTK_ULONGLONG: r->u.rval_ulonglong = v1->u.rval_ulonglong >> by ; break ;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+/* do arithmeric not of v (!v) */
-+LPROC do_op_not(tvalue *v)
-+{
-+ get_scalar_val(v,"!x");
-+ duel_set_symb_val(v,"!%s",v,0);
-+ switch(v->ctype->type_kind) {
-+ case CTK_PTR: v->u.rval_int = ! v->u.rval_ptr ; break ;
-+ case CTK_INT: v->u.rval_int = ! v->u.rval_int ; break ;
-+ case CTK_UINT: v->u.rval_int = ! v->u.rval_uint ; break ;
-+ case CTK_LONG: v->u.rval_int = ! v->u.rval_long ; break ;
-+ case CTK_ULONG: v->u.rval_int = ! v->u.rval_ulong ; break ;
-+ case CTK_LONGLONG: v->u.rval_int = ! v->u.rval_longlong ; break ;
-+ case CTK_ULONGLONG: v->u.rval_int = ! v->u.rval_ulonglong ; break ;
-+ case CTK_FLOAT: v->u.rval_int = ! v->u.rval_float ; break ;
-+ case CTK_DOUBLE: v->u.rval_int = ! v->u.rval_double ; break ;
-+ default: duel_assert(0);
-+ }
-+ v->ctype=ctype_int ; /* always returns an int */
-+}
-+
-+/* do bit-complement of v (~v) */
-+LPROC do_op_complement(tvalue *v)
-+{
-+ get_integral_val(v,"~x",NULL);
-+ duel_set_symb_val(v,"~%s",v,0);
-+ switch(v->ctype->type_kind) {
-+ case CTK_INT: v->u.rval_int = ~ v->u.rval_int ; break ;
-+ case CTK_UINT: v->u.rval_uint = ~ v->u.rval_uint ; break ;
-+ case CTK_LONG: v->u.rval_long = ~ v->u.rval_long ; break ;
-+ case CTK_ULONG: v->u.rval_ulong = ~ v->u.rval_ulong ; break ;
-+ case CTK_LONGLONG: v->u.rval_longlong = ~ v->u.rval_longlong ; break ;
-+ case CTK_ULONGLONG: v->u.rval_ulonglong = ~ v->u.rval_ulonglong ; break ;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+ /* do arithmeric minus of v (-v) */
-+LPROC do_op_minus(tvalue *v)
-+{
-+ get_numeric_val(v,"-x",NULL);
-+ duel_set_symb_val(v,"-%s",v,0);
-+ switch(v->ctype->type_kind) {
-+ case CTK_INT: v->u.rval_int = - v->u.rval_int ; break ;
-+ case CTK_UINT: v->u.rval_uint = - v->u.rval_uint ; break ;
-+ case CTK_LONG: v->u.rval_long = - v->u.rval_long ; break ;
-+ case CTK_ULONG: v->u.rval_ulong = - v->u.rval_ulong ; break ;
-+ case CTK_LONGLONG: v->u.rval_longlong = - v->u.rval_longlong ; break ;
-+ case CTK_ULONGLONG: v->u.rval_ulonglong = - v->u.rval_ulonglong ; break ;
-+ case CTK_FLOAT: v->u.rval_float = - v->u.rval_float ; break ;
-+ case CTK_DOUBLE: v->u.rval_double= - v->u.rval_double ; break ;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+/* do sizeif(exp) - simply return the size of the exp's type */
-+LPROC do_op_sizeofexp(tvalue *v)
-+{
-+ v->val_kind=VK_RVALUE ;
-+ v->u.rval_size_t=v->ctype->size ;
-+ v->ctype=ctype_size_t ;
-+ duel_set_symb_val(v,"sizeof(%s)",v,0);
-+}
-+
-+LPROC do_op_assignment(tvalue *v1,tvalue *v2,tvalue *r,char *op)
-+{
-+ char xopy[10],yopx[10] ;
-+ sprintf(xopy,"x%sy",op);
-+ sprintf(yopx,"y%sx",op);
-+ if(v1->val_kind!=VK_LVALUE && v1->val_kind!=VK_BVALUE)
-+ duel_op_error("operand x is not an lvalue for operator '%s'",xopy,v1,0);
-+
-+ if(ctype_kind_struct_like(v1->ctype)) {
-+ duel_check_type_eq(v1,v2,xopy);
-+ copy_lvalues(v1,v2,xopy);
-+ *r= *v2 ; /* return the result as an lvalue. this means (x1=x2)=x3
-+ is legal for struct, unlike ansi-c. */
-+ return ;
-+ }
-+ if(ctype_kind_numeric(v1->ctype)) get_numeric_val(v2,yopx,v1->ctype);
-+ else
-+ if(v1->ctype->type_kind==CTK_PTR) {
-+ get_pointer_val(v2,yopx,TRUE);
-+ duel_check_type_eq(v1,v2,xopy);
-+ }
-+ else duel_op_error("bad operand x type for operator '%s'",xopy,v1,0);
-+ put_rvalue(v1,v2,xopy);
-+ *r= *v2 ;
-+}
-+
-+LPROC do_op_increment(tvalue *v,char *op,int inc,bool postfix)
-+{
-+ tvalue lvalue_v,oldv ;
-+ char s[80] ;
-+ if(v->val_kind!=VK_LVALUE)
-+ duel_op_error("operand of '%s' must be an lvalue",op,v,0);
-+ lvalue_v= *v ;
-+ if(v->ctype->type_kind==CTK_PTR) get_pointer_val(v,op,FALSE);
-+ else get_integral_val(v,op,0);
-+ oldv= *v ;
-+
-+ switch(v->ctype->type_kind) {
-+ case CTK_INT: v->u.rval_int += inc ; break ;
-+ case CTK_UINT: v->u.rval_uint += inc ; break ;
-+ case CTK_LONG: v->u.rval_long += inc ; break ;
-+ case CTK_ULONG: v->u.rval_ulong += inc ; break ;
-+ case CTK_LONGLONG: v->u.rval_longlong += inc ; break ;
-+ case CTK_ULONGLONG: v->u.rval_ulonglong += inc ; break ;
-+ case CTK_PTR: v->u.rval_ptr += inc*v->ctype->u.kid->size ; break;
-+ default: duel_assert(0);
-+ }
-+ convert_scalar_type(v,lvalue_v.ctype,op); /* back to the original type */
-+ put_rvalue(&lvalue_v,v,op);
-+ if(postfix) { /* if prefix, keep v and its sym val*/
-+ *v= oldv ;
-+ convert_scalar_type(v,lvalue_v.ctype,op); /* back to original type */
-+ sprintf(s,"%%s%s",op);
-+ duel_set_symb_val(v,s,v,0);
-+ }
-+}
-+
-+/* unary op 'frame(n)' converts int n to a "frame type" */
-+LPROC do_op_frame(tvalue *v)
-+{
-+ int f=duel_get_int_val(v,"frame(x)");
-+ if(f<0 || f>=duel_get_frames_number())
-+ duel_gen_error("Frame number too big",0);
-+ v->val_kind=VK_FVALUE ;
-+ v->ctype=ctype_int ;
-+ v->u.fvalue=f ;
-+ duel_set_symb_val(v,"frame(%s)",v,0);
-+}
-+
-+/* unary op '(x)'. this only add parenthesis to the symbolic value, if needed*/
-+
-+LPROC do_op_parenthesis(tvalue *v)
-+{
-+ char *s=v->symb_val ;
-+ int l=strlen(s);
-+ if(s[0]=='(' && s[l-1]==')') return ; /* val is (x) dont make it ((x)) */
-+ while(*s!=0 && (isalnum(*s) || *s=='_')) s++ ; /* find first non alnum*/
-+ if(*s==0) return ; /* no need for (x) if x is a name or constant number */
-+ duel_set_symb_val(v,"(%s)",v,0);
-+}
-+
-+/***********************************************************************
-+ High-level functions, major entries to this module, evaluate a node
-+ with a standard (single value) result
-+ ***********************************************************************/
-+
-+
-+/* standardize a paramater to a function call according to the standard rules.
-+ * we currently don't support union/struct paramater passing
-+ */
-+
-+PROC duel_standardize_func_parm(tvalue *p)
-+{
-+ /* convert paramater into "standard" function calling */
-+ if(ctype_kind_integral(p->ctype)) get_integral_val(p,"f()",NULL);
-+ else
-+ if(ctype_kind_numeric(p->ctype)) /* float, double to double */
-+ convert_scalar_type(p,ctype_double,"f()");
-+ else
-+ if(ctype_kind_ptr_like(p->ctype)) get_pointer_val(p,"f()",FALSE);
-+ else
-+ duel_op_error("unsupported paramater type",0,p,0);
-+}
-+
-+
-+/* given a function (or pointer), find the first (top-most) frame that
-+ * the function is active in, and return the FVALUE for it
-+ */
-+PROC duel_find_func_frame(tvalue *v,char *op)
-+{
-+ int i, frames_no=duel_get_frames_number();
-+ get_pointer_val(v,op,FALSE);
-+
-+ for(i=0 ; i<frames_no ; i++) {
-+ ttarget_ptr frame_func = duel_get_function_for_frame(i);
-+ if(frame_func==v->u.rval_ptr) {
-+ v->val_kind=VK_FVALUE ;
-+ v->ctype=ctype_int ;
-+ v->u.rval_int=i ;
-+ return ;
-+ }
-+ }
-+ duel_op_error("func x is not on the call stack for operator '%s'",op,v,0);
-+}
-+
-+
-+/* compute the n'th result of v1..v2 operator.
-+ * result is returned in r, returns false if there isnt an nth result
-+ * v1,v2 are converted to integer values (but can be used to call this
-+ * function again. errors are reported if they arenot integral.
-+ */
-+
-+FUNC bool duel_do_op_to(tvalue *v1,tvalue *v2,int n,tvalue *r)
-+{
-+ int a,b,inc,x ;
-+ char *p,*fmt ;
-+
-+ if(!v1) { a=0 ; b=duel_get_int_val(v2,"..x")-1 ; }
-+ else if(!v2) { a=duel_get_int_val(v1,"x.."); b=INT_MAX ; }
-+ else { a=duel_get_int_val(v1,"x..y"); b=duel_get_int_val(v2,"x..y"); }
-+ if(a<=b) inc=1 ;
-+ else inc= -1 ;
-+ x=a+n*inc ;
-+ if(inc>0 && x>b || inc<0 && x<b) return FALSE ;
-+
-+ r->val_kind=VK_RVALUE ;
-+ r->ctype=ctype_int ;
-+ r->u.rval_int=x ;
-+ if(v1) p=v1->symb_val ;
-+ else p=v2->symb_val ;
-+ if( *p=='0' && p[1]=='x' || p[1]=='X') fmt="0x%x" ;
-+ else if(*p=='0' && p[1]>='0' && p[1]<='7') fmt="0%o" ;
-+ else if(*p=='\'' && isascii(x) && isprint(x)) fmt="'%c'" ;
-+ else fmt="%d" ;
-+ sprintf(r->symb_val,fmt,x);
-+ return TRUE ;
-+}
-+
-+/* convert value to True/False and return it
-+ * in case of an illegal operand, indicateds the operator is (op)
-+ * main use: in operators '&&' '||' and 'if'
-+ */
-+
-+FUNC bool duel_mk_logical(tvalue *v,char *op)
-+{
-+ get_scalar_val(v,op); /* verify v is scalar */
-+ do_op_not(v); /* convert and force 0 or 1 */
-+ v->u.rval_int = !v->u.rval_int ;
-+ sprintf(v->symb_val,"%d",v->u.rval_int);
-+ return(v->u.rval_int);
-+}
-+
-+/* cast the value v into type t. */
-+
-+PROC duel_do_cast(tctype *tout,tvalue *v)
-+{
-+ tctype *t=v->ctype ;
-+ if(ctype_kind_scalar(t) && ctype_kind_scalar(tout)) {
-+ if(tout->type_kind==CTK_ARRAY)
-+ duel_gen_error("casting to an array type is illegal",0);
-+ else convert_scalar_type(v,tout,"(cast) x");
-+ }
-+ else duel_op_error("illegal type conversion in cast op",0,v,0);
-+}
-+
-+
-+/* apply unary oprand op to the given value. The original value is
-+ * destoryed (of course)
-+ */
-+
-+PROC duel_apply_unary_op(topcode op,tvalue *v)
-+{
-+ switch(op) {
-+ case '(': do_op_parenthesis(v); break ;
-+ case '{': duel_sprint_scalar_value(v->symb_val,v);break ;
-+ case '-': do_op_minus(v); break ;
-+ case '!': do_op_not(v); break ;
-+ case '*': do_op_indirection(v); break ;
-+ case '~': do_op_complement(v); break ;
-+ case '&': do_op_address(v); break ;
-+ case OP_SIZ: do_op_sizeofexp(v); break ;
-+ case OP_INC: do_op_increment(v,"++",1,FALSE); break ;
-+ case OP_DEC: do_op_increment(v,"--",-1,FALSE); break ;
-+ case OP_FRAME: do_op_frame(v); break ;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+PROC duel_apply_post_unary_op(topcode op,tvalue *v)
-+{
-+ switch(op) {
-+ case OP_INC: do_op_increment(v,"++",1,TRUE); break ;
-+ case OP_DEC: do_op_increment(v,"--",-1,TRUE); break ;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+
-+/* apply_bin_op -- apply the operator op to the values v1 v2 and return
-+ * the result in r. the bin op is a 'regular' one, like
-+ * '+', '*', etc. in the C language.
-+ * note: v1,v2 are destroyed
-+ * returns: true if a value has been produced, false otherwise.
-+ * (ops like '+' always return true. ops like '<=?' also return false)
-+ */
-+
-+FUNC bool duel_apply_bin_op(topcode op,tvalue *v1,tvalue *v2,tvalue *r)
-+{
-+ switch(op) {
-+ case '[': do_op_index(v1,v2,r); break ;
-+ case '+': do_op_add(v1,v2,r); break ;
-+ case '-': do_op_subtract(v1,v2,r); break ;
-+ case '*': do_op_multiply(v1,v2,r); break ;
-+ case '/': do_op_divide(v1,v2,r); break ;
-+ case '%': do_op_reminder(v1,v2,r); break ;
-+ case '|': do_op_or(v1,v2,r); break;
-+ case '&': do_op_and(v1,v2,r); break ;
-+ case '^': do_op_xor(v1,v2,r); break ;
-+ case OP_LSH: do_op_leftshift(v1,v2,r); break ;
-+ case OP_RSH: do_op_rightshift(v1,v2,r); break ;
-+ case OP_EQ: do_op_eq(v1,v2,r); break ;
-+ case OP_NE: do_op_ne(v1,v2,r); break ;
-+ case OP_GE: do_op_ge(v1,v2,r); break ;
-+ case OP_LE: do_op_le(v1,v2,r); break ;
-+ case '<': do_op_ls(v1,v2,r); break ;
-+ case '>': do_op_gt(v1,v2,r); break ;
-+ case OP_EQQ:
-+ case OP_NEQ:
-+ case OP_GEQ:
-+ case OP_LEQ:
-+ case OP_LSQ:
-+ case OP_GTQ: return do_compare_questionmark(op,v1,v2,r);
-+ case '=': do_op_assignment(v1,v2,r,"="); break ;
-+ default: duel_assert(0);
-+ }
-+ return TRUE ;
-+}
---- gdb/duel/global.h
-+++ gdb/duel/global.h
-@@ -0,0 +1,450 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* this include file contains global definitions for duel. All global info
-+ * is shared thru this single file.
-+ */
-+
-+/*
-+ * $Log: 10_all_gdb-6.6-duel.patch,v $
-+ * Revision 1.1 2008/04/06 23:59:05 vapier
-+ * initial 6.8 patchset based on last 6.7.1 patchset
-+ *
-+ * Revision 1.12 93/03/12 05:50:35 mg
-+ * uses tuint instead of uint, etc.
-+ *
-+ * Revision 1.11 93/02/27 06:03:26 mg
-+ * added HP9000 support by not defining uint etc
-+ * clean annoying enum {x,y,} warnings
-+ *
-+ * Revision 1.10 93/02/03 21:49:32 mg
-+ * support "signed char"
-+ *
-+ * Revision 1.9 93/01/12 21:52:11 mg
-+ * cleanup and set for release
-+ *
-+ * Revision 1.8 93/01/07 00:10:53 mg
-+ * macros for func ptr auto-convert
-+ *
-+ * Revision 1.7 93/01/03 07:30:23 mg
-+ * *** empty log message ***
-+ *
-+ * Revision 1.6 92/12/24 23:49:25 mg
-+ * *** empty log message ***
-+ *
-+ * Revision 1.5 92/10/19 15:07:58 mg
-+ * fvalue added (not ready yet), svalues dropped
-+ *
-+ * Revision 1.4 92/10/14 02:05:37 mg
-+ * misc
-+ *
-+ * Revision 1.3 92/09/16 11:11:54 mg
-+ * add builtin ctype_charptr
-+ *
-+ * Revision 1.2 92/09/15 05:47:49 mg
-+ * some ops added
-+ *
-+ */
-+
-+
-+/* The following definitions are common programming tricks that I use
-+ * in every program I write. I hope they are obvious. the FUNC/PROC
-+ * constants are useful mainly when editing (to find a function def.)
-+ * or when grep'ing on source files. DEF is set to "extern" by default,
-+ * allowing declaration and definition of globals in one source. only
-+ * duel.c should have #define DEF before including duel.h
-+ */
-+
-+#define FUNC
-+#define PROC void
-+#define LPROC static void
-+#define LFUNC static
-+
-+#ifndef DEF
-+#define DEF extern /* declare only, 'int x' become 'extern int x'*/
-+#endif
-+
-+/* use simpler names for unsigned types, very common,
-+ * too common, indeed, so I forced 't' as a prefix.
-+ */
-+
-+typedef unsigned int tuint ;
-+typedef unsigned char tuchar ;
-+typedef unsigned short tushort ;
-+typedef unsigned long tulong ;
-+typedef unsigned long long tulonglong ;
-+
-+typedef signed char tschar ; /* explicit signed char */
-+typedef int bool ; /* suppose to be just 0,1 */
-+#define FALSE 0
-+#define TRUE 1
-+
-+ /* these should be inline functions, they replace common lib func which
-+ * change from system to system.
-+ * duel_assert can be modified to call duel_fatal, so gdb itself isn't
-+ * aborted because on an internal duel error.
-+ */
-+
-+#define duel_assert(x) assert(x)
-+#define duel_bzero(x,y) memset(x,0,y)
-+#define duel_bcopy(x,y,s) memcpy(x,y,s)
-+
-+
-+
-+/*************
-+ Parsing: the expression is converted into a tree.
-+ Each node of this tree is of 'tnode' type.
-+ Nodes can be:
-+ An operator (like '+', or ':=' or 'for')
-+ A constant (numbers. Strings are pointers to space!)
-+ A symbol.
-+ A regular expression (really a symbol extention)
-+
-+ The evaluation of any node results in:
-+ 1. 'Environment': duel variables and their values
-+ 2. symbolic expression which describe the computation
-+ meaning: keep the parentethis. in the expression a<<(3+b) (even if not needed!)
-+ 3. A type & value
-+
-+ Values:
-+ Values are always a fixed length area of bytes; Any C type is like that.
-+**************/
-+
-+
-+/****** TYPES *******
-+ A type is described in the typical compiler's way, which is also gdb's
-+ way. That is, a type is made of 'atomic' types, like 'pointer to',
-+ 'array of', etc. Each atomic type is described by a 'ctype' node. Ctype
-+ node points to other ctype nodes as required. For example, a ctype node
-+ of 'array of' will point to the node 'int' for the 'C' type array of int.
-+ [The name ctype is used to indicate the C language type; 'type' is too
-+ generic a term]
-+ Example:
-+ char *(*f[])() ;
-+ Here, f is an array of pointers to functions returning a pointer to char.
-+ The type is described with the top node being of CTK_ARRAY type. It
-+ points to a 'CTK_PTR' node, which points to a 'CTK_FUNC' node which
-+ points to a 'CTK_PTR' node which points to a 'CTK_CHAR' node which has,
-+ as size, 1.
-+
-+ The size of a type is the number of bytes occupied by it. it is zero
-+ for types like 'function'. An array of 10 integers will have as size
-+ 10*sizeof(int)
-+
-+ A note on UCHAR vs CHAR vs SCHAR:
-+ Internally, duel supports all three forums (for aritmetic).
-+ For output, only "char" types are considered ASCII, and will be displayed
-+ as 'A' instead of "65", etc. The same is true for char[] and char*.
-+ GDB doesn't really support "signed char", but some compilers do;
-+ we convert "signed char" into just a "char" when the default char is signed.
-+ This is only significant for output.
-+ Maybe duel shouldn't support "char" at all, and force everything to be
-+ "schar" or "uchar". I'm not sure. I prefer "char" as a distinct type
-+ which implies "string" and uchar/schar as "integral".
-+ ********************/
-+
-+typedef enum { /* 'C' Type atomic primitive Kinds (CTK_) */
-+ CTK_VOID, /* void type 'void' */
-+ CTK_CHAR, /* primitive types */
-+ CTK_SCHAR, /* signed char (ansi c) */
-+ CTK_UCHAR, /* note order is used in some macros */
-+ CTK_SHORT,
-+ CTK_USHORT,
-+ CTK_INT,
-+ CTK_UINT,
-+ CTK_LONG,
-+ CTK_ULONG,
-+ CTK_LONGLONG,
-+ CTK_ULONGLONG,
-+ CTK_FLOAT,
-+ CTK_DOUBLE,
-+ CTK_PTR, /* pointer '*' */
-+ CTK_ARRAY, /* array '[]' */
-+ CTK_FUNC, /* a function '()' */
-+ CTK_STRUCT, /* a sturcture 'struct{}' */
-+ CTK_UNION, /* a union 'union{}' */
-+ CTK_ENUM /* enum type 'enum{}' */
-+ } tctype_kind ;
-+
-+typedef struct { /* a field (of struct) info */
-+ char *name ; /* field name */
-+ struct sctype *ctype ; /* field type */
-+ int bitpos, bitlen ; /* for bit fields only */
-+} tctype_field ;
-+
-+typedef struct { /* an enumerator (constant of an enum) info */
-+ char *name ; /* enumerator name */
-+ int val ; /* value assigned to the name */
-+ /* question: ansi-C say cosnt fit in int?*/
-+} tctype_enumerator ;
-+
-+
-+typedef struct sctype { /* a 'C' type description */
-+ tctype_kind type_kind ;
-+ char *name ; /* named of this type, if any */
-+ size_t size ; /* size (total bytes) for this type */
-+ union {
-+ struct sctype *kid ; /* pointer to next atomic type */
-+ struct {
-+ int fields_no ;
-+ tctype_field *fields ; /* union/struct fields */
-+ } f ;
-+ struct {
-+ tctype_kind real_type_kind ; /* the type used for storage of the enum */
-+ int enumerators_no ;
-+ tctype_enumerator *enumerators ; /* enum's type enumerators list */
-+ } e;
-+ } u ;
-+ } tctype ;
-+
-+
-+/**** BASIC C TYPES
-+ these are initialized at run type to point to the basic C types.
-+ basic types are never created again, e.g. pointer comparison with
-+ these is sufficient to check type equality.
-+ the voidptr is (void*) which is a basic type (what zero is converted
-+ to when it is a pointer).
-+ ptrdiff_t and size_t are actually pointing to their actualy types,
-+ ie. normally point to ctype_int.
-+ ****/
-+
-+DEF tctype *ctype_int, *ctype_uint, *ctype_short, *ctype_ushort,
-+ *ctype_char, *ctype_schar, *ctype_uchar,
-+ *ctype_long, *ctype_ulong, *ctype_longlong, *ctype_ulonglong,
-+ *ctype_float, *ctype_double,
-+ *ctype_void, *ctype_charptr,
-+ *ctype_voidptr,*ctype_ptrdiff_t,*ctype_size_t ;
-+
-+/* type checking macros */
-+
-+/** tell if type is a struct or union */
-+#define ctype_kind_struct_like(t) ((t)->type_kind==CTK_STRUCT || \
-+ (t)->type_kind==CTK_UNION)
-+
-+/** tell if type is a pointer or can be made one (array, func) */
-+#define ctype_kind_ptr_like(t) ((t)->type_kind==CTK_PTR || \
-+ (t)->type_kind==CTK_ARRAY || (t)->type_kind==CTK_FUNC)
-+/* tell if type is numeric */
-+#define ctype_kind_numeric(t) (((t)->type_kind>=CTK_CHAR && \
-+ (t)->type_kind<=CTK_DOUBLE) || (t)->type_kind==CTK_ENUM)
-+
-+/* tell if type is integral */
-+#define ctype_kind_integral(t) ((t)->type_kind>=CTK_CHAR && \
-+ (t)->type_kind<=CTK_ULONG || (t)->type_kind==CTK_ENUM)
-+
-+/* tell if type fits into fixed memory size (void not included) */
-+#define ctype_kind_scalar(t) (ctype_kind_numeric(t) || ctype_kind_ptr_like(t))
-+
-+/* tell if type is a "base" ie can't have kids */
-+
-+#define ctype_kind_base(t) ((t)->type_kind>=CTK_VOID && \
-+ (t)->type_kind<=CTK_DOUBLE)
-+
-+/* tell if a type is a function pointer or like a func ptr (ie a func!) */
-+#define ctype_kind_func_ptr_like(t) ((t)->type_kind==CTK_FUNC || \
-+ (t)->type_kind==CTK_PTR && t->u.kid->type_kind==CTK_FUNC)
-+
-+
-+/***** VALUES
-+ used to keep information when evaluating an expression. A value is
-+ either:
-+ 1) a right-value, which is represented in a fixed number of bytes that
-+ actually contain its value. Example: result of '+' operation.
-+ 2) a left-value. This is a reference to the actual value, which
-+ resides in the debuggee's address space.
-+ 3) a special-value. This contains a long value specifying a special
-+ target location (e.g. register) from which values can be fetched
-+ or written to. However, special-values can not be manipulated (i.e
-+ have an offset added to them, as done to an lvalue struct).
-+
-+ Note that the operation '*x' starts with x as an lvalue - a pointer to
-+ x is kept. Then, '*x' is executed, fetching the value of x and creating
-+ another lvalue, which points to where x has pointed to! This allows
-+ &*x to be executed, as well as *x=1 or &x[1] ...
-+ When the value of an lvalue is actually needed, it must be fetched
-+ from the debugge's space.
-+ *****/
-+
-+#define VALUE_MAX_CONST_SIZE 8
-+#define VALUE_MAX_SYMBOLIC_SIZE 128
-+
-+typedef long tptrsize_int ; /* type so that
-+ tptrsize x; char *p ;
-+ p == (char*) (tptrsize) p
-+ */
-+
-+ /* type that represent a target address space location. */
-+
-+typedef char* ttarget_ptr ; /* pointer to target's address */
-+
-+typedef struct {
-+ ttarget_ptr lvalue ; /* pointer to target's location of struct*/
-+ int bitpos,bitlen ; /* as specified in the field info of stuct*/
-+ } tbvalue_info ;
-+
-+typedef enum {
-+ VK_RVALUE, /* this value represent a constant, in the rval_ union */
-+ VK_LVALUE, /* this value represent a left-value. address in lvalue*/
-+ VK_BVALUE, /* a bit-field lvalue, given as point and bitpos/bitlen*/
-+ VK_FVALUE /* a frame, fvalue contains it number */
-+ } tval_kind ;
-+
-+typedef struct {
-+ tval_kind val_kind ;
-+ tctype *ctype ; /* type of this value */
-+ union {
-+ ttarget_ptr lvalue ; /* location in target of the value */
-+ tbvalue_info bvalue ; /* location in target of a bitfield */
-+ int fvalue ; /* a frame number (0 = top of stack) */
-+ char rval_char ;
-+ tschar rval_schar ;
-+ tuchar rval_uchar ;
-+ short rval_short ;
-+ tushort rval_ushort ;
-+ int rval_int ;
-+ tuint rval_uint ;
-+ long rval_long ;
-+ tulong rval_ulong ;
-+ long long rval_longlong ;
-+ tulonglong rval_ulonglong ;
-+ float rval_float ;
-+ double rval_double ;
-+ ttarget_ptr rval_ptr ;
-+ ptrdiff_t rval_ptrdiff_t ; /* Synonyms to one of the above fields! */
-+ size_t rval_size_t ; /* normally these are simply = rval_int */
-+ } u ;
-+ char symb_val[VALUE_MAX_SYMBOLIC_SIZE];
-+ } tvalue ;
-+
-+
-+typedef struct sval_lcell { /* a cell on a linked-list containing a tvalue*/
-+ tvalue val ;
-+ struct sval_lcell *next ;
-+ } tval_lcell ;
-+
-+typedef struct { /* a linked list of tvalue's */
-+ tval_lcell *head ;
-+ tval_lcell *tail ;
-+} tval_list ;
-+
-+/**** OP CODES ****
-+ Opcodes are divided into groups, or 'kinds'. For example, all the
-+ C regular unary operators, binary operators, etc.
-+ An opcode is defined by its 'kind' and actual value. The value is,
-+ in most cases, a single char. For example, the C plus operator is
-+ defined as op_kind=OPK_BIN and op='+'. The C operator '+=' is
-+ defined as op_kind=OPK_ASSIGN and op='+'.
-+ some operators are uniquely identified by type alone (e.g. func call).
-+ In the lexer there is a table of actual operators as tokens, and
-+ the kind & value assigned to each.
-+ Several opertors use more than one char, and are defined below.
-+ the OPK_SBIN, etc kinds are special in the sense that A op B isn't
-+ computed in the normal way of the C language (i.e. compute both sides,
-+ then apply the operator). Such operators include ',' '&&', etc.
-+ **********/
-+typedef enum {
-+ /* '+' '-' etc are used directly and have their ascii value */
-+ OP_LSH = 300, /* '<<' */
-+ OP_RSH = 301, /* '>>' */
-+ OP_INC = 302, /* '++' */
-+ OP_DEC = 303, /* '--' */
-+ OP_ARR = 304, /* '->' */
-+ OP_AND = 305, /* '&&' */
-+ OP_OR = 306, /* '||' */
-+ OP_EQ = 307, /* '==' */
-+ OP_GE = 308, /* '>=' */
-+ OP_LE = 309, /* '<=' */
-+ OP_NE = 310, /* '!=' */
-+ OP_SIZ = 311, /* 'sizeof' */
-+ OP_TO = 312, /* '..' */
-+ OP_EQQ = 313, /* '==?' */
-+ OP_NEQ = 314, /* '!=?' */
-+ OP_GEQ = 315, /* '>=?' */
-+ OP_LEQ = 316, /* '<=?' */
-+ OP_GTQ = 317, /* '>?' */
-+ OP_LSQ = 318, /* '<?' */
-+ OP_IMP = 319, /* '=>' */
-+ OP_IF = 320, /* if() */
-+ OP_DEF = 321, /* ':=' */
-+ OP_DFS = 322, /* '-->' */
-+ OP_BFS = 323, /* '->>' */
-+ OP_POS = 324, /* '>--' */
-+ OP_IOS = 325, /* '->-' */
-+ OP_SEL = 326, /*'x[[y]]'*/
-+ OP_FOR = 327, /*for(;;)'*/
-+ OP_WHILE= 328, /*while() */
-+ OP_DECL = 329, /* var decl*/
-+ OP_FRAME= 330 /* frame(i)*/
-+ } topcode ;
-+
-+/**** OPCODE KINDS ****/
-+
-+typedef enum { /* the kind of the opcode, 'OPK_' = OPcode Kind */
-+ OPK_UNARY =0, /* regular unary operator */
-+ OPK_SUNARY =1, /* special unary operator (sizeof) */
-+ OPK_POST_UNARY =2, /* post unary operator (x++ etc) */
-+ OPK_BIN =3, /* regular binary operator */
-+ OPK_SBIN =4, /* special binary operator */
-+ OPK_TRI =5, /* trinary (eg ?:) operator */
-+ OPK_QUAD =6, /* quad (e.g.for(;;)) operator */
-+ OPK_ASSIGN =7, /* assignment ie =, +=, -= etc */
-+ OPK_FUNC =8, /* function call. 2nd kid made of ',' kids for parms */
-+ OPK_CAST =9, /* type cast. 2nd kid convert to type in 1st kid */
-+ OPK_NUM_OF =10 /* number of OPK_* op kinds */
-+ } top_kind ;
-+
-+
-+/**** NODE KINDS ****/
-+
-+typedef enum { /* the kind of node */
-+ NK_OP, /* contain an operator */
-+ NK_CONST, /* contains a constant */
-+ NK_NAME, /* contains a name/symbol */
-+ NK_CTYPE /* contain a 'C' type */
-+ } tnode_kind ;
-+
-+#define NODE_MAX_KIDS 4 /* maximum no of kids per node */
-+#define NODE_MAX_SYM_LEN 50 /* maximum length for a symbol */
-+
-+/* the following structure is used to store one node of the expression tree.
-+ * It contains two parts: (a) information to describe the node and (b)
-+ * information used during the evaluation of the node.
-+ *
-+ * This structure could/should be optimized with ugly unions (e.g., for
-+ * a node describing a constant(node_kind==NK_CONST) there is no need for
-+ * the op, kids or any eval stuff!). However, only few nodes (less than 100?)
-+ * are expected to be in memory at any time (how complex can a user
-+ * expression be?). Hence, for clarity, no unions where used.
-+ *
-+ * All nodes have kids in the typical way. the opcode OPK_FUNC node is tricky:
-+ * see parsing - the commas are handled as operators and not as part of the
-+ * syntax. when a func call is evaluated, the top comma nodes are used to
-+ * separate the arguments (this hack prevents complex parsing and complex tnode
-+ * with variable num of kids, which would force the kids[] to be malloc etc.)
-+ */
-+
-+typedef struct snode { /* a single node on an expression tree */
-+ tnode_kind node_kind ; /* what kind of note this is */
-+ /* NK_OP node info: op_kind,op,kids */
-+ int src_pos ; /* starting source code location (op etc) */
-+ top_kind op_kind ; /* opcode type (unary,bin etc) */
-+ topcode op ; /* actual opcode: '-' for both unary&bin '-'*/
-+ struct snode *kids[NODE_MAX_KIDS] ; /* pointers to node's kids */
-+ tvalue cnst ; /* NK_CONST info - constant value */
-+ char *name ; /* NK_NAME info - variable name */
-+ tctype *ctype ; /* NK_CTYPE info - a type */
-+
-+ struct { /* information used during node evaluation */
-+ int level ; /* evaluation level (0=none, 1=left in x etc)*/
-+ tvalue v1,v2 ; /* keep last computed operands, etc */
-+ tval_list vlist ; /* value list for node (used in --> etc ops) */
-+ int counter ; /* used for counting */
-+ } eval ;
-+ } tnode ;
-+
-+
-+DEF bool duel_debug ; /* debugging duel-itself mode */
-+DEF bool duel_output_pipe_style ; /* pipe-style output of values */
-+
-+/* this things are machine dependent stuff */
-+
-+#define BITS_PER_BYTE 8 /* no of bits in (char) (right. try '9' :-) */
---- gdb/duel/internals.doc
-+++ gdb/duel/internals.doc
-@@ -0,0 +1,129 @@
-+DUEL 1.0x INTERNALS
-+This documents some of the basics internal info, and might help porting
-+duel. Incomplete and probably badly written. sorry.
-+
-+Entry points and modules
-+--------------------------
-+duel_eval_and_parse is entry point into duel, in duel.c
-+duel_parse in parse.y does all parsing
-+duel_eval in eval.c makes the evaluation
-+evalop.c contains low-level evaluation
-+misc.c contains misc stuff
-+types.c type create/manage
-+output.c all output goes thru duel_printf
-+output2.c same as output, but support sending eval output to a pipe,
-+ like the duel.pipe perl script.
-+print.c all output of values is done here
-+eval.c high level evaluation code (generators)
-+evalops.c low level evaluation code (operators)
-+error.c handle erros, display error info "nicely"
-+
-+start reading the code from duel.c, then global.h, then eval.c.
-+eval.c is hairy, especially the state-keeping code. The goto's are
-+intentional, they convey control better than other constructs.
-+
-+Types
-+------
-+A relatively straight-forward system, if you have read code of real C
-+compilers. A type is a "graph" with each node being a base type or
-+a composition of other types. see global.h and types.c
-+
-+Value system
-+-------------
-+also pretty simple, either an LVALUE, which have u.lvalue point to it,
-+or an RVALUE, so u.rval_type contains the actual value. There is also
-+a special BVALUE hack to hold lvalued bitfields, which is only useful
-+is someone implements modifying a bitfield. and there is an FVALUE, which
-+is just stored in u.rval_int but has the special value type (it was either
-+this or add a new TYPE, i preferred a new value).
-+Note the there is no "register" type support. You must read register variables
-+as rvalues (duelgdb.c does that). I don't think it is essential, since
-+gdb can be used directly to modify such values (this might be a
-+problem in watchpoint/cond.breaks however). Also cc -g don't usually keep
-+stuff in registers. We could add "SVALUE" for these.
-+Bitfields are a pain, but bvalue is really needed, eg for x[..100].bitfield=0
-+
-+Memory allocation
-+-----------------
-+go through duel_malloc/duel_free.
-+Memory is allocated only for (a) a new node, while parsing, (b) a value pushed
-+on stack for x-->y operator (c) duel aliases.
-+It is always safe to call duel_free_nodes which free everything except
-+for aliases.
-+Memory spill can occur in asynchronous interrupts (^C), but they at most
-+reflect items moved from one list to another. This isn't too bad.
-+
-+Interrupts
-+----------
-+Duel ignores the issues of interrupts, but is written so it can be
-+interrupted at any time. Naturally, some memory could be lost if an
-+operation is interrupted, since Duel does not setup critical sections.
-+However, interrupts will no result in bad internal structures, so it is
-+safe to call duel_free_nodes after an interrupt.
-+duelgdb.c implements exactly that - interrupts at all times, and cleanup
-+using duel_free_nodes.
-+
-+Parsing
-+--------
-+yacc is pretty weak, especially when I tried complex ops like x\y#z
-+(as a single, 3 val op!). I have up on such things and the syntax is
-+pretty clean. Things to watch for are the semicolon nonsense,
-+especially with optional-expressions (as in for(a;b;c);), the T hack
-+for user types (only fix is to delay decision on (x)(y) till runtime
-+or make clearer rules (consider something; (x)(y), do you parse x as a type
-+and ignore the possible x:=printf in "something", etc), and the use of ","
-+regular op and nodes for function parameters (the parser knows only about
-+a single parameter, an exp!).
-+
-+Search ops
-+-----------
-+Straight forward stacking in dfs_... in eval.c
-+Note things are put in reversed, so root-->(left,right) does what you
-+expect. Also linked-lists could be greatly optimized.
-+The functionality for ->> (BFS) is already in, all you need is to
-+make the stack into a queue by pushing from the other side (really append)
-+
-+Multi-expressions
-+--------------------
-+As far as I know, you could save root (in duel.h) and use it to evaluate
-+as often as needed (e.g for breakpoints/watchpoints), the internals
-+of the nodes hold all eval info. You must reset the expression
-+with eval_stop, if u dont eval it to the last value. Also make sure you
-+cleanup the dot stack. Aliases (in misc.c) could become scoped, of course.
-+
-+Interface to the debugger
-+-------------------------
-+
-+What DUEL needs:
-+1. A way to access the symbol table for variable names, types, etc.
-+2. A way to access the value of a variable, both for read and writes.
-+3. A way to call debuggee functions.
-+4. A way to get locals of frame n
-+5. misc functions, eg memory alloc, entery/exit code
-+
-+In practice, you will probably take duelgdb.c and modify it until you
-+get the "right thing" for your debugger.
-+NOTE: duelgdb.c was written from scratch and has *no* GNU code in it.
-+
-+The most complex issue is types - you must pass names in a tvalue,
-+which include a tctype (the C reminds one of a "C" type, not just 'type'
-+which is ambiguous). The code to convert gdb types into duel types is
-+typical. Watch out for recursive struct pointers (the hash table handles
-+these problems), and for partial types, e.g. pointer to struct which
-+contains no fields (size zero!).
-+
-+You can return a BVALUE an LVALUE (preferred) or an RVALUE for a name
-+lookup. use RVALUE for names found in registers, and return the actual
-+value.
-+
-+if a frame number is given for symbol lookup, only local variables
-+allocated in that frame should be returned. (else return none. don't
-+return a global if it exist with the same name, this will make the dot
-+stack compute things wrong).
-+
-+Node that this doesnt help with scoping problems (for duel)- e.g.
-+you can't do myfunc.x if x is a static variable in myfunc. There needs to
-+be a more complex & general way in the language to specify this (i.e.
-+specify a source location in which the variable is visible, AND a frame
-+to use if the value is kept on a frame) frame(n).(scope(file,line).x)?
-+
---- gdb/duel/misc.c
-+++ gdb/duel/misc.c
-@@ -0,0 +1,142 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* misc function/library-like */
-+
-+/*
-+ * $Log: 10_all_gdb-6.6-duel.patch,v $
-+ * Revision 1.1 2008/04/06 23:59:05 vapier
-+ * initial 6.8 patchset based on last 6.7.1 patchset
-+ *
-+ * Revision 1.5 93/03/12 05:51:00 mg
-+ * support output redirection
-+ *
-+ * Revision 1.4 93/01/13 16:22:09 mg
-+ * allow malloc to return int (is a mini symbol on SUN)
-+ *
-+ * Revision 1.3 93/01/12 21:52:43 mg
-+ * moved aliases mgmt here
-+ * cleanup and set for release
-+ *
-+ */
-+
-+#include "duel.h"
-+
-+/* like strncpy, but put a zero at to[len] anyway.
-+ * are copied (hence taking len+1 bytes
-+ */
-+
-+FUNC char* strncpyz(char *to,char *from,size_t len)
-+{
-+ strncpy(to,from,len);
-+ to[len]=0 ;
-+ return to ;
-+}
-+
-+/* allocate n bytes in the target's space. Used for storing constant
-+ * strings when they are parsed, and for variables declaration
-+ * note: on SUN (and others?) gdb claims malloc to return an integer. we
-+ * accept this (silly but probably no harm done)
-+ */
-+
-+FUNC ttarget_ptr duel_alloc_target_space(size_t n)
-+{
-+ tvalue p,f,r,*parms[1] ;
-+
-+ p.val_kind=VK_RVALUE ; /* mk n into a value, to pass as parm */
-+ p.ctype=ctype_int ;
-+ p.u.rval_int=n ;
-+ parms[0]= &p ;
-+
-+ if(!duel_get_target_variable("malloc",-1,&f) ||
-+ f.ctype->type_kind!=CTK_FUNC ||
-+ f.ctype->u.kid->type_kind!=CTK_INT && f.ctype->u.kid->type_kind!=CTK_PTR)
-+ duel_fatal("malloc() function returning a pointer required in target");
-+
-+ duel_target_func_call(&f,parms,1,&r);
-+ if(r.u.rval_ptr==NULL) duel_fatal("target's malloc() failed");
-+ return r.u.rval_ptr ;
-+}
-+
-+PROC duel_free_val_list(tval_list *l) /*free a val list and mark list empty */
-+{
-+ tval_lcell *cell,*next ;
-+ for(cell=l->head ; cell!=NULL ; cell=next ) {
-+ next=cell->next ;
-+ duel_free(cell);
-+ }
-+ l->head=l->tail=NULL ;
-+}
-+
-+/* free all the memory allocated in the parse tree from node */
-+
-+PROC duel_free_nodes(tnode *n)
-+{
-+ int i;
-+ if(!n) return ;
-+ for(i=0 ; i<NODE_MAX_KIDS ; i++)
-+ duel_free_nodes(n->kids[i]);
-+ duel_free_val_list(&n->eval.vlist);
-+ duel_free(n);
-+}
-+
-+
-+
-+/* Aliases management */
-+
-+typedef struct sduel_var { /* an alias */
-+ char *name ;
-+ tvalue val ;
-+ struct sduel_var *next ;
-+ } tduel_var ;
-+tduel_var *duel_vars_head ;
-+
-+/* find the value of a duel variable, if exist (else return null */
-+
-+FUNC tvalue* duel_find_alias(char *name)
-+{
-+ tduel_var *p ;
-+ for(p=duel_vars_head ; p ; p=p->next) {
-+ if(strcmp(name,p->name)==0) return(&p->val);
-+ }
-+ return NULL ;
-+}
-+
-+/* set a value of a duel alias. Create var as needed */
-+
-+PROC duel_set_alias(char *name,tvalue *v)
-+{
-+ tduel_var *p ;
-+ tvalue *found = duel_find_alias(name) ;
-+ if(found!=NULL) *found= *v ;
-+ else {
-+ p=duel_malloc(sizeof(tduel_var)) ;
-+ p->next=duel_vars_head ;
-+ p->val= *v ;
-+ p->name=name ;
-+ duel_vars_head=p ;
-+ }
-+}
-+
-+PROC duel_clear_aliases(void) /* clear all defined aliases */
-+{
-+ tduel_var *p=duel_vars_head ;
-+ while(p) {
-+ tduel_var *q=p ;
-+ p=p->next ;
-+ duel_free(q);
-+ }
-+ duel_vars_head=0 ;
-+}
-+
-+PROC duel_show_aliases(void)
-+{
-+ tduel_var *p ;
-+ if(!duel_vars_head) duel_printf("No aliases defined\n");
-+ else {
-+ duel_printf("Aliases table:\n");
-+ for(p=duel_vars_head ; p ; p=p->next) {
-+ duel_printf("%s: ",p->name);
-+ duel_print_value(&p->val);
-+ }
-+ }
-+}
---- gdb/duel/output.c
-+++ gdb/duel/output.c
-@@ -0,0 +1,53 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* This module supports i/o for duel. Normally output goes to stdout,
-+ * but it could be piped out instead.
-+ * this module support minimal duel output w/o pipes. output2.c which
-+ * support piped i/o is still an alpha version.
-+ */
-+
-+#include <stdarg.h> /* for duel_printf */
-+#include "duel.h"
-+
-+/* output functions:
-+ * duel_printf all duel output goes thru this - like printf()
-+ * duel_flush used by duel to flush the output.
-+ */
-+
-+PROC duel_printf(char *fmt, ...) /* like printf, but for duel output */
-+{
-+ va_list args;
-+ va_start(args, fmt);
-+ vfprintf(stdout,fmt,args);
-+ va_end(args);
-+}
-+
-+PROC duel_flush(void) /* flush out output from duel */
-+{
-+ fflush(stdout);
-+}
-+
-+/* tells us the output is "directable" now. s is the expression
-+ * being evaluated for this */
-+
-+PROC duel_redirectable_output_start(char *s)
-+{
-+ if(s) duel_flush(); /* if(s) is always true. prevents warnings ...*/
-+}
-+
-+PROC duel_redirectable_output_end(void)
-+{
-+ duel_flush();
-+}
-+
-+PROC duel_redirectable_output_abort(void)
-+{
-+ duel_flush();
-+}
-+
-+PROC duel_redirectable_output_init(void)
-+{
-+}
---- gdb/duel/output2.c
-+++ gdb/duel/output2.c
-@@ -0,0 +1,141 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* This module supports i/o for duel. Normally output goes to stdout,
-+ * but it could be piped out instead.
-+ * Still alpha version.
-+ * HOW: if file duel.pipe exists, it is opened with stdin/out piped
-+ * here. results of expressions evaluations are sent to the pipe
-+ * with $$$START $$$END $$$ABORT and $$$SYM/$$$VAL. The pipe's
-+ * output is passed back here and is printed to stdout until
-+ * a $$$DONE is received. The pipe is normally a perl script,
-+ * that can processes the output at a symbolic level.
-+ */
-+
-+#include <stdarg.h> /* for duel_printf */
-+#include <sys/types.h> /* for stat() */
-+#include <sys/stat.h> /* " */
-+#include <fcntl.h> /* for popen impl. */
-+#include <signal.h> /* " */
-+
-+#include "duel.h"
-+
-+/* output functions:
-+ * duel_printf all duel output goes thru this - like printf()
-+ * duel_flush used by duel to flush the output.
-+ * duel_redirectable_output_start(s) - indicate start of output for exp s that
-+ * can be redirected to a pipe.
-+ * duel_redirectable_output_end() - indicate end of that output.
-+ * duel_redirectable_output_abort() - indicate output was aborted (error,intr)
-+ *
-+ * duel_redirectable_output_init() - called to init at first duel use.
-+ */
-+
-+static FILE *duel_outf = stdout ; /* current output stream */
-+static FILE *poutf,*pinf ; /* pipe i/o streams */
-+
-+#define PIPE_CMD "./duel.pipe" /* command to pipe into */
-+
-+bool bidir_popen(void)
-+{
-+ int pout[2],pin[2]; /* pin[0] is my input, pout[1] my output */
-+ int pid;
-+ struct stat s ;
-+
-+ if(stat(PIPE_CMD,&s)!=0 || !(s.st_mode & S_IEXEC)) return FALSE;
-+ if (pipe(pout) < 0 || pipe(pin) < 0) return FALSE ;
-+
-+ if ((pid = fork()) == 0) {
-+ signal(SIGINT, SIG_IGN);
-+ signal(SIGQUIT, SIG_IGN);
-+ dup2(pout[0],0); dup2(pin[1],1);
-+ close(pin[0]); close(pin[1]); close(pout[0]); close(pout[1]);
-+ execl(PIPE_CMD, PIPE_CMD, NULL);
-+ _exit(127);
-+ }
-+ close(pout[0]); close(pin[1]);
-+ if (pid == -1) return FALSE;
-+ pinf =fdopen(pin[0], "r");
-+ poutf=fdopen(pout[1],"w");
-+ if(fcntl(pin[0],F_SETFL,O_NDELAY) < 0) return FALSE ;
-+ return pinf!=NULL && poutf!=NULL ;
-+}
-+
-+
-+PROC duel_printf(char *fmt, ...) /* like printf, but for duel output */
-+{
-+ va_list args;
-+ va_start(args, fmt);
-+ vfprintf(duel_outf,fmt,args);
-+ va_end(args);
-+}
-+
-+PROC duel_flush(void) /* flush out output from duel */
-+{
-+ char s[256];
-+ fflush(duel_outf);
-+ while(pinf && fgets(s,sizeof(s),pinf)) /* note pinf is non blocking */
-+ printf("%s",s);
-+}
-+
-+LPROC duel_waitpipe(bool abort) /* wait for pipe to finish working */
-+{
-+ char s[256];
-+ if(abort) duel_printf("$$$ABORT\n"); /* write termination mesg */
-+ else duel_printf("$$$DONE\n");
-+ fflush(duel_outf);
-+ fcntl(fileno(pinf),F_SETFL,0); /* restore blocking for pipe */
-+ while(fgets(s,sizeof(s),pinf)!=NULL && strcmp(s,"$$$DONE\n")!=0)
-+ if(!abort) printf("%s",s);
-+ fcntl(fileno(pinf),F_SETFL,O_NDELAY);
-+ if(abort) printf("\n");
-+}
-+
-+/* tells us the output is "directable" now. s is the expression
-+ * being evaluated for this */
-+
-+PROC duel_redirectable_output_start(char *s)
-+{
-+ duel_flush();
-+ if(poutf) {
-+ duel_flush();
-+ duel_outf=poutf ;
-+ duel_output_pipe_style=1 ;
-+ duel_printf("$$$START: %s\n",s);
-+ duel_flush();
-+ }
-+}
-+
-+PROC duel_redirectable_output_end(void)
-+{
-+ duel_flush();
-+ if(poutf && duel_outf == poutf) {
-+ duel_waitpipe(FALSE);
-+ duel_outf=stdout ;
-+ duel_output_pipe_style=0 ;
-+ }
-+}
-+
-+PROC duel_redirectable_output_abort(void)
-+{
-+ if(poutf && duel_outf == poutf) {
-+ duel_waitpipe(TRUE);
-+ duel_outf=stdout ;
-+ duel_output_pipe_style=0 ;
-+ }
-+ duel_flush();
-+}
-+
-+PROC duel_redirectable_output_init(void)
-+{
-+ /* open the duel pipe, if available. Verify that duel.pipe
-+ * as an existing executable, because popen() does not, and can
-+ * later fail with pipe signal!
-+ */
-+ if(bidir_popen()) {
-+ duel_printf("Duel results directed to pipe \"duel.pipe\"\n");
-+ }
-+ else poutf=pinf=NULL ;
-+}
---- gdb/duel/parse.c
-+++ gdb/duel/parse.c
-@@ -0,0 +1,3326 @@
-+/* A Bison parser, made by GNU Bison 2.3. */
-+
-+/* Skeleton implementation for Bison's Yacc-like parsers in C
-+
-+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-+ Free Software Foundation, Inc.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2, or (at your option)
-+ any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
-+ Boston, MA 02110-1301, USA. */
-+
-+/* As a special exception, you may create a larger work that contains
-+ part or all of the Bison parser skeleton and distribute that work
-+ under terms of your choice, so long as that work isn't itself a
-+ parser generator using the skeleton or a modified version thereof
-+ as a parser skeleton. Alternatively, if you modify or redistribute
-+ the parser skeleton itself, you may (at your option) remove this
-+ special exception, which will cause the skeleton and the resulting
-+ Bison output files to be licensed under the GNU General Public
-+ License without this special exception.
-+
-+ This special exception was added by the Free Software Foundation in
-+ version 2.2 of Bison. */
-+
-+/* C LALR(1) parser skeleton written by Richard Stallman, by
-+ simplifying the original so-called "semantic" parser. */
-+
-+/* All symbols defined below should begin with yy or YY, to avoid
-+ infringing on user name space. This should be done even for local
-+ variables, as they might otherwise be expanded by user macros.
-+ There are some unavoidable exceptions within include files to
-+ define necessary library symbols; they are noted "INFRINGES ON
-+ USER NAME SPACE" below. */
-+
-+/* Identify Bison output. */
-+#define YYBISON 1
-+
-+/* Bison version. */
-+#define YYBISON_VERSION "2.3"
-+
-+/* Skeleton name. */
-+#define YYSKELETON_NAME "yacc.c"
-+
-+/* Pure parsers. */
-+#define YYPURE 0
-+
-+/* Using locations. */
-+#define YYLSP_NEEDED 0
-+
-+
-+
-+/* Tokens. */
-+#ifndef YYTOKENTYPE
-+# define YYTOKENTYPE
-+ /* Put the tokens into the symbol table, so that GDB and other debuggers
-+ know about them. */
-+ enum yytokentype {
-+ T_CONST = 258,
-+ T_SYM = 259,
-+ T_ASSIGN = 260,
-+ T_DEFVAR = 261,
-+ T_CHAR = 262,
-+ T_INT = 263,
-+ T_SHORT = 264,
-+ T_LONG = 265,
-+ T_UNSIGNED = 266,
-+ T_FLOAT = 267,
-+ T_DOUBLE = 268,
-+ T_VOID = 269,
-+ T_STRUCT = 270,
-+ T_UNION = 271,
-+ T_ENUM = 272,
-+ T_SIZEOF = 273,
-+ T_TYPEDEF_INDICATOR = 274,
-+ T_SIGNED = 275,
-+ T_IF = 276,
-+ T_ELSE = 277,
-+ T_FOR = 278,
-+ T_WHILE = 279,
-+ T_OR = 280,
-+ T_AND = 281,
-+ T_RSH = 282,
-+ T_LSH = 283,
-+ T_INC = 284,
-+ T_DEC = 285,
-+ T_COUNT = 286,
-+ T_FRAME = 287,
-+ T_TO = 288,
-+ T_DFS = 289,
-+ T_BFS = 290,
-+ T_ARROW = 291,
-+ T_OSEL = 292,
-+ T_CSEL = 293,
-+ T_IMP = 294,
-+ T_ANDL = 295,
-+ T_ORL = 296,
-+ T_EQ = 297,
-+ T_NE = 298,
-+ T_EQQ = 299,
-+ T_NEQ = 300,
-+ T_LE = 301,
-+ T_GE = 302,
-+ T_LSQ = 303,
-+ T_GTQ = 304,
-+ T_LEQ = 305,
-+ T_GEQ = 306,
-+ STMT = 307,
-+ UNARY = 308,
-+ T_POS = 309
-+ };
-+#endif
-+/* Tokens. */
-+#define T_CONST 258
-+#define T_SYM 259
-+#define T_ASSIGN 260
-+#define T_DEFVAR 261
-+#define T_CHAR 262
-+#define T_INT 263
-+#define T_SHORT 264
-+#define T_LONG 265
-+#define T_UNSIGNED 266
-+#define T_FLOAT 267
-+#define T_DOUBLE 268
-+#define T_VOID 269
-+#define T_STRUCT 270
-+#define T_UNION 271
-+#define T_ENUM 272
-+#define T_SIZEOF 273
-+#define T_TYPEDEF_INDICATOR 274
-+#define T_SIGNED 275
-+#define T_IF 276
-+#define T_ELSE 277
-+#define T_FOR 278
-+#define T_WHILE 279
-+#define T_OR 280
-+#define T_AND 281
-+#define T_RSH 282
-+#define T_LSH 283
-+#define T_INC 284
-+#define T_DEC 285
-+#define T_COUNT 286
-+#define T_FRAME 287
-+#define T_TO 288
-+#define T_DFS 289
-+#define T_BFS 290
-+#define T_ARROW 291
-+#define T_OSEL 292
-+#define T_CSEL 293
-+#define T_IMP 294
-+#define T_ANDL 295
-+#define T_ORL 296
-+#define T_EQ 297
-+#define T_NE 298
-+#define T_EQQ 299
-+#define T_NEQ 300
-+#define T_LE 301
-+#define T_GE 302
-+#define T_LSQ 303
-+#define T_GTQ 304
-+#define T_LEQ 305
-+#define T_GEQ 306
-+#define STMT 307
-+#define UNARY 308
-+#define T_POS 309
-+
-+
-+
-+
-+/* Copy the first part of user declarations. */
-+#line 1 "parse.y"
-+
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* this module contains the duel parser, in yacc, plus a simple lexer.
-+ * the lexer is slow, but duel expressions are tiny.
-+ * the parsing generate an AST with essentially no type checking.
-+ * names are only looked up when the refer explicitly to types. This forces
-+ * the use of "T" before user types. You can't parse (x)(y) correctly, if
-+ * you want the node to contain "cast" or "func", without knowing the x is
-+ * not a type. (It is interesting to note that (x *)(y) is clearly a cast,
-+ * but it can not be parsed without a context sensitive grammer!).
-+ *
-+ * Version 1.1 now accept (x) as a type cast, so (print)("hi") fails, but
-+ * (uint)z is ok. Also accepted is (uint*)z. T is still required in sizeof
-+ * and in variable declarations. A side effect was making "sizeof x" illegal
-+ * (since then sizeof(x)-1 was parsed sizeof((x)-1) with (x) a cast), so
-+ * now sizeof(x) must be used. Note that in C, sizoef(x)++ is acceptable,
-+ * and the '++' operate on x (which is optimized out!) This can be confusing.
-+ *
-+ * yacc is also not smart enough to recognize e.g. "if(e) e ; else e" as
-+ * a special case (redundent ';'). I hacked this in the lexer. It should
-+ * reduce the trouble with C->duel coding. (It can also be done for {e1}e2,
-+ * in some speical cases, e.g. if e2 is a keyword, or a name or a unary op,
-+ * but this can confuse some people, e.g. in {i}[5], so I left it alone.)
-+ * Finally, the %/ operator is accepted as "#/" and "%%" as "#", to those
-+ * who wish to keep gdb with # comments.
-+ * memory: nodes are alloc'ed dynamically. a parsing error loose so-far
-+ * allocated nodes, which is normally acceptable (yyerror can probably hack
-+ * into the yacc stack to release them.)
-+ */
-+
-+/*
-+ * $Log: 10_all_gdb-6.6-duel.patch,v $
-+ * Revision 1.1 2008/04/06 23:59:05 vapier
-+ * initial 6.8 patchset based on last 6.7.1 patchset
-+ *
-+ * Revision 1.14 93/03/17 11:04:12 mg
-+ * fixed (t*)x bug, was parsed as (t**)x
-+ *
-+ * Revision 1.13 93/03/12 06:15:09 mg
-+ * modified unary's a bit - cosmetics
-+ * support (x)y as type cast
-+ * support (x*)y as type cast
-+ * replace sizeof exp with sizeof(exp) to prevent clash with above
-+ * more cosmetics, including yyerror abort, tuint for uint.
-+ * takes anything after |> to be comment (pipe command really)
-+ *
-+ *
-+ * Revision 1.12 93/02/27 06:06:09 mg
-+ * added signed char parsing.
-+ *
-+ * Revision 1.11 93/02/23 19:15:38 mg
-+ * improved escaped char support
-+ *
-+ * Revision 1.10 93/02/03 21:49:34 mg
-+ * bug fix - yyerror calls now abort parsing (eg called from lex)
-+ *
-+ * Revision 1.9 93/01/12 21:53:07 mg
-+ * cleanup and set for release
-+ *
-+ * Revision 1.8 93/01/07 00:14:33 mg
-+ * add &&/ ||/
-+ * fixed parsing of trailing ';' was a mess.
-+ * ignore ';' before 'else' and '}' w/warning.
-+ *
-+ * Revision 1.7 93/01/03 07:31:01 mg
-+ * error reporting
-+ *
-+ * Revision 1.6 92/12/24 23:35:50 mg
-+ * began src pos support
-+ *
-+ * Revision 1.5 92/10/19 15:08:02 mg
-+ * frames() added; bug fixed
-+ *
-+ * Revision 1.4 92/10/14 02:06:32 mg
-+ * misc/change casting parsing/variable def.
-+ *
-+ * Revision 1.3 92/09/16 11:09:39 mg
-+ * add typedef/struct support, const strings
-+ * cleanup s/r conflict by setting ELSE to a token. explained some stuff in
-+ * comments.
-+ *
-+ * Revision 1.2 92/09/15 06:10:46 mg
-+ * cosmetics and new ops: x@y, for() while() ..x and x..
-+ * generic '.' and '_' support. x@y. '..x' and 'x..'. while(), for(), ?:
-+ *
-+ */
-+
-+#include "duel.h"
-+
-+static char *inputstr ; /* pointer to string being parsed */
-+static char *lexptr ; /* current lexer pointer into input str */
-+static tnode *root ; /* result of parsing stored here */
-+
-+/* pick unique names for globals of yacc. gdb has other parsers! */
-+#define yyparse duel_yyparse
-+#define yylex duel_yylex
-+#define yyerror duel_yyerror
-+#define yylval duel_yylval
-+#define yychar duel_yychar
-+#define yydebug duel_yydebug
-+#define yypact duel_yypact
-+#define yyr1 duel_yyr1
-+#define yyr2 duel_yyr2
-+#define yydef duel_yydef
-+#define yychk duel_yychk
-+#define yypgo duel_yypgo
-+#define yyact duel_yyact
-+#define yyexca duel_yyexca
-+#define yyerrflag duel_yyerrflag
-+#define yynerrs duel_yynerrs
-+#define yyps duel_yyps
-+#define yypv duel_yypv
-+#define yys duel_yys
-+#define yystate duel_yystate
-+#define yytmp duel_yytmp
-+#define yyv duel_yyv
-+#define yyval duel_yyval
-+#define yylloc duel_yylloc
-+
-+typedef struct { /* token info for operators */
-+ int src_pos ; /* source position */
-+ topcode opcode ; /* opcode */
-+ } topinfo ;
-+
-+typedef struct { /* token info for symbols */
-+ int src_pos ; /* source position */
-+ char *name ; /* symbol */
-+ } tnameinfo ;
-+
-+/* these are used as operators to mknode_... when source location is unknown*/
-+static topinfo seq_op = { -1,';' } ; /* sequencing operator, src pos unkown */
-+static topinfo decl_op = { -1,OP_DECL } ; /* declare var op, src pos unkown */
-+
-+/* local prototypes. */
-+LPROC yyerror(char *msg);
-+LFUNC int yylex (void);
-+
-+LPROC push_type(char desc) ;
-+LPROC push_type_int(char desc,tnode *n) ;
-+LFUNC bool pop_type(char *desc,int *size);
-+
-+LFUNC tnode* mknode_op(top_kind,topinfo opinfo,tnode*,tnode*,tnode*,tnode*);
-+LFUNC tnode* mknode_const(int src_pos,tctype *ctype);
-+LFUNC tnode* mknode_ctype(tctype *ctype);
-+LFUNC tnode* mknode_name(tnameinfo nameinfo);
-+LFUNC tnode* mknode_modified_ctype(tctype *base);
-+
-+#define mknode_post_unary(op,n) (mknode_op(OPK_POST_UNARY,op,n, 0, 0,0))
-+#define mknode_unary(op,n) (mknode_op(OPK_UNARY, op,n, 0, 0,0))
-+#define mknode_sunary(op,n) (mknode_op(OPK_SUNARY, op,n, 0, 0,0))
-+#define mknode_bin(op,n1,n2) (mknode_op(OPK_BIN, op,n1,n2,0,0))
-+#define mknode_sbin(op,n1,n2) (mknode_op(OPK_SBIN, op,n1,n2,0,0))
-+#define mknode_tri(op,n1,n2,n3) (mknode_op(OPK_TRI, op,n1,n2,n3,0))
-+
-+static tctype *decl_tbase ; /* used for variables decl */
-+
-+/* #define YYDEBUG 1 */
-+
-+
-+
-+/* Enabling traces. */
-+#ifndef YYDEBUG
-+# define YYDEBUG 0
-+#endif
-+
-+/* Enabling verbose error messages. */
-+#ifdef YYERROR_VERBOSE
-+# undef YYERROR_VERBOSE
-+# define YYERROR_VERBOSE 1
-+#else
-+# define YYERROR_VERBOSE 0
-+#endif
-+
-+/* Enabling the token table. */
-+#ifndef YYTOKEN_TABLE
-+# define YYTOKEN_TABLE 0
-+#endif
-+
-+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-+typedef union YYSTYPE
-+#line 163 "parse.y"
-+{
-+ tnode *node ; /* node pointer for constructed exp tree */
-+ tctype *ctype; /* type for type nodes */
-+ tnameinfo nameinfo ; /* a name/symbol + src position */
-+ topinfo opinfo; /* keyword/operator + source position */
-+ }
-+/* Line 187 of yacc.c. */
-+#line 372 "parse.c"
-+ YYSTYPE;
-+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-+# define YYSTYPE_IS_DECLARED 1
-+# define YYSTYPE_IS_TRIVIAL 1
-+#endif
-+
-+
-+
-+/* Copy the second part of user declarations. */
-+
-+
-+/* Line 216 of yacc.c. */
-+#line 385 "parse.c"
-+
-+#ifdef short
-+# undef short
-+#endif
-+
-+#ifdef YYTYPE_UINT8
-+typedef YYTYPE_UINT8 yytype_uint8;
-+#else
-+typedef unsigned char yytype_uint8;
-+#endif
-+
-+#ifdef YYTYPE_INT8
-+typedef YYTYPE_INT8 yytype_int8;
-+#elif (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+typedef signed char yytype_int8;
-+#else
-+typedef short int yytype_int8;
-+#endif
-+
-+#ifdef YYTYPE_UINT16
-+typedef YYTYPE_UINT16 yytype_uint16;
-+#else
-+typedef unsigned short int yytype_uint16;
-+#endif
-+
-+#ifdef YYTYPE_INT16
-+typedef YYTYPE_INT16 yytype_int16;
-+#else
-+typedef short int yytype_int16;
-+#endif
-+
-+#ifndef YYSIZE_T
-+# ifdef __SIZE_TYPE__
-+# define YYSIZE_T __SIZE_TYPE__
-+# elif defined size_t
-+# define YYSIZE_T size_t
-+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-+# define YYSIZE_T size_t
-+# else
-+# define YYSIZE_T unsigned int
-+# endif
-+#endif
-+
-+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-+
-+#ifndef YY_
-+# if YYENABLE_NLS
-+# if ENABLE_NLS
-+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-+# define YY_(msgid) dgettext ("bison-runtime", msgid)
-+# endif
-+# endif
-+# ifndef YY_
-+# define YY_(msgid) msgid
-+# endif
-+#endif
-+
-+/* Suppress unused-variable warnings by "using" E. */
-+#if ! defined lint || defined __GNUC__
-+# define YYUSE(e) ((void) (e))
-+#else
-+# define YYUSE(e) /* empty */
-+#endif
-+
-+/* Identity function, used to suppress warnings about constant conditions. */
-+#ifndef lint
-+# define YYID(n) (n)
-+#else
-+#if (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+static int
-+YYID (int i)
-+#else
-+static int
-+YYID (i)
-+ int i;
-+#endif
-+{
-+ return i;
-+}
-+#endif
-+
-+#if ! defined yyoverflow || YYERROR_VERBOSE
-+
-+/* The parser invokes alloca or malloc; define the necessary symbols. */
-+
-+# ifdef YYSTACK_USE_ALLOCA
-+# if YYSTACK_USE_ALLOCA
-+# ifdef __GNUC__
-+# define YYSTACK_ALLOC __builtin_alloca
-+# elif defined __BUILTIN_VA_ARG_INCR
-+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-+# elif defined _AIX
-+# define YYSTACK_ALLOC __alloca
-+# elif defined _MSC_VER
-+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-+# define alloca _alloca
-+# else
-+# define YYSTACK_ALLOC alloca
-+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-+# ifndef _STDLIB_H
-+# define _STDLIB_H 1
-+# endif
-+# endif
-+# endif
-+# endif
-+# endif
-+
-+# ifdef YYSTACK_ALLOC
-+ /* Pacify GCC's `empty if-body' warning. */
-+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
-+# ifndef YYSTACK_ALLOC_MAXIMUM
-+ /* The OS might guarantee only one guard page at the bottom of the stack,
-+ and a page size can be as small as 4096 bytes. So we cannot safely
-+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
-+ to allow for a few compiler-allocated temporary stack slots. */
-+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-+# endif
-+# else
-+# define YYSTACK_ALLOC YYMALLOC
-+# define YYSTACK_FREE YYFREE
-+# ifndef YYSTACK_ALLOC_MAXIMUM
-+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-+# endif
-+# if (defined __cplusplus && ! defined _STDLIB_H \
-+ && ! ((defined YYMALLOC || defined malloc) \
-+ && (defined YYFREE || defined free)))
-+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-+# ifndef _STDLIB_H
-+# define _STDLIB_H 1
-+# endif
-+# endif
-+# ifndef YYMALLOC
-+# define YYMALLOC malloc
-+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-+# endif
-+# endif
-+# ifndef YYFREE
-+# define YYFREE free
-+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+void free (void *); /* INFRINGES ON USER NAME SPACE */
-+# endif
-+# endif
-+# endif
-+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-+
-+
-+#if (! defined yyoverflow \
-+ && (! defined __cplusplus \
-+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-+
-+/* A type that is properly aligned for any stack member. */
-+union yyalloc
-+{
-+ yytype_int16 yyss;
-+ YYSTYPE yyvs;
-+ };
-+
-+/* The size of the maximum gap between one aligned stack and the next. */
-+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-+
-+/* The size of an array large to enough to hold all stacks, each with
-+ N elements. */
-+# define YYSTACK_BYTES(N) \
-+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
-+ + YYSTACK_GAP_MAXIMUM)
-+
-+/* Copy COUNT objects from FROM to TO. The source and destination do
-+ not overlap. */
-+# ifndef YYCOPY
-+# if defined __GNUC__ && 1 < __GNUC__
-+# define YYCOPY(To, From, Count) \
-+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-+# else
-+# define YYCOPY(To, From, Count) \
-+ do \
-+ { \
-+ YYSIZE_T yyi; \
-+ for (yyi = 0; yyi < (Count); yyi++) \
-+ (To)[yyi] = (From)[yyi]; \
-+ } \
-+ while (YYID (0))
-+# endif
-+# endif
-+
-+/* Relocate STACK from its old location to the new one. The
-+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
-+ elements in the stack, and YYPTR gives the new location of the
-+ stack. Advance YYPTR to a properly aligned location for the next
-+ stack. */
-+# define YYSTACK_RELOCATE(Stack) \
-+ do \
-+ { \
-+ YYSIZE_T yynewbytes; \
-+ YYCOPY (&yyptr->Stack, Stack, yysize); \
-+ Stack = &yyptr->Stack; \
-+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-+ yyptr += yynewbytes / sizeof (*yyptr); \
-+ } \
-+ while (YYID (0))
-+
-+#endif
-+
-+/* YYFINAL -- State number of the termination state. */
-+#define YYFINAL 77
-+/* YYLAST -- Last index in YYTABLE. */
-+#define YYLAST 1420
-+
-+/* YYNTOKENS -- Number of terminals. */
-+#define YYNTOKENS 81
-+/* YYNNTS -- Number of nonterminals. */
-+#define YYNNTS 18
-+/* YYNRULES -- Number of rules. */
-+#define YYNRULES 129
-+/* YYNRULES -- Number of states. */
-+#define YYNSTATES 238
-+
-+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
-+#define YYUNDEFTOK 2
-+#define YYMAXUTOK 309
-+
-+#define YYTRANSLATE(YYX) \
-+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-+
-+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-+static const yytype_uint8 yytranslate[] =
-+{
-+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 48, 2, 46, 2, 38, 31, 2,
-+ 42, 43, 36, 34, 26, 35, 39, 37, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 80, 25,
-+ 32, 27, 33, 28, 47, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 40, 2, 41, 30, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 44, 29, 45, 49, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
-+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
-+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
-+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
-+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
-+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79
-+};
-+
-+#if YYDEBUG
-+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
-+ YYRHS. */
-+static const yytype_uint16 yyprhs[] =
-+{
-+ 0, 0, 3, 5, 7, 10, 14, 16, 18, 21,
-+ 23, 27, 28, 32, 34, 38, 40, 44, 50, 53,
-+ 58, 60, 66, 73, 80, 88, 98, 107, 113, 118,
-+ 121, 124, 127, 130, 133, 136, 139, 142, 145, 148,
-+ 151, 154, 159, 164, 169, 173, 177, 181, 185, 189,
-+ 193, 198, 203, 208, 212, 216, 221, 226, 233, 237,
-+ 241, 245, 249, 253, 257, 261, 265, 269, 273, 277,
-+ 281, 285, 289, 293, 297, 301, 305, 309, 313, 317,
-+ 321, 325, 329, 335, 339, 343, 347, 351, 354, 357,
-+ 361, 365, 369, 371, 373, 374, 376, 378, 380, 383,
-+ 387, 393, 396, 401, 402, 405, 407, 410, 413, 415,
-+ 417, 420, 422, 425, 428, 432, 435, 439, 443, 448,
-+ 450, 453, 456, 460, 462, 464, 466, 469, 472, 475
-+};
-+
-+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-+static const yytype_int8 yyrhs[] =
-+{
-+ 82, 0, -1, 83, -1, 85, -1, 85, 25, -1,
-+ 85, 25, 84, -1, 84, -1, 92, -1, 92, 25,
-+ -1, 86, -1, 85, 25, 86, -1, -1, 97, 87,
-+ 88, -1, 89, -1, 88, 26, 89, -1, 90, -1,
-+ 42, 90, 43, -1, 42, 90, 43, 42, 43, -1,
-+ 36, 90, -1, 90, 40, 3, 41, -1, 94, -1,
-+ 21, 42, 91, 43, 91, -1, 21, 42, 91, 43,
-+ 91, 22, -1, 21, 42, 91, 43, 22, 91, -1,
-+ 21, 42, 91, 43, 91, 22, 91, -1, 23, 42,
-+ 93, 25, 91, 25, 93, 43, 91, -1, 23, 42,
-+ 93, 25, 91, 25, 93, 43, -1, 24, 42, 91,
-+ 43, 91, -1, 24, 42, 91, 43, -1, 36, 91,
-+ -1, 31, 91, -1, 35, 91, -1, 48, 91, -1,
-+ 49, 91, -1, 56, 91, -1, 65, 91, -1, 66,
-+ 91, -1, 54, 91, -1, 55, 91, -1, 91, 54,
-+ -1, 91, 55, -1, 18, 42, 95, 43, -1, 18,
-+ 42, 91, 43, -1, 57, 42, 91, 43, -1, 91,
-+ 59, 91, -1, 91, 60, 91, -1, 91, 46, 94,
-+ -1, 91, 47, 91, -1, 91, 61, 91, -1, 91,
-+ 39, 91, -1, 91, 40, 91, 41, -1, 91, 62,
-+ 91, 63, -1, 91, 42, 93, 43, -1, 42, 92,
-+ 43, -1, 44, 92, 45, -1, 42, 95, 43, 91,
-+ -1, 42, 98, 43, 91, -1, 42, 98, 36, 96,
-+ 43, 91, -1, 91, 36, 91, -1, 91, 37, 91,
-+ -1, 91, 38, 91, -1, 91, 34, 91, -1, 91,
-+ 35, 91, -1, 91, 53, 91, -1, 91, 52, 91,
-+ -1, 91, 67, 91, -1, 91, 68, 91, -1, 91,
-+ 69, 91, -1, 91, 70, 91, -1, 91, 71, 91,
-+ -1, 91, 72, 91, -1, 91, 75, 91, -1, 91,
-+ 76, 91, -1, 91, 32, 91, -1, 91, 33, 91,
-+ -1, 91, 73, 91, -1, 91, 74, 91, -1, 91,
-+ 31, 91, -1, 91, 29, 91, -1, 91, 30, 91,
-+ -1, 91, 51, 91, -1, 91, 50, 91, -1, 91,
-+ 28, 91, 80, 91, -1, 91, 27, 91, -1, 91,
-+ 5, 91, -1, 94, 6, 91, -1, 91, 58, 91,
-+ -1, 58, 91, -1, 91, 58, -1, 91, 26, 91,
-+ -1, 91, 64, 91, -1, 92, 25, 91, -1, 91,
-+ -1, 91, -1, -1, 3, -1, 94, -1, 98, -1,
-+ 97, 96, -1, 42, 96, 43, -1, 42, 96, 43,
-+ 42, 43, -1, 36, 96, -1, 96, 40, 3, 41,
-+ -1, -1, 19, 98, -1, 7, -1, 20, 7, -1,
-+ 11, 7, -1, 8, -1, 11, -1, 11, 8, -1,
-+ 10, -1, 10, 8, -1, 11, 10, -1, 11, 10,
-+ 8, -1, 10, 10, -1, 10, 10, 8, -1, 11,
-+ 10, 10, -1, 11, 10, 10, 8, -1, 9, -1,
-+ 9, 8, -1, 11, 9, -1, 11, 9, 8, -1,
-+ 12, -1, 13, -1, 14, -1, 15, 98, -1, 16,
-+ 98, -1, 17, 98, -1, 4, -1
-+};
-+
-+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-+static const yytype_uint16 yyrline[] =
-+{
-+ 0, 211, 211, 214, 215, 216, 217, 219, 220, 222,
-+ 223, 226, 226, 228, 229, 232, 236, 237, 238, 239,
-+ 240, 251, 252, 254, 256, 259, 261, 263, 265, 271,
-+ 272, 273, 274, 275, 276, 277, 278, 279, 280, 281,
-+ 282, 283, 284, 285, 288, 289, 291, 292, 293, 294,
-+ 295, 296, 297, 298, 299, 302, 313, 317, 326, 327,
-+ 328, 329, 330, 331, 332, 333, 334, 335, 336, 337,
-+ 338, 339, 340, 341, 342, 343, 344, 345, 346, 347,
-+ 348, 349, 352, 356, 357, 358, 363, 364, 365, 366,
-+ 367, 370, 371, 374, 375, 378, 379, 385, 387, 392,
-+ 393, 394, 395, 396, 413, 423, 424, 425, 426, 427,
-+ 428, 429, 430, 431, 432, 433, 434, 435, 436, 437,
-+ 438, 439, 440, 441, 442, 443, 444, 447, 450, 455
-+};
-+#endif
-+
-+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
-+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
-+static const char *const yytname[] =
-+{
-+ "$end", "error", "$undefined", "T_CONST", "T_SYM", "T_ASSIGN",
-+ "T_DEFVAR", "T_CHAR", "T_INT", "T_SHORT", "T_LONG", "T_UNSIGNED",
-+ "T_FLOAT", "T_DOUBLE", "T_VOID", "T_STRUCT", "T_UNION", "T_ENUM",
-+ "T_SIZEOF", "T_TYPEDEF_INDICATOR", "T_SIGNED", "T_IF", "T_ELSE", "T_FOR",
-+ "T_WHILE", "';'", "','", "'='", "'?'", "'|'", "'^'", "'&'", "'<'", "'>'",
-+ "'+'", "'-'", "'*'", "'/'", "'%'", "'.'", "'['", "']'", "'('", "')'",
-+ "'{'", "'}'", "'#'", "'@'", "'!'", "'~'", "T_OR", "T_AND", "T_RSH",
-+ "T_LSH", "T_INC", "T_DEC", "T_COUNT", "T_FRAME", "T_TO", "T_DFS",
-+ "T_BFS", "T_ARROW", "T_OSEL", "T_CSEL", "T_IMP", "T_ANDL", "T_ORL",
-+ "T_EQ", "T_NE", "T_EQQ", "T_NEQ", "T_LE", "T_GE", "T_LSQ", "T_GTQ",
-+ "T_LEQ", "T_GEQ", "STMT", "UNARY", "T_POS", "':'", "$accept", "start",
-+ "duel_inp", "duel_exp", "all_decls", "vars_decl", "@1", "var_decl",
-+ "name_decl1", "name_decl", "exp", "sm_exp", "oexp", "nameexp", "type",
-+ "type_mod", "typebase", "name", 0
-+};
-+#endif
-+
-+# ifdef YYPRINT
-+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-+ token YYLEX-NUM. */
-+static const yytype_uint16 yytoknum[] =
-+{
-+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
-+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
-+ 275, 276, 277, 278, 279, 59, 44, 61, 63, 124,
-+ 94, 38, 60, 62, 43, 45, 42, 47, 37, 46,
-+ 91, 93, 40, 41, 123, 125, 35, 64, 33, 126,
-+ 280, 281, 282, 283, 284, 285, 286, 287, 288, 289,
-+ 290, 291, 292, 293, 294, 295, 296, 297, 298, 299,
-+ 300, 301, 302, 303, 304, 305, 306, 307, 308, 309,
-+ 58
-+};
-+# endif
-+
-+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-+static const yytype_uint8 yyr1[] =
-+{
-+ 0, 81, 82, 83, 83, 83, 83, 84, 84, 85,
-+ 85, 87, 86, 88, 88, 89, 90, 90, 90, 90,
-+ 90, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-+ 91, 92, 92, 93, 93, 91, 91, 94, 95, 96,
-+ 96, 96, 96, 96, 97, 97, 97, 97, 97, 97,
-+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
-+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 98
-+};
-+
-+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-+static const yytype_uint8 yyr2[] =
-+{
-+ 0, 2, 1, 1, 2, 3, 1, 1, 2, 1,
-+ 3, 0, 3, 1, 3, 1, 3, 5, 2, 4,
-+ 1, 5, 6, 6, 7, 9, 8, 5, 4, 2,
-+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-+ 2, 4, 4, 4, 3, 3, 3, 3, 3, 3,
-+ 4, 4, 4, 3, 3, 4, 4, 6, 3, 3,
-+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-+ 3, 3, 5, 3, 3, 3, 3, 2, 2, 3,
-+ 3, 3, 1, 1, 0, 1, 1, 1, 2, 3,
-+ 5, 2, 4, 0, 2, 1, 2, 2, 1, 1,
-+ 2, 1, 2, 2, 3, 2, 3, 3, 4, 1,
-+ 2, 2, 3, 1, 1, 1, 2, 2, 2, 1
-+};
-+
-+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
-+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
-+ means the default is an error. */
-+static const yytype_uint8 yydefact[] =
-+{
-+ 0, 95, 129, 105, 108, 119, 111, 109, 123, 124,
-+ 125, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 2, 6, 3, 9, 92,
-+ 7, 96, 11, 97, 120, 112, 115, 107, 110, 121,
-+ 113, 126, 127, 128, 0, 104, 106, 0, 94, 0,
-+ 30, 31, 29, 0, 0, 103, 97, 0, 32, 33,
-+ 37, 38, 34, 0, 87, 35, 36, 1, 4, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 94, 0, 0, 0, 0,
-+ 0, 0, 39, 40, 88, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 8, 0, 0, 116, 122, 114, 117, 0, 0, 0,
-+ 93, 0, 0, 0, 53, 0, 103, 103, 98, 103,
-+ 0, 54, 0, 5, 10, 84, 89, 83, 0, 78,
-+ 79, 77, 73, 74, 61, 62, 58, 59, 60, 49,
-+ 0, 0, 46, 47, 81, 80, 64, 63, 86, 44,
-+ 45, 48, 0, 90, 65, 66, 67, 68, 69, 70,
-+ 75, 76, 71, 72, 91, 85, 0, 0, 12, 13,
-+ 15, 20, 118, 42, 41, 0, 0, 28, 55, 101,
-+ 0, 0, 0, 56, 43, 0, 50, 52, 51, 18,
-+ 0, 0, 0, 0, 21, 0, 27, 99, 0, 0,
-+ 82, 16, 14, 0, 23, 22, 94, 0, 102, 57,
-+ 0, 19, 24, 0, 100, 17, 26, 25
-+};
-+
-+/* YYDEFGOTO[NTERM-NUM]. */
-+static const yytype_int16 yydefgoto[] =
-+{
-+ -1, 34, 35, 36, 37, 38, 122, 188, 189, 190,
-+ 39, 40, 131, 41, 64, 138, 42, 43
-+};
-+
-+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-+ STATE-NUM. */
-+#define YYPACT_NINF -105
-+static const yytype_int16 yypact[] =
-+{
-+ 843, -105, -105, -105, -105, 15, 46, 23, -105, -105,
-+ -105, 39, 39, 39, -15, 39, 44, 16, 34, 64,
-+ 892, 892, 892, 843, 892, 892, 892, 892, 892, 892,
-+ 67, 892, 892, 892, 110, -105, -105, 86, -105, 667,
-+ 87, 108, -105, -105, -105, -105, 109, -105, -105, 111,
-+ 47, -105, -105, -105, 843, -105, -105, 892, 892, 892,
-+ 148, 148, 148, 1, 73, -17, -14, -10, 148, 148,
-+ 148, 148, 148, 892, 1302, 1076, 1028, -105, 843, 892,
-+ 892, 892, 892, 892, 892, 892, 892, 892, 892, 892,
-+ 892, 892, 892, 892, 892, 892, 39, 892, 892, 892,
-+ 892, 892, -105, -105, 941, 892, 892, 892, 892, 892,
-+ 892, 892, 892, 892, 892, 892, 892, 892, 892, 892,
-+ 892, 892, 0, -105, -105, -105, 113, 249, 75, 300,
-+ 667, 98, 351, 892, -105, 892, -17, -17, 84, -17,
-+ 892, -105, 402, -105, -105, 769, 718, 769, 191, 1123,
-+ 1169, 1214, 1331, 1331, 1358, 1358, 148, 148, 148, -105,
-+ 453, 88, -105, -105, 1028, 1076, 932, 932, 1302, -105,
-+ -105, -105, 504, 667, 1259, 1259, 1259, 1259, 1331, 1331,
-+ 1331, 1331, 1331, 1331, 667, 769, 0, 0, 106, -105,
-+ 90, -105, -105, -105, -105, 104, 892, 892, 148, 84,
-+ -19, 130, 7, 148, -105, 892, -105, -105, -105, 90,
-+ 9, 0, 133, 892, 564, 616, 667, 95, 97, 892,
-+ 980, 99, -105, 101, 667, 892, 892, 100, -105, 148,
-+ 102, -105, 667, 107, -105, -105, 892, 667
-+};
-+
-+/* YYPGOTO[NTERM-NUM]. */
-+static const yytype_int8 yypgoto[] =
-+{
-+ -105, -105, -105, 66, -105, 69, -105, -105, -62, -104,
-+ -20, 79, -92, -82, 103, -91, -13, 5
-+};
-+
-+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
-+ positive, shift that token. If negative, reduce the rule which
-+ number is the opposite. If zero, do what YYDEFACT says.
-+ If YYTABLE_NINF, syntax error. */
-+#define YYTABLE_NINF -1
-+static const yytype_int16 yytable[] =
-+{
-+ 60, 61, 62, 161, 2, 68, 69, 70, 71, 72,
-+ 65, 74, 75, 76, 162, 133, 51, 52, 53, 136,
-+ 55, 201, 139, 44, 217, 137, 133, 54, 66, 140,
-+ 47, 48, 49, 50, 127, 141, 186, 129, 130, 132,
-+ 191, 65, 187, 2, 134, 199, 200, 201, 202, 212,
-+ 219, 56, 221, 142, 45, 125, 46, 126, 57, 145,
-+ 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
-+ 156, 157, 158, 159, 160, 130, 58, 163, 164, 165,
-+ 166, 167, 209, 210, 168, 169, 170, 171, 172, 173,
-+ 174, 175, 176, 177, 178, 179, 180, 181, 182, 183,
-+ 184, 185, 63, 67, 191, 191, 59, 1, 2, 73,
-+ 77, 78, 120, 184, 121, 198, 135, 123, 194, 124,
-+ 203, 192, 14, 196, 201, 17, 213, 18, 19, 191,
-+ 212, 207, 211, 218, 233, 20, 223, 227, 228, 21,
-+ 22, 230, 231, 234, 143, 235, 23, 144, 24, 222,
-+ 236, 0, 25, 26, 0, 0, 0, 128, 27, 28,
-+ 29, 30, 31, 0, 0, 0, 0, 0, 0, 32,
-+ 33, 0, 0, 0, 0, 214, 215, 216, 0, 0,
-+ 0, 0, 0, 0, 0, 220, 0, 93, 94, 0,
-+ 95, 0, 0, 224, 96, 97, 79, 0, 0, 229,
-+ 0, 0, 102, 103, 0, 232, 130, 105, 106, 107,
-+ 108, 0, 0, 0, 0, 0, 237, 80, 81, 82,
-+ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
-+ 93, 94, 0, 95, 0, 0, 0, 96, 97, 0,
-+ 0, 98, 99, 100, 101, 102, 103, 0, 0, 104,
-+ 105, 106, 107, 108, 79, 109, 0, 0, 110, 111,
-+ 112, 113, 114, 115, 116, 117, 118, 119, 0, 0,
-+ 0, 205, 0, 0, 0, 80, 81, 82, 83, 84,
-+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
-+ 0, 95, 193, 0, 0, 96, 97, 0, 0, 98,
-+ 99, 100, 101, 102, 103, 79, 0, 104, 105, 106,
-+ 107, 108, 0, 109, 0, 0, 110, 111, 112, 113,
-+ 114, 115, 116, 117, 118, 119, 80, 81, 82, 83,
-+ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
-+ 94, 0, 95, 195, 0, 0, 96, 97, 0, 0,
-+ 98, 99, 100, 101, 102, 103, 79, 0, 104, 105,
-+ 106, 107, 108, 0, 109, 0, 0, 110, 111, 112,
-+ 113, 114, 115, 116, 117, 118, 119, 80, 81, 82,
-+ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
-+ 93, 94, 0, 95, 197, 0, 0, 96, 97, 0,
-+ 0, 98, 99, 100, 101, 102, 103, 79, 0, 104,
-+ 105, 106, 107, 108, 0, 109, 0, 0, 110, 111,
-+ 112, 113, 114, 115, 116, 117, 118, 119, 80, 81,
-+ 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
-+ 92, 93, 94, 0, 95, 204, 0, 0, 96, 97,
-+ 0, 0, 98, 99, 100, 101, 102, 103, 79, 0,
-+ 104, 105, 106, 107, 108, 0, 109, 0, 0, 110,
-+ 111, 112, 113, 114, 115, 116, 117, 118, 119, 80,
-+ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
-+ 91, 92, 93, 94, 206, 95, 0, 0, 0, 96,
-+ 97, 0, 0, 98, 99, 100, 101, 102, 103, 79,
-+ 0, 104, 105, 106, 107, 108, 0, 109, 0, 0,
-+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
-+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
-+ 90, 91, 92, 93, 94, 0, 95, 0, 0, 0,
-+ 96, 97, 0, 0, 98, 99, 100, 101, 102, 103,
-+ 0, 0, 104, 105, 106, 107, 108, 208, 109, 79,
-+ 0, 110, 111, 112, 113, 114, 115, 116, 117, 118,
-+ 119, 0, 0, 0, 0, 0, 225, 0, 0, 0,
-+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
-+ 90, 91, 92, 93, 94, 0, 95, 0, 0, 0,
-+ 96, 97, 0, 0, 98, 99, 100, 101, 102, 103,
-+ 0, 79, 104, 105, 106, 107, 108, 0, 109, 0,
-+ 0, 110, 111, 112, 113, 114, 115, 116, 117, 118,
-+ 119, 226, 80, 81, 82, 83, 84, 85, 86, 87,
-+ 88, 89, 90, 91, 92, 93, 94, 0, 95, 0,
-+ 0, 0, 96, 97, 0, 0, 98, 99, 100, 101,
-+ 102, 103, 79, 0, 104, 105, 106, 107, 108, 0,
-+ 109, 0, 0, 110, 111, 112, 113, 114, 115, 116,
-+ 117, 118, 119, 80, 81, 82, 83, 84, 85, 86,
-+ 87, 88, 89, 90, 91, 92, 93, 94, 0, 95,
-+ 0, 0, 0, 96, 97, 0, 0, 98, 99, 100,
-+ 101, 102, 103, 79, 0, 104, 105, 106, 107, 108,
-+ 0, 109, 0, 0, 110, 111, 112, 113, 114, 115,
-+ 116, 117, 118, 119, 80, 81, 82, 83, 84, 85,
-+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 0,
-+ 95, 0, 0, 0, 96, 97, 0, 0, 98, 99,
-+ 100, 101, 102, 103, 79, 0, 104, 105, 106, 107,
-+ 108, 0, 0, 0, 0, 110, 111, 112, 113, 114,
-+ 115, 116, 117, 118, 119, 0, 81, 82, 83, 84,
-+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
-+ 0, 95, 0, 0, 0, 96, 97, 0, 0, 98,
-+ 99, 100, 101, 102, 103, 0, 0, 104, 105, 106,
-+ 107, 108, 0, 0, 0, 0, 110, 111, 112, 113,
-+ 114, 115, 116, 117, 118, 119, 1, 2, 0, 0,
-+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
-+ 13, 14, 15, 16, 17, 0, 18, 19, 0, 0,
-+ 0, 0, 0, 0, 20, 0, 0, 0, 21, 22,
-+ 0, 0, 0, 0, 0, 23, 0, 24, 0, 0,
-+ 0, 25, 26, 0, 0, 1, 2, 27, 28, 29,
-+ 30, 31, 0, 0, 0, 0, 0, 0, 32, 33,
-+ 14, 0, 0, 17, 0, 18, 19, 0, 0, 0,
-+ 0, 0, 0, 20, 0, 0, 0, 21, 22, 0,
-+ 0, 0, 0, 0, 23, 0, 24, 0, 0, 0,
-+ 25, 26, 0, 0, 1, 2, 27, 28, 29, 30,
-+ 31, 0, 0, 0, 0, 0, 0, 32, 33, 14,
-+ 0, 0, 17, 0, 18, 19, 88, 89, 90, 91,
-+ 92, 93, 94, 0, 95, 0, 21, 22, 96, 97,
-+ 0, 0, 0, 23, 0, 24, 102, 103, 0, 25,
-+ 26, 105, 106, 107, 108, 27, 28, 29, 30, -1,
-+ 0, 0, 0, 0, 0, 0, 32, 33, 82, 83,
-+ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
-+ 94, 0, 95, 0, 0, 0, 96, 97, 0, 0,
-+ 98, 99, 100, 101, 102, 103, 0, 0, 104, 105,
-+ 106, 107, 108, 0, 0, 0, 0, 110, 111, 112,
-+ 113, 114, 115, 116, 117, 118, 119, 83, 84, 85,
-+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 0,
-+ 95, 0, 0, 0, 96, 97, 0, 0, 0, 99,
-+ 100, 101, 102, 103, 0, 0, 104, 105, 106, 107,
-+ 108, 0, 0, 0, 0, 110, 111, 112, 113, 114,
-+ 115, 116, 117, 118, 119, 83, 84, 85, 86, 87,
-+ 88, 89, 90, 91, 92, 93, 94, 0, 95, 0,
-+ 0, 0, 96, 97, 0, 0, 0, 0, 100, 101,
-+ 102, 103, 0, 0, 104, 105, 106, 107, 108, 0,
-+ 0, 0, 0, 110, 111, 112, 113, 114, 115, 116,
-+ 117, 118, 119, 84, 85, 86, 87, 88, 89, 90,
-+ 91, 92, 93, 94, 0, 95, 0, 0, 0, 96,
-+ 97, 0, 0, 0, 0, 100, 101, 102, 103, 0,
-+ 0, 104, 105, 106, 107, 108, 0, 0, 0, 0,
-+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
-+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
-+ 0, 95, 0, 0, 0, 96, 97, 0, 0, 0,
-+ 0, 100, 101, 102, 103, 0, 0, 104, 105, 106,
-+ 107, 108, 0, 0, 0, 0, 110, 111, 112, 113,
-+ 114, 115, 116, 117, 118, 119, 86, 87, 88, 89,
-+ 90, 91, 92, 93, 94, 0, 95, 0, 0, 0,
-+ 96, 97, 0, 0, 0, 0, 100, 101, 102, 103,
-+ 0, 0, 104, 105, 106, 107, 108, 0, 0, 0,
-+ 0, 110, 111, 112, 113, 114, 115, 116, 117, 118,
-+ 119, 86, 87, 88, 89, 90, 91, 92, 93, 94,
-+ 0, 95, 0, 0, 0, 96, 97, 0, 0, 0,
-+ 0, 100, 101, 102, 103, 0, 0, 104, 105, 106,
-+ 107, 108, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 114, 115, 116, 117, 118, 119, 88, 89, 90, 91,
-+ 92, 93, 94, 0, 95, 0, 0, 0, 96, 97,
-+ 0, 0, 0, 0, 100, 101, 102, 103, 0, 0,
-+ -1, 105, 106, 107, 108, 88, 89, 90, 91, 92,
-+ 93, 94, 0, 95, 0, 0, 0, 96, 97, 0,
-+ 0, 0, 0, 100, 101, 102, 103, 0, 0, 104,
-+ 105, 106, 107, 108, 90, 91, 92, 93, 94, 0,
-+ 95, 0, 0, 0, 96, 97, 0, 0, 0, 0,
-+ 0, 0, 102, 103, 0, 0, 0, 105, 106, 107,
-+ 108
-+};
-+
-+static const yytype_int16 yycheck[] =
-+{
-+ 20, 21, 22, 95, 4, 25, 26, 27, 28, 29,
-+ 23, 31, 32, 33, 96, 25, 11, 12, 13, 36,
-+ 15, 40, 36, 8, 43, 42, 25, 42, 23, 43,
-+ 7, 8, 9, 10, 54, 45, 36, 57, 58, 59,
-+ 122, 54, 42, 4, 43, 136, 137, 40, 139, 40,
-+ 43, 7, 43, 73, 8, 8, 10, 10, 42, 79,
-+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
-+ 90, 91, 92, 93, 94, 95, 42, 97, 98, 99,
-+ 100, 101, 186, 187, 104, 105, 106, 107, 108, 109,
-+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
-+ 120, 121, 23, 24, 186, 187, 42, 3, 4, 42,
-+ 0, 25, 25, 133, 6, 135, 43, 8, 43, 8,
-+ 140, 8, 18, 25, 40, 21, 22, 23, 24, 211,
-+ 40, 43, 26, 3, 226, 31, 3, 42, 41, 35,
-+ 36, 42, 41, 43, 78, 43, 42, 78, 44, 211,
-+ 43, -1, 48, 49, -1, -1, -1, 54, 54, 55,
-+ 56, 57, 58, -1, -1, -1, -1, -1, -1, 65,
-+ 66, -1, -1, -1, -1, 195, 196, 197, -1, -1,
-+ -1, -1, -1, -1, -1, 205, -1, 39, 40, -1,
-+ 42, -1, -1, 213, 46, 47, 5, -1, -1, 219,
-+ -1, -1, 54, 55, -1, 225, 226, 59, 60, 61,
-+ 62, -1, -1, -1, -1, -1, 236, 26, 27, 28,
-+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
-+ 39, 40, -1, 42, -1, -1, -1, 46, 47, -1,
-+ -1, 50, 51, 52, 53, 54, 55, -1, -1, 58,
-+ 59, 60, 61, 62, 5, 64, -1, -1, 67, 68,
-+ 69, 70, 71, 72, 73, 74, 75, 76, -1, -1,
-+ -1, 80, -1, -1, -1, 26, 27, 28, 29, 30,
-+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-+ -1, 42, 43, -1, -1, 46, 47, -1, -1, 50,
-+ 51, 52, 53, 54, 55, 5, -1, 58, 59, 60,
-+ 61, 62, -1, 64, -1, -1, 67, 68, 69, 70,
-+ 71, 72, 73, 74, 75, 76, 26, 27, 28, 29,
-+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
-+ 40, -1, 42, 43, -1, -1, 46, 47, -1, -1,
-+ 50, 51, 52, 53, 54, 55, 5, -1, 58, 59,
-+ 60, 61, 62, -1, 64, -1, -1, 67, 68, 69,
-+ 70, 71, 72, 73, 74, 75, 76, 26, 27, 28,
-+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
-+ 39, 40, -1, 42, 43, -1, -1, 46, 47, -1,
-+ -1, 50, 51, 52, 53, 54, 55, 5, -1, 58,
-+ 59, 60, 61, 62, -1, 64, -1, -1, 67, 68,
-+ 69, 70, 71, 72, 73, 74, 75, 76, 26, 27,
-+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
-+ 38, 39, 40, -1, 42, 43, -1, -1, 46, 47,
-+ -1, -1, 50, 51, 52, 53, 54, 55, 5, -1,
-+ 58, 59, 60, 61, 62, -1, 64, -1, -1, 67,
-+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 26,
-+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
-+ 37, 38, 39, 40, 41, 42, -1, -1, -1, 46,
-+ 47, -1, -1, 50, 51, 52, 53, 54, 55, 5,
-+ -1, 58, 59, 60, 61, 62, -1, 64, -1, -1,
-+ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
-+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
-+ 36, 37, 38, 39, 40, -1, 42, -1, -1, -1,
-+ 46, 47, -1, -1, 50, 51, 52, 53, 54, 55,
-+ -1, -1, 58, 59, 60, 61, 62, 63, 64, 5,
-+ -1, 67, 68, 69, 70, 71, 72, 73, 74, 75,
-+ 76, -1, -1, -1, -1, -1, 22, -1, -1, -1,
-+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
-+ 36, 37, 38, 39, 40, -1, 42, -1, -1, -1,
-+ 46, 47, -1, -1, 50, 51, 52, 53, 54, 55,
-+ -1, 5, 58, 59, 60, 61, 62, -1, 64, -1,
-+ -1, 67, 68, 69, 70, 71, 72, 73, 74, 75,
-+ 76, 25, 26, 27, 28, 29, 30, 31, 32, 33,
-+ 34, 35, 36, 37, 38, 39, 40, -1, 42, -1,
-+ -1, -1, 46, 47, -1, -1, 50, 51, 52, 53,
-+ 54, 55, 5, -1, 58, 59, 60, 61, 62, -1,
-+ 64, -1, -1, 67, 68, 69, 70, 71, 72, 73,
-+ 74, 75, 76, 26, 27, 28, 29, 30, 31, 32,
-+ 33, 34, 35, 36, 37, 38, 39, 40, -1, 42,
-+ -1, -1, -1, 46, 47, -1, -1, 50, 51, 52,
-+ 53, 54, 55, 5, -1, 58, 59, 60, 61, 62,
-+ -1, 64, -1, -1, 67, 68, 69, 70, 71, 72,
-+ 73, 74, 75, 76, 26, 27, 28, 29, 30, 31,
-+ 32, 33, 34, 35, 36, 37, 38, 39, 40, -1,
-+ 42, -1, -1, -1, 46, 47, -1, -1, 50, 51,
-+ 52, 53, 54, 55, 5, -1, 58, 59, 60, 61,
-+ 62, -1, -1, -1, -1, 67, 68, 69, 70, 71,
-+ 72, 73, 74, 75, 76, -1, 27, 28, 29, 30,
-+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-+ -1, 42, -1, -1, -1, 46, 47, -1, -1, 50,
-+ 51, 52, 53, 54, 55, -1, -1, 58, 59, 60,
-+ 61, 62, -1, -1, -1, -1, 67, 68, 69, 70,
-+ 71, 72, 73, 74, 75, 76, 3, 4, -1, -1,
-+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-+ 17, 18, 19, 20, 21, -1, 23, 24, -1, -1,
-+ -1, -1, -1, -1, 31, -1, -1, -1, 35, 36,
-+ -1, -1, -1, -1, -1, 42, -1, 44, -1, -1,
-+ -1, 48, 49, -1, -1, 3, 4, 54, 55, 56,
-+ 57, 58, -1, -1, -1, -1, -1, -1, 65, 66,
-+ 18, -1, -1, 21, -1, 23, 24, -1, -1, -1,
-+ -1, -1, -1, 31, -1, -1, -1, 35, 36, -1,
-+ -1, -1, -1, -1, 42, -1, 44, -1, -1, -1,
-+ 48, 49, -1, -1, 3, 4, 54, 55, 56, 57,
-+ 58, -1, -1, -1, -1, -1, -1, 65, 66, 18,
-+ -1, -1, 21, -1, 23, 24, 34, 35, 36, 37,
-+ 38, 39, 40, -1, 42, -1, 35, 36, 46, 47,
-+ -1, -1, -1, 42, -1, 44, 54, 55, -1, 48,
-+ 49, 59, 60, 61, 62, 54, 55, 56, 57, 58,
-+ -1, -1, -1, -1, -1, -1, 65, 66, 28, 29,
-+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
-+ 40, -1, 42, -1, -1, -1, 46, 47, -1, -1,
-+ 50, 51, 52, 53, 54, 55, -1, -1, 58, 59,
-+ 60, 61, 62, -1, -1, -1, -1, 67, 68, 69,
-+ 70, 71, 72, 73, 74, 75, 76, 29, 30, 31,
-+ 32, 33, 34, 35, 36, 37, 38, 39, 40, -1,
-+ 42, -1, -1, -1, 46, 47, -1, -1, -1, 51,
-+ 52, 53, 54, 55, -1, -1, 58, 59, 60, 61,
-+ 62, -1, -1, -1, -1, 67, 68, 69, 70, 71,
-+ 72, 73, 74, 75, 76, 29, 30, 31, 32, 33,
-+ 34, 35, 36, 37, 38, 39, 40, -1, 42, -1,
-+ -1, -1, 46, 47, -1, -1, -1, -1, 52, 53,
-+ 54, 55, -1, -1, 58, 59, 60, 61, 62, -1,
-+ -1, -1, -1, 67, 68, 69, 70, 71, 72, 73,
-+ 74, 75, 76, 30, 31, 32, 33, 34, 35, 36,
-+ 37, 38, 39, 40, -1, 42, -1, -1, -1, 46,
-+ 47, -1, -1, -1, -1, 52, 53, 54, 55, -1,
-+ -1, 58, 59, 60, 61, 62, -1, -1, -1, -1,
-+ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
-+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-+ -1, 42, -1, -1, -1, 46, 47, -1, -1, -1,
-+ -1, 52, 53, 54, 55, -1, -1, 58, 59, 60,
-+ 61, 62, -1, -1, -1, -1, 67, 68, 69, 70,
-+ 71, 72, 73, 74, 75, 76, 32, 33, 34, 35,
-+ 36, 37, 38, 39, 40, -1, 42, -1, -1, -1,
-+ 46, 47, -1, -1, -1, -1, 52, 53, 54, 55,
-+ -1, -1, 58, 59, 60, 61, 62, -1, -1, -1,
-+ -1, 67, 68, 69, 70, 71, 72, 73, 74, 75,
-+ 76, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-+ -1, 42, -1, -1, -1, 46, 47, -1, -1, -1,
-+ -1, 52, 53, 54, 55, -1, -1, 58, 59, 60,
-+ 61, 62, -1, -1, -1, -1, -1, -1, -1, -1,
-+ 71, 72, 73, 74, 75, 76, 34, 35, 36, 37,
-+ 38, 39, 40, -1, 42, -1, -1, -1, 46, 47,
-+ -1, -1, -1, -1, 52, 53, 54, 55, -1, -1,
-+ 58, 59, 60, 61, 62, 34, 35, 36, 37, 38,
-+ 39, 40, -1, 42, -1, -1, -1, 46, 47, -1,
-+ -1, -1, -1, 52, 53, 54, 55, -1, -1, 58,
-+ 59, 60, 61, 62, 36, 37, 38, 39, 40, -1,
-+ 42, -1, -1, -1, 46, 47, -1, -1, -1, -1,
-+ -1, -1, 54, 55, -1, -1, -1, 59, 60, 61,
-+ 62
-+};
-+
-+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-+ symbol of state STATE-NUM. */
-+static const yytype_uint8 yystos[] =
-+{
-+ 0, 3, 4, 7, 8, 9, 10, 11, 12, 13,
-+ 14, 15, 16, 17, 18, 19, 20, 21, 23, 24,
-+ 31, 35, 36, 42, 44, 48, 49, 54, 55, 56,
-+ 57, 58, 65, 66, 82, 83, 84, 85, 86, 91,
-+ 92, 94, 97, 98, 8, 8, 10, 7, 8, 9,
-+ 10, 98, 98, 98, 42, 98, 7, 42, 42, 42,
-+ 91, 91, 91, 92, 95, 97, 98, 92, 91, 91,
-+ 91, 91, 91, 42, 91, 91, 91, 0, 25, 5,
-+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
-+ 36, 37, 38, 39, 40, 42, 46, 47, 50, 51,
-+ 52, 53, 54, 55, 58, 59, 60, 61, 62, 64,
-+ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
-+ 25, 6, 87, 8, 8, 8, 10, 91, 95, 91,
-+ 91, 93, 91, 25, 43, 43, 36, 42, 96, 36,
-+ 43, 45, 91, 84, 86, 91, 91, 91, 91, 91,
-+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-+ 91, 93, 94, 91, 91, 91, 91, 91, 91, 91,
-+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-+ 91, 91, 91, 91, 91, 91, 36, 42, 88, 89,
-+ 90, 94, 8, 43, 43, 43, 25, 43, 91, 96,
-+ 96, 40, 96, 91, 43, 80, 41, 43, 63, 90,
-+ 90, 26, 40, 22, 91, 91, 91, 43, 3, 43,
-+ 91, 43, 89, 3, 91, 22, 25, 42, 41, 91,
-+ 42, 41, 91, 93, 43, 43, 43, 91
-+};
-+
-+#define yyerrok (yyerrstatus = 0)
-+#define yyclearin (yychar = YYEMPTY)
-+#define YYEMPTY (-2)
-+#define YYEOF 0
-+
-+#define YYACCEPT goto yyacceptlab
-+#define YYABORT goto yyabortlab
-+#define YYERROR goto yyerrorlab
-+
-+
-+/* Like YYERROR except do call yyerror. This remains here temporarily
-+ to ease the transition to the new meaning of YYERROR, for GCC.
-+ Once GCC version 2 has supplanted version 1, this can go. */
-+
-+#define YYFAIL goto yyerrlab
-+
-+#define YYRECOVERING() (!!yyerrstatus)
-+
-+#define YYBACKUP(Token, Value) \
-+do \
-+ if (yychar == YYEMPTY && yylen == 1) \
-+ { \
-+ yychar = (Token); \
-+ yylval = (Value); \
-+ yytoken = YYTRANSLATE (yychar); \
-+ YYPOPSTACK (1); \
-+ goto yybackup; \
-+ } \
-+ else \
-+ { \
-+ yyerror (YY_("syntax error: cannot back up")); \
-+ YYERROR; \
-+ } \
-+while (YYID (0))
-+
-+
-+#define YYTERROR 1
-+#define YYERRCODE 256
-+
-+
-+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
-+ If N is 0, then set CURRENT to the empty location which ends
-+ the previous symbol: RHS[0] (always defined). */
-+
-+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-+#ifndef YYLLOC_DEFAULT
-+# define YYLLOC_DEFAULT(Current, Rhs, N) \
-+ do \
-+ if (YYID (N)) \
-+ { \
-+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
-+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
-+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
-+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
-+ } \
-+ else \
-+ { \
-+ (Current).first_line = (Current).last_line = \
-+ YYRHSLOC (Rhs, 0).last_line; \
-+ (Current).first_column = (Current).last_column = \
-+ YYRHSLOC (Rhs, 0).last_column; \
-+ } \
-+ while (YYID (0))
-+#endif
-+
-+
-+/* YY_LOCATION_PRINT -- Print the location on the stream.
-+ This macro was not mandated originally: define only if we know
-+ we won't break user code: when these are the locations we know. */
-+
-+#ifndef YY_LOCATION_PRINT
-+# if YYLTYPE_IS_TRIVIAL
-+# define YY_LOCATION_PRINT(File, Loc) \
-+ fprintf (File, "%d.%d-%d.%d", \
-+ (Loc).first_line, (Loc).first_column, \
-+ (Loc).last_line, (Loc).last_column)
-+# else
-+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-+# endif
-+#endif
-+
-+
-+/* YYLEX -- calling `yylex' with the right arguments. */
-+
-+#ifdef YYLEX_PARAM
-+# define YYLEX yylex (YYLEX_PARAM)
-+#else
-+# define YYLEX yylex ()
-+#endif
-+
-+/* Enable debugging if requested. */
-+#if YYDEBUG
-+
-+# ifndef YYFPRINTF
-+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-+# define YYFPRINTF fprintf
-+# endif
-+
-+# define YYDPRINTF(Args) \
-+do { \
-+ if (yydebug) \
-+ YYFPRINTF Args; \
-+} while (YYID (0))
-+
-+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-+do { \
-+ if (yydebug) \
-+ { \
-+ YYFPRINTF (stderr, "%s ", Title); \
-+ yy_symbol_print (stderr, \
-+ Type, Value); \
-+ YYFPRINTF (stderr, "\n"); \
-+ } \
-+} while (YYID (0))
-+
-+
-+/*--------------------------------.
-+| Print this symbol on YYOUTPUT. |
-+`--------------------------------*/
-+
-+/*ARGSUSED*/
-+#if (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+static void
-+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-+#else
-+static void
-+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
-+ FILE *yyoutput;
-+ int yytype;
-+ YYSTYPE const * const yyvaluep;
-+#endif
-+{
-+ if (!yyvaluep)
-+ return;
-+# ifdef YYPRINT
-+ if (yytype < YYNTOKENS)
-+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-+# else
-+ YYUSE (yyoutput);
-+# endif
-+ switch (yytype)
-+ {
-+ default:
-+ break;
-+ }
-+}
-+
-+
-+/*--------------------------------.
-+| Print this symbol on YYOUTPUT. |
-+`--------------------------------*/
-+
-+#if (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+static void
-+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
-+#else
-+static void
-+yy_symbol_print (yyoutput, yytype, yyvaluep)
-+ FILE *yyoutput;
-+ int yytype;
-+ YYSTYPE const * const yyvaluep;
-+#endif
-+{
-+ if (yytype < YYNTOKENS)
-+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-+ else
-+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-+
-+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
-+ YYFPRINTF (yyoutput, ")");
-+}
-+
-+/*------------------------------------------------------------------.
-+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-+| TOP (included). |
-+`------------------------------------------------------------------*/
-+
-+#if (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+static void
-+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
-+#else
-+static void
-+yy_stack_print (bottom, top)
-+ yytype_int16 *bottom;
-+ yytype_int16 *top;
-+#endif
-+{
-+ YYFPRINTF (stderr, "Stack now");
-+ for (; bottom <= top; ++bottom)
-+ YYFPRINTF (stderr, " %d", *bottom);
-+ YYFPRINTF (stderr, "\n");
-+}
-+
-+# define YY_STACK_PRINT(Bottom, Top) \
-+do { \
-+ if (yydebug) \
-+ yy_stack_print ((Bottom), (Top)); \
-+} while (YYID (0))
-+
-+
-+/*------------------------------------------------.
-+| Report that the YYRULE is going to be reduced. |
-+`------------------------------------------------*/
-+
-+#if (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+static void
-+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
-+#else
-+static void
-+yy_reduce_print (yyvsp, yyrule)
-+ YYSTYPE *yyvsp;
-+ int yyrule;
-+#endif
-+{
-+ int yynrhs = yyr2[yyrule];
-+ int yyi;
-+ unsigned long int yylno = yyrline[yyrule];
-+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
-+ yyrule - 1, yylno);
-+ /* The symbols being reduced. */
-+ for (yyi = 0; yyi < yynrhs; yyi++)
-+ {
-+ fprintf (stderr, " $%d = ", yyi + 1);
-+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
-+ &(yyvsp[(yyi + 1) - (yynrhs)])
-+ );
-+ fprintf (stderr, "\n");
-+ }
-+}
-+
-+# define YY_REDUCE_PRINT(Rule) \
-+do { \
-+ if (yydebug) \
-+ yy_reduce_print (yyvsp, Rule); \
-+} while (YYID (0))
-+
-+/* Nonzero means print parse trace. It is left uninitialized so that
-+ multiple parsers can coexist. */
-+int yydebug;
-+#else /* !YYDEBUG */
-+# define YYDPRINTF(Args)
-+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-+# define YY_STACK_PRINT(Bottom, Top)
-+# define YY_REDUCE_PRINT(Rule)
-+#endif /* !YYDEBUG */
-+
-+
-+/* YYINITDEPTH -- initial size of the parser's stacks. */
-+#ifndef YYINITDEPTH
-+# define YYINITDEPTH 200
-+#endif
-+
-+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
-+ if the built-in stack extension method is used).
-+
-+ Do not make this value too large; the results are undefined if
-+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
-+ evaluated with infinite-precision integer arithmetic. */
-+
-+#ifndef YYMAXDEPTH
-+# define YYMAXDEPTH 10000
-+#endif
-+
-+
-+
-+#if YYERROR_VERBOSE
-+
-+# ifndef yystrlen
-+# if defined __GLIBC__ && defined _STRING_H
-+# define yystrlen strlen
-+# else
-+/* Return the length of YYSTR. */
-+#if (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+static YYSIZE_T
-+yystrlen (const char *yystr)
-+#else
-+static YYSIZE_T
-+yystrlen (yystr)
-+ const char *yystr;
-+#endif
-+{
-+ YYSIZE_T yylen;
-+ for (yylen = 0; yystr[yylen]; yylen++)
-+ continue;
-+ return yylen;
-+}
-+# endif
-+# endif
-+
-+# ifndef yystpcpy
-+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-+# define yystpcpy stpcpy
-+# else
-+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
-+ YYDEST. */
-+#if (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+static char *
-+yystpcpy (char *yydest, const char *yysrc)
-+#else
-+static char *
-+yystpcpy (yydest, yysrc)
-+ char *yydest;
-+ const char *yysrc;
-+#endif
-+{
-+ char *yyd = yydest;
-+ const char *yys = yysrc;
-+
-+ while ((*yyd++ = *yys++) != '\0')
-+ continue;
-+
-+ return yyd - 1;
-+}
-+# endif
-+# endif
-+
-+# ifndef yytnamerr
-+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
-+ quotes and backslashes, so that it's suitable for yyerror. The
-+ heuristic is that double-quoting is unnecessary unless the string
-+ contains an apostrophe, a comma, or backslash (other than
-+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
-+ null, do not copy; instead, return the length of what the result
-+ would have been. */
-+static YYSIZE_T
-+yytnamerr (char *yyres, const char *yystr)
-+{
-+ if (*yystr == '"')
-+ {
-+ YYSIZE_T yyn = 0;
-+ char const *yyp = yystr;
-+
-+ for (;;)
-+ switch (*++yyp)
-+ {
-+ case '\'':
-+ case ',':
-+ goto do_not_strip_quotes;
-+
-+ case '\\':
-+ if (*++yyp != '\\')
-+ goto do_not_strip_quotes;
-+ /* Fall through. */
-+ default:
-+ if (yyres)
-+ yyres[yyn] = *yyp;
-+ yyn++;
-+ break;
-+
-+ case '"':
-+ if (yyres)
-+ yyres[yyn] = '\0';
-+ return yyn;
-+ }
-+ do_not_strip_quotes: ;
-+ }
-+
-+ if (! yyres)
-+ return yystrlen (yystr);
-+
-+ return yystpcpy (yyres, yystr) - yyres;
-+}
-+# endif
-+
-+/* Copy into YYRESULT an error message about the unexpected token
-+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
-+ including the terminating null byte. If YYRESULT is null, do not
-+ copy anything; just return the number of bytes that would be
-+ copied. As a special case, return 0 if an ordinary "syntax error"
-+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
-+ size calculation. */
-+static YYSIZE_T
-+yysyntax_error (char *yyresult, int yystate, int yychar)
-+{
-+ int yyn = yypact[yystate];
-+
-+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-+ return 0;
-+ else
-+ {
-+ int yytype = YYTRANSLATE (yychar);
-+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
-+ YYSIZE_T yysize = yysize0;
-+ YYSIZE_T yysize1;
-+ int yysize_overflow = 0;
-+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-+ int yyx;
-+
-+# if 0
-+ /* This is so xgettext sees the translatable formats that are
-+ constructed on the fly. */
-+ YY_("syntax error, unexpected %s");
-+ YY_("syntax error, unexpected %s, expecting %s");
-+ YY_("syntax error, unexpected %s, expecting %s or %s");
-+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
-+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-+# endif
-+ char *yyfmt;
-+ char const *yyf;
-+ static char const yyunexpected[] = "syntax error, unexpected %s";
-+ static char const yyexpecting[] = ", expecting %s";
-+ static char const yyor[] = " or %s";
-+ char yyformat[sizeof yyunexpected
-+ + sizeof yyexpecting - 1
-+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
-+ * (sizeof yyor - 1))];
-+ char const *yyprefix = yyexpecting;
-+
-+ /* Start YYX at -YYN if negative to avoid negative indexes in
-+ YYCHECK. */
-+ int yyxbegin = yyn < 0 ? -yyn : 0;
-+
-+ /* Stay within bounds of both yycheck and yytname. */
-+ int yychecklim = YYLAST - yyn + 1;
-+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-+ int yycount = 1;
-+
-+ yyarg[0] = yytname[yytype];
-+ yyfmt = yystpcpy (yyformat, yyunexpected);
-+
-+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-+ {
-+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-+ {
-+ yycount = 1;
-+ yysize = yysize0;
-+ yyformat[sizeof yyunexpected - 1] = '\0';
-+ break;
-+ }
-+ yyarg[yycount++] = yytname[yyx];
-+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-+ yysize_overflow |= (yysize1 < yysize);
-+ yysize = yysize1;
-+ yyfmt = yystpcpy (yyfmt, yyprefix);
-+ yyprefix = yyor;
-+ }
-+
-+ yyf = YY_(yyformat);
-+ yysize1 = yysize + yystrlen (yyf);
-+ yysize_overflow |= (yysize1 < yysize);
-+ yysize = yysize1;
-+
-+ if (yysize_overflow)
-+ return YYSIZE_MAXIMUM;
-+
-+ if (yyresult)
-+ {
-+ /* Avoid sprintf, as that infringes on the user's name space.
-+ Don't have undefined behavior even if the translation
-+ produced a string with the wrong number of "%s"s. */
-+ char *yyp = yyresult;
-+ int yyi = 0;
-+ while ((*yyp = *yyf) != '\0')
-+ {
-+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
-+ {
-+ yyp += yytnamerr (yyp, yyarg[yyi++]);
-+ yyf += 2;
-+ }
-+ else
-+ {
-+ yyp++;
-+ yyf++;
-+ }
-+ }
-+ }
-+ return yysize;
-+ }
-+}
-+#endif /* YYERROR_VERBOSE */
-+
-+
-+/*-----------------------------------------------.
-+| Release the memory associated to this symbol. |
-+`-----------------------------------------------*/
-+
-+/*ARGSUSED*/
-+#if (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+static void
-+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
-+#else
-+static void
-+yydestruct (yymsg, yytype, yyvaluep)
-+ const char *yymsg;
-+ int yytype;
-+ YYSTYPE *yyvaluep;
-+#endif
-+{
-+ YYUSE (yyvaluep);
-+
-+ if (!yymsg)
-+ yymsg = "Deleting";
-+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-+
-+ switch (yytype)
-+ {
-+
-+ default:
-+ break;
-+ }
-+}
-+
-+
-+/* Prevent warnings from -Wmissing-prototypes. */
-+
-+#ifdef YYPARSE_PARAM
-+#if defined __STDC__ || defined __cplusplus
-+int yyparse (void *YYPARSE_PARAM);
-+#else
-+int yyparse ();
-+#endif
-+#else /* ! YYPARSE_PARAM */
-+#if defined __STDC__ || defined __cplusplus
-+int yyparse (void);
-+#else
-+int yyparse ();
-+#endif
-+#endif /* ! YYPARSE_PARAM */
-+
-+
-+
-+/* The look-ahead symbol. */
-+int yychar;
-+
-+/* The semantic value of the look-ahead symbol. */
-+YYSTYPE yylval;
-+
-+/* Number of syntax errors so far. */
-+int yynerrs;
-+
-+
-+
-+/*----------.
-+| yyparse. |
-+`----------*/
-+
-+#ifdef YYPARSE_PARAM
-+#if (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+int
-+yyparse (void *YYPARSE_PARAM)
-+#else
-+int
-+yyparse (YYPARSE_PARAM)
-+ void *YYPARSE_PARAM;
-+#endif
-+#else /* ! YYPARSE_PARAM */
-+#if (defined __STDC__ || defined __C99__FUNC__ \
-+ || defined __cplusplus || defined _MSC_VER)
-+int
-+yyparse (void)
-+#else
-+int
-+yyparse ()
-+
-+#endif
-+#endif
-+{
-+
-+ int yystate;
-+ int yyn;
-+ int yyresult;
-+ /* Number of tokens to shift before error messages enabled. */
-+ int yyerrstatus;
-+ /* Look-ahead token as an internal (translated) token number. */
-+ int yytoken = 0;
-+#if YYERROR_VERBOSE
-+ /* Buffer for error messages, and its allocated size. */
-+ char yymsgbuf[128];
-+ char *yymsg = yymsgbuf;
-+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-+#endif
-+
-+ /* Three stacks and their tools:
-+ `yyss': related to states,
-+ `yyvs': related to semantic values,
-+ `yyls': related to locations.
-+
-+ Refer to the stacks thru separate pointers, to allow yyoverflow
-+ to reallocate them elsewhere. */
-+
-+ /* The state stack. */
-+ yytype_int16 yyssa[YYINITDEPTH];
-+ yytype_int16 *yyss = yyssa;
-+ yytype_int16 *yyssp;
-+
-+ /* The semantic value stack. */
-+ YYSTYPE yyvsa[YYINITDEPTH];
-+ YYSTYPE *yyvs = yyvsa;
-+ YYSTYPE *yyvsp;
-+
-+
-+
-+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
-+
-+ YYSIZE_T yystacksize = YYINITDEPTH;
-+
-+ /* The variables used to return semantic value and location from the
-+ action routines. */
-+ YYSTYPE yyval;
-+
-+
-+ /* The number of symbols on the RHS of the reduced rule.
-+ Keep to zero when no symbol should be popped. */
-+ int yylen = 0;
-+
-+ YYDPRINTF ((stderr, "Starting parse\n"));
-+
-+ yystate = 0;
-+ yyerrstatus = 0;
-+ yynerrs = 0;
-+ yychar = YYEMPTY; /* Cause a token to be read. */
-+
-+ /* Initialize stack pointers.
-+ Waste one element of value and location stack
-+ so that they stay on the same level as the state stack.
-+ The wasted elements are never initialized. */
-+
-+ yyssp = yyss;
-+ yyvsp = yyvs;
-+
-+ goto yysetstate;
-+
-+/*------------------------------------------------------------.
-+| yynewstate -- Push a new state, which is found in yystate. |
-+`------------------------------------------------------------*/
-+ yynewstate:
-+ /* In all cases, when you get here, the value and location stacks
-+ have just been pushed. So pushing a state here evens the stacks. */
-+ yyssp++;
-+
-+ yysetstate:
-+ *yyssp = yystate;
-+
-+ if (yyss + yystacksize - 1 <= yyssp)
-+ {
-+ /* Get the current used size of the three stacks, in elements. */
-+ YYSIZE_T yysize = yyssp - yyss + 1;
-+
-+#ifdef yyoverflow
-+ {
-+ /* Give user a chance to reallocate the stack. Use copies of
-+ these so that the &'s don't force the real ones into
-+ memory. */
-+ YYSTYPE *yyvs1 = yyvs;
-+ yytype_int16 *yyss1 = yyss;
-+
-+
-+ /* Each stack pointer address is followed by the size of the
-+ data in use in that stack, in bytes. This used to be a
-+ conditional around just the two extra args, but that might
-+ be undefined if yyoverflow is a macro. */
-+ yyoverflow (YY_("memory exhausted"),
-+ &yyss1, yysize * sizeof (*yyssp),
-+ &yyvs1, yysize * sizeof (*yyvsp),
-+
-+ &yystacksize);
-+
-+ yyss = yyss1;
-+ yyvs = yyvs1;
-+ }
-+#else /* no yyoverflow */
-+# ifndef YYSTACK_RELOCATE
-+ goto yyexhaustedlab;
-+# else
-+ /* Extend the stack our own way. */
-+ if (YYMAXDEPTH <= yystacksize)
-+ goto yyexhaustedlab;
-+ yystacksize *= 2;
-+ if (YYMAXDEPTH < yystacksize)
-+ yystacksize = YYMAXDEPTH;
-+
-+ {
-+ yytype_int16 *yyss1 = yyss;
-+ union yyalloc *yyptr =
-+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-+ if (! yyptr)
-+ goto yyexhaustedlab;
-+ YYSTACK_RELOCATE (yyss);
-+ YYSTACK_RELOCATE (yyvs);
-+
-+# undef YYSTACK_RELOCATE
-+ if (yyss1 != yyssa)
-+ YYSTACK_FREE (yyss1);
-+ }
-+# endif
-+#endif /* no yyoverflow */
-+
-+ yyssp = yyss + yysize - 1;
-+ yyvsp = yyvs + yysize - 1;
-+
-+
-+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-+ (unsigned long int) yystacksize));
-+
-+ if (yyss + yystacksize - 1 <= yyssp)
-+ YYABORT;
-+ }
-+
-+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-+
-+ goto yybackup;
-+
-+/*-----------.
-+| yybackup. |
-+`-----------*/
-+yybackup:
-+
-+ /* Do appropriate processing given the current state. Read a
-+ look-ahead token if we need one and don't already have one. */
-+
-+ /* First try to decide what to do without reference to look-ahead token. */
-+ yyn = yypact[yystate];
-+ if (yyn == YYPACT_NINF)
-+ goto yydefault;
-+
-+ /* Not known => get a look-ahead token if don't already have one. */
-+
-+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
-+ if (yychar == YYEMPTY)
-+ {
-+ YYDPRINTF ((stderr, "Reading a token: "));
-+ yychar = YYLEX;
-+ }
-+
-+ if (yychar <= YYEOF)
-+ {
-+ yychar = yytoken = YYEOF;
-+ YYDPRINTF ((stderr, "Now at end of input.\n"));
-+ }
-+ else
-+ {
-+ yytoken = YYTRANSLATE (yychar);
-+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
-+ }
-+
-+ /* If the proper action on seeing token YYTOKEN is to reduce or to
-+ detect an error, take that action. */
-+ yyn += yytoken;
-+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
-+ goto yydefault;
-+ yyn = yytable[yyn];
-+ if (yyn <= 0)
-+ {
-+ if (yyn == 0 || yyn == YYTABLE_NINF)
-+ goto yyerrlab;
-+ yyn = -yyn;
-+ goto yyreduce;
-+ }
-+
-+ if (yyn == YYFINAL)
-+ YYACCEPT;
-+
-+ /* Count tokens shifted since error; after three, turn off error
-+ status. */
-+ if (yyerrstatus)
-+ yyerrstatus--;
-+
-+ /* Shift the look-ahead token. */
-+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-+
-+ /* Discard the shifted token unless it is eof. */
-+ if (yychar != YYEOF)
-+ yychar = YYEMPTY;
-+
-+ yystate = yyn;
-+ *++yyvsp = yylval;
-+
-+ goto yynewstate;
-+
-+
-+/*-----------------------------------------------------------.
-+| yydefault -- do the default action for the current state. |
-+`-----------------------------------------------------------*/
-+yydefault:
-+ yyn = yydefact[yystate];
-+ if (yyn == 0)
-+ goto yyerrlab;
-+ goto yyreduce;
-+
-+
-+/*-----------------------------.
-+| yyreduce -- Do a reduction. |
-+`-----------------------------*/
-+yyreduce:
-+ /* yyn is the number of a rule to reduce with. */
-+ yylen = yyr2[yyn];
-+
-+ /* If YYLEN is nonzero, implement the default value of the action:
-+ `$$ = $1'.
-+
-+ Otherwise, the following line sets YYVAL to garbage.
-+ This behavior is undocumented and Bison
-+ users should not rely upon it. Assigning to YYVAL
-+ unconditionally makes the parser a bit smaller, and it avoids a
-+ GCC warning that YYVAL may be used uninitialized. */
-+ yyval = yyvsp[1-yylen];
-+
-+
-+ YY_REDUCE_PRINT (yyn);
-+ switch (yyn)
-+ {
-+ case 2:
-+#line 211 "parse.y"
-+ { root=(yyvsp[(1) - (1)].node) ; ;}
-+ break;
-+
-+ case 5:
-+#line 216 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node));;}
-+ break;
-+
-+ case 8:
-+#line 220 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (2)].opinfo),(yyvsp[(1) - (2)].node),0); ;}
-+ break;
-+
-+ case 10:
-+#line 223 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 11:
-+#line 226 "parse.y"
-+ { decl_tbase=(yyvsp[(1) - (1)].ctype) ; ;}
-+ break;
-+
-+ case 12:
-+#line 226 "parse.y"
-+ { (yyval.node)=(yyvsp[(3) - (3)].node) ; ;}
-+ break;
-+
-+ case 14:
-+#line 229 "parse.y"
-+ { (yyval.node)=mknode_sbin(seq_op,(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 15:
-+#line 232 "parse.y"
-+ { (yyval.node)=mknode_sbin(decl_op,(yyvsp[(1) - (1)].node),
-+ mknode_modified_ctype(decl_tbase)); ;}
-+ break;
-+
-+ case 16:
-+#line 236 "parse.y"
-+ { (yyval.node)=(yyvsp[(2) - (3)].node) ; ;}
-+ break;
-+
-+ case 17:
-+#line 237 "parse.y"
-+ { (yyval.node)=(yyvsp[(2) - (5)].node) ; push_type('('); ;}
-+ break;
-+
-+ case 18:
-+#line 238 "parse.y"
-+ { (yyval.node)=(yyvsp[(2) - (2)].node) ; push_type('*'); ;}
-+ break;
-+
-+ case 19:
-+#line 239 "parse.y"
-+ { (yyval.node)=(yyvsp[(1) - (4)].node) ; push_type_int('[',(yyvsp[(3) - (4)].node)); ;}
-+ break;
-+
-+ case 21:
-+#line 251 "parse.y"
-+ { (yyval.node)=mknode_tri((yyvsp[(1) - (5)].opinfo),(yyvsp[(3) - (5)].node),(yyvsp[(5) - (5)].node),0); ;}
-+ break;
-+
-+ case 22:
-+#line 253 "parse.y"
-+ { (yyval.node)=mknode_tri((yyvsp[(1) - (6)].opinfo),(yyvsp[(3) - (6)].node),(yyvsp[(5) - (6)].node),0); ;}
-+ break;
-+
-+ case 23:
-+#line 255 "parse.y"
-+ { (yyval.node)=mknode_tri((yyvsp[(1) - (6)].opinfo),(yyvsp[(3) - (6)].node),0,(yyvsp[(6) - (6)].node)); ;}
-+ break;
-+
-+ case 24:
-+#line 257 "parse.y"
-+ { (yyval.node)=mknode_tri((yyvsp[(1) - (7)].opinfo),(yyvsp[(3) - (7)].node),(yyvsp[(5) - (7)].node),(yyvsp[(7) - (7)].node)); ;}
-+ break;
-+
-+ case 25:
-+#line 260 "parse.y"
-+ { (yyval.node)=mknode_op(OPK_QUAD,(yyvsp[(1) - (9)].opinfo),(yyvsp[(3) - (9)].node),(yyvsp[(5) - (9)].node),(yyvsp[(7) - (9)].node),(yyvsp[(9) - (9)].node)); ;}
-+ break;
-+
-+ case 26:
-+#line 262 "parse.y"
-+ { (yyval.node)=mknode_op(OPK_QUAD,(yyvsp[(1) - (8)].opinfo),(yyvsp[(3) - (8)].node),(yyvsp[(5) - (8)].node),(yyvsp[(7) - (8)].node),0); ;}
-+ break;
-+
-+ case 27:
-+#line 264 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(1) - (5)].opinfo),(yyvsp[(3) - (5)].node),(yyvsp[(5) - (5)].node)); ;}
-+ break;
-+
-+ case 28:
-+#line 266 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(1) - (4)].opinfo),(yyvsp[(3) - (4)].node),0); ;}
-+ break;
-+
-+ case 29:
-+#line 271 "parse.y"
-+ { (yyval.node)=mknode_unary( (yyvsp[(1) - (2)].opinfo),(yyvsp[(2) - (2)].node)); ;}
-+ break;
-+
-+ case 30:
-+#line 272 "parse.y"
-+ { (yyval.node)=mknode_unary( (yyvsp[(1) - (2)].opinfo),(yyvsp[(2) - (2)].node)); ;}
-+ break;
-+
-+ case 31:
-+#line 273 "parse.y"
-+ { (yyval.node)=mknode_unary( (yyvsp[(1) - (2)].opinfo),(yyvsp[(2) - (2)].node)); ;}
-+ break;
-+
-+ case 32:
-+#line 274 "parse.y"
-+ { (yyval.node)=mknode_unary( (yyvsp[(1) - (2)].opinfo),(yyvsp[(2) - (2)].node)); ;}
-+ break;
-+
-+ case 33:
-+#line 275 "parse.y"
-+ { (yyval.node)=mknode_unary( (yyvsp[(1) - (2)].opinfo),(yyvsp[(2) - (2)].node)); ;}
-+ break;
-+
-+ case 34:
-+#line 276 "parse.y"
-+ { (yyval.node)=mknode_sunary((yyvsp[(1) - (2)].opinfo),(yyvsp[(2) - (2)].node)); ;}
-+ break;
-+
-+ case 35:
-+#line 277 "parse.y"
-+ { (yyval.node)=mknode_sunary((yyvsp[(1) - (2)].opinfo),(yyvsp[(2) - (2)].node)); ;}
-+ break;
-+
-+ case 36:
-+#line 278 "parse.y"
-+ { (yyval.node)=mknode_sunary((yyvsp[(1) - (2)].opinfo),(yyvsp[(2) - (2)].node)); ;}
-+ break;
-+
-+ case 37:
-+#line 279 "parse.y"
-+ { (yyval.node)=mknode_unary( (yyvsp[(1) - (2)].opinfo),(yyvsp[(2) - (2)].node)); ;}
-+ break;
-+
-+ case 38:
-+#line 280 "parse.y"
-+ { (yyval.node)=mknode_unary( (yyvsp[(1) - (2)].opinfo),(yyvsp[(2) - (2)].node)); ;}
-+ break;
-+
-+ case 39:
-+#line 281 "parse.y"
-+ { (yyval.node)=mknode_post_unary((yyvsp[(2) - (2)].opinfo),(yyvsp[(1) - (2)].node)); ;}
-+ break;
-+
-+ case 40:
-+#line 282 "parse.y"
-+ { (yyval.node)=mknode_post_unary((yyvsp[(2) - (2)].opinfo),(yyvsp[(1) - (2)].node)); ;}
-+ break;
-+
-+ case 41:
-+#line 283 "parse.y"
-+ { (yyval.node)=mknode_sunary((yyvsp[(1) - (4)].opinfo),(yyvsp[(3) - (4)].node)); ;}
-+ break;
-+
-+ case 42:
-+#line 284 "parse.y"
-+ { (yyval.node)=mknode_unary((yyvsp[(1) - (4)].opinfo),(yyvsp[(3) - (4)].node)); ;}
-+ break;
-+
-+ case 43:
-+#line 285 "parse.y"
-+ { (yyval.node)=mknode_unary( (yyvsp[(1) - (4)].opinfo),(yyvsp[(3) - (4)].node)); ;}
-+ break;
-+
-+ case 44:
-+#line 288 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 45:
-+#line 289 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 46:
-+#line 291 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 47:
-+#line 292 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 48:
-+#line 293 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 49:
-+#line 294 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 50:
-+#line 295 "parse.y"
-+ { (yyval.node)=mknode_bin( (yyvsp[(2) - (4)].opinfo),(yyvsp[(1) - (4)].node),(yyvsp[(3) - (4)].node)); ;}
-+ break;
-+
-+ case 51:
-+#line 296 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (4)].opinfo),(yyvsp[(1) - (4)].node),(yyvsp[(3) - (4)].node)); ;}
-+ break;
-+
-+ case 52:
-+#line 297 "parse.y"
-+ { (yyval.node)=mknode_op(OPK_FUNC,(yyvsp[(2) - (4)].opinfo),(yyvsp[(1) - (4)].node),(yyvsp[(3) - (4)].node),0,0); ;}
-+ break;
-+
-+ case 53:
-+#line 298 "parse.y"
-+ { (yyval.node)=mknode_unary((yyvsp[(1) - (3)].opinfo),(yyvsp[(2) - (3)].node)); ;}
-+ break;
-+
-+ case 54:
-+#line 299 "parse.y"
-+ { (yyval.node)=mknode_unary((yyvsp[(1) - (3)].opinfo),(yyvsp[(2) - (3)].node)); ;}
-+ break;
-+
-+ case 55:
-+#line 303 "parse.y"
-+ { (yyval.node)=mknode_op(OPK_CAST,(yyvsp[(1) - (4)].opinfo),(yyvsp[(2) - (4)].node),(yyvsp[(4) - (4)].node),0,0); ;}
-+ break;
-+
-+ case 56:
-+#line 313 "parse.y"
-+ {
-+ tctype *t=duel_get_target_typedef((yyvsp[(2) - (4)].nameinfo).name);
-+ if(t==NULL) yyerror("not a typedef name");
-+ (yyval.node)=mknode_op(OPK_CAST,(yyvsp[(1) - (4)].opinfo),mknode_ctype(t),(yyvsp[(4) - (4)].node),0,0); ;}
-+ break;
-+
-+ case 57:
-+#line 317 "parse.y"
-+ {
-+ tctype *t=duel_get_target_typedef((yyvsp[(2) - (6)].nameinfo).name);
-+ if(t==NULL) yyerror("not a typedef name");
-+ push_type('*');
-+ (yyval.node)=mknode_op(OPK_CAST,(yyvsp[(1) - (6)].opinfo),mknode_modified_ctype(t),(yyvsp[(6) - (6)].node),0,0); ;}
-+ break;
-+
-+ case 58:
-+#line 326 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 59:
-+#line 327 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 60:
-+#line 328 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 61:
-+#line 329 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 62:
-+#line 330 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 63:
-+#line 331 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 64:
-+#line 332 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 65:
-+#line 333 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 66:
-+#line 334 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 67:
-+#line 335 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 68:
-+#line 336 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 69:
-+#line 337 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 70:
-+#line 338 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 71:
-+#line 339 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 72:
-+#line 340 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 73:
-+#line 341 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 74:
-+#line 342 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 75:
-+#line 343 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 76:
-+#line 344 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 77:
-+#line 345 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 78:
-+#line 346 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 79:
-+#line 347 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 80:
-+#line 348 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 81:
-+#line 349 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 82:
-+#line 353 "parse.y"
-+ { (yyval.node)=mknode_tri((yyvsp[(2) - (5)].opinfo),(yyvsp[(1) - (5)].node),(yyvsp[(3) - (5)].node),(yyvsp[(5) - (5)].node)); ;}
-+ break;
-+
-+ case 83:
-+#line 356 "parse.y"
-+ { (yyval.node)=mknode_bin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 84:
-+#line 357 "parse.y"
-+ { (yyval.node)=mknode_op(OPK_ASSIGN,(yyvsp[(2) - (3)].opinfo), (yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node),0,0); ;}
-+ break;
-+
-+ case 85:
-+#line 358 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 86:
-+#line 363 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 87:
-+#line 364 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(1) - (2)].opinfo), 0,(yyvsp[(2) - (2)].node)); ;}
-+ break;
-+
-+ case 88:
-+#line 365 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (2)].opinfo),(yyvsp[(1) - (2)].node), 0); ;}
-+ break;
-+
-+ case 89:
-+#line 366 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 90:
-+#line 367 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 91:
-+#line 370 "parse.y"
-+ { (yyval.node)=mknode_sbin((yyvsp[(2) - (3)].opinfo),(yyvsp[(1) - (3)].node),(yyvsp[(3) - (3)].node)); ;}
-+ break;
-+
-+ case 94:
-+#line 375 "parse.y"
-+ { (yyval.node)=0 ; ;}
-+ break;
-+
-+ case 97:
-+#line 385 "parse.y"
-+ { (yyval.node)=mknode_name((yyvsp[(1) - (1)].nameinfo)) ; ;}
-+ break;
-+
-+ case 98:
-+#line 387 "parse.y"
-+ { (yyval.node)=mknode_modified_ctype((yyvsp[(1) - (2)].ctype)); ;}
-+ break;
-+
-+ case 100:
-+#line 393 "parse.y"
-+ { push_type('('); ;}
-+ break;
-+
-+ case 101:
-+#line 394 "parse.y"
-+ { push_type('*'); ;}
-+ break;
-+
-+ case 102:
-+#line 395 "parse.y"
-+ { push_type_int('[',(yyvsp[(3) - (4)].node)); ;}
-+ break;
-+
-+ case 104:
-+#line 413 "parse.y"
-+ {
-+ (yyval.ctype)=duel_get_target_typedef((yyvsp[(2) - (2)].nameinfo).name);
-+ if((yyval.ctype)==NULL) {
-+ tvalue v;
-+ if(duel_get_target_variable((yyvsp[(2) - (2)].nameinfo).name,-1,&v)) (yyval.ctype)=v.ctype;
-+ else yyerror("not a typedef name");
-+ }
-+ ;}
-+ break;
-+
-+ case 105:
-+#line 423 "parse.y"
-+ { (yyval.ctype) = ctype_char; ;}
-+ break;
-+
-+ case 106:
-+#line 424 "parse.y"
-+ { (yyval.ctype) = ctype_schar; ;}
-+ break;
-+
-+ case 107:
-+#line 425 "parse.y"
-+ { (yyval.ctype) = ctype_uchar; ;}
-+ break;
-+
-+ case 108:
-+#line 426 "parse.y"
-+ { (yyval.ctype) = ctype_int; ;}
-+ break;
-+
-+ case 109:
-+#line 427 "parse.y"
-+ { (yyval.ctype) = ctype_uint; ;}
-+ break;
-+
-+ case 110:
-+#line 428 "parse.y"
-+ { (yyval.ctype) = ctype_uint; ;}
-+ break;
-+
-+ case 111:
-+#line 429 "parse.y"
-+ { (yyval.ctype) = ctype_long; ;}
-+ break;
-+
-+ case 112:
-+#line 430 "parse.y"
-+ { (yyval.ctype) = ctype_long; ;}
-+ break;
-+
-+ case 113:
-+#line 431 "parse.y"
-+ { (yyval.ctype) = ctype_ulong; ;}
-+ break;
-+
-+ case 114:
-+#line 432 "parse.y"
-+ { (yyval.ctype) = ctype_ulong; ;}
-+ break;
-+
-+ case 115:
-+#line 433 "parse.y"
-+ { (yyval.ctype) = ctype_longlong; ;}
-+ break;
-+
-+ case 116:
-+#line 434 "parse.y"
-+ { (yyval.ctype) = ctype_longlong; ;}
-+ break;
-+
-+ case 117:
-+#line 435 "parse.y"
-+ { (yyval.ctype) = ctype_ulonglong; ;}
-+ break;
-+
-+ case 118:
-+#line 436 "parse.y"
-+ { (yyval.ctype) = ctype_ulonglong; ;}
-+ break;
-+
-+ case 119:
-+#line 437 "parse.y"
-+ { (yyval.ctype) = ctype_short; ;}
-+ break;
-+
-+ case 120:
-+#line 438 "parse.y"
-+ { (yyval.ctype) = ctype_short; ;}
-+ break;
-+
-+ case 121:
-+#line 439 "parse.y"
-+ { (yyval.ctype) = ctype_ushort; ;}
-+ break;
-+
-+ case 122:
-+#line 440 "parse.y"
-+ { (yyval.ctype) = ctype_ushort; ;}
-+ break;
-+
-+ case 123:
-+#line 441 "parse.y"
-+ { (yyval.ctype) = ctype_float ; ;}
-+ break;
-+
-+ case 124:
-+#line 442 "parse.y"
-+ { (yyval.ctype) = ctype_double; ;}
-+ break;
-+
-+ case 125:
-+#line 443 "parse.y"
-+ { (yyval.ctype) = ctype_void; ;}
-+ break;
-+
-+ case 126:
-+#line 445 "parse.y"
-+ { (yyval.ctype) = duel_get_target_struct_tag((yyvsp[(2) - (2)].nameinfo).name);
-+ if((yyval.ctype)==NULL) yyerror("not a struct tag"); ;}
-+ break;
-+
-+ case 127:
-+#line 448 "parse.y"
-+ { (yyval.ctype) = duel_get_target_union_tag((yyvsp[(2) - (2)].nameinfo).name);
-+ if((yyval.ctype)==NULL) yyerror("not a union tag"); ;}
-+ break;
-+
-+ case 128:
-+#line 451 "parse.y"
-+ { (yyval.ctype) = duel_get_target_enum_tag((yyvsp[(2) - (2)].nameinfo).name);
-+ if((yyval.ctype)==NULL) yyerror("not an enum tag"); ;}
-+ break;
-+
-+
-+/* Line 1267 of yacc.c. */
-+#line 2627 "parse.c"
-+ default: break;
-+ }
-+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-+
-+ YYPOPSTACK (yylen);
-+ yylen = 0;
-+ YY_STACK_PRINT (yyss, yyssp);
-+
-+ *++yyvsp = yyval;
-+
-+
-+ /* Now `shift' the result of the reduction. Determine what state
-+ that goes to, based on the state we popped back to and the rule
-+ number reduced by. */
-+
-+ yyn = yyr1[yyn];
-+
-+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-+ yystate = yytable[yystate];
-+ else
-+ yystate = yydefgoto[yyn - YYNTOKENS];
-+
-+ goto yynewstate;
-+
-+
-+/*------------------------------------.
-+| yyerrlab -- here on detecting error |
-+`------------------------------------*/
-+yyerrlab:
-+ /* If not already recovering from an error, report this error. */
-+ if (!yyerrstatus)
-+ {
-+ ++yynerrs;
-+#if ! YYERROR_VERBOSE
-+ yyerror (YY_("syntax error"));
-+#else
-+ {
-+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
-+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
-+ {
-+ YYSIZE_T yyalloc = 2 * yysize;
-+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
-+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
-+ if (yymsg != yymsgbuf)
-+ YYSTACK_FREE (yymsg);
-+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
-+ if (yymsg)
-+ yymsg_alloc = yyalloc;
-+ else
-+ {
-+ yymsg = yymsgbuf;
-+ yymsg_alloc = sizeof yymsgbuf;
-+ }
-+ }
-+
-+ if (0 < yysize && yysize <= yymsg_alloc)
-+ {
-+ (void) yysyntax_error (yymsg, yystate, yychar);
-+ yyerror (yymsg);
-+ }
-+ else
-+ {
-+ yyerror (YY_("syntax error"));
-+ if (yysize != 0)
-+ goto yyexhaustedlab;
-+ }
-+ }
-+#endif
-+ }
-+
-+
-+
-+ if (yyerrstatus == 3)
-+ {
-+ /* If just tried and failed to reuse look-ahead token after an
-+ error, discard it. */
-+
-+ if (yychar <= YYEOF)
-+ {
-+ /* Return failure if at end of input. */
-+ if (yychar == YYEOF)
-+ YYABORT;
-+ }
-+ else
-+ {
-+ yydestruct ("Error: discarding",
-+ yytoken, &yylval);
-+ yychar = YYEMPTY;
-+ }
-+ }
-+
-+ /* Else will try to reuse look-ahead token after shifting the error
-+ token. */
-+ goto yyerrlab1;
-+
-+
-+/*---------------------------------------------------.
-+| yyerrorlab -- error raised explicitly by YYERROR. |
-+`---------------------------------------------------*/
-+yyerrorlab:
-+
-+ /* Pacify compilers like GCC when the user code never invokes
-+ YYERROR and the label yyerrorlab therefore never appears in user
-+ code. */
-+ if (/*CONSTCOND*/ 0)
-+ goto yyerrorlab;
-+
-+ /* Do not reclaim the symbols of the rule which action triggered
-+ this YYERROR. */
-+ YYPOPSTACK (yylen);
-+ yylen = 0;
-+ YY_STACK_PRINT (yyss, yyssp);
-+ yystate = *yyssp;
-+ goto yyerrlab1;
-+
-+
-+/*-------------------------------------------------------------.
-+| yyerrlab1 -- common code for both syntax error and YYERROR. |
-+`-------------------------------------------------------------*/
-+yyerrlab1:
-+ yyerrstatus = 3; /* Each real token shifted decrements this. */
-+
-+ for (;;)
-+ {
-+ yyn = yypact[yystate];
-+ if (yyn != YYPACT_NINF)
-+ {
-+ yyn += YYTERROR;
-+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
-+ {
-+ yyn = yytable[yyn];
-+ if (0 < yyn)
-+ break;
-+ }
-+ }
-+
-+ /* Pop the current state because it cannot handle the error token. */
-+ if (yyssp == yyss)
-+ YYABORT;
-+
-+
-+ yydestruct ("Error: popping",
-+ yystos[yystate], yyvsp);
-+ YYPOPSTACK (1);
-+ yystate = *yyssp;
-+ YY_STACK_PRINT (yyss, yyssp);
-+ }
-+
-+ if (yyn == YYFINAL)
-+ YYACCEPT;
-+
-+ *++yyvsp = yylval;
-+
-+
-+ /* Shift the error token. */
-+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-+
-+ yystate = yyn;
-+ goto yynewstate;
-+
-+
-+/*-------------------------------------.
-+| yyacceptlab -- YYACCEPT comes here. |
-+`-------------------------------------*/
-+yyacceptlab:
-+ yyresult = 0;
-+ goto yyreturn;
-+
-+/*-----------------------------------.
-+| yyabortlab -- YYABORT comes here. |
-+`-----------------------------------*/
-+yyabortlab:
-+ yyresult = 1;
-+ goto yyreturn;
-+
-+#ifndef yyoverflow
-+/*-------------------------------------------------.
-+| yyexhaustedlab -- memory exhaustion comes here. |
-+`-------------------------------------------------*/
-+yyexhaustedlab:
-+ yyerror (YY_("memory exhausted"));
-+ yyresult = 2;
-+ /* Fall through. */
-+#endif
-+
-+yyreturn:
-+ if (yychar != YYEOF && yychar != YYEMPTY)
-+ yydestruct ("Cleanup: discarding lookahead",
-+ yytoken, &yylval);
-+ /* Do not reclaim the symbols of the rule which action triggered
-+ this YYABORT or YYACCEPT. */
-+ YYPOPSTACK (yylen);
-+ YY_STACK_PRINT (yyss, yyssp);
-+ while (yyssp != yyss)
-+ {
-+ yydestruct ("Cleanup: popping",
-+ yystos[*yyssp], yyvsp);
-+ YYPOPSTACK (1);
-+ }
-+#ifndef yyoverflow
-+ if (yyss != yyssa)
-+ YYSTACK_FREE (yyss);
-+#endif
-+#if YYERROR_VERBOSE
-+ if (yymsg != yymsgbuf)
-+ YYSTACK_FREE (yymsg);
-+#endif
-+ /* Make sure YYID is used. */
-+ return YYID (yyresult);
-+}
-+
-+
-+#line 456 "parse.y"
-+
-+
-+static struct stoken { /* all opcodes we recognize */
-+ char *opstr ; /* op code as a string */
-+ int token ; /* token to return to yacc */
-+ int opcode ; /* opcode value associated with the token */
-+ } tokens[] = { /* the special tokens, longer ones 1st! */
-+ {">>=",T_ASSIGN, OP_RSH},
-+ {"<<=",T_ASSIGN, OP_LSH},
-+ {"-->",T_DFS, OP_DFS},
-+ {"->>",T_BFS, OP_BFS},
-+ {"==?", T_EQQ, OP_EQQ},
-+ {"!=?", T_NEQ, OP_NEQ},
-+ {"<=?", T_LEQ, OP_LEQ},
-+ {">=?", T_GEQ, OP_GEQ},
-+ {"&&/", T_ANDL, OP_AND},
-+ {"||/", T_ORL, OP_OR},
-+
-+ {"<?", T_LSQ, OP_LSQ},
-+ {">?", T_GTQ, OP_GTQ},
-+ {"#/", T_COUNT, '#' },
-+ {"%/", T_COUNT, '#' }, /* gdb insists to recognize # as start of comma!*/
-+ {"%%", '#', '#' }, /* same. so %/ for #/ and %% for #. not doc!*/
-+ {"+=", T_ASSIGN, '+'},
-+ {"-=", T_ASSIGN, '-'},
-+ {"*=", T_ASSIGN, '*'},
-+ {"/=", T_ASSIGN, '/'},
-+ {"%=", T_ASSIGN, '%'},
-+ {"|=", T_ASSIGN, '|'},
-+ {"&=", T_ASSIGN, '&'},
-+ {"^=", T_ASSIGN, '^'},
-+ {":=", T_DEFVAR,OP_DEF},
-+ {"++", T_INC, OP_INC },
-+ {"--", T_DEC, OP_DEC },
-+ {"->", T_ARROW, OP_ARR },
-+ {"&&", T_AND, OP_AND },
-+ {"||", T_OR, OP_OR },
-+ {"<<", T_LSH, OP_LSH },
-+ {">>", T_RSH, OP_RSH },
-+ {"==", T_EQ, OP_EQ },
-+ {"!=", T_NE, OP_NE },
-+ {"<=", T_LE, OP_LE },
-+ {">=", T_GE, OP_GE },
-+ {"..", T_TO, OP_TO },
-+ {"=>", T_IMP, OP_IMP },
-+ {"[[", T_OSEL, OP_SEL },
-+ {"]]", T_CSEL, OP_SEL },
-+ };
-+
-+static struct skeyword { /* all keywords we recognize */
-+ char *keyword_str ; /* keyword as a string */
-+ int token ; /* token to return to yacc */
-+ topcode opcode ; /* opcode associated w/keyword */
-+ } keywords[] = {
-+ {"if", T_IF , OP_IF},
-+ {"else", T_ELSE },
-+ {"for", T_FOR , OP_FOR},
-+ {"while", T_WHILE , OP_WHILE},
-+ {"sizeof", T_SIZEOF , OP_SIZ},
-+ {"frame", T_FRAME , OP_FRAME},
-+
-+ {"T", T_TYPEDEF_INDICATOR },
-+ {"struct", T_STRUCT },
-+ {"union", T_UNION },
-+ {"enum", T_ENUM },
-+
-+ {"unsigned",T_UNSIGNED },
-+ {"signed", T_SIGNED },
-+ {"short", T_SHORT },
-+ {"long", T_LONG },
-+ {"char", T_CHAR },
-+ {"int", T_INT },
-+ {"double", T_DOUBLE },
-+ {"float", T_FLOAT },
-+ {"void", T_VOID },
-+ } ;
-+
-+
-+LFUNC tnode* duel_lex_int(void) /* parse next token as integer num */
-+{
-+ tnode *n ;
-+ tulonglong val=0 ;
-+ char *p=lexptr ;
-+ bool is_l=0,is_u=0 ;
-+ int base=10 ;
-+ int src_pos=lexptr-inputstr ;
-+
-+ if(*p=='0') { /* figure out the base */
-+ p++ ;
-+ if(*p=='x' || *p=='X') base=16,p++ ;
-+ else
-+ if(isdigit(*p)) base=8 ; /* avoid having '0' as a base 8 (uint) */
-+ }
-+
-+ while(isdigit(*p) || base==16 && isxdigit(*p)) { /* get the value */
-+ val*=base ;
-+ if(isupper(*p)) val+= *p-'A'+10 ;
-+ else if(islower(*p)) val+= *p-'a'+10 ;
-+ else val+= *p-'0' ;
-+ p++ ;
-+ }
-+ for (;*p;p++) { /* yuk. figure 0L etc */
-+ if (*p == 'l' || *p == 'L') is_l++;
-+ else if(*p == 'u' || *p == 'U') is_u++;
-+ else break;
-+ }
-+ is_u=is_u || base!=10 ;
-+
-+ if((is_l>1 && is_u) || (long long) val < 0 || ((tulong) val != val && is_u)) {
-+ n=mknode_const(src_pos,ctype_ulonglong);
-+ n->cnst.u.rval_ulonglong=val ;
-+ }
-+ else
-+ if(is_l>1 || (tulong) val != val) {
-+ n=mknode_const(src_pos,ctype_longlong) ;
-+ n->cnst.u.rval_longlong=(long long) val ;
-+ }
-+ else
-+ if((is_l && is_u) || (long) val < 0 || ((tuint) val != val && is_u)) {
-+ n=mknode_const(src_pos,ctype_ulong);
-+ n->cnst.u.rval_ulong=val ;
-+ }
-+ else
-+ if(is_l || (tuint) val != val) {
-+ n=mknode_const(src_pos,ctype_long) ;
-+ n->cnst.u.rval_long=(long) val ;
-+ }
-+ else
-+ if(is_u || (int) val < 0) {
-+ n=mknode_const(src_pos,ctype_uint) ;
-+ n->cnst.u.rval_uint=(tuint) val ;
-+ }
-+ else {
-+ n=mknode_const(src_pos,ctype_int) ;
-+ n->cnst.u.rval_int=(int) val ;
-+ }
-+ strncpyz(n->cnst.symb_val,lexptr,p-lexptr); /* save the symbolic val*/
-+ lexptr=p ;
-+ return n ;
-+}
-+
-+LFUNC tnode* duel_lex_float(void) /* parse next token as float num */
-+{
-+ tnode *n=0 ;
-+ char *p=lexptr ;
-+ double val ;
-+ char c,tmpc ;
-+ bool ok=TRUE;
-+ int src_pos = lexptr - inputstr ;
-+
-+ /* this is disgusting.. why isnt there a lib call to recognize floats?! */
-+ while(isdigit(*p)) p++ ;
-+ if(*p=='.') p++ ;
-+ while(isdigit(*p)) p++ ;
-+ if(*p=='e' || *p=='E') {
-+ p++ ;
-+ if(*p=='+' || *p=='-') p++ ;
-+ if(!isdigit(*p)) ok=FALSE ; /* force digit (scanf allows 1e-.2 ?!) */
-+ while(isdigit(*p)) p++ ;
-+ }
-+ tmpc= *p ; *p=0 ;
-+ ok=ok && sscanf(lexptr,"%lf%c",&val,&c)==1 ;
-+ *p=tmpc ;
-+ if(!ok) yyerror("Invalid float constant.");
-+
-+ n=mknode_const(src_pos,ctype_double);
-+ n->cnst.u.rval_double=val ;
-+ strncpyz(n->cnst.symb_val,lexptr,p-lexptr); /* save the symbolic val*/
-+ lexptr=p ;
-+ return(n);
-+}
-+
-+/* parse_escaped_char -- parse an escaped char (e.g. '\n').
-+ * lexptr expected to point to text right after the '\'.
-+ * return: actual char value (e.g. 012 if 'n' or '012' is found.)
-+ * lexptr is advanced after the espaced char.
-+ */
-+
-+LFUNC char parse_escaped_char(void)
-+{
-+ char retc ;
-+ switch(lexptr[0]) {
-+ /*case 'a': retc='\a' ; break ; /* some compilers don't support it. */
-+ case 'b': retc='\b' ; break ;
-+ case 'f': retc='\f' ; break ;
-+ case 'n': retc='\n' ; break ;
-+ case 'r': retc='\r' ; break ;
-+ case 't': retc='\t' ; break ;
-+ case 'v': retc='\v' ; break ;
-+ case 'x': yyerror("hex char const not yet suppported");
-+ case '0': case '1': case '2': case '3':
-+ retc= lexptr[0] - '0' ;
-+ if(lexptr[1]>='0' && lexptr[1]<='7')
-+ retc= retc* 010 + *++lexptr - '0' ;
-+ if(lexptr[1]>='0' && lexptr[1]<='7')
-+ retc= retc* 010 + *++lexptr - '0' ;
-+ break ;
-+ default: retc=lexptr[0] ; /* default also takes care of '\'' '\\' */
-+ }
-+ lexptr++ ;
-+ return retc ;
-+}
-+
-+/* FUNC yylex -- return the next token to yacc.
-+ * GLOBALS: lexptr point to the string we are parsing next. it is updated.
-+ */
-+
-+LFUNC int yylex (void)
-+{
-+ int c,i,src_pos ;
-+ char *p ;
-+
-+ for(c= *lexptr; c==' ' || c=='\t' || c=='\n' ; c= *++lexptr); /* skip blank*/
-+
-+ src_pos = lexptr - inputstr ; /* current char being parsed */
-+ yylval.opinfo.src_pos = src_pos ;
-+
-+ if(*lexptr=='\0' || strncmp(lexptr,"|>",2)==0) return 0 ; /* end of expr */
-+
-+ for (i = 0; i < sizeof(tokens)/sizeof(struct stoken) ; i++) {
-+ int l=strlen(tokens[i].opstr) ; /* check next token vs table */
-+ if(strncmp(lexptr,tokens[i].opstr,l)==0) {
-+ lexptr+=l ;
-+ yylval.opinfo.opcode = tokens[i].opcode;
-+ return tokens[i].token ;
-+ }
-+ }
-+
-+ switch (c = *lexptr) {
-+ case '\'': /* char constant, but stored as int (ansi-c) */
-+ p=lexptr++ ;
-+ c = *lexptr++ ;
-+ if (c == '\\') c=parse_escaped_char();
-+ if( *lexptr++ != '\'') yyerror("Invalid character constant.");
-+ yylval.node=mknode_const(src_pos,ctype_int) ;
-+ yylval.node->cnst.u.rval_int=c ;
-+ strncpyz(yylval.node->cnst.symb_val,p,lexptr-p); /*save the symbol. val*/
-+ return T_CONST ;
-+
-+ case '0': /* chk hex */
-+ if(lexptr[1]=='x' || lexptr[1]=='X') {
-+ yylval.node=duel_lex_int();
-+ return T_CONST ;
-+ }
-+ /* fall thru for other numbers */
-+ case '1': case '2': case '3': /* decimal or floating point number */
-+ case '4': case '5': case '6': case '7': case '8': case '9':
-+ for(p=lexptr ; *p>='0' && *p<='9' ; p++ ) ; /*find next non digit*/
-+ if(*p=='.' && p[1]!='.' || *p=='e' || *p=='E')
-+ yylval.node=duel_lex_float();
-+ else yylval.node=duel_lex_int();
-+ return T_CONST ;
-+
-+ case '(': case ')':
-+ case '<': case '>':
-+ case '[': case ']':
-+ case '{': case '}':
-+ case '+': case '-': case '*': case '/': case '%':
-+ case '|': case '&': case '^': case '~': case '!':
-+ case ',': case '?': case ':': case '=':
-+ case '.': case '@': case '$': case '#': case '`': case '\\':
-+ lexptr++;
-+ yylval.opinfo.opcode=c ;
-+ return c;
-+ case ';': { /* hack, ignore ';' before '}' and else. for C compatability*/
-+ char *save_lexptr= ++lexptr ;
-+ int tok=yylex() ; /* hack, call myself for next token */
-+ if(tok=='}' || tok==T_ELSE) {
-+ duel_printf("warning: useless ';' ignored\n");
-+ return tok ;
-+ }
-+ /* else restore position and return the ';' */
-+ lexptr=save_lexptr ;
-+ yylval.opinfo.opcode=';' ;
-+ yylval.opinfo.src_pos = src_pos ;
-+ return ';';
-+ }
-+ case '"': {
-+ char s[512] ;
-+ size_t len=0 ;
-+ ttarget_ptr dptr ;
-+ tnode *n ;
-+
-+ p=lexptr++ ;
-+ while((c= *lexptr++)!='"') {
-+ if (c == '\\') c=parse_escaped_char();
-+ s[len++]=c ;
-+ }
-+ s[len++]=0 ;
-+ dptr=duel_alloc_target_space(len);
-+ duel_put_target_bytes(dptr,s,len);
-+
-+ n=mknode_const(src_pos,ctype_charptr);
-+ n->cnst.u.rval_ptr=dptr ;
-+ len=lexptr-p ;
-+ if(len>60) len=60 ;
-+ strncpyz(n->cnst.symb_val,p,len); /* save the symbolic val*/
-+ yylval.node=n ;
-+ return T_CONST ;
-+ }
-+ }
-+
-+ if(c != '_' && !isalpha(c))
-+ yyerror ("Invalid character in expression.");
-+
-+ p=lexptr ;
-+ do { c= *++lexptr ; } while(c=='_' || isalnum(c));
-+
-+ for (i = 0; i < sizeof(keywords)/sizeof(struct skeyword) ; i++) {
-+ int l=strlen(keywords[i].keyword_str) ; /* check next token vs keywords*/
-+ if(l==lexptr-p && strncmp(p,keywords[i].keyword_str,l)==0) {
-+ yylval.opinfo.opcode=keywords[i].opcode ;
-+ return keywords[i].token ;
-+ }
-+ }
-+
-+ /* the symbol/name found is not a reserved word, so return it as a T_SYM
-+ */
-+
-+ i=lexptr-p ; /* length of string found (symbol/name) */
-+ yylval.nameinfo.src_pos=src_pos ;
-+ yylval.nameinfo.name=duel_malloc(i+1);
-+ strncpyz(yylval.nameinfo.name,p,i);
-+ return T_SYM;
-+}
-+
-+LPROC yyerror(char *msg)
-+{
-+ int i,n=lexptr-inputstr ;
-+ duel_printf("%s\n",inputstr);
-+ for(i=0 ; i<n ; i++) duel_printf("-");
-+ duel_printf("^ %s\n",msg);
-+ duel_abort(); /* terminate parsing. some callers depend on this*/
-+}
-+
-+/*************************************************************************/
-+/* utility functions used to parse the expression and build it as a tree */
-+/*************************************************************************/
-+
-+/* mknode_op -- make a tree node of type op with given opcode and kids
-+ */
-+
-+LFUNC tnode* mknode_op(top_kind op_kind,topinfo opinfo,
-+ tnode *k1,tnode *k2,tnode *k3,tnode *k4)
-+{
-+ tnode *n ;
-+ duel_assert(opinfo.opcode>' ');
-+ n=(tnode *) duel_malloc(sizeof(tnode));
-+ duel_bzero((char*) n,sizeof(tnode));
-+ n->node_kind=NK_OP ;
-+ n->op_kind=op_kind ;
-+ n->op=opinfo.opcode ;
-+ n->src_pos=opinfo.src_pos ;
-+ n->kids[0]=k1 ; n->kids[1]=k2 ; n->kids[2]=k3 ; n->kids[3]=k4 ;
-+ return n ;
-+}
-+
-+
-+ /* mknode_const -- make a constant node for the given type.
-+ */
-+
-+LFUNC tnode* mknode_const(int src_pos,tctype *ctype)
-+{
-+ tnode *n ;
-+ n=(tnode *) duel_malloc(sizeof(tnode));
-+ duel_bzero((char*) n,sizeof(tnode));
-+ n->node_kind=NK_CONST ;
-+ n->src_pos=src_pos ;
-+ n->cnst.val_kind=VK_RVALUE ;
-+ n->cnst.ctype=ctype ;
-+ return n ;
-+}
-+
-+ /* mknode_ctype -- make a node of the given c-type.
-+ */
-+
-+LFUNC tnode* mknode_ctype(tctype *ctype)
-+{
-+ tnode *n ;
-+ n=(tnode *) duel_malloc(sizeof(tnode));
-+ duel_bzero((char*) n,sizeof(tnode));
-+ n->node_kind=NK_CTYPE ;
-+ n->ctype=ctype ;
-+ return n ;
-+}
-+
-+ /* mknode_name -- make a node of the given name/symbol.
-+ * input is pointer to the saved name (on heap)
-+ */
-+
-+LFUNC tnode* mknode_name(tnameinfo nameinfo)
-+{
-+ tnode *n ;
-+ n=(tnode *) duel_malloc(sizeof(tnode));
-+ duel_bzero((char*) n,sizeof(tnode));
-+ n->node_kind=NK_NAME ;
-+ n->name=nameinfo.name ;
-+ n->src_pos=nameinfo.src_pos ;
-+ return n ;
-+}
-+
-+/* In order to parse C types, which are 'reversed' in the parser, a stack
-+ * is used to push abstract declarators, e.g. in (*)() we first push a func
-+ * indicator '(' and then push a pointer indicator '*'. for arrays we push
-+ * a '[' and the array size.
-+ * This stack is popped and a ctype is constructed at the end of the
-+ * abstract type parsing. The following functions implement the stack
-+ */
-+
-+typedef struct stype_desc { /* stack of type descriptors is made of these */
-+ char desc ;
-+ int size ;
-+ struct stype_desc *next ; /* next on stack */
-+ } ttype_desc ;
-+
-+ttype_desc *top = 0 ;
-+
-+
-+LPROC push_type(char desc) /* put desc on the types stack */
-+{
-+ ttype_desc *p = (ttype_desc* ) duel_malloc(sizeof(ttype_desc));
-+ p->desc=desc ;
-+ p->size=0 ;
-+ p->next=top ;
-+ top=p ;
-+}
-+
-+/* push_type_int -- same as push_type but also set the size parameter, which
-+ * is given as a constant node (which is expected to be int)
-+ */
-+
-+LPROC push_type_int(char desc,tnode *n)
-+{
-+ duel_assert(n->node_kind==NK_CONST);
-+ if(n->cnst.ctype != ctype_int ||
-+ n->cnst.u.rval_int <=0 ) duel_gen_error("Illegal array size",0);
-+ push_type(desc);
-+ top->size=n->cnst.u.rval_int ;
-+}
-+
-+LFUNC bool pop_type(char *desc,int *size) /* pop item from stack. */
-+{
-+ ttype_desc *p = top ;
-+ if(p==0) return FALSE ;
-+ *desc=p->desc ;
-+ *size=p->size ;
-+ top=p->next ;
-+ duel_free(p) ;
-+ return TRUE ;
-+}
-+
-+
-+/* abstract type-modifiers were pushed on a stack. Retrieve
-+ * them (reversed) creating type nodes as we go
-+ * input: base type (e.g. 'long').
-+ * returns: node of the modified type.
-+ * modification is based on the stack of things pushed while parsing.
-+ */
-+
-+LFUNC tnode* mknode_modified_ctype(tctype *base)
-+{
-+ int size;
-+ char tdesc ; /* descriptor of abs decl eg '*' */
-+ tctype *t=base ; /* type under construction */
-+
-+ while(pop_type(&tdesc,&size)) /* pop next abs decl */
-+ switch (tdesc) {
-+ case '*': t=duel_mkctype_ptr(t); break ;
-+ case '(': t=duel_mkctype_func(t); break ;
-+ case '[': t=duel_mkctype_array(t,size); break ;
-+ }
-+ return mknode_ctype(t) ;
-+}
-+
-+/* entry point for parsing. the given expression is parsed into the given
-+ * node as root.
-+ */
-+
-+FUNC tnode* duel_parse(char *s)
-+{
-+ lexptr=inputstr=s ;
-+ top=0 ; /* reset the types stack */
-+ if(duel_yyparse()) root=NULL ;
-+ return root ;
-+}
-+
---- gdb/duel/parse.y
-+++ gdb/duel/parse.y
-@@ -0,0 +1,940 @@
-+%{
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* this module contains the duel parser, in yacc, plus a simple lexer.
-+ * the lexer is slow, but duel expressions are tiny.
-+ * the parsing generate an AST with essentially no type checking.
-+ * names are only looked up when the refer explicitly to types. This forces
-+ * the use of "T" before user types. You can't parse (x)(y) correctly, if
-+ * you want the node to contain "cast" or "func", without knowing the x is
-+ * not a type. (It is interesting to note that (x *)(y) is clearly a cast,
-+ * but it can not be parsed without a context sensitive grammer!).
-+ *
-+ * Version 1.1 now accept (x) as a type cast, so (print)("hi") fails, but
-+ * (uint)z is ok. Also accepted is (uint*)z. T is still required in sizeof
-+ * and in variable declarations. A side effect was making "sizeof x" illegal
-+ * (since then sizeof(x)-1 was parsed sizeof((x)-1) with (x) a cast), so
-+ * now sizeof(x) must be used. Note that in C, sizoef(x)++ is acceptable,
-+ * and the '++' operate on x (which is optimized out!) This can be confusing.
-+ *
-+ * yacc is also not smart enough to recognize e.g. "if(e) e ; else e" as
-+ * a special case (redundent ';'). I hacked this in the lexer. It should
-+ * reduce the trouble with C->duel coding. (It can also be done for {e1}e2,
-+ * in some speical cases, e.g. if e2 is a keyword, or a name or a unary op,
-+ * but this can confuse some people, e.g. in {i}[5], so I left it alone.)
-+ * Finally, the %/ operator is accepted as "#/" and "%%" as "#", to those
-+ * who wish to keep gdb with # comments.
-+ * memory: nodes are alloc'ed dynamically. a parsing error loose so-far
-+ * allocated nodes, which is normally acceptable (yyerror can probably hack
-+ * into the yacc stack to release them.)
-+ */
-+
-+/*
-+ * $Log: 10_all_gdb-6.6-duel.patch,v $
-+ * Revision 1.1 2008/04/06 23:59:05 vapier
-+ * initial 6.8 patchset based on last 6.7.1 patchset
-+ *
-+ * Revision 1.14 93/03/17 11:04:12 mg
-+ * fixed (t*)x bug, was parsed as (t**)x
-+ *
-+ * Revision 1.13 93/03/12 06:15:09 mg
-+ * modified unary's a bit - cosmetics
-+ * support (x)y as type cast
-+ * support (x*)y as type cast
-+ * replace sizeof exp with sizeof(exp) to prevent clash with above
-+ * more cosmetics, including yyerror abort, tuint for uint.
-+ * takes anything after |> to be comment (pipe command really)
-+ *
-+ *
-+ * Revision 1.12 93/02/27 06:06:09 mg
-+ * added signed char parsing.
-+ *
-+ * Revision 1.11 93/02/23 19:15:38 mg
-+ * improved escaped char support
-+ *
-+ * Revision 1.10 93/02/03 21:49:34 mg
-+ * bug fix - yyerror calls now abort parsing (eg called from lex)
-+ *
-+ * Revision 1.9 93/01/12 21:53:07 mg
-+ * cleanup and set for release
-+ *
-+ * Revision 1.8 93/01/07 00:14:33 mg
-+ * add &&/ ||/
-+ * fixed parsing of trailing ';' was a mess.
-+ * ignore ';' before 'else' and '}' w/warning.
-+ *
-+ * Revision 1.7 93/01/03 07:31:01 mg
-+ * error reporting
-+ *
-+ * Revision 1.6 92/12/24 23:35:50 mg
-+ * began src pos support
-+ *
-+ * Revision 1.5 92/10/19 15:08:02 mg
-+ * frames() added; bug fixed
-+ *
-+ * Revision 1.4 92/10/14 02:06:32 mg
-+ * misc/change casting parsing/variable def.
-+ *
-+ * Revision 1.3 92/09/16 11:09:39 mg
-+ * add typedef/struct support, const strings
-+ * cleanup s/r conflict by setting ELSE to a token. explained some stuff in
-+ * comments.
-+ *
-+ * Revision 1.2 92/09/15 06:10:46 mg
-+ * cosmetics and new ops: x@y, for() while() ..x and x..
-+ * generic '.' and '_' support. x@y. '..x' and 'x..'. while(), for(), ?:
-+ *
-+ */
-+
-+#include "duel.h"
-+
-+static char *inputstr ; /* pointer to string being parsed */
-+static char *lexptr ; /* current lexer pointer into input str */
-+static tnode *root ; /* result of parsing stored here */
-+
-+/* pick unique names for globals of yacc. gdb has other parsers! */
-+#define yyparse duel_yyparse
-+#define yylex duel_yylex
-+#define yyerror duel_yyerror
-+#define yylval duel_yylval
-+#define yychar duel_yychar
-+#define yydebug duel_yydebug
-+#define yypact duel_yypact
-+#define yyr1 duel_yyr1
-+#define yyr2 duel_yyr2
-+#define yydef duel_yydef
-+#define yychk duel_yychk
-+#define yypgo duel_yypgo
-+#define yyact duel_yyact
-+#define yyexca duel_yyexca
-+#define yyerrflag duel_yyerrflag
-+#define yynerrs duel_yynerrs
-+#define yyps duel_yyps
-+#define yypv duel_yypv
-+#define yys duel_yys
-+#define yystate duel_yystate
-+#define yytmp duel_yytmp
-+#define yyv duel_yyv
-+#define yyval duel_yyval
-+#define yylloc duel_yylloc
-+
-+typedef struct { /* token info for operators */
-+ int src_pos ; /* source position */
-+ topcode opcode ; /* opcode */
-+ } topinfo ;
-+
-+typedef struct { /* token info for symbols */
-+ int src_pos ; /* source position */
-+ char *name ; /* symbol */
-+ } tnameinfo ;
-+
-+/* these are used as operators to mknode_... when source location is unknown*/
-+static topinfo seq_op = { -1,';' } ; /* sequencing operator, src pos unkown */
-+static topinfo decl_op = { -1,OP_DECL } ; /* declare var op, src pos unkown */
-+
-+/* local prototypes. */
-+LPROC yyerror(char *msg);
-+LFUNC int yylex (void);
-+
-+LPROC push_type(char desc) ;
-+LPROC push_type_int(char desc,tnode *n) ;
-+LFUNC bool pop_type(char *desc,int *size);
-+
-+LFUNC tnode* mknode_op(top_kind,topinfo opinfo,tnode*,tnode*,tnode*,tnode*);
-+LFUNC tnode* mknode_const(int src_pos,tctype *ctype);
-+LFUNC tnode* mknode_ctype(tctype *ctype);
-+LFUNC tnode* mknode_name(tnameinfo nameinfo);
-+LFUNC tnode* mknode_modified_ctype(tctype *base);
-+
-+#define mknode_post_unary(op,n) (mknode_op(OPK_POST_UNARY,op,n, 0, 0,0))
-+#define mknode_unary(op,n) (mknode_op(OPK_UNARY, op,n, 0, 0,0))
-+#define mknode_sunary(op,n) (mknode_op(OPK_SUNARY, op,n, 0, 0,0))
-+#define mknode_bin(op,n1,n2) (mknode_op(OPK_BIN, op,n1,n2,0,0))
-+#define mknode_sbin(op,n1,n2) (mknode_op(OPK_SBIN, op,n1,n2,0,0))
-+#define mknode_tri(op,n1,n2,n3) (mknode_op(OPK_TRI, op,n1,n2,n3,0))
-+
-+static tctype *decl_tbase ; /* used for variables decl */
-+
-+/* #define YYDEBUG 1 */
-+
-+%}
-+
-+%union
-+ {
-+ tnode *node ; /* node pointer for constructed exp tree */
-+ tctype *ctype; /* type for type nodes */
-+ tnameinfo nameinfo ; /* a name/symbol + src position */
-+ topinfo opinfo; /* keyword/operator + source position */
-+ }
-+
-+%type <node> start duel_inp duel_exp exp type nameexp sm_exp oexp
-+%type <node> all_decls vars_decl var_decl name_decl1 name_decl
-+%type <ctype> typebase
-+%type <nameinfo> name
-+
-+%token <node> T_CONST
-+%token <nameinfo> T_SYM
-+%token <opinfo> T_ASSIGN T_DEFVAR
-+
-+
-+%token <opinfo> T_CHAR T_INT T_SHORT T_LONG T_UNSIGNED T_FLOAT T_DOUBLE T_VOID
-+%token <opinfo> T_STRUCT T_UNION T_ENUM T_SIZEOF T_TYPEDEF_INDICATOR T_SIGNED
-+
-+%token <opinfo> T_IF T_ELSE T_FOR T_WHILE
-+%token <opinfo> ';' ',' '=' '?' '|' '^' '&' '<' '>' '+' '-' '*' '/' '%'
-+%token <opinfo> '.' '[' ']' '(' ')' '{' '}' '#' '@' '!' '~'
-+%token <opinfo> T_OR T_AND T_RSH T_LSH T_INC T_DEC T_COUNT T_FRAME T_TO
-+%token <opinfo> T_DFS T_BFS T_ARROW T_OSEL T_CSEL T_IMP T_ANDL T_ORL
-+%token <opinfo> T_EQ T_NE T_EQQ T_NEQ T_LE T_GE T_LSQ T_GTQ T_LEQ T_GEQ
-+
-+%left ';'
-+%right STMT T_ELSE
-+%right T_IMP
-+%right ','
-+%right '=' T_ASSIGN T_DEFVAR
-+%right '?'
-+%left T_OR T_ORL
-+%left T_AND T_ANDL
-+%left '|'
-+%left '^'
-+%left '&'
-+%left T_EQ T_NE T_EQQ T_NEQ
-+%left '<' '>' T_LE T_GE T_LSQ T_GTQ T_LEQ T_GEQ
-+%nonassoc T_TO
-+%left T_LSH T_RSH
-+%left '+' '-'
-+%left '*' '/' '%'
-+%right UNARY '!' '~' T_INC T_DEC T_COUNT T_FRAME
-+%left T_DFS T_BFS T_POS T_ARROW '.' '[' ']' '(' ')' '{' '}' '#' '@' T_OSEL T_CSEL
-+%%
-+
-+start : duel_inp { root=$1 ; }
-+ ;
-+
-+duel_inp : all_decls
-+ | all_decls ';'
-+ | all_decls ';' duel_exp { $$=mknode_sbin($2,$1,$3);}
-+ | duel_exp
-+ ;
-+duel_exp : sm_exp
-+ | sm_exp ';' { $$=mknode_sbin($2,$1,0); }
-+ ;
-+all_decls: vars_decl
-+ | all_decls ';' vars_decl { $$=mknode_sbin($2,$1,$3); }
-+ ;
-+
-+vars_decl: typebase { decl_tbase=$1 ; } var_decl { $$=$3 ; }
-+ ;
-+var_decl : name_decl1
-+ | var_decl ',' name_decl1 { $$=mknode_sbin(seq_op,$1,$3); }
-+ ;
-+
-+name_decl1: name_decl { $$=mknode_sbin(decl_op,$1,
-+ mknode_modified_ctype(decl_tbase)); }
-+ ;
-+
-+name_decl : '(' name_decl ')' { $$=$2 ; }
-+ | '(' name_decl ')' '(' ')' { $$=$2 ; push_type('('); }
-+ | '*' name_decl { $$=$2 ; push_type('*'); }
-+ | name_decl '[' T_CONST ']' { $$=$1 ; push_type_int('[',$3); }
-+ | nameexp
-+ ;
-+
-+/* Statements - not really, these are expressions too!
-+ Notes: for(;;) oexp - will create lots of shift/reduce conflicts,
-+ 'for(;;;)' and 'for(;;) exp' are specified
-+ instead and yacc handle this as a "standard" s/r.
-+ the only diff is yacc dont complain on these!
-+ if() - same comments as above, plus, we prevent meaningless
-+ if's like in C: ' if(x); else;' - a useless statement.
-+ */
-+exp : T_IF '(' exp ')' exp %prec STMT { $$=mknode_tri($1,$3,$5,0); }
-+ | T_IF '(' exp ')' exp T_ELSE %prec STMT
-+ { $$=mknode_tri($1,$3,$5,0); }
-+ | T_IF '(' exp ')' T_ELSE exp %prec STMT
-+ { $$=mknode_tri($1,$3,0,$6); }
-+ | T_IF '(' exp ')' exp T_ELSE exp %prec STMT
-+ { $$=mknode_tri($1,$3,$5,$7); }
-+
-+ | T_FOR '(' oexp ';' exp ';' oexp ')' exp %prec STMT
-+ { $$=mknode_op(OPK_QUAD,$1,$3,$5,$7,$9); }
-+ | T_FOR '(' oexp ';' exp ';' oexp ')' %prec STMT
-+ { $$=mknode_op(OPK_QUAD,$1,$3,$5,$7,0); }
-+ | T_WHILE '(' exp ')' exp %prec STMT
-+ { $$=mknode_sbin($1,$3,$5); }
-+ | T_WHILE '(' exp ')' %prec STMT
-+ { $$=mknode_sbin($1,$3,0); }
-+ ;
-+
-+/* Expressions */
-+
-+exp : '*' exp %prec UNARY { $$=mknode_unary( $1,$2); }
-+ | '&' exp %prec UNARY { $$=mknode_unary( $1,$2); }
-+ | '-' exp %prec UNARY { $$=mknode_unary( $1,$2); }
-+ | '!' exp { $$=mknode_unary( $1,$2); }
-+ | '~' exp { $$=mknode_unary( $1,$2); }
-+ | T_COUNT exp { $$=mknode_sunary($1,$2); }
-+ | T_ANDL exp { $$=mknode_sunary($1,$2); }
-+ | T_ORL exp { $$=mknode_sunary($1,$2); }
-+ | T_INC exp { $$=mknode_unary( $1,$2); }
-+ | T_DEC exp { $$=mknode_unary( $1,$2); }
-+ | exp T_INC { $$=mknode_post_unary($2,$1); }
-+ | exp T_DEC { $$=mknode_post_unary($2,$1); }
-+ | T_SIZEOF '(' type ')' { $$=mknode_sunary($1,$3); }
-+ | T_SIZEOF '(' exp ')' { $$=mknode_unary($1,$3); }
-+ | T_FRAME '(' exp ')' %prec UNARY { $$=mknode_unary( $1,$3); }
-+ ;
-+
-+exp : exp T_DFS exp { $$=mknode_sbin($2,$1,$3); }
-+ | exp T_BFS exp { $$=mknode_sbin($2,$1,$3); }
-+
-+ | exp '#' nameexp { $$=mknode_sbin($2,$1,$3); }
-+ | exp '@' exp { $$=mknode_sbin($2,$1,$3); }
-+ | exp T_ARROW exp { $$=mknode_sbin($2,$1,$3); }
-+ | exp '.' exp { $$=mknode_sbin($2,$1,$3); }
-+ | exp '[' exp ']' { $$=mknode_bin( $2,$1,$3); }
-+ | exp T_OSEL exp T_CSEL { $$=mknode_sbin($2,$1,$3); }
-+ | exp '(' oexp ')' %prec '.' { $$=mknode_op(OPK_FUNC,$2,$1,$3,0,0); }
-+ | '(' sm_exp ')' { $$=mknode_unary($1,$2); }
-+ | '{' sm_exp '}' { $$=mknode_unary($1,$2); }
-+ ;
-+
-+exp : '(' type ')' exp %prec UNARY
-+ { $$=mknode_op(OPK_CAST,$1,$2,$4,0,0); }
-+/* HACKS to handle the most common cast cases with a typedef, without
-+ * requiring a 'T'. This code breaks (printf)("hi"), which returns the
-+ * error "printf not a typedef", but otherwise it works ok.
-+ * It might be confusing since "(uint *)p" works but "(uint (*)())p" wont,
-+ * but it seems that (uint*)p, (uint)x are the most common, and users get
-+ * confused w/o them.
-+ * The code below works essentially with context-sensitive parsing!
-+ * see the hacked %prec for nameexp which prevents yacc s/r warning!
-+ */
-+ | '(' name ')' exp %prec UNARY {
-+ tctype *t=duel_get_target_typedef($2.name);
-+ if(t==NULL) yyerror("not a typedef name");
-+ $$=mknode_op(OPK_CAST,$1,mknode_ctype(t),$4,0,0); }
-+ | '(' name '*' type_mod ')' exp %prec UNARY {
-+ tctype *t=duel_get_target_typedef($2.name);
-+ if(t==NULL) yyerror("not a typedef name");
-+ push_type('*');
-+ $$=mknode_op(OPK_CAST,$1,mknode_modified_ctype(t),$6,0,0); }
-+ ;
-+
-+ /* Bin ops in decreasing precedence order: */
-+
-+exp : exp '*' exp { $$=mknode_bin($2,$1,$3); }
-+ | exp '/' exp { $$=mknode_bin($2,$1,$3); }
-+ | exp '%' exp { $$=mknode_bin($2,$1,$3); }
-+ | exp '+' exp { $$=mknode_bin($2,$1,$3); }
-+ | exp '-' exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_LSH exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_RSH exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_EQ exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_NE exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_EQQ exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_NEQ exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_LE exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_GE exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_LEQ exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_GEQ exp { $$=mknode_bin($2,$1,$3); }
-+ | exp '<' exp { $$=mknode_bin($2,$1,$3); }
-+ | exp '>' exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_LSQ exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_GTQ exp { $$=mknode_bin($2,$1,$3); }
-+ | exp '&' exp { $$=mknode_bin($2,$1,$3); }
-+ | exp '|' exp { $$=mknode_bin($2,$1,$3); }
-+ | exp '^' exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_AND exp { $$=mknode_sbin($2,$1,$3); }
-+ | exp T_OR exp { $$=mknode_sbin($2,$1,$3); }
-+ ;
-+
-+exp : exp '?' exp ':' exp %prec '?'
-+ { $$=mknode_tri($2,$1,$3,$5); }
-+ ;
-+
-+exp : exp '=' exp { $$=mknode_bin($2,$1,$3); }
-+ | exp T_ASSIGN exp { $$=mknode_op(OPK_ASSIGN,$2, $1,$3,0,0); }
-+ |nameexp T_DEFVAR exp { $$=mknode_sbin($2,$1,$3); }
-+ ;
-+
-+ /* generating expressions */
-+
-+exp : exp T_TO exp { $$=mknode_sbin($2,$1,$3); }
-+ | T_TO exp { $$=mknode_sbin($1, 0,$2); }
-+ | exp T_TO { $$=mknode_sbin($2,$1, 0); }
-+ | exp ',' exp { $$=mknode_sbin($2,$1,$3); }
-+ | exp T_IMP exp { $$=mknode_sbin($2,$1,$3); }
-+ ;
-+
-+sm_exp : sm_exp ';' exp { $$=mknode_sbin($2,$1,$3); }
-+ | exp
-+ ;
-+
-+oexp : exp /* optional expression, eg in for() */
-+ | { $$=0 ; }
-+ ;
-+
-+exp : T_CONST ;
-+exp : nameexp ;
-+ /* convert a string input (name) into an expression.
-+ * precedence of '+' is a hack to make the special case
-+ * of (x*)(y) parsed as a cast, without shift/reduce conflict
-+ *(this would work the same w/o the '+' but gives warning)
-+ */
-+nameexp : name %prec '+' { $$=mknode_name($1) ; } ;
-+
-+type : typebase type_mod { $$=mknode_modified_ctype($1); }
-+ ;
-+/* type_mod has no value. bison warning is meaningless. I cant find a way
-+ * to shut it up
-+ */
-+type_mod: '(' type_mod ')'
-+ | '(' type_mod ')' '(' ')' { push_type('('); }
-+ | '*' type_mod { push_type('*'); }
-+ | type_mod '[' T_CONST ']' { push_type_int('[',$3); }
-+ |
-+ ;
-+
-+
-+/* note that names are evaluated at runtime. hence (name)(x) is ambigious
-+ * as either a function call or a cast.
-+ * We could identify a typedef 'name' as such and return a special token from
-+ * the lexr, but this will make 'x.(5+y)' illegal if y is both a field and
-+ * a typedef (Note that gdb's own code include such things).
-+ *
-+ * there is a complex solution, that keeps the the casting as a syntax tree,
-+ * and compute ctype at runtime, too. However, we want to compute all types at
-+ * parse time. Out solution forces the reserved word T_TYPEDEF_INDICATOR to
-+ * appear before any typedef name. (the reserved word is normally just 'T')
-+ * example: instead of '(list *) x' use in duel: '(T list *) x'
-+ */
-+
-+typebase: T_TYPEDEF_INDICATOR name {
-+ $$=duel_get_target_typedef($2.name);
-+ if($$==NULL) {
-+ tvalue v;
-+ if(duel_get_target_variable($2.name,-1,&v)) $$=v.ctype;
-+ else yyerror("not a typedef name");
-+ }
-+ }
-+ ;
-+
-+typebase: T_CHAR { $$ = ctype_char; }
-+ | T_SIGNED T_CHAR { $$ = ctype_schar; }
-+ | T_UNSIGNED T_CHAR { $$ = ctype_uchar; }
-+ | T_INT { $$ = ctype_int; }
-+ | T_UNSIGNED { $$ = ctype_uint; }
-+ | T_UNSIGNED T_INT { $$ = ctype_uint; }
-+ | T_LONG { $$ = ctype_long; }
-+ | T_LONG T_INT { $$ = ctype_long; }
-+ | T_UNSIGNED T_LONG { $$ = ctype_ulong; }
-+ | T_UNSIGNED T_LONG T_INT { $$ = ctype_ulong; }
-+ | T_LONG T_LONG { $$ = ctype_longlong; }
-+ | T_LONG T_LONG T_INT { $$ = ctype_longlong; }
-+ | T_UNSIGNED T_LONG T_LONG { $$ = ctype_ulonglong; }
-+ | T_UNSIGNED T_LONG T_LONG T_INT { $$ = ctype_ulonglong; }
-+ | T_SHORT { $$ = ctype_short; }
-+ | T_SHORT T_INT { $$ = ctype_short; }
-+ | T_UNSIGNED T_SHORT { $$ = ctype_ushort; }
-+ | T_UNSIGNED T_SHORT T_INT { $$ = ctype_ushort; }
-+ | T_FLOAT { $$ = ctype_float ; }
-+ | T_DOUBLE { $$ = ctype_double; }
-+ | T_VOID { $$ = ctype_void; }
-+ | T_STRUCT name
-+ { $$ = duel_get_target_struct_tag($2.name);
-+ if($$==NULL) yyerror("not a struct tag"); }
-+ | T_UNION name
-+ { $$ = duel_get_target_union_tag($2.name);
-+ if($$==NULL) yyerror("not a union tag"); }
-+ | T_ENUM name
-+ { $$ = duel_get_target_enum_tag($2.name);
-+ if($$==NULL) yyerror("not an enum tag"); }
-+ ;
-+
-+name : T_SYM ;
-+%%
-+
-+static struct stoken { /* all opcodes we recognize */
-+ char *opstr ; /* op code as a string */
-+ int token ; /* token to return to yacc */
-+ int opcode ; /* opcode value associated with the token */
-+ } tokens[] = { /* the special tokens, longer ones 1st! */
-+ {">>=",T_ASSIGN, OP_RSH},
-+ {"<<=",T_ASSIGN, OP_LSH},
-+ {"-->",T_DFS, OP_DFS},
-+ {"->>",T_BFS, OP_BFS},
-+ {"==?", T_EQQ, OP_EQQ},
-+ {"!=?", T_NEQ, OP_NEQ},
-+ {"<=?", T_LEQ, OP_LEQ},
-+ {">=?", T_GEQ, OP_GEQ},
-+ {"&&/", T_ANDL, OP_AND},
-+ {"||/", T_ORL, OP_OR},
-+
-+ {"<?", T_LSQ, OP_LSQ},
-+ {">?", T_GTQ, OP_GTQ},
-+ {"#/", T_COUNT, '#' },
-+ {"%/", T_COUNT, '#' }, /* gdb insists to recognize # as start of comma!*/
-+ {"%%", '#', '#' }, /* same. so %/ for #/ and %% for #. not doc!*/
-+ {"+=", T_ASSIGN, '+'},
-+ {"-=", T_ASSIGN, '-'},
-+ {"*=", T_ASSIGN, '*'},
-+ {"/=", T_ASSIGN, '/'},
-+ {"%=", T_ASSIGN, '%'},
-+ {"|=", T_ASSIGN, '|'},
-+ {"&=", T_ASSIGN, '&'},
-+ {"^=", T_ASSIGN, '^'},
-+ {":=", T_DEFVAR,OP_DEF},
-+ {"++", T_INC, OP_INC },
-+ {"--", T_DEC, OP_DEC },
-+ {"->", T_ARROW, OP_ARR },
-+ {"&&", T_AND, OP_AND },
-+ {"||", T_OR, OP_OR },
-+ {"<<", T_LSH, OP_LSH },
-+ {">>", T_RSH, OP_RSH },
-+ {"==", T_EQ, OP_EQ },
-+ {"!=", T_NE, OP_NE },
-+ {"<=", T_LE, OP_LE },
-+ {">=", T_GE, OP_GE },
-+ {"..", T_TO, OP_TO },
-+ {"=>", T_IMP, OP_IMP },
-+ {"[[", T_OSEL, OP_SEL },
-+ {"]]", T_CSEL, OP_SEL },
-+ };
-+
-+static struct skeyword { /* all keywords we recognize */
-+ char *keyword_str ; /* keyword as a string */
-+ int token ; /* token to return to yacc */
-+ topcode opcode ; /* opcode associated w/keyword */
-+ } keywords[] = {
-+ {"if", T_IF , OP_IF},
-+ {"else", T_ELSE },
-+ {"for", T_FOR , OP_FOR},
-+ {"while", T_WHILE , OP_WHILE},
-+ {"sizeof", T_SIZEOF , OP_SIZ},
-+ {"frame", T_FRAME , OP_FRAME},
-+
-+ {"T", T_TYPEDEF_INDICATOR },
-+ {"struct", T_STRUCT },
-+ {"union", T_UNION },
-+ {"enum", T_ENUM },
-+
-+ {"unsigned",T_UNSIGNED },
-+ {"signed", T_SIGNED },
-+ {"short", T_SHORT },
-+ {"long", T_LONG },
-+ {"char", T_CHAR },
-+ {"int", T_INT },
-+ {"double", T_DOUBLE },
-+ {"float", T_FLOAT },
-+ {"void", T_VOID },
-+ } ;
-+
-+
-+LFUNC tnode* duel_lex_int(void) /* parse next token as integer num */
-+{
-+ tnode *n ;
-+ tulonglong val=0 ;
-+ char *p=lexptr ;
-+ bool is_l=0,is_u=0 ;
-+ int base=10 ;
-+ int src_pos=lexptr-inputstr ;
-+
-+ if(*p=='0') { /* figure out the base */
-+ p++ ;
-+ if(*p=='x' || *p=='X') base=16,p++ ;
-+ else
-+ if(isdigit(*p)) base=8 ; /* avoid having '0' as a base 8 (uint) */
-+ }
-+
-+ while(isdigit(*p) || base==16 && isxdigit(*p)) { /* get the value */
-+ val*=base ;
-+ if(isupper(*p)) val+= *p-'A'+10 ;
-+ else if(islower(*p)) val+= *p-'a'+10 ;
-+ else val+= *p-'0' ;
-+ p++ ;
-+ }
-+ for (;*p;p++) { /* yuk. figure 0L etc */
-+ if (*p == 'l' || *p == 'L') is_l++;
-+ else if(*p == 'u' || *p == 'U') is_u++;
-+ else break;
-+ }
-+ is_u=is_u || base!=10 ;
-+
-+ if((is_l>1 && is_u) || (long long) val < 0 || ((tulong) val != val && is_u)) {
-+ n=mknode_const(src_pos,ctype_ulonglong);
-+ n->cnst.u.rval_ulonglong=val ;
-+ }
-+ else
-+ if(is_l>1 || (tulong) val != val) {
-+ n=mknode_const(src_pos,ctype_longlong) ;
-+ n->cnst.u.rval_longlong=(long long) val ;
-+ }
-+ else
-+ if((is_l && is_u) || (long) val < 0 || ((tuint) val != val && is_u)) {
-+ n=mknode_const(src_pos,ctype_ulong);
-+ n->cnst.u.rval_ulong=val ;
-+ }
-+ else
-+ if(is_l || (tuint) val != val) {
-+ n=mknode_const(src_pos,ctype_long) ;
-+ n->cnst.u.rval_long=(long) val ;
-+ }
-+ else
-+ if(is_u || (int) val < 0) {
-+ n=mknode_const(src_pos,ctype_uint) ;
-+ n->cnst.u.rval_uint=(tuint) val ;
-+ }
-+ else {
-+ n=mknode_const(src_pos,ctype_int) ;
-+ n->cnst.u.rval_int=(int) val ;
-+ }
-+ strncpyz(n->cnst.symb_val,lexptr,p-lexptr); /* save the symbolic val*/
-+ lexptr=p ;
-+ return n ;
-+}
-+
-+LFUNC tnode* duel_lex_float(void) /* parse next token as float num */
-+{
-+ tnode *n=0 ;
-+ char *p=lexptr ;
-+ double val ;
-+ char c,tmpc ;
-+ bool ok=TRUE;
-+ int src_pos = lexptr - inputstr ;
-+
-+ /* this is disgusting.. why isnt there a lib call to recognize floats?! */
-+ while(isdigit(*p)) p++ ;
-+ if(*p=='.') p++ ;
-+ while(isdigit(*p)) p++ ;
-+ if(*p=='e' || *p=='E') {
-+ p++ ;
-+ if(*p=='+' || *p=='-') p++ ;
-+ if(!isdigit(*p)) ok=FALSE ; /* force digit (scanf allows 1e-.2 ?!) */
-+ while(isdigit(*p)) p++ ;
-+ }
-+ tmpc= *p ; *p=0 ;
-+ ok=ok && sscanf(lexptr,"%lf%c",&val,&c)==1 ;
-+ *p=tmpc ;
-+ if(!ok) yyerror("Invalid float constant.");
-+
-+ n=mknode_const(src_pos,ctype_double);
-+ n->cnst.u.rval_double=val ;
-+ strncpyz(n->cnst.symb_val,lexptr,p-lexptr); /* save the symbolic val*/
-+ lexptr=p ;
-+ return(n);
-+}
-+
-+/* parse_escaped_char -- parse an escaped char (e.g. '\n').
-+ * lexptr expected to point to text right after the '\'.
-+ * return: actual char value (e.g. 012 if 'n' or '012' is found.)
-+ * lexptr is advanced after the espaced char.
-+ */
-+
-+LFUNC char parse_escaped_char(void)
-+{
-+ char retc ;
-+ switch(lexptr[0]) {
-+ /*case 'a': retc='\a' ; break ; /* some compilers don't support it. */
-+ case 'b': retc='\b' ; break ;
-+ case 'f': retc='\f' ; break ;
-+ case 'n': retc='\n' ; break ;
-+ case 'r': retc='\r' ; break ;
-+ case 't': retc='\t' ; break ;
-+ case 'v': retc='\v' ; break ;
-+ case 'x': yyerror("hex char const not yet suppported");
-+ case '0': case '1': case '2': case '3':
-+ retc= lexptr[0] - '0' ;
-+ if(lexptr[1]>='0' && lexptr[1]<='7')
-+ retc= retc* 010 + *++lexptr - '0' ;
-+ if(lexptr[1]>='0' && lexptr[1]<='7')
-+ retc= retc* 010 + *++lexptr - '0' ;
-+ break ;
-+ default: retc=lexptr[0] ; /* default also takes care of '\'' '\\' */
-+ }
-+ lexptr++ ;
-+ return retc ;
-+}
-+
-+/* FUNC yylex -- return the next token to yacc.
-+ * GLOBALS: lexptr point to the string we are parsing next. it is updated.
-+ */
-+
-+LFUNC int yylex (void)
-+{
-+ int c,i,src_pos ;
-+ char *p ;
-+
-+ for(c= *lexptr; c==' ' || c=='\t' || c=='\n' ; c= *++lexptr); /* skip blank*/
-+
-+ src_pos = lexptr - inputstr ; /* current char being parsed */
-+ yylval.opinfo.src_pos = src_pos ;
-+
-+ if(*lexptr=='\0' || strncmp(lexptr,"|>",2)==0) return 0 ; /* end of expr */
-+
-+ for (i = 0; i < sizeof(tokens)/sizeof(struct stoken) ; i++) {
-+ int l=strlen(tokens[i].opstr) ; /* check next token vs table */
-+ if(strncmp(lexptr,tokens[i].opstr,l)==0) {
-+ lexptr+=l ;
-+ yylval.opinfo.opcode = tokens[i].opcode;
-+ return tokens[i].token ;
-+ }
-+ }
-+
-+ switch (c = *lexptr) {
-+ case '\'': /* char constant, but stored as int (ansi-c) */
-+ p=lexptr++ ;
-+ c = *lexptr++ ;
-+ if (c == '\\') c=parse_escaped_char();
-+ if( *lexptr++ != '\'') yyerror("Invalid character constant.");
-+ yylval.node=mknode_const(src_pos,ctype_int) ;
-+ yylval.node->cnst.u.rval_int=c ;
-+ strncpyz(yylval.node->cnst.symb_val,p,lexptr-p); /*save the symbol. val*/
-+ return T_CONST ;
-+
-+ case '0': /* chk hex */
-+ if(lexptr[1]=='x' || lexptr[1]=='X') {
-+ yylval.node=duel_lex_int();
-+ return T_CONST ;
-+ }
-+ /* fall thru for other numbers */
-+ case '1': case '2': case '3': /* decimal or floating point number */
-+ case '4': case '5': case '6': case '7': case '8': case '9':
-+ for(p=lexptr ; *p>='0' && *p<='9' ; p++ ) ; /*find next non digit*/
-+ if(*p=='.' && p[1]!='.' || *p=='e' || *p=='E')
-+ yylval.node=duel_lex_float();
-+ else yylval.node=duel_lex_int();
-+ return T_CONST ;
-+
-+ case '(': case ')':
-+ case '<': case '>':
-+ case '[': case ']':
-+ case '{': case '}':
-+ case '+': case '-': case '*': case '/': case '%':
-+ case '|': case '&': case '^': case '~': case '!':
-+ case ',': case '?': case ':': case '=':
-+ case '.': case '@': case '$': case '#': case '`': case '\\':
-+ lexptr++;
-+ yylval.opinfo.opcode=c ;
-+ return c;
-+ case ';': { /* hack, ignore ';' before '}' and else. for C compatability*/
-+ char *save_lexptr= ++lexptr ;
-+ int tok=yylex() ; /* hack, call myself for next token */
-+ if(tok=='}' || tok==T_ELSE) {
-+ duel_printf("warning: useless ';' ignored\n");
-+ return tok ;
-+ }
-+ /* else restore position and return the ';' */
-+ lexptr=save_lexptr ;
-+ yylval.opinfo.opcode=';' ;
-+ yylval.opinfo.src_pos = src_pos ;
-+ return ';';
-+ }
-+ case '"': {
-+ char s[512] ;
-+ size_t len=0 ;
-+ ttarget_ptr dptr ;
-+ tnode *n ;
-+
-+ p=lexptr++ ;
-+ while((c= *lexptr++)!='"') {
-+ if (c == '\\') c=parse_escaped_char();
-+ s[len++]=c ;
-+ }
-+ s[len++]=0 ;
-+ dptr=duel_alloc_target_space(len);
-+ duel_put_target_bytes(dptr,s,len);
-+
-+ n=mknode_const(src_pos,ctype_charptr);
-+ n->cnst.u.rval_ptr=dptr ;
-+ len=lexptr-p ;
-+ if(len>60) len=60 ;
-+ strncpyz(n->cnst.symb_val,p,len); /* save the symbolic val*/
-+ yylval.node=n ;
-+ return T_CONST ;
-+ }
-+ }
-+
-+ if(c != '_' && !isalpha(c))
-+ yyerror ("Invalid character in expression.");
-+
-+ p=lexptr ;
-+ do { c= *++lexptr ; } while(c=='_' || isalnum(c));
-+
-+ for (i = 0; i < sizeof(keywords)/sizeof(struct skeyword) ; i++) {
-+ int l=strlen(keywords[i].keyword_str) ; /* check next token vs keywords*/
-+ if(l==lexptr-p && strncmp(p,keywords[i].keyword_str,l)==0) {
-+ yylval.opinfo.opcode=keywords[i].opcode ;
-+ return keywords[i].token ;
-+ }
-+ }
-+
-+ /* the symbol/name found is not a reserved word, so return it as a T_SYM
-+ */
-+
-+ i=lexptr-p ; /* length of string found (symbol/name) */
-+ yylval.nameinfo.src_pos=src_pos ;
-+ yylval.nameinfo.name=duel_malloc(i+1);
-+ strncpyz(yylval.nameinfo.name,p,i);
-+ return T_SYM;
-+}
-+
-+LPROC yyerror(char *msg)
-+{
-+ int i,n=lexptr-inputstr ;
-+ duel_printf("%s\n",inputstr);
-+ for(i=0 ; i<n ; i++) duel_printf("-");
-+ duel_printf("^ %s\n",msg);
-+ duel_abort(); /* terminate parsing. some callers depend on this*/
-+}
-+
-+/*************************************************************************/
-+/* utility functions used to parse the expression and build it as a tree */
-+/*************************************************************************/
-+
-+/* mknode_op -- make a tree node of type op with given opcode and kids
-+ */
-+
-+LFUNC tnode* mknode_op(top_kind op_kind,topinfo opinfo,
-+ tnode *k1,tnode *k2,tnode *k3,tnode *k4)
-+{
-+ tnode *n ;
-+ duel_assert(opinfo.opcode>' ');
-+ n=(tnode *) duel_malloc(sizeof(tnode));
-+ duel_bzero((char*) n,sizeof(tnode));
-+ n->node_kind=NK_OP ;
-+ n->op_kind=op_kind ;
-+ n->op=opinfo.opcode ;
-+ n->src_pos=opinfo.src_pos ;
-+ n->kids[0]=k1 ; n->kids[1]=k2 ; n->kids[2]=k3 ; n->kids[3]=k4 ;
-+ return n ;
-+}
-+
-+
-+ /* mknode_const -- make a constant node for the given type.
-+ */
-+
-+LFUNC tnode* mknode_const(int src_pos,tctype *ctype)
-+{
-+ tnode *n ;
-+ n=(tnode *) duel_malloc(sizeof(tnode));
-+ duel_bzero((char*) n,sizeof(tnode));
-+ n->node_kind=NK_CONST ;
-+ n->src_pos=src_pos ;
-+ n->cnst.val_kind=VK_RVALUE ;
-+ n->cnst.ctype=ctype ;
-+ return n ;
-+}
-+
-+ /* mknode_ctype -- make a node of the given c-type.
-+ */
-+
-+LFUNC tnode* mknode_ctype(tctype *ctype)
-+{
-+ tnode *n ;
-+ n=(tnode *) duel_malloc(sizeof(tnode));
-+ duel_bzero((char*) n,sizeof(tnode));
-+ n->node_kind=NK_CTYPE ;
-+ n->ctype=ctype ;
-+ return n ;
-+}
-+
-+ /* mknode_name -- make a node of the given name/symbol.
-+ * input is pointer to the saved name (on heap)
-+ */
-+
-+LFUNC tnode* mknode_name(tnameinfo nameinfo)
-+{
-+ tnode *n ;
-+ n=(tnode *) duel_malloc(sizeof(tnode));
-+ duel_bzero((char*) n,sizeof(tnode));
-+ n->node_kind=NK_NAME ;
-+ n->name=nameinfo.name ;
-+ n->src_pos=nameinfo.src_pos ;
-+ return n ;
-+}
-+
-+/* In order to parse C types, which are 'reversed' in the parser, a stack
-+ * is used to push abstract declarators, e.g. in (*)() we first push a func
-+ * indicator '(' and then push a pointer indicator '*'. for arrays we push
-+ * a '[' and the array size.
-+ * This stack is popped and a ctype is constructed at the end of the
-+ * abstract type parsing. The following functions implement the stack
-+ */
-+
-+typedef struct stype_desc { /* stack of type descriptors is made of these */
-+ char desc ;
-+ int size ;
-+ struct stype_desc *next ; /* next on stack */
-+ } ttype_desc ;
-+
-+ttype_desc *top = 0 ;
-+
-+
-+LPROC push_type(char desc) /* put desc on the types stack */
-+{
-+ ttype_desc *p = (ttype_desc* ) duel_malloc(sizeof(ttype_desc));
-+ p->desc=desc ;
-+ p->size=0 ;
-+ p->next=top ;
-+ top=p ;
-+}
-+
-+/* push_type_int -- same as push_type but also set the size parameter, which
-+ * is given as a constant node (which is expected to be int)
-+ */
-+
-+LPROC push_type_int(char desc,tnode *n)
-+{
-+ duel_assert(n->node_kind==NK_CONST);
-+ if(n->cnst.ctype != ctype_int ||
-+ n->cnst.u.rval_int <=0 ) duel_gen_error("Illegal array size",0);
-+ push_type(desc);
-+ top->size=n->cnst.u.rval_int ;
-+}
-+
-+LFUNC bool pop_type(char *desc,int *size) /* pop item from stack. */
-+{
-+ ttype_desc *p = top ;
-+ if(p==0) return FALSE ;
-+ *desc=p->desc ;
-+ *size=p->size ;
-+ top=p->next ;
-+ duel_free(p) ;
-+ return TRUE ;
-+}
-+
-+
-+/* abstract type-modifiers were pushed on a stack. Retrieve
-+ * them (reversed) creating type nodes as we go
-+ * input: base type (e.g. 'long').
-+ * returns: node of the modified type.
-+ * modification is based on the stack of things pushed while parsing.
-+ */
-+
-+LFUNC tnode* mknode_modified_ctype(tctype *base)
-+{
-+ int size;
-+ char tdesc ; /* descriptor of abs decl eg '*' */
-+ tctype *t=base ; /* type under construction */
-+
-+ while(pop_type(&tdesc,&size)) /* pop next abs decl */
-+ switch (tdesc) {
-+ case '*': t=duel_mkctype_ptr(t); break ;
-+ case '(': t=duel_mkctype_func(t); break ;
-+ case '[': t=duel_mkctype_array(t,size); break ;
-+ }
-+ return mknode_ctype(t) ;
-+}
-+
-+/* entry point for parsing. the given expression is parsed into the given
-+ * node as root.
-+ */
-+
-+FUNC tnode* duel_parse(char *s)
-+{
-+ lexptr=inputstr=s ;
-+ top=0 ; /* reset the types stack */
-+ if(duel_yyparse()) root=NULL ;
-+ return root ;
-+}
---- gdb/duel/patchlevel.h
-+++ gdb/duel/patchlevel.h
-@@ -0,0 +1,7 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+#define PATCHLEVEL 4
-+#define VERSION "DUEL 1.20"
---- gdb/duel/print.c
-+++ gdb/duel/print.c
-@@ -0,0 +1,299 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* handle value/type printing */
-+
-+/*
-+ * $Log: 10_all_gdb-6.6-duel.patch,v $
-+ * Revision 1.1 2008/04/06 23:59:05 vapier
-+ * initial 6.8 patchset based on last 6.7.1 patchset
-+ *
-+ * Revision 1.9 93/03/12 06:01:00 mg
-+ * cosmetics: tuint for uint, etc.
-+ * display union like structs
-+ * suport piped output
-+ * note for all pointers if illegal, better handling of string bad pointers
-+ *
-+ * Revision 1.8 93/02/27 06:06:50 mg
-+ * removed usage of fabs() so -lm is not required in gdb's linking (HP9000)
-+ *
-+ * Revision 1.7 93/02/26 05:00:42 mg
-+ * fixed display of *p for void *p
-+ *
-+ * Revision 1.6 93/02/23 20:57:56 mg
-+ * *** empty log message ***
-+ *
-+ * Revision 1.5 93/02/23 19:16:00 mg
-+ * improved escaped char support
-+ *
-+ * Revision 1.4 93/02/03 21:54:49 mg
-+ * support "signed char"
-+ *
-+ * Revision 1.3 93/01/12 21:53:45 mg
-+ * cleanup and set for release
-+ *
-+ * Revision 1.2 93/01/07 00:14:34 mg
-+ * print union name
-+ *
-+ * Revision 1.1 93/01/03 07:31:55 mg
-+ * Initial revision
-+ *
-+ */
-+
-+#include "duel.h"
-+
-+/* print type information (no new lines)
-+ * parm 'expand' controls expansion level for structs & unions. normally 1.
-+ */
-+
-+PROC duel_print_type(tctype *t,int expand)
-+{
-+ int i ;
-+ tctype *kid=t->u.kid ;
-+
-+ switch(t->type_kind) {
-+ case CTK_VOID: duel_printf("void ") ; break ;
-+ case CTK_CHAR: duel_printf("char ") ; break ;
-+ case CTK_SCHAR: duel_printf("schar ") ; break ;
-+ case CTK_UCHAR: duel_printf("uchar ") ; break ;
-+ case CTK_USHORT: duel_printf("ushort ") ; break ;
-+ case CTK_SHORT: duel_printf("short ") ; break ;
-+ case CTK_INT: duel_printf("int ") ; break ;
-+ case CTK_UINT: duel_printf("uint ") ; break ;
-+ case CTK_LONG: duel_printf("long ") ; break ;
-+ case CTK_ULONG: duel_printf("ulong ") ; break ;
-+ case CTK_LONGLONG: duel_printf("longong ") ; break ;
-+ case CTK_ULONGLONG: duel_printf("ulonglong ") ; break ;
-+ case CTK_FLOAT: duel_printf("float ") ; break ;
-+ case CTK_DOUBLE: duel_printf("double ") ; break ;
-+ case CTK_ENUM: duel_printf("enum %s ",t->name); break ;
-+
-+ case CTK_PTR:
-+ if(ctype_kind_base(kid)) {
-+ duel_print_type(kid,0);
-+ duel_printf("* ");
-+ }
-+ else {
-+ duel_printf("ptr to ");
-+ duel_print_type(kid,expand-1) ;
-+ }
-+ break ;
-+ case CTK_ARRAY: {
-+ int n=t->size ;
-+ if(kid->size>0) n/=kid->size ;
-+
-+ if(ctype_kind_base(kid)) {
-+ duel_print_type(kid,0);
-+ duel_printf("[%d] ",n);
-+ }
-+ else {
-+ duel_printf("array [%d] of ",n);
-+ duel_print_type(kid,expand) ;
-+ }
-+ }
-+ break ;
-+ case CTK_FUNC: duel_printf("func returning ");
-+ duel_print_type(kid,expand);
-+ break ;
-+ case CTK_STRUCT:
-+ if(expand <= 0) {
-+ duel_printf("struct %s ",t->name);
-+ break ;
-+ }
-+ duel_printf("struct %s { ",t->name) ;
-+ for(i=0 ; i<t->u.f.fields_no ; i++) {
-+ tctype_field *f= &t->u.f.fields[i] ;
-+ duel_print_type(f->ctype,expand-1);
-+ duel_printf("%s ",f->name);
-+ if(f->bitlen != 0) duel_printf(":%d ",f->bitlen);
-+ duel_printf("; ");
-+ }
-+ duel_printf("} ; ");
-+ break ;
-+ case CTK_UNION: duel_printf("union %s",t->name) ; break ;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+/* display char 'c' in a "neat" way, e.g. c='\n' is displayed as such,
-+ * etc. Special case for c==quote (normally ' or "), we add '\\'
-+ * return a pointer to a static string which is overriden each call etc
-+ */
-+char *neat_char(char c,char quote)
-+{
-+ static char s[8] ;
-+ switch(c) {
-+ case '\0': strcpy(s,"\\0"); break ;
-+ case '\n': strcpy(s,"\\n"); break ;
-+ case '\r': strcpy(s,"\\r"); break ;
-+ case '\t': strcpy(s,"\\t"); break ;
-+ case '\\': strcpy(s,"\\\\"); break ;
-+ default:
-+ if(!isprint(c) || !isascii(c)) sprintf(s,"\\%3.3o",c & 0377);
-+ else
-+ if(c==quote) sprintf(s,"\\%c",c);
-+ else sprintf(s,"%c",c);
-+ }
-+ return s ;
-+}
-+
-+/* print the given scalar value into string s.
-+ * for none-scalar values, print the lval's address.
-+ * note: v's value is not modified.
-+ */
-+
-+PROC duel_sprint_scalar_value(char *s,tvalue *v)
-+{
-+ bool ok ;
-+ tvalue rval ; /* copy of v, but as an rval */
-+ rval = *v ;
-+ if(v->val_kind==VK_FVALUE) {
-+ sprintf(s,"frame(%d)",v->u.fvalue);
-+ return ;
-+ }
-+ if(v->val_kind==VK_LVALUE) {
-+ char tmpstr[256],*m="" ; /* tmpstr= temporary for check, m= message */
-+ int sz = v->ctype->size ; /* size of object ref. */
-+ if(sz<1) sz=1 ;
-+ if(sz>256) sz=256 ;
-+ /* check for null and bad (try read sz bytes at addr ) references */
-+ if(v->u.lvalue==NULL ||
-+ !duel_get_target_bytes(v->u.lvalue,tmpstr,sz)) m=" [ILLEGAL]" ;
-+
-+ switch(v->ctype->type_kind) {
-+ case CTK_VOID: sprintf(s,"void @%p%s",v->u.lvalue,m); return;
-+ case CTK_STRUCT: sprintf(s,"struct @%p%s",v->u.lvalue,m); return;
-+ case CTK_UNION: sprintf(s,"union @%p%s",v->u.lvalue,m); return;
-+ case CTK_FUNC: sprintf(s,"func @%p%s",v->u.lvalue,m) ; return;
-+ case CTK_ARRAY:
-+ if(*m!='\0' || v->ctype->u.kid!=ctype_char) {
-+ sprintf(s,"array @%p%s",v->u.lvalue,m);
-+ return;
-+ }
-+ }
-+ /* convert scalar type to rvalue */
-+ if(!duel_try_get_rvalue(&rval,"")) {
-+ sprintf(s,"ref @%p [ILLEGAL]",v->u.lvalue,m);
-+ return ;
-+ }
-+ }
-+ else
-+ if(v->val_kind==VK_BVALUE) {
-+ if(!duel_try_get_rvalue(&rval,"")) {
-+ sprintf(s,"ref @%p [ILLEGAL]",v->u.bvalue.lvalue);
-+ return ;
-+ }
-+ }
-+
-+ switch(rval.ctype->type_kind) { /* handle rvalues */
-+ case CTK_VOID: sprintf(s,"void") ; break ;
-+ case CTK_CHAR: sprintf(s,"'%s'",neat_char(rval.u.rval_char,'\''));break;
-+ case CTK_SHORT: sprintf(s,"%d", rval.u.rval_short) ; break ;
-+ case CTK_INT: sprintf(s,"%d", rval.u.rval_int) ; break ;
-+ case CTK_LONG: sprintf(s,"%ldL", rval.u.rval_long) ; break ;
-+ case CTK_LONGLONG: sprintf(s,"%lldLL", rval.u.rval_longlong) ; break ;
-+ case CTK_SCHAR: if(rval.u.rval_schar==0) sprintf(s,"'\\0'");
-+ else sprintf(s,"%d", rval.u.rval_schar) ; break ;
-+ case CTK_UCHAR: if(rval.u.rval_uchar==0) sprintf(s,"'\\0'");
-+ else sprintf(s,"'\\x%d'", rval.u.rval_uchar) ; break ;
-+ case CTK_USHORT: if(rval.u.rval_ushort==0) sprintf(s,"0");
-+ else sprintf(s,"0x%x", rval.u.rval_ushort) ; break ;
-+ case CTK_UINT: if(rval.u.rval_uint==0) sprintf(s,"0");
-+ else sprintf(s,"0x%x", rval.u.rval_uint) ; break ;
-+ case CTK_ULONG: if(rval.u.rval_ulong==0L) sprintf(s,"0");
-+ else sprintf(s,"0x%lxUL", rval.u.rval_ulong) ; break ;
-+ case CTK_ULONGLONG: if(rval.u.rval_ulonglong==0L) sprintf(s,"0");
-+ else sprintf(s,"0x%llxULL", rval.u.rval_ulonglong) ; break ;
-+ case CTK_FLOAT: rval.u.rval_double=rval.u.rval_float ;
-+ case CTK_DOUBLE: { double x=rval.u.rval_double ;
-+ if(x >= -1e-6 && x <= 1e-6 || x >= 1e8 || x <= -1e8)
-+ sprintf(s,"%.4le",x); /* standard 'e' fmt */
-+ else { /* fixed point removing trailing '0'*/
-+ int l;
-+ sprintf(s,"%.8lf",x);
-+ l=strlen(s)-1;
-+ while(s[l]=='0' && s[l-1]!='.') s[l--]=0 ;
-+ }
-+ }
-+ break ;
-+ case CTK_PTR:
-+ if(rval.u.rval_ptr==NULL) sprintf(s,"NULL");
-+ else {
-+ char sval[41];
-+ bool ok=duel_get_target_bytes(rval.u.lvalue,sval,1);
-+ if(ok && rval.ctype->u.kid==ctype_char) {
-+ int i ;
-+ duel_get_target_bytes(rval.u.lvalue,sval,41);
-+ strcpy(s,"\"");
-+ for(i=0 ; i<40 && sval[i]!='\0' ; i++)
-+ strcat(s,neat_char(sval[i],'"'));
-+ if(sval[i]=='\0') strcat(s,"\"");
-+ else strcat(s,"...\"");
-+ }
-+ else sprintf(s,"@%p%s",rval.u.rval_ptr,ok? "":" [ILLEGAL]");
-+ }
-+ break ;
-+ case CTK_ENUM: {
-+ int i, n=rval.ctype->u.e.enumerators_no ;
-+ tctype_enumerator *e=rval.ctype->u.e.enumerators ;
-+ int val=duel_get_int_val(v,"");
-+ for(i=0 ; i<n ; i++)
-+ if(e[i].val == val) { strcpy(s,e[i].name); return ;}
-+ sprintf(s,"%d",val);
-+ }
-+ break ;
-+ default: duel_assert(0);
-+ }
-+}
-+
-+/* print the given value, symbolic+val. Handles structures */
-+
-+PROC duel_print_value(tvalue *v)
-+{
-+ tctype *t=v->ctype ;
-+ int i ;
-+ bool topipe=duel_output_pipe_style ;
-+ char s[160];
-+
-+ duel_printf(topipe? "$$$SYM: %s\n":"%s",v->symb_val);
-+
-+ if(duel_debug && !topipe) {
-+ duel_printf("`` %s '' ",v->symb_val);
-+ duel_printf("{ ");
-+ duel_print_type(v->ctype,2);
-+ duel_printf("} ");
-+ if(v->val_kind==VK_LVALUE) {
-+ duel_printf("lval @%p",v->u.lvalue);
-+ }
-+ else
-+ if(v->val_kind==VK_BVALUE) {
-+ duel_printf("bval @%p [%d,%d]",v->u.bvalue.lvalue,v->u.bvalue.bitpos,
-+ v->u.bvalue.bitlen);
-+ }
-+ duel_printf("\n");
-+ }
-+
-+ duel_sprint_scalar_value(s,v);
-+ if(v->val_kind==VK_LVALUE && strstr(s,"ILLEGAL")==NULL) {
-+ switch(t->type_kind) {
-+ case CTK_UNION:
-+ case CTK_STRUCT:
-+ duel_printf(topipe? "$$$VAL: { " : " = { ");
-+ for(i=0 ; i<t->u.f.fields_no ; i++) {
-+ tvalue u ;
-+ char *name=t->u.f.fields[i].name ;
-+ duel_get_dot_name(v,name,&u);
-+ duel_sprint_scalar_value(s,&u);
-+ duel_printf("%s = %s",name,s) ;
-+ if(i < t->u.f.fields_no-1) duel_printf(", ");
-+ }
-+ duel_printf(" }\n");
-+ return ;
-+ case CTK_ARRAY: ; /* not handled except for char[] as scalar*/
-+ }
-+ }
-+
-+ if(topipe) duel_printf("$$$VAL: %s",s);
-+ else
-+ if(strcmp(v->symb_val,s)!=0) duel_printf(" = %s",s);
-+ duel_printf("\n");
-+}
---- gdb/duel/proto.h
-+++ gdb/duel/proto.h
-@@ -0,0 +1,101 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* prototypes for all of duel's global functions */
-+
-+FUNC tctype* duel_mkctype_ptr(tctype *t);
-+FUNC tctype* duel_mkctype_func(tctype *t);
-+FUNC tctype* duel_mkctype_array(tctype *t,int size);
-+FUNC tctype* duel_mkctype_struct(char *name,size_t size,int fields_no,
-+ bool is_union);
-+PROC duel_mkctype_struct_field(tctype *t,int field_no,char *name,
-+ int bitpos,int bitlen, tctype *fctype);
-+FUNC tctype* duel_mkctype_enum(char *name,tctype_kind real_type_kind,
-+ size_t size,int enumerators_no);
-+PROC duel_mkctype_enumerator(tctype *t,int enumerator_no,char *name,int val);
-+
-+PROC duel_init_basic_ctypes(void);
-+
-+PROC duel_print_value(tvalue *v);
-+PROC duel_print_type(tctype *t,int expand);
-+PROC duel_sprint_scalar_value(char *s,tvalue *v);
-+
-+
-+PROC duel_fatal(char *msg);
-+PROC duel_abort(void);
-+PROC duel_cleanup(void *);
-+
-+FUNC tnode* duel_parse(char *s);
-+
-+
-+PROC duel_reset_eval(void);
-+FUNC bool duel_eval(tnode *n,tvalue *v);
-+FUNC bool duel_get_dot_name(tvalue *v,char *name,tvalue *ret);
-+
-+FUNC tnode* duel_set_eval_loc(tnode *n);
-+FUNC char* duel_set_input_string(char *s);
-+PROC duel_op_error(char *mesg,char *op,tvalue *v1,tvalue *v2);
-+PROC duel_gen_error(char *mesg,char *arg1);
-+
-+PROC duel_parse_and_eval(char *s);
-+
-+FUNC bool duel_try_get_rvalue(tvalue *v,char *op);
-+PROC duel_standardize_func_parm(tvalue *p);
-+FUNC bool duel_do_op_to(tvalue *v1,tvalue *v2,int n,tvalue *r);
-+PROC duel_do_cast(tctype *tout,tvalue *v);
-+FUNC bool duel_mk_logical(tvalue *v,char *op);
-+PROC duel_set_symb_val(tvalue *r,char *format,tvalue *v1,tvalue *v2);
-+PROC duel_get_struct_val(tvalue *v,char *op);
-+PROC duel_get_struct_ptr_val(tvalue *v,char *op);
-+FUNC int duel_get_int_val(tvalue *v,char *op);
-+FUNC int duel_get_posint_val(tvalue *v,char *op);
-+PROC duel_apply_unary_op(topcode op,tvalue *v);
-+PROC duel_apply_post_unary_op(topcode op,tvalue *v);
-+FUNC bool duel_apply_bin_op(topcode op,tvalue *v1,tvalue *v2,tvalue *r);
-+PROC duel_find_func_frame(tvalue *v,char *op);
-+
-+/* output management */
-+
-+PROC duel_printf(char *fmt, ...);
-+PROC duel_flush(void);
-+PROC duel_redirectable_output_start(char *);
-+PROC duel_redirectable_output_end(void);
-+PROC duel_redirectable_output_abort(void);
-+PROC duel_redirectable_output_init(void);
-+
-+/* debugger dependent functions */
-+
-+FUNC void* duel_malloc(size_t size);
-+PROC duel_free(void *);
-+
-+FUNC bool duel_get_target_bytes(ttarget_ptr from,void *to,size_t n);
-+FUNC bool duel_put_target_bytes(ttarget_ptr to,void *from,size_t n);
-+
-+FUNC bool duel_get_target_bitfield(ttarget_ptr struct_at,int bitpos,
-+ int bitlen,void *to,tctype_kind tkind);
-+FUNC bool duel_get_target_variable(char *name, int frame_no, tvalue *v);
-+FUNC tctype* duel_get_target_typedef(char *name);
-+FUNC tctype* duel_get_target_struct_tag(char *name);
-+FUNC tctype* duel_get_target_union_tag(char *name);
-+FUNC tctype* duel_get_target_enum_tag(char *name);
-+FUNC ttarget_ptr duel_alloc_target_space(size_t n);
-+
-+FUNC int duel_get_frames_number(void);
-+FUNC ttarget_ptr duel_get_function_for_frame(int frame_no);
-+PROC duel_target_func_call(tvalue *func, tvalue *parms[],
-+ int parms_no,tvalue *ret);
-+
-+/* prototypes for misc functions */
-+
-+FUNC char* strncpyz(char *to,char *from,size_t len);
-+
-+PROC duel_free_val_list(tval_list *l);
-+PROC duel_free_nodes(tnode *);
-+
-+FUNC tvalue* duel_find_alias(char *name);
-+PROC duel_set_alias(char *name,tvalue *v);
-+PROC duel_clear_aliases(void);
-+PROC duel_show_aliases(void);
-+
---- gdb/duel/tsuite.c
-+++ gdb/duel/tsuite.c
-@@ -0,0 +1,64 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* this is a test program to be used with tsuite.gdb */
-+
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <string.h>
-+
-+int gint ;
-+typedef unsigned int uint ;
-+
-+struct { int a,b ; char *name ; } emp[100] ;
-+enum { MIKI, DAVE, ELA } us ;
-+struct snode { int code ; struct snode *left,*right ; } ;
-+typedef struct snode tnode ;
-+
-+/* amazing, but DEC compiled strcmp such that gdb thinks it returns void */
-+int mystrcmp(s,t) char *s; char *t; { return strcmp(s,t); }
-+
-+void main()
-+{
-+ char *s="main string" ;
-+ FILE *out=stdout ; /* stdout is not a variable on some machines */
-+ /* will use fflush(out) from debugger */
-+ int i ;
-+ tnode *root,*p,**q ;
-+
-+ for(i=0 ; i<100 ; i++) {
-+ emp[i].a=i ; emp[i].b=i*i ;
-+ emp[i].name=(char*) malloc(10);
-+ sprintf(emp[i].name,"emp%3.3d",i);
-+ }
-+ emp[53].a=76 ; /* bug */
-+ emp[36].b-- ; /* bug */
-+ emp[74].name[3]='5' ; /* another bug */
-+
-+ root=(tnode*) malloc(sizeof(tnode));
-+ root->left=root->right=0 ;
-+ root->code=5000 ;
-+ for(i=1 ; i<10000 ; i++) { /* insert elements into tree */
-+ int code=((i*997*1013)>>10)%11000 ; /* "fixed" "random" generaor */
-+ if(code<0) code= -code ;
-+ p=root ;
-+ while(p) {
-+ if(p->code==code) break ;
-+ if(p->code<code) q= &p->right, p=p->right ;
-+ else q= &p->left, p=p->left ;
-+ }
-+ if(p==0) {
-+ p=(tnode*) malloc(sizeof(tnode));
-+ p->code=code ;
-+ if(i>8680) p->code+=(i<9210)? 1:-1 ; /* bug */
-+ p->left=p->right=0 ;
-+ *q=p ;
-+ }
-+ }
-+
-+ printf("trivial tsuite program\n");
-+ printf("trivial tsuite program\n");
-+}
-+
---- gdb/duel/tsuite.gdb
-+++ gdb/duel/tsuite.gdb
-@@ -0,0 +1,126 @@
-+set prompt
-+## DUEL - A Very High Level Debugging Langauge.
-+## Public domain code
-+## Written by Michael Golan mg@cs.princeton.edu
-+##$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $
-+##
-+## test suite for duel, can be used with duelself or gdb
-+##
-+file tsuite
-+b 60
-+b 61
-+r
-+## check constants
-+dl (1..5)*(2,(double) 2/3)
-+## declare array x, set it, search it
-+dl int x[100] ;
-+dl x[0..99]= -1 ;
-+dl x[i:=20..40]=2+i*i ;
-+dl x[20..23,38..40]
-+dl x[..100] >=? 33*33 <=? 35*35
-+dl x[..100]=> ((_>=33*33) & (_<= 35*35)) ==? 1
-+dl (*(x+(7..9)))++
-+dl y:= &x[7] ;
-+dl y[0..2]
-+dl x+7 == y
-+dl (x[..99]>?0)@(_>100)
-+dl printf("%d\n",1..10);
-+dl printf("x is: "); printf("%d, ",x[0..99]>? 0); printf("\n");fflush(out);
-+dl int j ; for(j=0 ; j<100 ; j++) if(x[j]>37*37) printf("x[%d]=%d\n",j,x[j]);fflush(out);
-+dl printf("%d\n",1..5);
-+## check void type
-+dl void *p
-+dl p = &p
-+dl p,*p
-+## errors
-+dl 1e+++3
-+dl i=4 ;
-+dl x=6 ;
-+dl x++ ;
-+dl --i ;
-+## cleanup
-+dl alias
-+dl clear
-+## access some variables
-+dl s
-+dl s[4..8]
-+dl s[6..]@0
-+dl l:=#/s[0..]@0
-+dl s[l-2..l]
-+dl gint
-+dl gint++
-+dl gint++
-+dl --gint
-+dl gint
-+dl main.s
-+dl ++main.s
-+dl main ==? main
-+dl main == main
-+dl frames_no
-+dl frame(0).s
-+dl frame(0).(gint+0)
-+dl sizeof(gint)
-+dl sizeof(T uint)
-+dl sizeof(T uint*)
-+dl sizeof(T emp)
-+dl sizeof(emp)
-+dl sizeof(emp[0])
-+dl (uint)-1
-+dl (uint*)(gint=gint-9)
-+dl *(uint*)&gint
-+dl T uint myuint ; myuint = -1
-+## some errors
-+dl frame(0).gint
-+dl frame(0).(gint)
-+dl frame(0).ha
-+dl sizeof(uint)
-+dl sizeof gint
-+dl main == printf
-+dl main+1
-+dl main > printf
-+dl printf+3
-+dl T int x
-+dl uint y
-+dl T uint z = 5
-+## finally, do some serious checks using the bugs in the programs
-+dl emp[4]
-+dl emp[k:=..100].a !=? k
-+dl (emp[k:=..100].a !=? k)[[0]] ; emp[{k}]
-+dl emp[k:=..100].if(a!=k) _
-+dl emp[k:=..100].b !=? k*k
-+dl emp[k:=..100].if(b!=k*k) _,{k}*{k}
-+dl emp[k:=..100]=>if(_.b!=k*k) _,{k}*{k}
-+dl char s[80];
-+dl ..100 => (sprintf(s,"emp%3.3d",_) ; emp[_].name[0..]@0#j !=? s[j])
-+dl ..100 => (sprintf(s,"emp%3.3d",_) ; mystrcmp(emp[_].name,s)!=?0)
-+dl ..100 => (sprintf(s,"emp%3.3d",_) ; emp[_].name=>if(mystrcmp(_,s))_)
-+## now, lets try some pointers and --> stuff!
-+dl root-->left[[..8]]->code
-+dl root-->(left,right)[[..30]]->code
-+dl #/root-->(left,right)
-+dl root->(left,right) => #/_-->(left,right)
-+dl root->(left->left,left->right,right->left,right->right)=> #/_-->(left,right)
-+## this cause very long symbolic vals, core dump/bad results before duel 1.10.3
-+dl #/(root+0000000000000000000000000000000000000000000000000000)-->(left,right)
-+## compute min, max, check for dups, no-show
-+dl root-->left[[#/root-->left-1]]->code
-+dl root-->right[[#/root-->right-1]]->code
-+dl int codes[11000] ; codes[..11000]=0 ; codes[root-->(left,right)->code]++ ;
-+dl codes[..11000] >? 1
-+dl (codes[..11000] ==? 0 )[[..10]]
-+dl (..11000 => if(!codes[_]) _)[[..10]]
-+## check consistency
-+dl root-->(left,right)->((left!=?0)->code >=? code, (right!=?0)->code <=? code)
-+dl root-->(left,right)->((left!=?0)->code>=code, (right!=?0)->code<=code)==?1
-+dl (1000..=>if(&&/( 2,3.._-1 =>__%_)) _)[[..10]]
-+## enums
-+dl ELA
-+dl (T us) 1
-+dl us=1 ; us
-+dl MIKI..ELA
-+## more errors
-+dl emp[0]=us
-+dl emp=us
-+dl us=emp
-+## the end
-+
---- gdb/duel/tsuite.gdb.out
-+++ gdb/duel/tsuite.gdb.out
-@@ -0,0 +1,293 @@
-+GDB is free software and you are welcome to distribute copies of it
-+ under certain conditions; type "show copying" to see the conditions.
-+There is absolutely no warranty for GDB; type "show warranty" for details.
-+GDB 4.8, Copyright 1993 Free Software Foundation, Inc.
-+(gdb) Reading symbols from tsuite...done.
-+ Breakpoint 1 at 0x400518: file tsuite.c, line 60.
-+ Note: breakpoint 1 also set at pc 0x400518.
-+Breakpoint 2 at 0x400518: file tsuite.c, line 61.
-+ Starting program: /tmp_mnt/n/fs/grad2/mg/duel/tsuite/tsuite
-+
-+Breakpoint 1, main () at tsuite.c:61
-+61 printf("trivial tsuite program\n");
-+ DUEL 1.10.4, public domain debugging language. "dl" for help
-+1*2 = 2
-+1*(2/3) = 0.66666667
-+2*2 = 4
-+2*(2/3) = 1.33333333
-+3*2 = 6
-+3*(2/3) = 2.0
-+4*2 = 8
-+4*(2/3) = 2.66666667
-+5*2 = 10
-+5*(2/3) = 3.33333333
-+ x[20] = 402
-+x[21] = 443
-+x[22] = 486
-+x[23] = 531
-+x[38] = 1446
-+x[39] = 1523
-+x[40] = 1602
-+ x[33] = 1091
-+x[34] = 1158
-+ (x[33]>=33*33)&(x[33]<=35*35) = 1
-+(x[34]>=33*33)&(x[34]<=35*35) = 1
-+ (*(x+7))++ = -1
-+(*(x+8))++ = -1
-+(*(x+9))++ = -1
-+ y[0] = 0
-+y[1] = 0
-+y[2] = 0
-+ x+7==y = 1
-+ 1
-+2
-+3
-+4
-+5
-+6
-+7
-+8
-+9
-+10
-+x is: 402, 443, 486, 531, 578, 627, 678, 731, 786, 843, 902, 963, 1026, 1091, 1158, 1227, 1298, 1371, 1446, 1523, 1602,
-+ x[37]=1371
-+x[38]=1446
-+x[39]=1523
-+x[40]=1602
-+ &p = @10020020
-+ p = @10020020
-+*p = void @10020020
-+ 1e+++3
-+^ Invalid float constant.
-+ Error: i=4 ;
-+ -^-- operand x is not an lvalue for operator 'x=y'
-+operand ``i'' -- type: int
-+ -- value: 40
-+ Error: x=6 ;
-+ -^-- bad operand x type for operator 'x=y'
-+operand ``x'' -- type: int [100]
-+ -- value: array @1001f000
-+ Error: x++ ;
-+ -^-- operand x of '++' is not integral
-+operand ``x'' -- type: int [100]
-+ -- value: array @1001f000
-+ Error: --i ;
-+ ^-- operand of '--' must be an lvalue
-+operand ``i'' -- type: int
-+ -- value: 40
-+ Aliases table:
-+p: p = @10020020
-+j: j = 100
-+y: &x[7] = @1001f01c
-+i: 40
-+x: x = array @1001f000
-+ Aliases table cleared
-+ s = "main string"
-+ s[4] = ' '
-+s[5] = 's'
-+s[6] = 't'
-+s[7] = 'r'
-+s[8] = 'i'
-+ s[6] = 't'
-+s[7] = 'r'
-+s[8] = 'i'
-+s[9] = 'n'
-+s[10] = 'g'
-+ #/(s[0] ...) = 11
-+ s[9] = 'n'
-+s[10] = 'g'
-+s[11] = '\0'
-+ gint = 0
-+ gint++ = 0
-+ gint++ = 1
-+ gint = 1
-+ gint = 1
-+ main.s = "main string"
-+ main.s = "ain string"
-+ main = func @004001f0
-+ main==main = 1
-+ frames_no = 1
-+ frame(0).s = "ain string"
-+ frame(0).(gint+0) = 1
-+ sizeof(gint) = 0x4
-+ sizeof(unsigned int) = 0x4
-+ sizeof(T) = 0x4
-+ sizeof(T) = 0x4b0
-+ sizeof(emp) = 0x4b0
-+ sizeof(emp[0]) = 0xc
-+ -1 = 0xffffffff
-+ (gint-9) = @fffffff8 [ILLEGAL]
-+ *&gint = 0xfffffff8
-+ -1 = 0xffffffff
-+ Error: frame(0).gint
-+ --------^-- field not found in operator '.'
-+operand ``frame(0)'' -- type: int
-+ -- value: frame(0)
-+ frame(0).(gint)
-+---------------^ syntax error
-+ Error: frame(0).ha
-+ --------^-- field not found in operator '.'
-+operand ``frame(0)'' -- type: int
-+ -- value: frame(0)
-+ Error: sizeof(uint)
-+ -------^-- variable 'uint' not found
-+ sizeof gint
-+-----------^ syntax error
-+ Error: main == printf
-+ -----^-- incompatible types for op ==
-+operand1 ``main'' -- type: ptr to func returning void
-+ -- value: @004001f0
-+operand2 ``printf'' -- type: ptr to func returning int
-+ -- value: @00400ca0
-+ Error: main+1
-+ ----^-- unknown pointer object size for '+' op
-+operand ``main'' -- type: ptr to func returning void
-+ -- value: @004001f0
-+ Error: main > printf
-+ -----^-- incompatible types for op >
-+operand1 ``main'' -- type: ptr to func returning void
-+ -- value: @004001f0
-+operand2 ``printf'' -- type: ptr to func returning int
-+ -- value: @00400ca0
-+ Error: printf+3
-+ ------^-- unknown pointer object size for '+' op
-+operand ``printf'' -- type: ptr to func returning int
-+ -- value: @00400ca0
-+ T int x
-+-----^ syntax error
-+ uint y
-+------^ syntax error
-+ T uint z = 5
-+----------^ syntax error
-+ emp[4] = { a = 4, b = 16, name = "emp004" }
-+ emp[53].a = 76
-+ emp[53] = { a = 76, b = 2809, name = "emp053" }
-+ emp[53] = { a = 76, b = 2809, name = "emp053" }
-+ emp[36].b = 1295
-+ emp[36] = { a = 36, b = 1295, name = "emp036" }
-+emp[36].36*36 = 1296
-+ emp[36] = { a = 36, b = 1295, name = "emp036" }
-+36*36 = 1296
-+ (emp[74].name[3]) = '5'
-+ (mystrcmp(emp[74].name,s)) = 5
-+ (emp[74].name) = "emp574"
-+ root->code = 5000
-+root->left->code = 986
-+root-->left[[2]]->code = 835
-+root-->left[[3]]->code = 684
-+root-->left[[4]]->code = 533
-+root-->left[[5]]->code = 383
-+root-->left[[6]]->code = 232
-+root-->left[[7]]->code = 81
-+ root->code = 5000
-+root->left->code = 986
-+root-->left[[2]]->code = 835
-+root-->left[[3]]->code = 684
-+root-->left[[4]]->code = 533
-+root-->left[[5]]->code = 383
-+root-->left[[6]]->code = 232
-+root-->left[[7]]->code = 81
-+root-->left[[8]]->code = 12
-+root-->left[[9]]->code = 2
-+root-->left[[9]]->right->code = 5
-+root-->left[[9]]->right->left->code = 4
-+root-->left[[9]]-->right[[2]]->code = 11
-+root-->left[[9]]-->right[[2]]->left->code = 8
-+root-->left[[9]]-->right[[2]]-->left[[2]]->code = 7
-+root-->left[[9]]-->right[[2]]->left->right->code = 10
-+root-->left[[8]]->right->code = 24
-+root-->left[[8]]->right->left->code = 15
-+root-->left[[8]]->right-->left[[2]]->code = 14
-+root-->left[[8]]->right->left->right->code = 17
-+root-->left[[8]]->right->left->right->left->code = 16
-+root-->left[[8]]->right->left-->right[[2]]->code = 23
-+root-->left[[8]]->right->left-->right[[2]]->left->code = 20
-+root-->left[[8]]->right->left-->right[[2]]-->left[[2]]->code = 19
-+root-->left[[8]]->right->left-->right[[2]]->left->right->code = 22
-+root-->left[[8]]->right->left-->right[[2]]->left->right->left->code = 21
-+root-->left[[8]]-->right[[2]]->code = 36
-+root-->left[[8]]-->right[[2]]->left->code = 27
-+root-->left[[8]]-->right[[2]]->left->right->code = 35
-+root-->left[[8]]-->right[[2]]->left->right->left->code = 32
-+ #/(root ...) = 7144
-+ #/(root->left ...) = 3249
-+#/(root->right ...) = 3894
-+ #/(root->(left->left) ...) = 641
-+#/(root->(left->right) ...) = 2607
-+#/(root->(right->left) ...) = 595
-+#/(root->(right->right) ...) = 3298
-+ #/((root+0000000000000000000000000000000000000000000000000000) ...) = 7144
-+ root-->left[[9]]->code = 2
-+ root-->right[[14]]->code = 10999
-+ codes[2122] = 2
-+codes[2308] = 2
-+codes[5081] = 2
-+codes[5267] = 2
-+codes[8040] = 2
-+codes[9026] = 2
-+codes[9363] = 2
-+ (codes[0]) = 0
-+(codes[1]) = 0
-+(codes[3]) = 0
-+(codes[6]) = 0
-+(codes[9]) = 0
-+(codes[13]) = 0
-+(codes[18]) = 0
-+(codes[25]) = 0
-+(codes[26]) = 0
-+(codes[29]) = 0
-+ 0
-+1
-+3
-+6
-+9
-+13
-+18
-+25
-+26
-+29
-+ root->left-->right[[2]]-->left[[6]]->right->left-->right[[5]]->left->right->left->(right->code) = 2122
-+root->left-->right[[2]]-->left[[5]]-->right[[3]]->left->right->left->right->(left->code) = 2308
-+root->right-->left[[6]]->right->left-->right[[5]]->left->right->left->(right->code) = 5081
-+root->right-->left[[5]]-->right[[3]]->left->right->left->right->(left->code) = 5267
-+root-->right[[4]]-->left[[6]]->right->left-->right[[5]]->left->right->left->(right->code) = 8040
-+root-->right[[5]]-->left[[6]]->right->left-->right[[5]]->left->right->left->(right->code) = 9026
-+root-->right[[5]]-->left[[4]]-->right[[3]]->left->right->left->right->(left->code) = 9363
-+ root->left-->right[[2]]-->left[[6]]->right->left-->right[[5]]->left->right->left->(right->code<=code) = 1
-+root->left-->right[[2]]-->left[[5]]-->right[[3]]->left->right->left->right->(left->code>=code) = 1
-+root->right-->left[[6]]->right->left-->right[[5]]->left->right->left->(right->code<=code) = 1
-+root->right-->left[[5]]-->right[[3]]->left->right->left->right->(left->code>=code) = 1
-+root-->right[[4]]-->left[[6]]->right->left-->right[[5]]->left->right->left->(right->code<=code) = 1
-+root-->right[[5]]-->left[[6]]->right->left-->right[[5]]->left->right->left->(right->code<=code) = 1
-+root-->right[[5]]-->left[[4]]-->right[[3]]->left->right->left->right->(left->code>=code) = 1
-+ 1009
-+1013
-+1019
-+1021
-+1031
-+1033
-+1039
-+1049
-+1051
-+1061
-+ ELA
-+ 1 = DAVE
-+ us = DAVE
-+ 0
-+1
-+2
-+ Error: emp[0]=us
-+ ------^-- incompatible types for op x=y
-+operand1 ``emp[0]'' -- type: struct .F13 { int a ; int b ; char * name ; } ;
-+ -- value: struct @10001510
-+operand2 ``us'' -- type: enum .F14
-+ -- value: DAVE
-+ Error: emp=us
-+ ---^-- bad operand x type for operator 'x=y'
-+operand ``emp'' -- type: array [100] of struct .F13 { int a ; int b ; char * name ; } ;
-+ -- value: array @10001510
-+ Error: us=emp
-+ --^-- operand x of 'y=x' is not numeric
-+operand ``emp'' -- type: array [100] of struct .F13 { int a ; int b ; char * name ; } ;
-+ -- value: array @10001510
-+
---- gdb/duel/tsuite.self
-+++ gdb/duel/tsuite.self
-@@ -0,0 +1,111 @@
-+## DUEL - A Very High Level Debugging Langauge.
-+## Public domain code
-+## Written by Michael Golan mg@cs.princeton.edu
-+## $Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $
-+
-+##
-+## test suite for duel, can be used with duelself or gdb
-+##
-+
-+## check constants
-+(1..5)*(2,(double) 2/3)
-+
-+## declare array x, set it, search it
-+
-+int x[100] ;
-+x[0..99]= -1 ;
-+x[i:=20..40]=2+i*i ;
-+x[20..23,38..40]
-+x[..100] >=? 33*33 <=? 35*35
-+x[..100]=> ((_>=33*33) & (_<= 35*35)) ==? 1
-+x
-+x+5
-+*(x+7..9)++
-+*(x+(7..9))++
-+(*(x+(7..9)))++
-+y:= &x[7] ;
-+y[0..2]
-+x+7 == y
-+(x[..99]>?0)@(_>500)
-+
-+printf("x is: "); printf("%d, ",x[0..99]>? 0); printf("\n");
-+int j ; for(j=0 ; j<100 ; j++) if(x[j]>37*37) printf("x[%d]=%d\n",j,x[j]);
-+
-+printf("%d, ",1..5); printf("\n");
-+
-+## check void type
-+void *p
-+p = &p
-+p,*p
-+
-+## errors
-+
-+1e++4
-+& &x
-+i=4 ;
-+x=6 ;
-+x++ ;
-+--i ;
-+
-+## cleanup
-+
-+alias
-+clear
-+
-+## access some variables
-+s
-+s[3..7]
-+s[5..]@0
-+l:=#/s[0..]@0
-+s[l-2..l]
-+
-+gint
-+gint++
-+gint++
-+--gint
-+gint
-+main.s
-+main.s++
-+main.s++
-+
-+main
-+printf
-+main ==? main
-+main == main
-+
-+frames_no
-+frame(0).s
-+
-+## gint is a global, not local fro main in frame 0
-+frame(0).gint
-+## but when we eval (expr) under frame 0 scope, we find it ok.
-+frame(0).(gint)
-+
-+T uint myuint ; myuint = -1
-+
-+sizeof(int)
-+sizeof(long)
-+sizeof(int *)
-+sizeof(signed char*)
-+sizeof()
-+sizeof(gint)
-+sizeof gint
-+sizeof gint+1
-+## some errors
-+
-+main == main
-+main == printf
-+
-+main+1
-+malloc[4]
-+printf+3
-+
-+T int x
-+int x
-+uint y
-+T uint y = 5
-+T uint y
-+
-+## the end
-+
-+
---- gdb/duel/tsuite.self.out
-+++ gdb/duel/tsuite.self.out
-@@ -0,0 +1,263 @@
-+dl> ## DUEL - A Very High Level Debugging Langauge.
-+dl> ## Public domain code
-+dl> ## Written by Michael Golan mg@cs.princeton.edu
-+dl>
-+dl> ##
-+dl> ## test suite for duel, can be used with duelself or gdb
-+dl> ##
-+dl>
-+dl> ## check constants
-+dl> (1..5)*(2,(double) 2/3)
-+DUEL 1.10.4, public domain debugging language. "dl" for help
-+1*2 = 2
-+1*(2/3) = 0.66666667
-+2*2 = 4
-+2*(2/3) = 1.33333333
-+3*2 = 6
-+3*(2/3) = 2.0
-+4*2 = 8
-+4*(2/3) = 2.66666667
-+5*2 = 10
-+5*(2/3) = 3.33333333
-+dl>
-+dl> ## declare array x, set it, search it
-+dl>
-+dl> int x[100] ;
-+dl> x[0..99]= -1 ;
-+dl> x[i:=20..40]=2+i*i ;
-+dl> x[20..23,38..40]
-+x[20] = 402
-+x[21] = 443
-+x[22] = 486
-+x[23] = 531
-+x[38] = 1446
-+x[39] = 1523
-+x[40] = 1602
-+dl> x[..100] >=? 33*33 <=? 35*35
-+x[33] = 1091
-+x[34] = 1158
-+dl> x[..100]=> ((_>=33*33) & (_<= 35*35)) ==? 1
-+(x[33]>=33*33)&(x[33]<=35*35) = 1
-+(x[34]>=33*33)&(x[34]<=35*35) = 1
-+dl> x
-+x = array @10014000
-+dl> x+5
-+x+5 = @10014014
-+dl> *(x+7..9)++
-+Error: *(x+7..9)++
-+ -----^-- operand x of 'x..y' is not integral
-+operand ``x+7'' -- type: int *
-+ -- value: @1001401c
-+dl> *(x+(7..9))++
-+Error: *(x+(7..9))++
-+ -----------^-- operand of '++' must be an lvalue
-+operand ``(x+7)'' -- type: int *
-+ -- value: @1001401c
-+dl> (*(x+(7..9)))++
-+(*(x+7))++ = -1
-+(*(x+8))++ = -1
-+(*(x+9))++ = -1
-+dl> y:= &x[7] ;
-+dl> y[0..2]
-+y[0] = 0
-+y[1] = 0
-+y[2] = 0
-+dl> x+7 == y
-+x+7==y = 1
-+dl> (x[..99]>?0)@(_>500)
-+(x[20]) = 402
-+(x[21]) = 443
-+(x[22]) = 486
-+dl>
-+dl> printf("x is: "); printf("%d, ",x[0..99]>? 0); printf("\n");
-+x is: 402, 443, 486, 531, 578, 627, 678, 731, 786, 843, 902, 963, 1026, 1091, 1158, 1227, 1298, 1371, 1446, 1523, 1602,
-+dl> int j ; for(j=0 ; j<100 ; j++) if(x[j]>37*37) printf("x[%d]=%d\n",j,x[j]);
-+x[37]=1371
-+x[38]=1446
-+x[39]=1523
-+x[40]=1602
-+dl>
-+dl> printf("%d, ",1..5); printf("\n");
-+1, 2, 3, 4, 5,
-+dl>
-+dl> ## check void type
-+dl> void *p
-+dl> p = &p
-+&p = @10012138
-+dl> p,*p
-+p = @10012138
-+*p = void @10012138
-+dl>
-+dl> ## errors
-+dl>
-+dl> 1e++4
-+1e++4
-+^ Invalid float constant.
-+dl> & &x
-+Error: & &x
-+ ^-- operand x of '&x' is not a lvalue
-+operand ``&x'' -- type: ptr to int [100]
-+ -- value: @10014000
-+dl> i=4 ;
-+Error: i=4 ;
-+ -^-- operand x is not an lvalue for operator 'x=y'
-+operand ``i'' -- type: int
-+ -- value: 40
-+dl> x=6 ;
-+Error: x=6 ;
-+ -^-- bad operand x type for operator 'x=y'
-+operand ``x'' -- type: int [100]
-+ -- value: array @10014000
-+dl> x++ ;
-+Error: x++ ;
-+ -^-- operand x of '++' is not integral
-+operand ``x'' -- type: int [100]
-+ -- value: array @10014000
-+dl> --i ;
-+Error: --i ;
-+ ^-- operand of '--' must be an lvalue
-+operand ``i'' -- type: int
-+ -- value: 40
-+dl>
-+dl> ## cleanup
-+dl>
-+dl> alias
-+Aliases table:
-+p: p = @10012138
-+j: j = 100
-+y: &x[7] = @1001401c
-+i: 40
-+x: x = array @10014000
-+dl> clear
-+Aliases table cleared
-+dl>
-+dl> ## access some variables
-+dl> s
-+s = "main string"
-+dl> s[3..7]
-+s[3] = 'n'
-+s[4] = ' '
-+s[5] = 's'
-+s[6] = 't'
-+s[7] = 'r'
-+dl> s[5..]@0
-+s[5] = 's'
-+s[6] = 't'
-+s[7] = 'r'
-+s[8] = 'i'
-+s[9] = 'n'
-+s[10] = 'g'
-+dl> l:=#/s[0..]@0
-+#/(s[0] ...) = 11
-+dl> s[l-2..l]
-+s[9] = 'n'
-+s[10] = 'g'
-+s[11] = '\0'
-+dl>
-+dl> gint
-+gint = 0
-+dl> gint++
-+gint++ = 0
-+dl> gint++
-+gint++ = 1
-+dl> --gint
-+gint = 1
-+dl> gint
-+gint = 1
-+dl> main.s
-+main.s = "main string"
-+dl> main.s++
-+main.s++ = "main string"
-+dl> main.s++
-+main.s++ = "ain string"
-+dl>
-+dl> main
-+main = func @00400918
-+dl> printf
-+printf = func @004112b0
-+dl> main ==? main
-+main = func @00400918
-+dl> main == main
-+main==main = 1
-+dl>
-+dl> frames_no
-+frames_no = 1
-+dl> frame(0).s
-+frame(0).s = "in string"
-+dl>
-+dl> ## gint is a global, not local fro main in frame 0
-+dl> frame(0).gint
-+Error: frame(0).gint
-+ --------^-- field not found in operator '.'
-+operand ``frame(0)'' -- type: int
-+ -- value: frame(0)
-+dl> ## but when we eval (expr) under frame 0 scope, we find it ok.
-+dl> frame(0).(gint)
-+frame(0).(gint)
-+---------------^ syntax error
-+dl>
-+dl> T uint myuint ; myuint = -1
-+-1 = 0xffffffff
-+dl>
-+dl> sizeof(int)
-+sizeof(int) = 0x4
-+dl> sizeof(long)
-+sizeof(long) = 0x4
-+dl> sizeof(int *)
-+sizeof(T) = 0x4
-+dl> sizeof(signed char*)
-+sizeof(T) = 0x4
-+dl> sizeof()
-+sizeof()
-+--------^ syntax error
-+dl> sizeof(gint)
-+sizeof(gint) = 0x4
-+dl> sizeof gint
-+sizeof gint
-+-----------^ syntax error
-+dl> sizeof gint+1
-+sizeof gint+1
-+-----------^ syntax error
-+dl> ## some errors
-+dl>
-+dl> main == main
-+main==main = 1
-+dl> main == printf
-+Error: main == printf
-+ -----^-- incompatible types for op ==
-+operand1 ``main'' -- type: ptr to func returning void
-+ -- value: @00400918
-+operand2 ``printf'' -- type: ptr to func returning int
-+ -- value: @004112b0
-+dl>
-+dl> main+1
-+Error: main+1
-+ ----^-- unknown pointer object size for '+' op
-+operand ``main'' -- type: ptr to func returning void
-+ -- value: @00400918
-+dl> malloc[4]
-+Error: malloc[4]
-+ ------^-- unknown pointer object size for '+' op
-+operand ``malloc'' -- type: ptr to func returning void *
-+ -- value: @00411310
-+dl> printf+3
-+Error: printf+3
-+ ------^-- unknown pointer object size for '+' op
-+operand ``printf'' -- type: ptr to func returning int
-+ -- value: @004112b0
-+dl>
-+dl> T int x
-+T int x
-+-----^ syntax error
-+dl> int x
-+dl> uint y
-+uint y
-+------^ syntax error
-+dl> T uint y = 5
-+T uint y = 5
-+----------^ syntax error
-+dl> T uint y
-+dl>
-+dl> ## the end
-+dl>
-+dl>
---- gdb/duel/types.c
-+++ gdb/duel/types.c
-@@ -0,0 +1,200 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* this module contains the duel type system management
-+ */
-+
-+/*
-+ * $Log: 10_all_gdb-6.6-duel.patch,v $
-+ * Revision 1.1 2008/04/06 23:59:05 vapier
-+ * initial 6.8 patchset based on last 6.7.1 patchset
-+ *
-+ * Revision 1.8 93/03/12 06:01:50 mg
-+ * use tuint for uint etc
-+ *
-+ * Revision 1.7 93/02/03 21:55:26 mg
-+ * support "signed char"
-+ *
-+ * Revision 1.6 93/01/12 21:54:25 mg
-+ * cleanup and set for release
-+ *
-+ * Revision 1.5 93/01/03 07:31:24 mg
-+ * *** empty log message ***
-+ *
-+ * Revision 1.4 92/10/19 15:09:28 mg
-+ * support zero fields/enumerators because gdb have them sometimes.
-+ *
-+ * Revision 1.3 92/10/14 02:07:00 mg
-+ * misc
-+ *
-+ * Revision 1.2 92/09/16 11:11:43 mg
-+ * added builtin charptr type
-+ *
-+ */
-+
-+#include "duel.h"
-+
-+FUNC tctype* duel_mkctype_ptr(tctype *t)
-+{
-+ tctype *n ;
-+ n=(tctype *) duel_malloc(sizeof(tctype));
-+ duel_bzero((char*) n,sizeof(tctype));
-+ n->type_kind=CTK_PTR ;
-+ n->size=sizeof(void*);
-+ n->u.kid=t ;
-+ return n ;
-+}
-+
-+FUNC tctype* duel_mkctype_func(tctype *t)
-+{
-+ tctype *n ;
-+ n=(tctype *) duel_malloc(sizeof(tctype));
-+ duel_bzero((char*) n,sizeof(tctype));
-+ n->size=0 ;
-+ n->type_kind=CTK_FUNC ;
-+ n->u.kid=t ;
-+ return n ;
-+}
-+
-+/* create a struct or union type. The fields are not set here, but
-+ * filled individually with the next function
-+ * note the having zero fields is supported. This shouldnt be legal in C
-+ * but compilers allow pointer to sturct w/o every specifying the struct.
-+ * this is especially true for gdb itself!
-+ */
-+
-+FUNC tctype* duel_mkctype_struct(char *name,size_t size,int fields_no,
-+ bool is_union)
-+{
-+ tctype *n ;
-+ n=(tctype *) duel_malloc(sizeof(tctype));
-+ duel_bzero((char*) n,sizeof(tctype));
-+ n->name=name ;
-+ n->size=size ;
-+ if(is_union) n->type_kind=CTK_UNION ;
-+ else n->type_kind=CTK_STRUCT ;
-+ n->u.f.fields_no=fields_no ;
-+ if(fields_no==0) n->u.f.fields=NULL ;
-+ else {
-+ n->u.f.fields=(tctype_field *) duel_malloc(fields_no*sizeof(tctype_field));
-+ duel_bzero((char*) n->u.f.fields,fields_no*sizeof(tctype_field));
-+ }
-+ return n ;
-+}
-+
-+/* insert field (field_no) into sturct/union (t), with type fctype
-+ */
-+PROC duel_mkctype_struct_field(tctype *t,int field_no,char *name,
-+ int bitpos,int bitlen, tctype *fctype)
-+{
-+ tctype_field *f ;
-+ duel_assert(t->type_kind==CTK_STRUCT || t->type_kind==CTK_UNION);
-+ duel_assert(field_no>=0 && field_no <= t->u.f.fields_no);
-+ f= &t->u.f.fields[field_no] ;
-+ f->name=name ;
-+ f->bitpos=bitpos ;
-+ f->bitlen=bitlen ;
-+ f->ctype=fctype ;
-+}
-+
-+/* create an enum type. The enumerators are not set here, but
-+ * filled individually with the next function
-+ * again like sturct, we support zero enums. I am not sure its needed,
-+ * but better safe than sorry.
-+ */
-+
-+FUNC tctype* duel_mkctype_enum(char *name,tctype_kind real_type_kind,
-+ size_t size,int enumerators_no)
-+{
-+ tctype *n ;
-+ n=(tctype *) duel_malloc(sizeof(tctype));
-+ duel_bzero((char*) n,sizeof(tctype));
-+ n->name=name ;
-+ n->size=size ;
-+ n->type_kind=CTK_ENUM ;
-+ n->u.e.real_type_kind=real_type_kind ;
-+ n->u.e.enumerators_no=enumerators_no ;
-+ if(enumerators_no==0) n->u.e.enumerators=NULL ;
-+ else {
-+ n->u.e.enumerators= (tctype_enumerator *)
-+ duel_malloc(enumerators_no*sizeof(tctype_enumerator));
-+ duel_bzero((char*) n->u.e.enumerators,
-+ enumerators_no*sizeof(tctype_enumerator));
-+ }
-+ return n ;
-+}
-+
-+
-+/* insert enumerator (enumerator_no_ into an enum type (t), with given name/val
-+ */
-+PROC duel_mkctype_enumerator(tctype *t,int enumerator_no,char *name,int val)
-+{
-+ tctype_enumerator *e ;
-+ duel_assert(t->type_kind==CTK_ENUM);
-+ duel_assert(enumerator_no>=0 && enumerator_no <= t->u.e.enumerators_no);
-+ e= &t->u.e.enumerators[enumerator_no] ;
-+ e->name=name ;
-+ e->val=val ;
-+}
-+
-+FUNC tctype* duel_mkctype_array(tctype *t,int size)
-+{
-+ tctype *n ;
-+ if(t->size==0) duel_gen_error("array of a type of zero size is illegal",0);
-+ if(size<=0) duel_gen_error("array of size zero or negative is illegal",0);
-+ n=(tctype *) duel_malloc(sizeof(tctype));
-+ duel_bzero((char*) n,sizeof(tctype));
-+ n->type_kind=CTK_ARRAY ;
-+ n->size=size*t->size ;
-+ n->u.kid=t ;
-+ return n ;
-+}
-+
-+
-+LFUNC tctype* init_basic_ctype(tctype_kind tk,char *name,size_t size)
-+{
-+ tctype *p = duel_malloc(sizeof(tctype));
-+ p->type_kind=tk ;
-+ p->name=name ;
-+ p->size=size ;
-+ return p ;
-+}
-+
-+PROC duel_init_basic_ctypes(void)
-+{
-+ ctype_void= init_basic_ctype(CTK_VOID, "void", 0);
-+
-+ ctype_char =init_basic_ctype(CTK_CHAR, "char", sizeof(char));
-+ ctype_short =init_basic_ctype(CTK_SHORT, "short",sizeof(short));
-+ ctype_int =init_basic_ctype(CTK_INT, "int", sizeof(int));
-+ ctype_long =init_basic_ctype(CTK_LONG, "long", sizeof(long));
-+ ctype_longlong=init_basic_ctype(CTK_LONGLONG,"long long", sizeof(long long));
-+
-+ ctype_schar =init_basic_ctype(CTK_SCHAR, "signed char", sizeof(tschar));
-+ ctype_uchar =init_basic_ctype(CTK_UCHAR, "unsigned char", sizeof(tuchar));
-+ ctype_ushort =init_basic_ctype(CTK_USHORT, "unsigned short",sizeof(tushort));
-+ ctype_uint =init_basic_ctype(CTK_UINT, "unsigned int", sizeof(tuint));
-+ ctype_ulong =init_basic_ctype(CTK_ULONG, "unsigned long", sizeof(tulong));
-+ ctype_ulonglong=init_basic_ctype(CTK_ULONG, "unsigned long long", sizeof(tulonglong));
-+
-+ ctype_double=init_basic_ctype(CTK_DOUBLE, "double", sizeof(double));
-+ ctype_float =init_basic_ctype(CTK_FLOAT, "float", sizeof(float));
-+
-+ ctype_voidptr=duel_mkctype_ptr(ctype_void);
-+ ctype_charptr=duel_mkctype_ptr(ctype_char);
-+ /* find and set the special types.
-+ * support only a signed ptrdiff; size_t/ptrdiff must both be int or long
-+ */
-+ { ptrdiff_t p ; size_t s ;
-+ p= -1 ; s= -1 ;
-+ if(p>0) duel_gen_error("bad ptrdiff_t - unsigned",0);
-+
-+ if(sizeof(p)==sizeof(int)) ctype_ptrdiff_t=ctype_int ;
-+ else if(sizeof(p)==sizeof(long)) ctype_ptrdiff_t=ctype_long ;
-+ else duel_gen_error("bad ptrdiff_t size",0);
-+
-+ if(sizeof(s)==sizeof(int)) ctype_size_t= (s<0)? ctype_int:ctype_uint ;
-+ else
-+ if(sizeof(s)==sizeof(long)) ctype_size_t= (s<0)? ctype_long:ctype_ulong ;
-+ else duel_gen_error("bad size_t size",0);
-+ }
-+}
---- gdb/duel/wishlist.doc
-+++ gdb/duel/wishlist.doc
-@@ -0,0 +1,160 @@
-+
-+ += -= etc operators
-+ initialize variables e.g. int x=0 , maybe even scopes
-+ set declared var to zero.
-+ allow x++ for aliases as a special case.
-+ x->?y or x?->y to be like (x!=?0)->y OR x?? or ??x as (x!=?0)
-+
-+ +/ */ &/ |/ ^/ ==/ !=/ </ >/ <=/ >=/
-+ src(location) as scope
-+ istype(type,x) to check type of x
-+ ?x to check for x in current scope
-+ conditional break points, watchpoints
-+ better type checking of structs.
-+ bitfield assignment
-+ better builtin commands, help
-+ output formatting, duel/xodus, more general out(v)
-+ duel macros/functions
-+ \x and \\x
-+ check array bounds
-+ x->>y x->-y x>--y
-+ check cycles in --> expansion
-+ ..:+ ..:-
-+ print types, do so better
-+
-+DUEL.PIPE - make it general purpose
-+------------------------------------
-+see duel.pipe for some details.
-+should be made general purpose, so it is easy to modify/add functions.
-+many basic functions can be writted - sort, uniq, matrix, vector,
-+compress, etc.
-+
-+Checking for cycles in --> expansion
-+------------------------------------
-+One can easily add code to handle head-->(next!=?head), as well as
-+head-->(next!=?_). If you don't know what these do, you should RTFM again :-)
-+
-+You can also keep all pointers that have been expanded already,
-+hence detecting any kind of cycle. However, what to do in
-+such cases is debatable. Some users would like to see
-+cycles terminate expansion quietly, while others will want a fatal error
-+to be produced. This could be handled by an operator like x-->?y which
-+would indicate that cycles are ok and expansion should terminate quietly,
-+while x-->y produce an error on cycles.
-+
-+Another idea is to have _cyc defined inside -->, to allow the user to
-+do something about cycles, e.g. head-->(if(!_cyc) next). There are
-+several ways to manage _cyc: a boolean, or equal to head; true if
-+this is already a cycle, or a function cyc(next), which return true if
-+next would cycle, or return next unles it would cycle, etc.
-+This last one seems to handle most cases:
-+head-->(cyc(left),cyc(right)) - return tree, igoring cycles
-+head-->(cyc(0),left,right) - like head->(left,right), but mention of cyc
-+ which by itself does nothing, cause general
-+ cycle detection as errors
-+as above, but left!=?_ - detect general cycles, pointer to self ok
-+
-+While we adding cyc(), we can also add _depth to indicate current depth,
-+e.g. head-->(if(_depth<6) (left,right)) -- expand only to depth 6
-+and also acceess to the current path with _path(i), _path(0)=_ and
-+_path(_depth-1)=head
-+head-->(cyc(0), if(! ||/_path(.._deapth)==left) left, ...)
-+ which avoids cycles "in the path"
-+
-+If you an strong opinion on this subject, or a better idea, lemme know!
-+
-+Other expansions: x->>y x->-y x>--y
-+------------------------------------
-+x-->y applies DFS (Depth First Search). Another useful expansion would be
-+BFS (Breath First Search). It is simple to implement - y's values should
-+be put on a queue instead of a stack, and the code in place has been written
-+with this in mind (eval.c).
-+Others will probably want a post-order or in-order search instead of preorder
-+search as done by x-->y. I am not sure this is important enough to merit
-+new operators, but ->- for inorder and >-- for post order are reserved.
-+These, too, should be easy to implement, but it is very unclear that the
-+added complexity to the language is worth it. If you really need such
-+operators, lemme know.
-+
-+Increment count for x..y (x..y:+z and x..y:-z)
-+------------------------------------------------
-+The x..y operator could be extended to support an increment or decrement
-+value. This would allow 1..n to be written as 1..n:+1 so when n==0 it
-+will not produce the surprising 1,0 results.
-+However, 0..10:+2 could also be written as (0..5)*2, so it is unclear
-+that such operators are really needed (maybe just x..+y, x..-y to force
-+the direction).
-+
-+
-+Duel functions / print procedures
-+-------------------------------------
-+the command: dl define x expr
-+will define x to be duel procedure for expression expr.
-+x can then be used like an alias (indeed, it will probably be kept in
-+the alias table with a special value). x evaluation returns multiple
-+values.
-+There is no need parameters, since emp.x would call "x" using the implicit
-+parameter "_" set as emp. the expression for x is essentially put into
-+the code for the execution. Having no parameters (except implicit ones)
-+make it easier to document, use etc.
-+
-+Such functions (macros?) are most useful for output. e.g.
-+dl define empout val_type,a, u.if(val_type==0) code*6,name else code,z
-+dl emp.empout
-+will produce output for
-+ struct {
-+ int val_type,code ;
-+ char a;
-+ union { char *name ; double z ; } u
-+ } emp ;
-+
-+the empout procedure can be defined just once, and used to output such
-+unions as needed.
-+
-+The next step is to call such functions automatically for output and
-+for expansion. We add syntax like dl define out(type) expr
-+
-+then whenever an expression of the given type is to be printed, this
-+code is evaluated instead, e.g.:
-+dl define out(struct emp) ...
-+dl emp ## this calls the above out code for the output.
-+
-+We can also expand expressions by calling the right function, e.g.
-+The operator "\" calls a function to expand a specific type:
-+dl define \(struct list *) (_-->next)
-+dl if(\head#i == \head#j && i<j) \head[[i,j]]
-+
-+instead of writing this code (find non unique elements of linked list):
-+ if(head-->next#i == head-->next#j && i<j) head-->next[[i,j]]
-+
-+Both printing and expansion occurs automatically based on TYPE.
-+It is unclear if the an array is allowed to be expanded by a pointer
-+type expansion or not (i.e. is \(int *) to expand "int x[40]").
-+this might require an extension to types allowing \(int [n]) which matches
-+any int array and set n for the specific bound. Types could be extended
-+in a similar way, e.g. \(type **) _[0..]@0
-+which expands any array of pointers (e.g. argv).
-+This can quickly require scope-nesting for local aliases/variables.
-+
-+As before, it is unclear what of these is useful. Unless people depends on
-+duel heavily, and write such "output/expansion" functions for the project,
-+the features are useless (who is going to use this interactively?)
-+
-+Regular expressions for names. $xxx and `xxx`
-+----------------------------------------------
-+this allows things like emp.`value_*` to return all the value_something
-+fields. it is really useful with structs, especially if a grep-style hat (^)
-+is supported. Obviously extends to func.rexp, to show all locals, etc,
-+which will make it possible to write a stack-trace display in duel.
-+
-+exact semantics (e.g. what is matched and how) unclear.
-+
-+
-+Nicer #/
-+---------
-+
-+hash[..1024] => #/_-->next >? 2
-+
-+it is probably best if #/(exp) constructed (exp) as symbolic before it
-+gets the values. or maybe, yes, best is #/(e) symbolic is #/(e1..en)
-+where e1 is the first return symbolc, en the last.
---- gdb/duelgdb.c
-+++ gdb/duelgdb.c
-@@ -0,0 +1,694 @@
-+/* DUEL - A Very High Level Debugging Langauge. */
-+/* Public domain code */
-+/* Written by Michael Golan mg@cs.princeton.edu */
-+/*$Header: /var/cvsroot/gentoo/src/patchsets/gdb/6.8/10_all_gdb-6.6-duel.patch,v 1.1 2008/04/06 23:59:05 vapier Exp $*/
-+
-+/* debugger dependent module, it contains all of duel's access to
-+ * the outside world (debuggee, symbol table, etc)
-+ */
-+
-+/*
-+ * $Log: 10_all_gdb-6.6-duel.patch,v $
-+ * Revision 1.1 2008/04/06 23:59:05 vapier
-+ * initial 6.8 patchset based on last 6.7.1 patchset
-+ *
-+ * Revision 1.30 08/11/14 23:14:00 serg
-+ * ported to gdb 6.6.2, glibc 2.5
-+ *
-+ * Revision 1.20 93/03/20 10:35:48 mg
-+ * fixed system("date")... didnt work on OS/2
-+ *
-+ * Revision 1.19 93/03/13 03:28:49 mg
-+ * bug fixed frame(0).unknown_name caused a crash
-+ * bug fixed duel didnt support enum of length zero but turns out gdb tables
-+ * have such things (specifically, for some gdb internals!)
-+ *
-+ * Revision 1.18 93/03/12 05:43:22 mg
-+ * Version 1.10 - tuint instead of uint etc, fixed gdb48 recognis. problem
-+ *
-+ * Revision 1.17 93/02/27 06:01:01 mg
-+ * improved unsigned char default machines support,
-+ * convert explicit uchar into "char" if they are the same.
-+ *
-+ * Revision 1.16 93/02/23 19:11:10 mg
-+ * beauty changes + gdb4.8 support
-+ *
-+ * Revision 1.15 93/02/04 02:09:18 mg
-+ * fixed enum enum names
-+ *
-+ * Revision 1.14 93/02/04 00:54:26 mg
-+ * arr. fixed.
-+ *
-+ * Revision 1.13 93/02/03 21:54:14 mg
-+ * create duel.out unless compiling with NO_DUEL_OUT
-+ *
-+ * Revision 1.12 93/02/03 21:46:33 mg
-+ * fixed problems with null gdb type names.
-+ * support "signed char"
-+ *
-+ * Revision 1.11 93/01/21 21:22:15 mg
-+ * *** empty log message ***
-+ *
-+ * Revision 1.10 93/01/13 16:19:33 mg
-+ * support mini symbol table lookup (malloc, printf on SUN didnt work)
-+ *
-+ * Revision 1.9 93/01/12 21:30:04 mg
-+ * cleanup and set for release
-+ *
-+ * Revision 1.8 93/01/06 23:59:21 mg
-+ * new memory alloc/release. moved target's malloc into duel code
-+ * allow ^c to work, fixed help, fixed variable lookup for specific frame.
-+ *
-+ * Revision 1.7 93/01/03 07:27:11 mg
-+ * support function calls!
-+ *
-+ * Revision 1.6 92/12/24 23:33:13 mg
-+ * frames support
-+ *
-+ * Revision 1.5 92/10/19 15:06:29 mg
-+ * made lcc happy
-+ * no svalues
-+ * new registers support and way of getting vars.
-+ * these are temporary changes, new frames supports soon
-+ *
-+ * Revision 1.4 92/10/14 02:03:53 mg
-+ * misc/gdb4.6/duel vars using malloc
-+ *
-+ * Revision 1.3 92/09/16 11:06:22 mg
-+ * a lot more functions: get typedef/tags, alloc debuggee mem. +cosmetics
-+ *
-+ * Revision 1.2 92/09/15 05:37:28 mg
-+ * fix enum size bug. added headers
-+ *
-+ */
-+
-+
-+#include <stddef.h> /* used for ptrdiff_t and size_t */
-+#include <stdio.h>
-+#include <string.h>
-+#include <time.h> /* for time/ctime stamping of duel.out */
-+#include <assert.h>
-+
-+#include "defs.h"
-+#include "symtab.h"
-+#include "gdbtypes.h"
-+#include "gdbcore.h"
-+#include "frame.h"
-+#include "target.h"
-+#include "value.h"
-+#include "symfile.h"
-+#include "objfiles.h"
-+#include "gdbcmd.h"
-+#include "call-cmds.h"
-+#include "infcall.h"
-+
-+#include "duel/global.h"
-+#include "duel/proto.h"
-+
-+/* all output goes thru here */
-+
-+#include <stdarg.h>
-+
-+PROC duel_printf(char *fmt, ...) /* like printf, but for duel output */
-+{
-+ va_list args;
-+ va_start(args, fmt);
-+ vprintf_filtered(fmt,args);
-+ va_end(args);
-+}
-+
-+PROC duel_flush(void)
-+{ /* not yet. only really needed for redirections */
-+}
-+
-+PROC duel_redirectable_output_start(char *s)
-+{
-+}
-+
-+PROC duel_redirectable_output_end(void)
-+{
-+}
-+
-+PROC duel_redirectable_output_abort(void)
-+{
-+}
-+
-+PROC duel_redirectable_output_init(void)
-+{
-+}
-+
-+/* all duel memory allocations go thru here */
-+
-+FUNC void* duel_malloc(size_t size)
-+{
-+ void *p ;
-+ immediate_quit-- ; /* disable ^C while xmalloc */
-+ p=xmalloc(size); /* gdb's malloc, incl zero return chk */
-+ immediate_quit++ ;
-+ QUIT ; /* check if ^C while xmalloc called */
-+ return p ;
-+}
-+
-+PROC duel_free(void *p)
-+{
-+ immediate_quit-- ;
-+ free(p);
-+ immediate_quit++ ;
-+ QUIT ;
-+}
-+
-+/* fetch n bytes from the target at the given memory address.
-+ * the address to fetch from is given by (from).
-+ * the value is stored at the 'to' location, which points to space for
-+ * n bytes in the debugger.
-+ * if the address can not be accessed, false is returned (if all ok, ret true)
-+ */
-+
-+FUNC bool duel_get_target_bytes(ttarget_ptr from,void *to,size_t n)
-+{
-+ return target_read_memory((CORE_ADDR)from,to,n)==0;
-+}
-+
-+/* store n bytes to the debuggee. reverse parms from above */
-+FUNC bool duel_put_target_bytes(ttarget_ptr to,void *from,size_t n)
-+{
-+ return target_write_memory((CORE_ADDR)to,from,n)==0;
-+}
-+
-+/* fetch the value of a bitfield of a given structure.
-+ * struct_at - a pointer to the structure
-+ * bitpos - the position of the field, in bits (as given in the type)
-+ * bitlen - the length of the field in bits
-+ * to - pointer to tuint where value will be stored.
-+ * tkind - the type kind of the field (used to do sign extention if needed)
-+ * note: I'm unaware of any compiler with bitfields that are not int/tuint.
-+ */
-+
-+FUNC bool duel_get_target_bitfield(ttarget_ptr struct_at,int bitpos,
-+ int bitlen,void *to,tctype_kind tkind)
-+{
-+ tuint bits ;
-+ duel_assert(tkind==CTK_INT || tkind==CTK_UINT);
-+ if(!duel_get_target_bytes(struct_at+bitpos/8,&bits,sizeof(bits)))
-+ return FALSE;
-+
-+ /* now, move the field to the 'bottom' of bits, by shifting right */
-+ bitpos%=8 ; /* fix it to a bit offset inside the 'bits' */
-+ if (gdbarch_bits_big_endian (current_gdbarch))
-+ bits >>= (sizeof(bits)*8-bitpos-bitlen) ;
-+ else
-+ bits >>= bitpos ;
-+
-+ /* finally chop down 'bits' to only bitlen significant bits,
-+ * or sign-extend it if output field is 'int' and the sign is 1.
-+ * ~0 is all ones, shift it to have bitlen zeros. Complement to get
-+ * a bitlen string of 1's in the low-order bits. Common ugly hacks.
-+ * Note: this code assume 2's complement
-+ */
-+
-+ if(tkind==CTK_INT && (bits & 1<<(bitlen-1))) /* int field, negative sign */
-+ bits|= ~0<<bitlen ; /*sign extend */
-+ else bits&= ~(~0<<bitlen) ; /* clear all bits above the sign bit */
-+ *(tuint*) to= bits ;
-+
-+ return TRUE ;
-+}
-+
-+LFUNC struct type* duel_convert_type_to_gdb(tctype *ct);
-+LFUNC tctype* duel_convert_type_from_gdb(struct type *gv);
-+
-+/* convert gdb value into duel's. Used to fetch const, registers, func ret val
-+ * and convert a symbol into a reference.
-+ * otherwise, duel access target's memory directly.
-+ */
-+
-+LPROC duel_convert_value_from_gdb(struct value *gv, tvalue *dv)
-+{
-+ dv->ctype=duel_convert_type_from_gdb(value_type(gv));
-+ if(VALUE_LVAL(gv) == lval_memory) {
-+ dv->val_kind=VK_LVALUE ;
-+ dv->u.lvalue= (ttarget_ptr) VALUE_ADDRESS(gv) ; /*address of variable*/
-+ }
-+ else
-+ if(ctype_kind_scalar(dv->ctype) && (VALUE_LVAL(gv) == not_lval ||
-+ VALUE_LVAL(gv) == lval_register)) {
-+ dv->val_kind=VK_RVALUE ;
-+ duel_bcopy(&dv->u,value_contents_raw(gv),dv->ctype->size);
-+ }
-+ else
-+ duel_fatal("unsupported value type returned by gdb");
-+}
-+
-+
-+/* helper function converts duel values to gdb's values. used only to make
-+ * function calls to the target, so current support is weak.
-+ * gdb thinks long=int=pointers, so we go along with that.
-+ * To support arbitrary types like struct/union, we can probably fake it
-+ * by making a gdb lvalue. but i am not sure how/what
-+ */
-+
-+LFUNC struct value *convert_duel_val_to_gdb_val(tvalue *v)
-+{
-+ struct value *gv ;
-+ if(v->val_kind!=VK_RVALUE) return 0 ; /* cant handle lvals */
-+ switch(v->ctype->type_kind) {
-+/* duel standardize func parms, so this code is not required. if this
-+ * function is used for more than func parms, as its name implies, we will
-+ * need to do better than this.
-+ * there is no gdb "builtin_type_signed_char", so we assume char
-+ case CTK_CHAR:
-+ gv=value_from_longest(builtin_type_char,v->u.rval_char); break;
-+ case CTK_SCHAR:
-+ gv=value_from_longest(builtin_type_char,v->u.rval_schar); break;
-+ case CTK_UCHAR:
-+ gv=value_from_longest(builtin_type_unsigned_char,v->u.rval_char); break;
-+ case CTK_USHORT:
-+ gv=value_from_longest(builtin_type_unsigned_short,v->u.rval_ushort);break;
-+ case CTK_SHORT:
-+ gv=value_from_longest(builtin_type_unsigned_short,v->u.rval_short);break;
-+*/
-+ case CTK_INT:
-+ gv=value_from_longest(builtin_type_int, v->u.rval_int); break;
-+ case CTK_UINT:
-+ gv=value_from_longest(builtin_type_unsigned_int, v->u.rval_uint) ; break ;
-+ case CTK_LONG:
-+ gv=value_from_longest(builtin_type_long, v->u.rval_long) ; break ;
-+ case CTK_ULONG:
-+ gv=value_from_longest(builtin_type_unsigned_long,v->u.rval_ulong); break ;
-+ case CTK_LONGLONG:
-+ gv=value_from_longest(builtin_type_long_long, v->u.rval_longlong) ; break ;
-+ case CTK_ULONGLONG:
-+ gv=value_from_longest(builtin_type_unsigned_long_long,v->u.rval_ulonglong); break ;
-+ case CTK_FLOAT:
-+ gv=value_from_double(builtin_type_float, v->u.rval_float) ; break ;
-+ case CTK_DOUBLE:
-+ gv=value_from_double(builtin_type_double, v->u.rval_double) ; break ;
-+ case CTK_PTR:
-+ gv=value_from_longest(lookup_pointer_type(builtin_type_void),
-+ (long) v->u.rval_ptr) ;break ;
-+ default: duel_assert(0);
-+ }
-+ return gv ;
-+}
-+
-+/* make a function call to the target.
-+ * this is the only case where we convert duel tvalue into gdb's values.
-+ * gdb thinks long=int=pointers, so we go along with that.
-+ */
-+
-+PROC duel_target_func_call(tvalue *func, tvalue *parms[],
-+ int parms_no,tvalue *rval)
-+{
-+ struct value *gfunc, *grval, *gparms[20] ;
-+ int i ;
-+ struct type *gftype ;
-+
-+ duel_assert(func->val_kind==VK_LVALUE);
-+ for(i=0 ; i<parms_no ; i++) {
-+ gparms[i]=convert_duel_val_to_gdb_val(parms[i]) ;
-+ if(gparms[i]==NULL)
-+ duel_op_error("unsupported func call parm type",0,parms[i],0);
-+ }
-+ gftype =duel_convert_type_to_gdb(func->ctype);
-+ if(!gftype) duel_op_error("unsupported func return parm type",0,func,0);
-+ gftype = lookup_pointer_type(gftype);
-+ if(!gftype)
-+ duel_op_error("unsupproted func return type",0,func,0);
-+
-+ gfunc = value_from_longest(gftype,(LONGEST) func->u.lvalue);
-+
-+ grval=call_function_by_hand(gfunc,parms_no,gparms);
-+ if(func->ctype->u.kid->type_kind==CTK_VOID) return ; /* no return val*/
-+ duel_convert_value_from_gdb(grval,rval);
-+}
-+
-+
-+
-+#define TYPE_HASH_SIZE (1024*128)
-+#define type_hash_func(t) ( (((long)t&0xffff) + (((long)t>>16)&0xffff)) \
-+ % TYPE_HASH_SIZE )
-+struct {
-+ struct type *t ; /* gdb type ptr */
-+ tctype *ct ; /* duel type ptr */
-+} duel_thash[TYPE_HASH_SIZE] ;
-+
-+LPROC duel_add_hash(struct type *t, tctype *ct)
-+{
-+ int start,i=type_hash_func(t);
-+ start=i ;
-+ do {
-+ if(duel_thash[i].t==0) {
-+ duel_thash[i].t=t ;
-+ duel_thash[i].ct=ct ;
-+ return ;
-+ }
-+ if(duel_thash[i].t==t) {
-+ if(duel_thash[i].ct==ct) return ;
-+ duel_fatal("type hash table inconsistency ");
-+ }
-+ i= (i+1)%TYPE_HASH_SIZE ;
-+ } while(i!=start);
-+ duel_fatal("type hash table is full");
-+}
-+
-+LFUNC tctype* duel_find_hash(struct type *t)
-+{
-+ int start,i=type_hash_func(t);
-+ start=i ;
-+ do {
-+ if(duel_thash[i].t==0) break ;
-+ if(duel_thash[i].t==t) return duel_thash[i].ct ;
-+ i= (i+1)%TYPE_HASH_SIZE ;
-+ } while(i!=start);
-+ return NULL ;
-+}
-+
-+/* a simple conversion back to gdb types, used only for target func calls */
-+/* this is a hack and based on the assumption that the type was first
-+ * converted FROM gdb to duel. (turn out to be false for int func from
-+ * minimal symbols, so we do this as a special case.)
-+ */
-+LFUNC struct type* duel_convert_type_to_gdb(tctype *ct)
-+{
-+ int i ;
-+ for(i=0 ; i<TYPE_HASH_SIZE ; i++)
-+ if(duel_thash[i].ct==ct) return duel_thash[i].t ;
-+
-+ if(ct->type_kind==CTK_FUNC && ct->u.kid->type_kind==CTK_INT)
-+ return lookup_function_type (builtin_type_int);
-+ return NULL ;
-+}
-+
-+#define INTTYPE_CHAR 1
-+#define INTTYPE_SHORT 2
-+#define INTTYPE_INT 0
-+#define INTTYPE_LONG 4
-+#define INTTYPE_SIGNED 0
-+#define INTTYPE_UNSIGNED 16
-+
-+struct { char *name; int len; int codetype; } name_to_codetype[]=
-+{ {"char", 4, INTTYPE_CHAR },
-+ {"short", 5, INTTYPE_SHORT },
-+ {"int", 3, INTTYPE_INT },
-+ {"long", 4, INTTYPE_LONG },
-+ {"signed", 6, INTTYPE_SIGNED },
-+ {"unsigned", 8, INTTYPE_UNSIGNED },
-+ {0,0,0}
-+};
-+
-+ /* given a gdb type t, return an equivalent duel type */
-+
-+LFUNC tctype* duel_convert_type_from_gdb(struct type *t)
-+{
-+ tctype *ct=duel_find_hash(t);
-+ if(ct) return ct ;
-+
-+ if (duel_debug)
-+ duel_printf("gdb type: {%d, %s}\n", TYPE_CODE(t), TYPE_NAME(t));
-+
-+ switch (TYPE_CODE (t)) {
-+ case TYPE_CODE_BOOL:
-+ if(strcmp(TYPE_NAME(t),"bool")==0) ct=ctype_uchar ; /* XXX HACK */
-+ break;
-+ case TYPE_CODE_INT: {
-+ int i, type=0;
-+ char *s=TYPE_NAME(t);
-+ while (*s)
-+ for (i=0; name_to_codetype[i].name; i++) {
-+ if (strncmp(s,name_to_codetype[i].name,name_to_codetype[i].len) == 0) {
-+ s+=name_to_codetype[i].len;
-+ if (*s == ' ') s++;
-+ type+= name_to_codetype[i].codetype;
-+ break;
-+ }
-+ }
-+ if(type == INTTYPE_CHAR) ct=ctype_char ;
-+ else if(type == INTTYPE_CHAR + INTTYPE_UNSIGNED) ct=ctype_uchar ;
-+ else if(type == INTTYPE_SHORT) ct=ctype_short ;
-+ else if(type == INTTYPE_SHORT + INTTYPE_UNSIGNED) ct=ctype_ushort ;
-+ else if(type == INTTYPE_INT) ct=ctype_int ;
-+ else if(type == INTTYPE_UNSIGNED) ct=ctype_uint ;
-+ else if(type == INTTYPE_LONG) ct=ctype_long ;
-+ else if(type == INTTYPE_UNSIGNED + INTTYPE_LONG) ct=ctype_ulong ;
-+ else if(type == INTTYPE_LONG + INTTYPE_LONG) ct=ctype_longlong ;
-+ else if(type == INTTYPE_UNSIGNED + INTTYPE_LONG + INTTYPE_LONG) ct=ctype_ulonglong ;
-+ break;
-+ }
-+ case TYPE_CODE_FLT:
-+ if(strcmp(TYPE_NAME(t),"float")==0) ct=ctype_float ;
-+ else
-+ if(strcmp(TYPE_NAME(t),"double")==0) ct=ctype_double ;
-+ break;
-+ case TYPE_CODE_VOID:
-+ if(strcmp(TYPE_NAME(t),"void")==0) ct=ctype_void ;
-+ break;
-+ case TYPE_CODE_PTR:
-+ case TYPE_CODE_REF:
-+ {
-+ /* the pointer might get defined when converting the target, so
-+ * check the hashing again (reason: self-referencing structs)
-+ */
-+ tctype *target=duel_convert_type_from_gdb(TYPE_TARGET_TYPE(t));
-+ if((ct=duel_find_hash(t))==NULL) ct=duel_mkctype_ptr(target);
-+ }
-+ break ;
-+ case TYPE_CODE_FUNC:
-+ ct=duel_mkctype_func(duel_convert_type_from_gdb(TYPE_TARGET_TYPE(t)));
-+ break ;
-+ case TYPE_CODE_ARRAY:
-+ { int n=TYPE_LENGTH(TYPE_TARGET_TYPE(t));
-+ if(n!=0) n=TYPE_LENGTH(t)/n;
-+ ct=duel_mkctype_array(
-+ duel_convert_type_from_gdb(TYPE_TARGET_TYPE(t)),n);
-+ }
-+ break;
-+ case TYPE_CODE_STRUCT:
-+ case TYPE_CODE_UNION:
-+ { int i,n=TYPE_NFIELDS(t);
-+ char *name=TYPE_NAME(t);
-+ if(name == NULL) name="" ; /* duel can't handle null ptr! */
-+ if(strncmp(name,"struct ",7)==0) name+=7 ;
-+ if(strncmp(name,"union ",6)==0) name+=6 ;
-+ ct=duel_mkctype_struct(name,TYPE_LENGTH(t),n,
-+ TYPE_CODE(t)==TYPE_CODE_UNION);
-+ duel_add_hash(t,ct); /* so a pointer to myself is recognized */
-+ for(i=0 ; i<n ; i++)
-+ duel_mkctype_struct_field(ct,i,TYPE_FIELD_NAME(t,i),
-+ TYPE_FIELD_BITPOS(t,i), TYPE_FIELD_BITSIZE(t,i),
-+ duel_convert_type_from_gdb(TYPE_FIELD_TYPE(t,i)));
-+ }
-+ break ;
-+ case TYPE_CODE_ENUM:
-+ /* TYPE_LENGTH(t) tell how big it is. I assume signed integral types.
-+ * it is unclear if gdb supports unsigned enums and how
-+ * (e.g. enum { x=0,y=250 } stored in uchar
-+ * FIELDS contain the tags, BITPOS is the assigned value.
-+ */
-+ { int i,n=TYPE_NFIELDS(t),len=TYPE_LENGTH(t);
-+ char *name=TYPE_NAME(t);
-+ tctype_kind k ;
-+ if(name==NULL) name="" ; /* duel can't handle null ptr */
-+ if(strncmp(name,"enum ",5)==0) name+=5 ;
-+ /* select 'real' stored type. note order important if short==int.
-+ * long is not allowed as far as I know ANSI C (enums are conv. to int)
-+ * Amazingly, some internal gdb struct (sym) can have an enum of
-+ * size zero (enum language, gdb4.8). We allow this as int but warn.
-+ * gdb> p sizeof(sym->ginfo.lang_specific.language) gives zero
-+ */
-+ if(len==0) {
-+ duel_printf("Warning: enum %s is size zero. assumed int\n",name);
-+ len=sizeof(int);
-+ }
-+ if(len==sizeof(int)) k=CTK_INT ;
-+ else if(len==sizeof(short)) k=CTK_SHORT ;
-+ else if(len==sizeof(char)) k=CTK_CHAR ;
-+ else duel_assert(0);
-+
-+ ct=duel_mkctype_enum(name,k,len,n);
-+ for(i=0 ; i<n ; i++)
-+ duel_mkctype_enumerator(ct,i,TYPE_FIELD_NAME(t,i),
-+ TYPE_FIELD_BITPOS(t,i));
-+ }
-+ break ;
-+ case TYPE_CODE_TYPEDEF:
-+ ct=duel_convert_type_from_gdb(check_typedef(t));
-+ break ;
-+ case TYPE_CODE_UNDEF:
-+ break;
-+ }
-+ if(ct==0) duel_fatal("unsupported C type returned by gdb");
-+ duel_add_hash(t,ct);
-+ return ct ;
-+}
-+
-+/* optimize frame access so frame(100..0) doesnt start the search from 0
-+ * everytime. similar to selected_frame etc, but we dont want to mess up
-+ * gdb's own frame setup (for up/down/print etc)
-+ * this optimization should have been part of gdb, not here.
-+ * ie. duel_select_frame should be a simple fast gdb call.
-+ * we dont optimze going to frame 7 from frame 5 etc, this isn't typical.
-+ * set last/tot frames to -2 to assure recomputeations (-1 is not good enuf)
-+ */
-+
-+static struct frame_info * last_frame ; /* last frame pointer we used */
-+static int last_frame_no ; /* last frame number we used */
-+static int tot_frames_no ; /* tot number of frames */
-+
-+LFUNC struct frame_info * duel_select_frame(int frame_no)
-+{
-+ struct frame_info * frame ;
-+ if(last_frame_no==frame_no) frame=last_frame ;
-+ else
-+ if(last_frame_no==frame_no-1) frame=get_prev_frame(last_frame);
-+ else
-+ if(last_frame_no==frame_no+1) frame=get_next_frame(last_frame);
-+ else {
-+ int count=frame_no ;
-+ frame=get_current_frame();
-+ while (frame && --count >= 0)
-+ frame = get_prev_frame (frame);
-+ }
-+ duel_assert(frame); /* callee should have checked frames no*/
-+ last_frame = frame ;
-+ last_frame_no = frame_no ;
-+ return frame ;
-+}
-+
-+FUNC bool duel_get_target_variable(char *name, int frame_no, tvalue *v)
-+{
-+ struct symbol *sym;
-+ struct frame_info * frame ;
-+ struct block *blk ;
-+ int len ;
-+ struct value *gv ; /* gdb value */
-+
-+ if(frame_no== -1) { /* use the user selected frame and block */
-+ frame = get_selected_frame("Error!") ;
-+ blk = get_selected_block(0) ;
-+ }
-+ else {
-+ frame=duel_select_frame(frame_no) ;
-+ blk = get_frame_block(frame, 0);
-+ }
-+ sym = lookup_symbol (name, blk, VAR_DOMAIN,0,0);
-+ if(!sym) { /* look up the symbol that has no debug info*/
-+ struct minimal_symbol *m ;
-+ if(frame_no != -1) return FALSE ; /* only locals looked up- not found*/
-+ m=lookup_minimal_symbol (name,NULL, 0); /* find printf, malloc etc */
-+ if(m == NULL) return FALSE ;
-+ v->val_kind=VK_LVALUE ;
-+#ifdef SYMBOL_LANGUAGE
-+ /* in gdb4.8 the mini table changed. I use the existance of the above
-+ * #define symbol as hack to indicate gdb.4.8 */
-+ v->u.lvalue=(ttarget_ptr) SYMBOL_VALUE_ADDRESS(m);
-+#else
-+ v->u.lvalue=(ttarget_ptr) m->address ;
-+#endif
-+ /* guess it is an int if it is a data type, an int func if text */
-+ if(m->type == mst_data || m->type == mst_bss) v->ctype=ctype_int ;
-+ else
-+ if(m->type == mst_text) v->ctype=duel_mkctype_func(ctype_int);
-+ else return FALSE ;
-+ return TRUE ;
-+ }
-+ if(SYMBOL_CLASS(sym)==LOC_TYPEDEF) return FALSE ;
-+ /* if frame specificed, allow only local variables to be found */
-+ if(frame_no!= -1 && (SYMBOL_CLASS(sym)==LOC_STATIC ||
-+ SYMBOL_CLASS(sym)==LOC_BLOCK || SYMBOL_CLASS(sym)==LOC_CONST)) return FALSE;
-+ gv=read_var_value(sym,frame);
-+ if(gv==0) return FALSE ; /* frame not found or illegal */
-+ duel_convert_value_from_gdb(gv,v);
-+ return TRUE ;
-+}
-+
-+
-+/* return the total number of frames on the stack */
-+
-+FUNC int duel_get_frames_number(void)
-+{
-+ int n ;
-+ struct frame_info * frame ;
-+ if(tot_frames_no!= -2) return tot_frames_no ;
-+ frame=get_current_frame();
-+ for(n=0 ; frame ; n++)
-+ frame = get_prev_frame (frame);
-+ return tot_frames_no=n ;
-+}
-+
-+FUNC ttarget_ptr duel_get_function_for_frame(int frame_no)
-+{
-+ struct frame_info * frame=duel_select_frame(frame_no);
-+ struct symbol *sym = get_frame_function(frame);
-+ struct value *val = read_var_value(sym,frame);
-+ duel_assert(val!=0 && VALUE_LVAL(val) == lval_memory);
-+
-+ return (ttarget_ptr) VALUE_ADDRESS(val) ;
-+}
-+
-+FUNC tctype* duel_get_target_typedef(char *name)
-+{
-+ struct symbol *sym;
-+ sym = lookup_symbol (name, get_selected_block(0), VAR_DOMAIN,0,0);
-+ if(!sym || SYMBOL_CLASS(sym)!=LOC_TYPEDEF) {
-+ sym = lookup_symbol (name, 0, VAR_DOMAIN, 0,0);
-+ if(!sym || SYMBOL_CLASS(sym)!=LOC_TYPEDEF) return NULL ;
-+ }
-+ return duel_convert_type_from_gdb(SYMBOL_TYPE(sym));
-+}
-+
-+FUNC tctype* duel_get_target_struct_tag(char *name)
-+{
-+ struct symbol *sym;
-+ sym = lookup_symbol (name, get_selected_block(0), STRUCT_DOMAIN,0,0);
-+ if(!sym || TYPE_CODE(SYMBOL_TYPE(sym))!=TYPE_CODE_STRUCT) {
-+ sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0,0);
-+ if(!sym || TYPE_CODE(SYMBOL_TYPE(sym))!=TYPE_CODE_STRUCT) return NULL ;
-+ }
-+ return duel_convert_type_from_gdb(SYMBOL_TYPE(sym));
-+}
-+
-+FUNC tctype* duel_get_target_union_tag(char *name)
-+{
-+ struct symbol *sym;
-+ sym = lookup_symbol (name, get_selected_block(0), STRUCT_DOMAIN,0,0);
-+ if(!sym || TYPE_CODE(SYMBOL_TYPE(sym))!=TYPE_CODE_UNION) {
-+ sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0,0);
-+ if(!sym || TYPE_CODE(SYMBOL_TYPE(sym))!=TYPE_CODE_UNION) return NULL ;
-+ }
-+ return duel_convert_type_from_gdb(SYMBOL_TYPE(sym));
-+}
-+
-+FUNC tctype* duel_get_target_enum_tag(char *name)
-+{
-+ struct symbol *sym;
-+ sym = lookup_symbol (name, get_selected_block(0), STRUCT_DOMAIN,0,0);
-+ if(!sym || TYPE_CODE(SYMBOL_TYPE(sym))!=TYPE_CODE_ENUM) {
-+ sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0,0);
-+ if(!sym || TYPE_CODE(SYMBOL_TYPE(sym))!=TYPE_CODE_ENUM) return NULL ;
-+ }
-+ return duel_convert_type_from_gdb(SYMBOL_TYPE(sym));
-+}
-+
-+/*
-+ * entry point from gdb.
-+ * produce help in gdb's format, or call duel enter point.
-+ * we allow ^c to quit immidiatly, and setup memory release cleanup.
-+ */
-+
-+void duel_command(char *exp,int from_tty)
-+{
-+ last_frame_no = -2 ; /* recompute frame location on each dl command */
-+ tot_frames_no = -2 ;
-+
-+ make_cleanup(duel_cleanup, 0); /* clear all allocated mem */
-+ immediate_quit++ ;
-+ duel_parse_and_eval(exp);
-+ immediate_quit-- ;
-+}
-+
-+void
-+_initialize_duel()
-+{
-+ add_com ("duel", class_vars, duel_command,
-+"Evaluate Duel expressions. Duel is a very high level debugging language.\n\
-+\"dl help\" for help.\n");
-+ add_com_alias ("dl", "duel", class_vars, 1);
-+
-+}
diff --git a/src/patchsets/gdb/6.8/11_all_gdb-6.6-duel-integrate.patch b/src/patchsets/gdb/6.8/11_all_gdb-6.6-duel-integrate.patch
deleted file mode 100644
index d639b6cbd1..0000000000
--- a/src/patchsets/gdb/6.8/11_all_gdb-6.6-duel-integrate.patch
+++ /dev/null
@@ -1,59 +0,0 @@
---- gdb/Makefile.in
-+++ gdb/Makefile.in
-@@ -116,6 +116,9 @@
- # Where is the "-liberty" library? Typically in ../libiberty.
- LIBIBERTY = ../libiberty/libiberty.a
-
-+# Where is the DUEL library ? Always in duel/src
-+DUEL=duel/duel.a
-+
- # Where is the BFD library? Typically in ../bfd.
- BFD_DIR = ../bfd
- BFD = $(BFD_DIR)/libbfd.a
-@@ -383,9 +386,9 @@
- CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(INTL) $(LIBIBERTY) \
- $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \
- $(LIBICONV) $(LIBEXPAT) \
-- $(LIBIBERTY) $(WIN32LIBS)
-+ $(LIBIBERTY) $(WIN32LIBS) $(DUEL)
- CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE_DEPS) \
-- $(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS)
-+ $(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS) $(DUEL)
-
- ADD_FILES = $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
- ADD_DEPS = $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
-@@ -561,7 +564,7 @@
- ui-out.c utils.c ui-file.h ui-file.c \
- user-regs.c \
- valarith.c valops.c valprint.c value.c varobj.c vec.c \
-- wrapper.c \
-+ wrapper.c duelgdb.c \
- xml-tdesc.c xml-support.c
-
- LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
-@@ -948,7 +951,7 @@
- dwarf2expr.o dwarf2loc.o dwarf2-frame.o \
- ada-lang.o c-lang.o f-lang.o objc-lang.o \
- ui-out.o cli-out.o \
-- varobj.o vec.o wrapper.o \
-+ varobj.o vec.o wrapper.o duelgdb.o \
- jv-lang.o jv-valprint.o jv-typeprint.o \
- m2-lang.o p-lang.o p-typeprint.o p-valprint.o \
- scm-exp.o scm-lang.o scm-valprint.o \
-@@ -971,7 +974,7 @@
-
- TSOBS = inflow.o
-
--SUBDIRS = @subdirs@
-+SUBDIRS = @subdirs@ duel
-
- # For now, shortcut the "configure GDB for fewer languages" stuff.
- YYFILES = c-exp.c \
-@@ -3238,4 +3241,7 @@
- $(gdb_curses_h) $(gdb_assert_h)
- $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tui-winsource.c
-
-+$(DUEL):
-+ $(MAKE) $(FLAGS_TO_PASS) -C duel
-+
- ### end of the gdb Makefile.in.