home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / alt / sources / 3072 < prev    next >
Encoding:
Text File  |  1993-01-23  |  28.8 KB  |  844 lines

  1. Newsgroups: alt.sources
  2. Path: sparky!uunet!cs.utexas.edu!qt.cs.utexas.edu!yale.edu!newsserver.jvnc.net!princeton!csservices!tyrolia!mg
  3. From: mg@tyrolia (Michael Golan)
  4. Subject: Duel - a language for debugging C programs part 4/6
  5. Message-ID: <1993Jan22.034722.21178@csservices.Princeton.EDU>
  6. Sender: news@csservices.Princeton.EDU (USENET News System)
  7. Organization: Department of Computer Science, Princeton University
  8. Date: Fri, 22 Jan 1993 03:47:22 GMT
  9. Lines: 833
  10.  
  11. Submitted-by: mg@cs.princeton.edu
  12. Archive-name: duel/part04
  13.  
  14. #!/bin/sh
  15. # This is part 04 of duel
  16. if touch 2>&1 | fgrep 'amc' > /dev/null
  17.  then TOUCH=touch
  18.  else TOUCH=true
  19. fi
  20. # ============= src/eval.c ==============
  21. echo "x - extracting src/eval.c (Text)"
  22. sed 's/^X//' << 'SHAR_EOF' > src/eval.c &&
  23. X/*   DUEL - A Very High Level Debugging Langauge.  */
  24. X/*   Public domain code                            */
  25. X/*   Written by Michael Golan mg@cs.princeton.edu  */
  26. X/*$Header: /tmp_mnt/n/fs/grad2/mg/duel/RCS/eval.c,v 1.9 93/01/12 21:50:26 mg Exp $*/
  27. X
  28. X/* this module is the most critical code, the recursive evaluation
  29. X */
  30. X
  31. X/*
  32. X * $Log:    eval.c,v $
  33. X * Revision 1.9  93/01/12  21:50:26  mg
  34. X * cleanup and set for release
  35. X * 
  36. X * Revision 1.8  93/01/07  00:09:34  mg
  37. X * scope stack changes a bit.
  38. X * clear/aliases commands.
  39. X * func.x support, x.y etc force existance if y field of x., x=>y w/'_'
  40. X * allow fields in y for x@y, x pointer.
  41. X * fixed eval_node setup
  42. X * added &&/ ||/
  43. X * 
  44. X * 
  45. X * Revision 1.7  93/01/03  07:29:23  mg
  46. X * function calls, error reporting, printing.
  47. X * 
  48. X * Revision 1.6  92/12/24  23:33:48  mg
  49. X * frames support
  50. X * 
  51. X * Revision 1.5  92/10/19  15:06:35  mg
  52. X * *** empty log message ***
  53. X * 
  54. X * Revision 1.4  92/10/14  02:04:35  mg
  55. X * misc
  56. X * 
  57. X * Revision 1.3  92/09/16  11:04:16  mg
  58. X * *** empty log message ***
  59. X * 
  60. X * Revision 1.2  92/09/15  05:54:56  mg
  61. X * cosmetics and new ops: 
  62. X * generic '.' and '_'  support. x@y. '..x' and 'x..'.  while(), for(), ?:
  63. X * 
  64. X */
  65. X
  66. X#include "duel.h"
  67. X
  68. X
  69. X
  70. X#define DOT_STACK_SIZE 100    /* dot stack size, maximum no. of dots in stmt */
  71. X
  72. X/* the scope eval stack. 
  73. X * This is used for two purposes: to push _'s values, and to push structs
  74. X * and unions for x.y and x->y.
  75. X * realv is the real value for the left side operand. It is used for '_'
  76. X * fieldv is the one to be used to fetch fields. It is either the same
  77. X * as realv (e.g. for x.y), is *realv (for x->y) or null (for x=>y).
  78. X */
  79. Xstruct { 
  80. X    tvalue *realv ;     /* actual value for x in x.y or x->y etc. used for _ */
  81. X    tvalue *fieldv;     /* value to use for fetching fields, *realv for x->y */
  82. X  } dot_stack[DOT_STACK_SIZE] ;
  83. Xint dot_stack_top= -1 ;
  84. X
  85. XPROC duel_reset_eval(void)   /* reset evaluation states from previous eval */
  86. X{
  87. X  dot_stack_top= -1 ;   /* reset stack */
  88. X}
  89. X
  90. X/* try to find the given name on the dot_stack of structures.
  91. X * if found, return true and value in(v) else return false.
  92. X * the symbolic value is not set.
  93. X * if top_only, looks only at the top of the stack.
  94. X */
  95. XLFUNC bool find_dot_name(char *name,tvalue *v,bool top_only)
  96. X{
  97. X    int i,j ;
  98. X    tctype_field *f ;
  99. X    tctype *t ;
  100. X    tvalue *x;
  101. X
  102. X    for(i=dot_stack_top ; i>=0 ; i--) {           /* look at the stack[i]    */
  103. X        if(top_only && i!=dot_stack_top) break ;  /* consider only top of stk*/
  104. X        x=dot_stack[i].realv ;
  105. X        if(name[0]=='_' && name[1]==0 ||                           /* _ */
  106. X           name[1]=='_' && i==dot_stack_top-1 && name[2]==0 ||     /* __ */
  107. X           name[1]=='0'+dot_stack_top-i && name[2]==0) {           /* _[0-9] */
  108. X            *v = *x ;
  109. X            return TRUE ; 
  110. X        }
  111. X        x=dot_stack[i].fieldv;
  112. X        if(x->val_kind==VK_FVALUE) {
  113. X            if(!duel_get_target_variable(name,x->u.fvalue,v)) continue ;
  114. X            strcpy(v->symb_val,name);
  115. X            return TRUE ;
  116. X        }
  117. X        if(!x) continue ;
  118. X        t=x->ctype ;
  119. X        if(!ctype_kind_struct_like(t)) continue ;
  120. X        duel_assert(x->val_kind==VK_LVALUE);
  121. X        for(j=0 ; j<t->u.f.fields_no ; j++) {  /* look at field[j] of struct*/
  122. X            f= &t->u.f.fields[j] ;
  123. X            if(strcmp(f->name,name)==0) goto found ;
  124. X        }
  125. X    }
  126. X    return FALSE ;
  127. Xfound:
  128. X    v->ctype=f->ctype ;
  129. X    strcpy(v->symb_val,name);
  130. X    if(f->bitlen==0) {
  131. X       v->u.lvalue=x->u.lvalue+f->bitpos/BITS_PER_BYTE ;
  132. X       v->val_kind=VK_LVALUE ;
  133. X       return TRUE ;
  134. X   }
  135. X   /* special care for a bitfield */
  136. X   if(f->ctype->type_kind!=CTK_INT && f->ctype->type_kind!=CTK_UINT)
  137. X       duel_gen_error("bitfield '%s' must be int or unsigned",name);
  138. X    v->val_kind=VK_BVALUE ;
  139. X    v->u.bvalue.lvalue=x->u.lvalue ;
  140. X    v->u.bvalue.bitpos=f->bitpos ;
  141. X    v->u.bvalue.bitlen=f->bitlen ;
  142. X    return TRUE ;
  143. X}
  144. X
  145. X/* find the value of a given symbolic name and
  146. X * return in in v
  147. X * if name is not found, aborts with an error
  148. X */
  149. X
  150. XLPROC duel_eval_name(char *name,tvalue *v)
  151. X{
  152. X   tvalue *aval=duel_find_alias(name) ; /* find internal alias */
  153. X   if(aval!=NULL) *v= *aval ;
  154. X   else
  155. X   if(find_dot_name(name,v,FALSE)) return ;   /* setup name itself */
  156. X   else
  157. X   if(duel_get_target_variable(name,-1,v));
  158. X   else
  159. X   if(strcmp(name,"frames_no")==0) {            /* check special variables */
  160. X       v->val_kind=VK_RVALUE ;
  161. X       v->ctype=ctype_int ;
  162. X       v->u.rval_int=duel_get_frames_number();
  163. X   }
  164. X   else duel_gen_error("variable '%s' not found",name);
  165. X   strcpy(v->symb_val,name);
  166. X}
  167. X
  168. X
  169. XLPROC push_val(tval_list *l,tvalue *v)
  170. X{
  171. X  tval_lcell *e = duel_malloc(sizeof(tval_lcell));
  172. X  e->val = *v ;
  173. X  e->next=l->head ;
  174. X  l->head=e ;
  175. X  if(l->tail==0) l->tail=e ;
  176. X}
  177. X
  178. XLPROC append_val(tval_list *l,tvalue *v)
  179. X{
  180. X  tval_lcell *e=duel_malloc(sizeof(tval_lcell)) ;
  181. X  e->val = *v ;
  182. X  e->next=0 ;
  183. X  if(l->head==0) l->head=l->tail=e ;
  184. X  else     l->tail=l->tail->next=e ;
  185. X}
  186. X
  187. X/* push a whole val-list(ins) into (l) i.e. insert (ins) at the head of(l)
  188. X */
  189. X
  190. XLPROC push_val_list(tval_list *l,tval_list *ins)
  191. X{
  192. X  if(ins->head==NULL) return ;              /* inserted list is empty */
  193. X  if(l->head==NULL) { *l= *ins ; return ; }  /* insert-into is empty */
  194. X  ins->tail->next=l->head ;
  195. X  l->head=ins->head ;
  196. X}
  197. X
  198. X
  199. X/* remove first(top) element */
  200. XLFUNC bool pop_val(tval_list *l,tvalue *v)
  201. X{
  202. X  tval_lcell *e=l->head ;
  203. X  if(e==0) return(FALSE);
  204. X  *v=e->val ;
  205. X  l->head=e->next ;
  206. X  return(TRUE);
  207. X}
  208. X/* compute the symbolic value of one iteration of a search (eg -->) operator.
  209. X * Normally, for (x) and (y) the result x->y  is returned. 
  210. X * But, if x === a-->next[[n]] and y === next, then we 
  211. X * return a-->next[[m]] where m=n+1.
  212. X * Also, instead of returning x->y we return x-->y[[1]]
  213. X *
  214. X * note: this was not written for speed! I don't know if it takes
  215. X * a significant amount of time or not.
  216. X */
  217. X
  218. XLPROC set_search_symb_val(char *opcode,tvalue *xval,tvalue *yval)
  219. X{
  220. X    char *x = xval->symb_val ; 
  221. X    char *y = yval->symb_val ;
  222. X    int i,opl=strlen(opcode),xl=strlen(x),yl=strlen(y) ;
  223. X    char s[3*VALUE_MAX_SYMBOLIC_SIZE];
  224. X
  225. X    if(yl+2<xl && strcmp(x+xl-yl,y)==0 && x[xl-yl-2]=='-' && x[xl-yl-1]=='>') 
  226. X        sprintf(s,"%-.*s%s%s[[2]]",xl-yl-2,x,opcode,y);
  227. X    else {
  228. X    for(i=xl-1 ; i>0  ; i--)            /* see if we have op in x */
  229. X        if(strncmp(&x[i],opcode,opl)==0) break ;
  230. X    if(i>0 && strncmp(&x[i+opl],y,yl)==0 && 
  231. X       x[i+opl+yl]=='[' && x[i+opl+yl+1]=='[' && x[xl-2]==']' && x[xl-1]==']'){
  232. X        /* x seems to be something like  head-->next[1] */
  233. X        int j,val=0 ;
  234. X        for(j=i+opl+yl+2 ; j<xl-2 ; j++) {
  235. X            if(x[j]<'0' || x[j]>'9') goto simple ;
  236. X            val=10*val+x[j]-'0' ;       /* compute index */
  237. X        }
  238. X        sprintf(s,"%-.*s[[%d]]",i+opl+yl,x,val+1);   /* and re-create it */
  239. X    }
  240. X    else {
  241. Xsimple:         /* we failed to find a x-->y[z] pattern, make new one */
  242. X        sprintf(s,"%s->%s",x,y);
  243. X    }
  244. X   }
  245. X   s[VALUE_MAX_SYMBOLIC_SIZE]=0 ; /* chop as needed */
  246. X    strcpy(y,s);
  247. X}
  248. X
  249. XLPROC push_dot_stack(tvalue *realv,tvalue *fieldv)
  250. X{
  251. X   if(dot_stack_top==DOT_STACK_SIZE) 
  252. X       duel_gen_error("expression too complex ('.' and '->' levels)",0);
  253. X   dot_stack[++dot_stack_top].realv=realv ;
  254. X   dot_stack[dot_stack_top].fieldv=fieldv ;
  255. X}
  256. X
  257. XLPROC pop_dot_stack(void)
  258. X{
  259. X   duel_assert(dot_stack_top>=0);
  260. X   dot_stack_top-- ;
  261. X}
  262. X
  263. X/* a simple fetch of a field. used mainly when printing 
  264. X * v must be a struct with the given name field. value is returned in ret.
  265. X * return false if name not found.
  266. X */
  267. X
  268. XFUNC bool duel_get_dot_name(tvalue *v,char *name,tvalue *ret)
  269. X{
  270. X    bool ok ;
  271. X    push_dot_stack(v,v);
  272. X    ok=find_dot_name(name,ret,TRUE);
  273. X    pop_dot_stack();
  274. X    return ok ;
  275. X}
  276. X
  277. X/* evaluate x.y and similar "with" operators. Special care when y is a 
  278. X * name and not an expression -- force y to be a direct field of x.
  279. X * y is the 'y' node. v is value to return. op is opcode for error reports
  280. X * (rv,fv) are values to push on the dot stack. rv is the real 'x' value,
  281. X *         fv is the value of x to use for field lookup (fv= *rv for '->')
  282. X */
  283. X
  284. XLFUNC bool eval_dot(tnode *y,tvalue *v,char *op,tvalue *rv,tvalue *fv)
  285. X{
  286. X   bool ok ;
  287. X   push_dot_stack(rv,fv);
  288. X   if(y->node_kind!=NK_NAME) ok=duel_eval(y,v);  /* "with" style */
  289. X   else {                                        /* x.y y simply name */
  290. X      if(++y->eval.level>1) { y->eval.level=0 ; ok=FALSE ; }
  291. X      else {
  292. X        ok=find_dot_name(y->name,v,TRUE);
  293. X        if(!ok) duel_op_error("field not found in operator '%s'",op,rv,0);
  294. X      }
  295. X   }
  296. X   pop_dot_stack();
  297. X   return ok ;
  298. X}
  299. X
  300. X
  301. X/* evaluate special operators like '-->' '?:' etc */
  302. X
  303. X/* get the next result of an sop val:
  304. X * DFS:  init by pushing(x)
  305. X * Iterate: pop x, compute all x->y, push (reversed)
  306. X * out: x
  307. X
  308. X * POS: init by pushing(x), unmarked.
  309. X * Iterate: pop x, if marked return it. else push back, marked.
  310. X *          compute all x->y, push (reversed)
  311. X *          repeat until marked x is popped.
  312. X * out: poped x which is marked.
  313. X
  314. X * BFS: init by pushing(x)
  315. X * Iterate: get first(x), 
  316. X *      compute all x->y and put into queue.
  317. X *      return x.
  318. X */
  319. X
  320. X/* fetch the next value in a DFS search on x-->y. y is given as a node
  321. X * and x is popped of the given list. Value is returned in v.
  322. X * note: the results from x->y are reversed when pushed on the list,
  323. X * this is so x-->(left,right) would return the left first (put last on
  324. X * the stack, even though it is computed first!)
  325. X * malloc problem: newl is kept locally, so in case of ^C while here, mem 
  326. X * it points to will be lost. Normally only a few values
  327. X */
  328. X
  329. XLFUNC bool get_next_dfs_val(tval_list *l, tnode *y,tvalue *v)
  330. X{
  331. X   tvalue child,x ;
  332. X   tval_list newl ;
  333. X   newl.head=0 ;
  334. X   do {
  335. X       if(!pop_val(l,v)) return(FALSE) ;
  336. X       x= *v ;
  337. X       duel_get_struct_ptr_val(&x,"x-->y");
  338. X   } while(x.u.lvalue==0) ;     /* ignore null pointers */
  339. X   while(eval_dot(y,&child,"-->",v,&x)) {
  340. X       set_search_symb_val("-->",&x,&child);  /* makes x-->y[n] neatly */
  341. X       append_val(&newl,&child);                /* append to childs list */
  342. X   }
  343. X   push_val_list(l,&newl);              /* append new childs to stack */
  344. X   return(TRUE);                        /* returns the popped value in v */
  345. X}
  346. X
  347. X
  348. X/* stop the evaluation of the expression at node n. 
  349. X * useful with operators like first().
  350. X * each node keeps an internal state allowing it to produce the next value.
  351. X * this function resets those states. 
  352. X *
  353. X * How: the internal state is kept in n->eval.level. we reset level to zero
  354. X *      for the node and the subnodes. if the level is already zero,
  355. X *      the node has already gone to the 'initial state', so the subnodes
  356. X *      are not visited.
  357. X */
  358. X
  359. XLPROC stop_eval(tnode *n)
  360. X{
  361. X   int i;
  362. X   if(n==NULL || n->eval.level==0) return ; /* done! subnodes are also ok */
  363. X   n->eval.level=0 ; 
  364. X   for(i=0 ; i<NODE_MAX_KIDS ; i++) stop_eval(n->kids[i]);
  365. X}
  366. X
  367. X/* evaluate function paramaters. This recursive function should be called
  368. X * with the top node for the parms. Parms are parsed as "," operators.
  369. X * the function leaves the computed values "hanging" on v1 of each node.
  370. X */
  371. X
  372. XLFUNC bool eval_func_parms(tnode *n)
  373. X{
  374. X    tvalue *p = &n->eval.v1 ;
  375. X    if(n->node_kind==NK_OP && n->op_kind==OPK_SBIN && n->op==',') {
  376. X       while(n->eval.level==2 || duel_eval(n->kids[0],p)) {
  377. X          n->eval.level=2 ;  /* left side active parm in p */
  378. X          if(eval_func_parms(n->kids[1])) goto ok;
  379. X          n->eval.level=1 ;   /*re-eval */
  380. X       }
  381. X       return FALSE ;
  382. X   }
  383. X   else if(!duel_eval(n,p)) return FALSE;  /* eval last paramater */
  384. Xok:
  385. X   duel_standardize_func_parm(p); 
  386. X   return TRUE ;
  387. X}
  388. X
  389. XLFUNC bool eval_func_call(tnode *n,tvalue *v)
  390. X{
  391. X
  392. X   tvalue *f= &n->eval.v1 ;
  393. X   tvalue *parms[21];
  394. X   int i,parms_no ;
  395. X   tnode *p ;
  396. X
  397. Xagain:
  398. X   if(n->kids[1]==NULL) {       /* no parms */
  399. X       n->eval.level=1 ;
  400. X       if(!duel_eval(n->kids[0],f)) return FALSE ;
  401. X   }
  402. X   else {
  403. X      while(n->eval.level==2 || duel_eval(n->kids[0],f)) {
  404. X        n->eval.level=2 ;  /* function in f */
  405. X        if(eval_func_parms(n->kids[1])) goto ok;
  406. X        n->eval.level=1 ;   /*re-eval func */
  407. X      }
  408. X      return FALSE ;
  409. X    ok: ;
  410. X   }
  411. X
  412. X   if(f->ctype->type_kind!=CTK_FUNC) duel_op_error("bad function call",0,f,0);
  413. X
  414. X   p=n->kids[1] ;                       /* collect paramaters now */
  415. X   parms_no=0 ;
  416. X   while(p && p->node_kind==NK_OP && p->op_kind==OPK_SBIN && p->op==',') {
  417. X     parms[parms_no++]= &p->eval.v1 ;
  418. X     p=p->kids[1] ;
  419. X     if(parms_no>=20) duel_op_error("too many paramaters",0,0,0);
  420. X   }
  421. X   if(p) parms[parms_no++]= &p->eval.v1 ;       /* last paramater */
  422. X
  423. X   duel_target_func_call(f,parms,parms_no,v);
  424. X   if(f->ctype->u.kid->type_kind==CTK_VOID) goto again ; /* no return vals */
  425. X   duel_set_symb_val(v,"%s(",f,0);
  426. X   for(i=0 ; i<parms_no ; i++) 
  427. X      duel_set_symb_val(v,"%s%s,",v,parms[i]);
  428. X   if(parms_no>0) v->symb_val[strlen(v->symb_val)-1]='\0' ; /*chop ',' tail*/
  429. X   strcat(v->symb_val,")");
  430. X   return TRUE ;
  431. X}
  432. X
  433. X
  434. X/* evaluate for special operators: those the produce more than one value,
  435. X * binary ones. ',' '..' etc
  436. X */
  437. X
  438. XLFUNC bool duel_eval_sbin(tnode *n,tvalue *v)
  439. X{
  440. X   tval_list *vl = &n->eval.vlist ;
  441. X   tvalue y,*v1= &n->eval.v1, *v2= &n->eval.v2 ;
  442. X   tnode *kid0 = n->kids[0], *kid1 = n->kids[1] ;
  443. X   int vi ;
  444. X   bool ok ;
  445. X#define lev n->eval.level
  446. X
  447. X   duel_assert(n->node_kind==NK_OP && n->op_kind==OPK_SBIN);
  448. X   switch(n->op) {
  449. X   case OP_DECL:
  450. X           duel_assert(kid0->node_kind==NK_NAME && kid1->node_kind==NK_CTYPE);
  451. X           if(kid1->ctype->size<=0) duel_gen_error("illegal type size",0);
  452. X           v->val_kind=VK_LVALUE ;
  453. X           v->ctype=kid1->ctype ;
  454. X           v->u.lvalue=duel_alloc_target_space(kid1->ctype->size);
  455. X           strcpy(v->symb_val,kid0->name);
  456. X           duel_set_alias(kid0->name,v);
  457. X   break ;
  458. X   case OP_DEF:
  459. X           if(kid0->node_kind!=NK_NAME) 
  460. X                duel_gen_error("left side of := must be a simple var",0);
  461. X           if(!duel_eval(kid1,v)) return FALSE ;
  462. X           duel_set_alias(kid0->name,v);
  463. X           return TRUE ;
  464. X   case ',':
  465. X         if(lev==1 && duel_eval(kid0,v)) return TRUE ;
  466. X         lev=2 ;
  467. X         return duel_eval(kid1,v);
  468. X   case ';':  
  469. X         /*note: (x;) is not allowed in syntax, but is allowed here and 
  470. X          *means eval x, return nothing. used by parser, e.g. terminating ';'
  471. X          *produces no side effects 
  472. X          */
  473. X
  474. X         if(lev==1) while(duel_eval(kid0,v)) ; /* eval all left size */
  475. X         lev=2 ;
  476. X         return duel_eval(kid1,v); 
  477. X   break ;
  478. X   case OP_IMP:  /* a=>b  for each _=eval(a) return eval(b) (with _ set) */
  479. X             if(lev>1) goto im2 ;
  480. X             for(;;) {
  481. X                  if(!duel_eval(kid0,v1)) return FALSE ;
  482. X                  lev=2 ;
  483. X             im2: push_dot_stack(v1,0);
  484. X                  ok=duel_eval(kid1,v);
  485. X                  pop_dot_stack();
  486. X                  if(ok) return TRUE ;
  487. X             }
  488. X   case OP_IF:  /* if(a) b  return eval(b) for each eval(a)!=0 */
  489. X             if(lev>1) goto if2 ;
  490. X             for(;;) {
  491. X                  if(!duel_eval(kid0,v)) return FALSE ;
  492. X                  if(!duel_mk_logical(v,"if(x)y")) continue ;
  493. X                  lev=2 ;
  494. X             if2: if(duel_eval(kid1,v)) return TRUE ;
  495. X             }
  496. X   case OP_OR:  /* a||b normal 'C' logical or */
  497. X             if(lev>1) goto or2 ;
  498. X             for(;;) {
  499. X                  if(!duel_eval(kid0,v)) return FALSE ;
  500. X                  if(duel_mk_logical(v,"x||y")) {lev=1 ; return TRUE ;}
  501. X             or2: if(duel_eval(kid1,v)) {
  502. X                    lev=2 ;
  503. X                    duel_mk_logical(v,"y||x");
  504. X                    return TRUE ;
  505. X                  }
  506. X             }
  507. X   case OP_AND:  /* a&&b normal 'C' logical and */
  508. X             if(lev>1) goto an2 ;
  509. X             for(;;) {
  510. X                  if(!duel_eval(kid0,v)) return FALSE ;
  511. X                  if(!duel_mk_logical(v,"x&&y")) {lev=1 ; return TRUE ;}
  512. X             an2: if(duel_eval(kid1,v)) {
  513. X                    lev=2 ;
  514. X                    duel_mk_logical(v,"y&&x");
  515. X                    return TRUE ;
  516. X                  }
  517. X             }
  518. X   case '.':  
  519. X             if(lev>1) goto dt2 ;
  520. X             for(;;) {
  521. X                  if(!duel_eval(kid0,v1)) return FALSE ;
  522. X                  *v2 = * v1 ;  /* copy value for the lookup */
  523. X                  if(ctype_kind_func_ptr_like(v1->ctype))  /* func.x */ 
  524. X                      duel_find_func_frame(v2,"x.y");
  525. X                  else
  526. X                  if(v1->val_kind!=VK_FVALUE)  /* type check frame or struct*/
  527. X                      duel_get_struct_val(v1,"x.y");
  528. X                  lev=2 ;
  529. X             dt2: if(!eval_dot(kid1,v,".",v1,v2)) continue ;
  530. X                  if(v->ctype!=v->ctype || v1->val_kind!=v1->val_kind ||
  531. X                     strcmp(v->symb_val,v1->symb_val)!=0) /* check for x._ */
  532. X                      duel_set_symb_val(v,"%s.%s",v1,v);
  533. X                  return TRUE ;
  534. X             }
  535. X   case OP_ARR:
  536. X             if(lev>1) goto ar2 ;
  537. X             for(;;) {
  538. X                  if(!duel_eval(kid0,v1)) return FALSE ;
  539. X                  *v2 = *v1 ;           /* copy value for dereferencing */
  540. X                  duel_get_struct_ptr_val(v2,"x->y");
  541. X                  lev=2 ;
  542. X             ar2: if(!eval_dot(kid1,v,"->",v1,v2)) continue ;
  543. X                  if(v->ctype!=v->ctype || v1->val_kind!=v1->val_kind ||
  544. X                     strcmp(v->symb_val,v1->symb_val)!=0) /* check for x->_ */
  545. X                      duel_set_symb_val(v,"%s->%s",v1,v);
  546. X                  return TRUE ;
  547. X             }
  548. X   case OP_TO:  /* a..b  Is it legal to have 1..(5,6) sure! */
  549. X         if(lev>1) goto to2 ;
  550. X         do {
  551. X             if(kid0 && !duel_eval(kid0,v1)) break ;
  552. X             do {
  553. X               if(kid1 && !duel_eval(kid1,v2)) break ;
  554. X         to2:  if(duel_do_op_to(kid0? v1:0,kid1? v2:0,++lev-2,v)) return TRUE;
  555. X             } while(kid1);
  556. X         } while(kid0) ;  /* either one (kid0 null) or infinite iterations*/
  557. X   break ;
  558. X   case OP_SEL:          /* x[[y]] */
  559. X           if(lev==1) { lev=2 ; n->eval.counter= -1 ; }
  560. X           if(!duel_eval(kid1,v1)) {
  561. X               stop_eval(kid0);
  562. X               return FALSE ;
  563. X           }
  564. X           vi=duel_get_posint_val(v1,"y[[x]]");
  565. X           if(vi<=n->eval.counter) {
  566. X                   /* v is smaller than previous v value, so reset x and
  567. X                    * start over. Example: \x[1,5,3] after \x[1],
  568. X                    * we continue to get [5]. but to get [3] we reset
  569. X                    * Alternatively, we could have kept a list of old
  570. X                    * generated values.
  571. X                    */
  572. X               stop_eval(kid0) ;
  573. X               n->eval.counter= -1 ;
  574. X           }
  575. X           for( ; n->eval.counter<vi ; n->eval.counter++) 
  576. X               if(!duel_eval(kid0,v)) 
  577. X                   duel_op_error("operator x of y[[x]] too large",0,v1,0);
  578. X           return TRUE ; /* value is the last (v) computed */
  579. X   break ;
  580. X   case '@':             /* x@y - generate x stops when y true */
  581. X           if(!duel_eval(kid0,v)) return FALSE ;
  582. X           if(kid1->node_kind==NK_CONST) {      /* special case y constant */
  583. X               *v2=kid1->cnst ;
  584. X               *v1= *v ;        /* because 'apply_bin_op' destroy its args */
  585. X               duel_apply_bin_op(OP_EQ,v1,v2,&y);
  586. X               if(y.u.rval_int) { stop_eval(kid0); return FALSE ; }
  587. X               return TRUE ;
  588. X           }
  589. X           *v1 = *v ;           /* allow fields in y of x@y for x struct ptr */
  590. X           if(ctype_kind_ptr_like(v->ctype) && 
  591. X              ctype_kind_struct_like(v->ctype->u.kid))
  592. X               duel_get_struct_ptr_val(v1,"x@y");
  593. X
  594. X           while(eval_dot(kid1,v2,"@",v,v1)) /* check &&/y */
  595. X               if(!duel_mk_logical(v2,"y@x")) {  /* y==0, so dont stop x */
  596. X                   stop_eval(kid1);
  597. X                   return TRUE ;
  598. X               }
  599. X           stop_eval(kid0); 
  600. X    break ;
  601. X    case '#':            /* x#i define variable i as counter for gen. x*/
  602. X       if(kid1->node_kind!=NK_NAME) 
  603. X               duel_gen_error("x#y 2rd operand must be a name",0);
  604. X       if(!duel_eval(kid0,v)) return FALSE ;
  605. X       if(lev==1) { lev=2 ; n->eval.counter= -1 ; } /* first time */
  606. X       y.val_kind=VK_RVALUE ;
  607. X       y.ctype=ctype_int ;
  608. X       y.u.rval_int= ++n->eval.counter ;
  609. X       sprintf(y.symb_val,"%d",n->eval.counter);
  610. X       duel_set_alias(kid1->name,&y);
  611. X       return TRUE ;
  612. X   break ;
  613. X   case OP_DFS:          /* x-->y */
  614. X       if(lev>1) goto df2 ;
  615. X       for(;;) {
  616. X            if(!duel_eval(kid0,v)) return FALSE ;
  617. X            duel_free_val_list(vl);
  618. X            push_val(vl,v);
  619. X            lev=2 ;
  620. X       df2: if(get_next_dfs_val(vl,kid1,v)) return TRUE ;
  621. X       }
  622. X   break ;
  623. X   case OP_WHILE:       /* while(a) b  */
  624. X             if(lev==2) goto wh2 ;
  625. X             for(;;) {
  626. X                  while(duel_eval(kid0,v)) /* check &&/a */
  627. X                    if(!duel_mk_logical(v,"while(x)y")) {
  628. X                       stop_eval(kid0);
  629. X                       return FALSE ;
  630. X                    }
  631. X                  lev=2 ;
  632. X             wh2: if(duel_eval(kid1,v)) return TRUE ;
  633. X             }
  634. X   default: duel_assert(0);
  635. X   }
  636. X   return FALSE ;
  637. X#undef lev
  638. X}
  639. X
  640. X
  641. X
  642. XLFUNC bool duel_eval_tri(tnode *n,tvalue *v)
  643. X{
  644. X#define lev n->eval.level
  645. X   duel_assert(n->node_kind==NK_OP && n->op_kind==OPK_TRI);
  646. X   switch(n->op) {
  647. X   case OP_IF:  /* if(a) b else c return eval(b) for each eval(a)!=0
  648. X                 * and eval(c) for each eval(a)==0 (usu. (a) is one result*/
  649. X             if(lev>1) goto if2;
  650. X             for(;;) {
  651. X                   if(!duel_eval(n->kids[0],v)) return FALSE ;
  652. X                   lev=(duel_mk_logical(v,"if(x) y else z")? 2:3) ;
  653. X              if2: if(duel_eval(n->kids[lev-1],v)) return TRUE ;
  654. X             }
  655. X   case '?':    /* a? b:c has the same semantics as if(a) b else c */
  656. X             if(lev>1) goto qm2;
  657. X             for(;;) {
  658. X                   if(!duel_eval(n->kids[0],v)) return FALSE ;
  659. X                   lev=(duel_mk_logical(v,"x? y:z")? 2:3) ;
  660. X              qm2: if(duel_eval(n->kids[lev-1],v)) return TRUE ;
  661. X             }
  662. X   default: duel_assert(0);
  663. X   }
  664. X   return FALSE ;
  665. X#undef lev
  666. X}
  667. X
  668. XLFUNC bool duel_eval_quad(tnode *n,tvalue *v)
  669. X{
  670. X#define lev n->eval.level
  671. X   duel_assert(n->node_kind==NK_OP && n->op_kind==OPK_QUAD);
  672. X   switch(n->op) {
  673. X   case OP_FOR: /* for(a;b;c) d ;  */
  674. X             if(lev==1) { lev=2 ; while(duel_eval(n->kids[0],v)); }
  675. X             if(lev==3) goto fr3 ;
  676. X             for(;;) {
  677. X                  while(duel_eval(n->kids[1],v)) /* check &&/b */
  678. X                    if(!duel_mk_logical(v,"for(a;x;y)z")) {
  679. X                       stop_eval(n->kids[1]);
  680. X                       return FALSE ;
  681. X                    }
  682. X                  lev=3 ;
  683. X             fr3: if(duel_eval(n->kids[3],v)) return TRUE ;
  684. X                  while(duel_eval(n->kids[2],v));
  685. X             }
  686. X   default: duel_assert(0);
  687. X   }
  688. X   return FALSE ;
  689. X#undef lev
  690. X}
  691. X
  692. XFUNC bool duel_eval(tnode *n,tvalue *v)
  693. X{
  694. X   tvalue u,tmp ;
  695. X   bool ok=FALSE ;
  696. X   tnode *prev_loc ;
  697. X
  698. X   if(!n) return FALSE ;
  699. X   prev_loc=duel_set_eval_loc(n);        /* set current eval node, save prev */
  700. X   if(n->eval.level==0) n->eval.level=1 ; /* indicate node is 'active' */
  701. X
  702. X   switch(n->node_kind) {
  703. X      case NK_CONST: /* return a 'value' node made of this constant */
  704. X         if(n->eval.level==1) {
  705. X            n->eval.level=2 ;
  706. X            *v=n->cnst ;
  707. X            ok=TRUE ;
  708. X         }
  709. X      break ;
  710. X      case NK_NAME:
  711. X         if(n->eval.level==1) {
  712. X            n->eval.level=2 ;
  713. X            duel_eval_name(n->name,v);
  714. X            ok=TRUE ;
  715. X         }
  716. X      break ;
  717. X      case NK_OP:
  718. X         switch(n->op_kind) {
  719. X          case OPK_SUNARY:              /* special unary ops */
  720. X             if(n->op=='#') {
  721. X                 int count=0 ;
  722. X                 if(n->eval.level==1) {
  723. X                     while(duel_eval(n->kids[0],v)) count++ ;
  724. X                     v->val_kind=VK_RVALUE ;
  725. X                     v->ctype=ctype_int ;
  726. X                     v->u.rval_int=count ;
  727. X                     sprintf(v->symb_val,"%d",count);
  728. X                     n->eval.level=2 ;
  729. X                     ok=TRUE ;
  730. X                 }
  731. X             }
  732. X             else 
  733. X             if(n->op==OP_AND) {
  734. X                 if(n->eval.level==1) { int result=1 ;
  735. X                     while(duel_eval(n->kids[0],v)) {
  736. X                         if(!duel_mk_logical(v,"&&/x")) {
  737. X                             stop_eval(n->kids[0]);
  738. X                             result=0 ;
  739. X                             break ;
  740. X                         }
  741. X                     }
  742. X                     v->val_kind=VK_RVALUE ;
  743. X                     v->ctype=ctype_int ;
  744. X                     v->u.rval_int=result ;
  745. X                     sprintf(v->symb_val,"%d",result);
  746. X                     n->eval.level=2 ;
  747. X                     ok=TRUE ;
  748. X                 }
  749. X             }
  750. X             else 
  751. X             if(n->op==OP_OR) {
  752. X                 if(n->eval.level==1) { int result=0 ;
  753. X                     while(duel_eval(n->kids[0],v)) {
  754. X                         if(duel_mk_logical(v,"||/x")) {
  755. X                             stop_eval(n->kids[0]);
  756. X                             result=1 ;
  757. X                             break ;
  758. X                         }
  759. X                     }
  760. X                     v->val_kind=VK_RVALUE ;
  761. X                     v->ctype=ctype_int ;
  762. X                     v->u.rval_int=result ;
  763. X                     sprintf(v->symb_val,"%d",result);
  764. X                     n->eval.level=2 ;
  765. X                     ok=TRUE ;
  766. X                 }
  767. X             }
  768. X             else 
  769. X             if(n->op==OP_SIZ) {
  770. X                 if(n->eval.level==1) {
  771. X                     duel_assert(n->kids[0]->node_kind==NK_CTYPE);
  772. X                     v->val_kind=VK_RVALUE ;
  773. X                     v->ctype=ctype_size_t ;
  774. X                     v->u.rval_size_t=n->kids[0]->ctype->size ;
  775. X                     n->eval.level=2 ;
  776. X                     ok=TRUE ;
  777. X                 }
  778. X             }
  779. X             else duel_assert(0);
  780. X          break ;
  781. X          case OPK_UNARY:
  782. X            if(!duel_eval(n->kids[0],v)) break ;
  783. X            duel_apply_unary_op(n->op,v);
  784. X            ok=TRUE ;
  785. X          break ;
  786. X          case OPK_POST_UNARY:
  787. X            if(!duel_eval(n->kids[0],v)) break ;
  788. X            duel_apply_post_unary_op(n->op,v);
  789. X            ok=TRUE ;
  790. X          break ;
  791. X          case OPK_BIN:    /* a+b, compute and hold a, iterate on b, redo a */
  792. X             while(n->eval.level==2 || duel_eval(n->kids[0],&n->eval.v1)) {
  793. X                n->eval.level=2 ;  /* left side active op in vals[0] */
  794. X                while(duel_eval(n->kids[1],&u)) {
  795. X                  tmp= n->eval.v1 ;  /* copy left val, it is destoryed*/
  796. X                  ok=duel_apply_bin_op(n->op,&tmp,&u,v);
  797. X                  if(ok) goto done;
  798. X                }
  799. X                n->eval.level=1 ;   /*left side val no longer valid, re-eval*/
  800. X             }
  801. X          break ;
  802. X          case OPK_SBIN:   /* a,b etc, special ops */
  803. X             ok=duel_eval_sbin(n,v) ;
  804. X          break ;
  805. X          case OPK_TRI: 
  806. X             ok=duel_eval_tri(n,v) ;
  807. X          break ;
  808. X          case OPK_QUAD: 
  809. X             ok=duel_eval_quad(n,v) ;
  810. X          break ;
  811. X          case OPK_CAST:
  812. X             duel_assert(n->kids[0]->node_kind==NK_CTYPE);
  813. X             if(!duel_eval(n->kids[1],v)) break ;
  814. X             duel_do_cast(n->kids[0]->ctype,v);
  815. X             ok=TRUE ;
  816. X          break ;
  817. X          case OPK_ASSIGN: 
  818. X             duel_gen_error("modified assignment is not supported yet",0);
  819. X          case OPK_FUNC: 
  820. X             ok=eval_func_call(n,v) ;
  821. X          break ;
  822. X          default: duel_assert(0);
  823. X         }
  824. X      break ;
  825. X      default: duel_assert(0);
  826. X   }
  827. Xdone:
  828. X   if(!ok) n->eval.level=0 ;  /* no other val available */
  829. X   duel_set_eval_loc(prev_loc);
  830. X   return ok ;
  831. X}
  832. X
  833. X
  834. SHAR_EOF
  835. $TOUCH -am 0113165193 src/eval.c &&
  836. chmod 0644 src/eval.c ||
  837. echo "restore of src/eval.c failed"
  838. set `wc -c src/eval.c`;Wc_c=$1
  839. if test "$Wc_c" != "27680"; then
  840.     echo original size 27680, current size $Wc_c
  841. fi
  842. echo "End of part 4, continue with part 5"
  843. exit 0
  844.