Past[dir, place, ap.location] => {
IF dir = $left
OR dir = $right
THEN
ap.location.x ← ap.location.x + amount
ELSE
ap.location.y ← ap.location.y + amount;
};
Past[dir, place, urPos] => {
head, tail: CD.Position ← [0, 0];
newHead, newTail: CD.Position;
newDir: Stretch.Direction;
placeX, placeY: INT;
newPlace: INT;
-- create a vector starting at the stretch place and pointing 1 unit in the stretch direction
placeX ← place - ap.location.x;
placeY ← place - ap.location.y;
SELECT dir
FROM
up => {tail.y ← placeY; head.y ← placeY + 1;};
down => {tail.y ← placeY; head.y ← placeY - 1;};
right => {tail.x ← placeX; head.x ← placeX + 1;};
left => {tail.x ← placeX; head.x ← placeX - 1;};
ENDCASE;
[newTail, newHead] ← MapVector[tail, head, ap];
-- now use the vector to determine location & direction to stretch
IF tail.x = 0
THEN
newPlace ← newTail.y
ELSE
newPlace ← newTail.x;
SELECT
TRUE
FROM
newHead.x > newTail.x => newDir ← $right;
newHead.x < newTail.x => newDir ← $left;
newHead.y > newTail.y => newDir ← $up;
newHead.y < newTail.y => newDir ← $down;
ENDCASE => ERROR;
[newOb, msg] ← Stretch.DoStretch[ap.ob, design, newPlace, newDir, amount];
IF newOb = NIL THEN RETURN[NIL, msg];
ap.ob ← newOb;
};