C:/Users/Dennis/src/lang/bertrand/BERTRAND/bertrand/names.c

Go to the documentation of this file.
00001 /***********************************************************************
00002  *
00003  * Manage global hierarchical name space
00004  *
00005  **********************************************************************/
00006 
00007 #include "def.h"
00008 
00009 NAME_NODE *global_names;        /* root of global name space */
00010 
00011 /***********************************************************************
00012  *
00013  * Put names into name space.
00014  * If name already exists, increment its reference count.
00015  * Name space is stored as a tree.
00016  *
00017  * entry:       name string
00018  *              parent name space, to insert into
00019  *              type of name (op field for node)
00020  *
00021  * exit:        return pointer to name node
00022  *
00023  **********************************************************************/
00024 NODE *
00025 name_put(name, space, type)
00026 char *name;             /* identifier name */
00027 NAME_NODE *space;       /* parent name space node */
00028 OP *type;               /* type field for this name */
00029 {
00030 extern OP *undeclared_prim;     /* from primitive.c */
00031 char *char_copy();              /* from util.c */
00032 NODE *node_new();               /* from expr.c */
00033 
00034 register NAME_NODE *curr;
00035 register NAME_NODE *prev = NULL;
00036 register NAME_NODE *nn;
00037 register int val;
00038 
00039 #ifdef DEBUG
00040 printf("insert new name: %s'%s\n", name, type->pname);
00041 #endif
00042 
00043 if (!type) {    /* no type specified */
00044     fprintf(stderr, "name: %s\n", name);
00045     error("no type specified");
00046     }
00047 
00048 if (!space) {   /* no space specified */
00049     fprintf(stderr, "name: %s\n", name);
00050     error("no name space specified");
00051     }
00052 curr = space->child;
00053 
00054 /* link into name space */
00055 while(curr) {
00056     val = strcmp(curr->pval, name);
00057     if (val == 0) {             /* name already exists */
00058         curr->refs++;
00059         if (curr->op == undeclared_prim) curr->op = type;
00060         else if (type != undeclared_prim && curr->op != type) {
00061             fprintf(stderr, "name: %s, types: %s & %s\n",
00062                 name, curr->op->pname, type->pname);
00063             error("name with two different types!");
00064             }
00065         return (NODE *) curr;
00066         }
00067     if (val > 0) break;         /* insert here */
00068     /* otherwise, look at next node in list */
00069     prev = curr;
00070     curr = curr->next;
00071     }
00072 nn = (NAME_NODE *) node_new();
00073 nn->next = curr;
00074 if (prev) prev->next = nn;
00075 else space->child = nn;
00076 
00077 nn->op = type;
00078 nn->parent = space;
00079 nn->child = (NAME_NODE *) NULL;
00080 nn->pval = char_copy(name);
00081 nn->refs = 2;           /* One reference to this name */
00082                         /* plus parent reference */
00083 nn->value = (NODE *) NULL;
00084 nn->interest = 0;       /* Of no interest, yet */
00085 
00086 return((NODE *) nn);
00087 }
00088 
00089 /***********************************************************************
00090  *
00091  * Return a fresh pointer to a name.
00092  * Doesn't actually make a copy of a name, but it does increment
00093  * the reference count field.
00094  *
00095  * entry:       pointer to name node to be copied.
00096  *
00097  * exit:        pointer to same node.
00098  *
00099  ******************************************************************/
00100 NAME_NODE *
00101 name_copy(on)
00102 NAME_NODE *on;          /* old name */
00103 {
00104 on->refs++;
00105 return on;
00106 }
00107 
00108 /***********************************************************************
00109  *
00110  * Remove a reference to a name.
00111  * Decrements the reference count field.
00112  * If zero, then actually deletes the name.
00113  *
00114  * entry:       pointer to name node to be freed.
00115  *
00116  ******************************************************************/
00117 void
00118 name_free(fn)
00119 NAME_NODE *fn;          /* name to free */
00120 {
00121 void node_free();       /* from expr.c */
00122 void expr_free();       /* from expr.c */
00123 NAME_NODE *ch, *nch;    /* children */
00124 
00125 if (0 == --(fn->refs)) {
00126     /* actually delete this node */
00127     for (ch = fn->child; ch; ch = nch) {        /* free children */
00128         nch = ch->next;
00129         name_free(ch);
00130         }
00131     if (fn->value) expr_free(fn->value);        /* free value */
00132     node_free((NODE *) fn);
00133     }
00134 }
00135 
00136 /***********************************************************************
00137  *
00138  * Insert one name space into another.
00139  * Used to instantiate a rule.
00140  *
00141  * entry: space to insert, and space to insert into
00142  *        if space to be inserted into is null,
00143  *        makes a copy of space to insert
00144  *
00145  ******************************************************************/
00146 NAME_NODE *
00147 name_space_insert(ins, space)
00148 NAME_NODE *ins;         /* name space to be inserted */
00149 NAME_NODE *space;       /* name space to insert into */
00150 {
00151 NODE *node_new();               /* from expr.c */
00152 NODE *expr_copy();              /* from expr.c */
00153 extern OP *undeclared_prim;     /* from primitive.c */
00154 void name_print();              /* forward reference */
00155 register NAME_NODE *in, *sn;
00156 register NAME_NODE *pn = (NAME_NODE *) NULL;    /* previous */
00157 int cmpval;                     /* result of string comparison */
00158 
00159 if (!ins) return space;
00160 in = ins->child;
00161 if (!space) {   /* create dummy parent */
00162     space = (NAME_NODE *) node_new();
00163     space->op = ins->op;
00164     space->next = (NAME_NODE *) NULL;
00165     space->parent = (NAME_NODE *) NULL;
00166     space->child = (NAME_NODE *) NULL;
00167     space->pval = ins->pval;
00168 /*  space->value = ins->value; */
00169     space->value = (NODE *) NULL;
00170     space->refs = 1;
00171     space->interest = ins->interest;
00172     }
00173 sn = space->child;
00174 
00175 while (in) {    /* more nodes to insert */
00176     if (sn) cmpval = strcmp(sn->pval, in->pval);
00177     else cmpval = 1;
00178     if (cmpval < 0) {           /* skip node in space to insert into */
00179         pn = sn;
00180         sn = sn->next;
00181         }
00182     else if (cmpval > 0) {      /* insert here */
00183         if (in->op != undeclared_prim) {        /* parameter */
00184             if (in->value->op->arity & OP_NAME) /* set value fields */
00185                 name_space_insert(in, in->value);
00186             }
00187         else {          /* local variable */
00188             register NAME_NODE *tn = name_space_insert(in, (NAME_NODE *) NULL);
00189             tn->next = sn;
00190             tn->parent = space;
00191             in->value = (NODE *) tn;
00192             if (pn) pn->next = tn;
00193             else space->child = tn;
00194             pn = tn;
00195             }
00196         in = in->next;
00197         }
00198     else {                      /* name exists in both spaces */
00199         if (in->op != undeclared_prim) {        /* parameter */
00200             if (sn->value) {
00201                 fprintf(stderr, "parameter: ");
00202                 name_print(in);
00203                 fprintf(stderr, ", bound variable: ");
00204                 name_print(sn);
00205                 fprintf(stderr, "\n");
00206                 error("parameter has already been bound a value!");
00207                 }
00208             sn->value = expr_copy(in->value);
00209             if (in->value->op->arity & OP_NAME) /* set value fields */
00210                 name_space_insert(in, in->value);
00211             }
00212         else {
00213             sn->child = name_space_insert(in, sn)->child;
00214             in->value = (NODE *) sn;
00215             pn = sn;
00216             }
00217         in = in->next;
00218         sn = sn->next;
00219         }
00220     }
00221 return space;
00222 }
00223 
00224 /***********************************************************************
00225  *
00226  * Print out names.
00227  * qname_print is a recursive utility function.
00228  * name_print is the main entry point.
00229  * name_space_print dumps the entire name space tree.
00230  *
00231  ******************************************************************/
00232 void
00233 qname_print(qn)
00234 NAME_NODE *qn;          /* a single qualified name */
00235 {
00236 if (qn->parent) {
00237     qname_print(qn->parent);
00238     if (qn->parent->pval) fprintf(stderr, ".");
00239     }
00240 if (qn->pval) fprintf(stderr, "%s", qn->pval);
00241 }
00242 
00243 void
00244 name_print(fn)
00245 NAME_NODE *fn;  /* a full name */
00246 {
00247 qname_print(fn);
00248 if (fn->op->pname[0]) fprintf(stderr, "'%s", fn->op->pname);
00249 }
00250 
00251 name_space_print(ns)
00252 NAME_NODE *ns;
00253 {
00254 void expr_print();      /* from expr.c */
00255 register NAME_NODE *nn = ns;
00256 while(nn) {
00257     if (nn->pval) fprintf(stderr, " %s", nn->pval);
00258     if (nn->op->pname[0]) fprintf(stderr, "'%s", nn->op->pname);
00259     if (nn->value) {
00260         fprintf(stderr, "=");
00261         expr_print(nn->value);
00262         }
00263     if (nn->child) {
00264         fprintf(stderr, "(");
00265         name_space_print(nn->child);
00266         fprintf(stderr, ")");
00267         }
00268     nn = nn->next;
00269     }
00270 }
00271 
00272 /***********************************************************************
00273  *
00274  * Compare two names "lexically".
00275  * Return 0 if they are identically the name name.
00276  *
00277  ******************************************************************/
00278 int
00279 name_compare(n1, n2)
00280 NAME_NODE *n1, *n2;
00281 {
00282 if (n1 == n2) return 0;         /* same name */
00283 /* TO DO: this should do something more intelligent */
00284 if (n1 > n2) return 1;
00285 else return -1;
00286 }

Generated on Fri Jan 25 09:58:43 2008 for Bertrand by  doxygen 1.5.4