Article View: comp.lang.misc
Article #5335Iteration without coroutines
From: Chris Torek
Date: Mon, 21 Mar 1988 01:26
Date: Mon, 21 Mar 1988 01:26
123 lines
3979 bytes
3979 bytes
In article <1139@PT.CS.CMU.EDU> edw@IUS1.CS.CMU.EDU (Eddie Wyatt) writes:
> But do you need coroutines to implimented generlized iteration. ...
> void iterate_inorder(root,func)
> TREE *root;
> void (*func)();
> {
> if (root != NULLPTR(TREE))
> {
> iterate_inorder(root->left,func);
> func(root->val);
> iterate_inorder(root->right,func);
> }
> }
>
> I do see one problem though, which is dealing with variable
> referenced inside the loop. They would have to become
> global.
This replaces coroutine iteration with stack recursion; I think the
two are provably equivalent (but I am not going to [try to] prove it
here).
The variables need not be global; and indeed, I added a similar routine
to Gosling Emacs in a situation in which I wanted the variables to be
local. The code (real, working, code, in all its gory, I mean glory)
is as follows:
/*
* Iterate over a table, calling the given function with each entry
* and with the given pointer. The table is first sorted.
*/
TableIterate(t, f, a)
register struct table *t;
register int (*f)();
caddr_t a; /* this is a `generic pointer' */
{
register int n;
if (t->t_sorted <= 0)
SortEntries(t);
for (n = 0; n < t->t_size; n++)
(*f)(t->t_ents[n], a);
}
[and in another file]
/*
* Apropos matching is carried out in a context consisting of a keyword,
* the original buffer, and a flag that is set whenever a buffer specific
* variable is matched.
*/
struct AproposContext {
char *keyword;
struct buffer *old;
int AnyBufferSpecific;
};
static
AproposVarMatch(te, context)
struct tentry *te;
caddr_t context;
{
register struct AproposContext *c = (struct AproposContext *)context;
struct Binding *b;
int type;
char buf[100];
/* ignore it if the name matches nowhere */
if (sindex(te->te_name, c->keyword) == 0)
return;
/* or if the variable is unbound */
if ((b = tetod(te, struct VariableName *)->v_binding) == NULL)
return;
/* footnote any variables that are buffer specific */
if (b->BufferSpecific || b->IsDefault ||
b->IsSystem && b->b.b_Default) {
type = '*';
c->AnyBufferSpecific = 1;
} else
type = ' ';
/* print name and (truncated to `reasonable' length) value */
(void) sprintfl(buf, sizeof buf, "%-30s%c = %s\n", te->te_name,
type, CanonicalValue(b, c->old));
InsStr(buf);
}
[AproposMacMatch deleted; it is much the same]
static
DoApropos(context)
caddr_t context;
{
register struct AproposContext *c = (struct AproposContext *)context;
c->AnyBufferSpecific = 0;
TableIterate(&MacTable, AproposMacMatch, c);
TableIterate(&VarTable, AproposVarMatch, c);
if (c->AnyBufferSpecific)
InsCStr("\n*Buffer Specific\n", 18);
}
static
Apropos()
{
struct AproposContext context;
if ((context.keyword = getnbstr(": apropos keyword: ")) == NULL)
return (0);
context.old = bf_cur;
ShowSomething("Help", (char *)NULL, DoApropos, (caddr_t)&context);
return (0);
}
[Incidentally, ShowSomething itself uses another similar iterator.
Perhaps the fanciest of all is in the routine that gives help for
partial matches; when I rewrote it, I made it produce a column-sorted
list of possible matches, where the columns are of the width deemed
most appropriate given the length of the matching strings. But that
one uses global variables.]
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
Technical Details
Message-ID:
<10744@mimsy.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!purdue!umd5!mimsy!chrisReferences:
<2827@enea.se> <1557@pasteur.Berkeley.Edu> <3764@bloom-beacon.MIT.EDU> <1139@PT.CS.CMU.EDU>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!purdue!umd5!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.misc Subject: Iteration without coroutines Message-ID: <10744@mimsy.UUCP> Date: 21 Mar 88 01:26:09 GMT References: <2827@enea.se> <1557@pasteur.Berkeley.Edu> <3764@bloom-beacon.MIT.EDU> <1139@PT.CS.CMU.EDU> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 123