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