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

Go to the documentation of this file.
00001 #include "def.h"
00002 
00003 /*************************************************************
00004  *
00005  *  Define a primitive operator or type.
00006  *  Insert in operator tables (if not null).
00007  *  Return pointer to operator node.
00008  *
00009  *************************************************************/
00010 
00011 OP *
00012 primitive(name, arity, super, oplist, eval)
00013 char *name;             /* name of primitive */
00014 short arity;            /* kind of operator */
00015 OP *super;              /* supertype */
00016 OP **oplist;            /* list to put it in */
00017 short eval;             /* special eval function */
00018 {
00019 void op_put();          /* from ops.c */
00020 OP *op_new();           /* from ops.c */
00021 
00022 OP *top = op_new(strlen(name));
00023 strcpy(top->pname, name);
00024 top->arity = arity;
00025 top->super = super;
00026 top->eval = eval;
00027 if (oplist) op_put(oplist, top);
00028 return top;
00029 }
00030 
00031 /***********************************************************************
00032  *
00033  * Initilize variables.
00034  *
00035  *    Create operators which describe names.
00036  *    Return initial subject expression.
00037  *
00038  ***********************************************************************/
00039 NODE *init()
00040 {
00041     /* op_new takes integer argument, which is length of name */
00042     OP *op_new();                       /* from ops.c */
00043     NODE *node_new();                   /* from expr.c */
00044     extern OP *name_op;                 /* from ops.c */
00045     extern OP *undeclared_prim;         /* from primitive.c */
00046     void primitive_init();              /* from primitive.c */
00047     void op_mem_free();                 /* from ops.c */
00048     extern NAME_NODE *global_names;     /* from names.c */
00049     extern int lineno, charno;          /* from scan.c */
00050     extern int verbose;                 /* from main.c */
00051 
00052     register TERM_NODE *insex;  /* initial subject expression */
00053     OP *main_op;                /* operator for initial subject expression */
00054     static char noname[] = "";          /* static so it won't go away */
00055 
00056     op_mem_free();              /* make sure operator memory is empty */
00057     primitive_init();           /* initialize all machine primitives */
00058 
00059     lineno = 1;
00060     charno = 0;
00061     verbose = FALSE;
00062 
00063     /* initial subject expression operator */
00064     main_op = primitive("main", NULLARY, (OP *) NULL, &name_op, 0);
00065 
00066     /* initialize global name space */
00067     global_names = (NAME_NODE *) node_new();
00068     global_names->op = undeclared_prim;
00069     global_names->next = (NAME_NODE *) NULL;
00070     global_names->parent = (NAME_NODE *) NULL;
00071     global_names->child = (NAME_NODE *) NULL;
00072     global_names->pval = noname;        /* no name. */
00073     global_names->refs = 1;     /* will never delete */
00074     global_names->interest = 0;
00075 
00076     /* create and return initial subject expression */
00077     insex = (TERM_NODE *) node_new();
00078     insex->op = main_op;
00079     insex->label = global_names;
00080     global_names->refs++;       /* since we have a pointer to it */
00081     insex->left = (NODE *) NULL;
00082     insex->right = (NODE *) NULL;
00083     return (NODE *) insex;
00084 }
00085 
00086 /***********************************************************************
00087  *
00088  * Routines to manage nodes for stacks.
00089  * Used for the parse and match stacks.
00090  *
00091  ***********************************************************************/
00092 
00093 #define NUM_ST     50           /* number of parse stack nodes to allocate */
00094 static SNODE *st_mem = NULL;            /* free parse stack nodes */
00095 static SNODE *all_st_mem = NULL;        /* pointer to all stack memory */
00096  
00097 /***********************************************************************
00098  *
00099  * Get a stack node.  Allocate memory for it if necessary.
00100  *
00101  * exit:        pointer to a fresh stack node
00102  *
00103  ***********************************************************************/
00104 SNODE *
00105 st_get()
00106 {
00107 char *malloc();
00108 SNODE *temp;            /* node to be allocated to stack */ 
00109 
00110 if (!st_mem) {
00111     register int i;
00112 #   ifdef DEBUG
00113     printf("allocating stack nodes\n");
00114 #   endif
00115     st_mem = (SNODE *) malloc((sizeof (SNODE *)) + (NUM_ST * sizeof (SNODE)));
00116     if (!st_mem) error("out of memory");
00117 
00118     /* Save pointer to the beginning of this chunk of memory and link
00119        it to other allocated chunks (to be freed at end of program). */
00120     *((SNODE **) st_mem) = all_st_mem;;
00121     all_st_mem = st_mem; 
00122     /* real memory starts after first word */
00123     st_mem = (SNODE *) (((char *)st_mem) + sizeof(SNODE *));
00124 
00125     for (i = 0; i < NUM_ST-1 ; i++)     /* link list */
00126         st_mem[i].next = &st_mem[i+1];
00127     st_mem[NUM_ST-1].next = NULL;
00128     }
00129 
00130 temp = st_mem;
00131 st_mem = st_mem->next;
00132 return temp;
00133 }
00134 
00135 /***********************************************************************
00136  *
00137  * Free a stack node.
00138  *
00139  * exit:        free list counter incremented
00140  *              node pushed back on free list
00141  *              return new top of free list
00142  *
00143  ***********************************************************************/
00144 void
00145 st_free(p)
00146 SNODE *p;
00147 {
00148 p->next = st_mem;
00149 st_mem = p;
00150 }
00151 
00152 
00153 /***********************************************************************
00154  *
00155  * Free all stack nodes.
00156  *
00157  ***********************************************************************/
00158 void
00159 st_mem_free()
00160 {
00161 register SNODE *t;
00162 void free();
00163 
00164 while(all_st_mem) {
00165     t = *((SNODE **) all_st_mem);
00166     free(all_st_mem);
00167     all_st_mem = t;
00168     }
00169 st_mem = (SNODE *) NULL;
00170 }
00171 
00172 /*********************************************************************
00173  *
00174  * Routines to manage character string memory.
00175  * For the time being, these are very simple.
00176  * TO DO: make these more efficient.
00177  *
00178  *********************************************************************/
00179 
00180 /*********************************************************************
00181  *
00182  * Allocate a new character string and copy the contents of
00183  * the argument string into it.
00184  *
00185  * returns:     pointer to new string
00186  *
00187  *********************************************************************/
00188 char *
00189 char_copy(s)
00190 char *s;
00191 {
00192 char *t;        /* new character string */
00193 int ss;         /* size of argument string s */
00194 char *calloc();
00195 
00196 ss = strlen(s) + 1;     /* one extra for null terminator */
00197 t = (char *) calloc(ss, sizeof(char));
00198 if (!t) error("out of character string memory");
00199 strcpy(t, s);
00200 return(t);
00201 }
00202 
00203 
00204 
00205 /***********************************************************************
00206  *
00207  * Free a character string.
00208  * String must have been allocated by char_copy (or calloc).
00209  *
00210  ***********************************************************************/
00211 void
00212 char_free(s)
00213 char *s;
00214 {
00215     void free();
00216 
00217     free(s);
00218 }
00219 
00220 /***********************************************************************
00221  *
00222  * Error routine
00223  *
00224  * exit:        abort program
00225  *
00226  ***********************************************************************/
00227 void
00228 error(s)
00229 char *s;
00230 {
00231 extern int lineno, charno;      /* from scanner.c */
00232 extern char *infilename;
00233 fflush(stdout);
00234 if (lineno) {
00235     if (charno == 0) fprintf(stderr, "file %s, line %d: ", infilename, lineno-1);
00236     else fprintf(stderr, "file %s, line %d, before position %d: ",
00237         infilename, lineno, charno);
00238     }
00239 fprintf(stderr, "%s\n", s);
00240 fflush(stderr);
00241 exit(1);
00242 }
00243 
00244 /* flush stderr output buffer.  Used only during debugging */
00245 void fl() { fprintf(stderr, "\n"); fflush(stderr); }

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