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