+/*
+ * Find the end of a module name. Return nil if there is none
+ * in the given string.
+ */
+
+private String findModuleMark (s)
+String s;
+{
+ register char *p, *r;
+ register boolean done;
+
+ p = s;
+ done = false;
+ do {
+ if (*p == ':') {
+ done = true;
+ r = p;
+ } else if (*p == '\0') {
+ done = true;
+ r = nil;
+ } else {
+ ++p;
+ }
+ } while (not done);
+ return r;
+}
+
+/*
+ * Resolve a type reference by modifying to be the appropriate type.
+ *
+ * If the reference has a name, then it refers to an opaque type and
+ * the actual type is directly accessible. Otherwise, we must use
+ * the type reference string, which is of the form "module:{module:}name".
+ */
+
+public resolveRef (t)
+Symbol t;
+{
+ register char *p;
+ char *start;
+ Symbol s, m, outer;
+ Name n;
+
+ if (t->name != nil) {
+ s = t;
+ } else {
+ start = t->symvalue.typeref;
+ outer = program;
+ p = findModuleMark(start);
+ while (p != nil) {
+ *p = '\0';
+ n = identname(start, true);
+ find(m, n) where m->block == outer endfind(m);
+ if (m == nil) {
+ p = nil;
+ outer = nil;
+ s = nil;
+ } else {
+ outer = m;
+ start = p + 1;
+ p = findModuleMark(start);
+ }
+ }
+ if (outer != nil) {
+ n = identname(start, true);
+ find(s, n) where s->block == outer endfind(s);
+ }
+ }
+ if (s != nil and s->type != nil) {
+ t->name = s->type->name;
+ t->class = s->type->class;
+ t->type = s->type->type;
+ t->chain = s->type->chain;
+ t->symvalue = s->type->symvalue;
+ t->block = s->type->block;
+ }
+}
+
+public integer regnum (s)