1: #include "../h/rt.h"
   2: 
   3: /*
   4:  * x <-> y - swap values of x and y.
   5:  * Reverses swap if resumed.
   6:  */
   7: 
   8: rswap(nargs, arg2v, arg2, arg1, arg0)
   9: int nargs;
  10: struct descrip arg2v, arg2, arg1, arg0;
  11:    {
  12:    register union block *bp1, *bp2;
  13:    int adj1, adj2;
  14: 
  15:    SetBound;
  16:    /*
  17:     * x and y must be variables.
  18:     */
  19:    if (QUAL(arg1) || !VAR(arg1))
  20:       runerr(111, &arg1);
  21:    if (QUAL(arg2) || !VAR(arg2))
  22:       runerr(111, &arg2);
  23:    /*
  24:     * Make copies of x and y as variables in arg0 and arg2v.
  25:     */
  26:    arg0 = arg1;
  27:    arg2v = arg2;
  28:    adj1 = adj2 = 0;
  29:    if (arg1.type == D_TVSUBS && arg2.type == D_TVSUBS) {
  30:       bp1 = BLKLOC(arg1);
  31:       bp2 = BLKLOC(arg2);
  32:       if (VARLOC(bp1->tvsubs.ssvar) == VARLOC(bp2->tvsubs.ssvar)) {
  33:          /*
  34:           * x and y are both substrings of the same string, set
  35:           *  adj1 and adj2 for use in locating the substrings after
  36:           *  an assignment has been made.  If x is to the right of y,
  37:           *  set adj1 := *x - *y, otherwise if y is to the right of x,
  38:           *  set adj2 := *y - *x.  Note that the adjustment values may
  39:           *  be negative.
  40:           */
  41:          if (bp1->tvsubs.sspos > bp2->tvsubs.sspos)
  42:             adj1 = bp1->tvsubs.sslen - bp2->tvsubs.sslen;
  43:          else if (bp2->tvsubs.sspos > bp1->tvsubs.sspos)
  44:             adj2 = bp2->tvsubs.sslen - bp1->tvsubs.sslen;
  45:             }
  46:       }
  47:    DeRef(arg1)
  48:    DeRef(arg2)
  49:    /*
  50:     * Do x := y
  51:     */
  52:    doasgn(&arg0, &arg2);
  53:    if (adj2 != 0)
  54:       /*
  55:        * y is to the right of x and the assignment x := y has shifted
  56:        *  the position of y.  Add adj2 to the position of y to account
  57:        *  for the replacement of x by y.
  58:        */
  59:       BLKLOC(arg2)->tvsubs.sspos += adj2;
  60:    doasgn(&arg2v, &arg1);
  61:    /*
  62:     * Do y := x
  63:     */
  64:    if (adj1 != 0)
  65:       /*
  66:        * x is to the right of y and the assignment y := x has shifted
  67:        *  the position of x.  Add adj2 to the position of x to account
  68:        *  for the replacement of y by x.
  69:        */
  70:       BLKLOC(arg1)->tvsubs.sspos += adj1;
  71:    /*
  72:     * Suspend x with the assignment in effect.
  73:     */
  74:    suspend();
  75:    /*
  76:     * If resumed, the assignments are undone.  Note that the string position
  77:     *  adjustments are identical to those done earlier.
  78:     */
  79:    doasgn(&arg0, &arg1);        /* restore x */
  80:    if (adj2 != 0)
  81:       BLKLOC(arg2)->tvsubs.sspos += adj2;
  82:    doasgn(&arg2v, &arg2);        /* restore y */
  83:    if (adj1 != 0)
  84:       BLKLOC(arg1)->tvsubs.sspos += adj1;
  85:    fail();
  86:    }
  87: 
  88: Opblockx(rswap,3,"<->",2)

Defined functions

rswap defined in line 8; used 1 times
  • in line 88
Last modified: 1984-11-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 482
Valid CSS Valid XHTML 1.0 Strict