theScript = Script.Make(Script.The.asString)
result = theScript.DoIt( { ... arguments ...} )
The first routine was simple to solve because only one call was made per iteration:
int locate_endpoint(v, vo, r)
point_t *v;
point_t *vo;
int r;
{
node_t *rptr = &qs[r];
switch (rptr->nodetype)
{
case T_SINK:
return rptr->trnum;
case T_Y:
if (_greater_than(v, &rptr->yval)) /* above */
return locate_endpoint(v, vo, rptr->right);
else if (_equal_to(v, &rptr->yval)) /* the point is already */
{ /* inserted. */
if (_greater_than(vo, &rptr->yval)) /* above */
return locate_endpoint(v, vo, rptr->right);
else
return locate_endpoint(v, vo, rptr->left); /* below */
}
else
return locate_endpoint(v, vo, rptr->left); /* below */
...
}
The approach I took was to set up an infinite loop, reassigning the
value of variable "r" as necessary:
v = SELF.Get(0)
vo = SELF.Get(1)
r = SELF.Get(2)
while (TRUE)
rptr = _qs.Get(r)
nt = rptr.Get(0)
if (nt = "T_SINK") then
return rptr.Get(3)
elseif (nt = "T_Y") then
if (av.Run("P.GT",{v,rptr.Get(2)})) then
r = rptr.Get(6)
elseif (v = rptr.Get(2)) then
if (av.Run("P.GT",{vo,rptr.Get(2)})) then
r = rptr.Get(6)
else
r = rptr.Get(5)
end
else
r = rptr.Get(5)
end
...
end
The other routine was more difficult to solve because it made multiple
calls per iteration:
static int traverse_polygon(mcur, trnum, from, dir)
int mcur;
int trnum;
int from;
int dir;
{
...
int do_switch = FALSE;
if ((trnum <= 0) || visited[trnum])
return 0;
visited[trnum] = TRUE;
if ((t->u0 <= 0) && (t->u1 <= 0))
{
if ((t->d0 > 0) && (t->d1 > 0)) /* downward opening triangle */
{
v0 = tr[t->d1].lseg;
v1 = t->lseg;
if (from == t->d1)
{
do_switch = TRUE;
mnew = make_new_monotone_poly(mcur, v1, v0);
traverse_polygon(mcur, t->d1, trnum, TR_FROM_UP);
traverse_polygon(mnew, t->d0, trnum, TR_FROM_UP);
}
...
}
I solved the problem by using a Stack object to store arguments:
'**** initialize stack
theStack = Stack.Make
theStack.Push({SELF.Get(0),SELF.Get(1),SELF.Get(2),SELF.GET(3)})
retval = ""
...
while (TRUE)
if (theStack.IsEmpty) then
return retval
end
arglist = theStack.Pop
mcur = arglist.Get(0)
trnum = arglist.Get(1)
from = arglist.Get(2)
dir = arglist.Get(3)
do_switch = FALSE
cond = FALSE
if (trnum <= 0) then
cond = TRUE
elseif (visited.Get(trnum)) then
cond = TRUE
else
t = _tr.Get(trnum)
end
if (cond) then
retval = 0
continue
end
visited.Set(trnum,TRUE)
sn = sn + 1
av.SetStatus(100*sn/sd)
if ((t.Get(4) <= 0) and (t.Get(5) <= 0)) then
if ((t.Get(6) > 0) and (t.Get(7) > 0)) then
'**** downward opening triangle
v0 = _tr.Get(t.Get(7)).Get(0)
v1 = t.Get(0)
if (from = t.Get(7)) then
do_switch = TRUE
mnew = av.Run("P.NewMonotone",{mcur, v1, v0})
theStack.Push({mnew,t.Get(6),trnum,"TR_FROM_UP"})
theStack.Push({mcur,t.Get(7),trnum,"TR_FROM_UP"})
...
end
Note that because of the nature of Stacks (Last-In-First-Out), the order
of the Push requests is reversed.If you want to take a better look at the routines, you can access them via the Web. The original C code may be downloaded at:
http://www.cs.unc.edu/~dm/CODE/GEM/chapter.html
and the Avenue code may be downloaded at:
http://www.pierssen.com/arcview/esoteric.htm