/[cvs]/stack/stack.c
ViewVC logotype

Diff of /stack/stack.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.10 by masse, Tue Jan 8 17:31:27 2002 UTC revision 1.16 by masse, Thu Jan 31 22:32:59 2002 UTC
# Line 11  Line 11 
11    
12  typedef struct stack_item  typedef struct stack_item
13  {  {
14    enum {value, string, ref, func, symbol, list} type;    enum {
15        value,                      /* Integer */
16        string,
17        ref,            /* Reference (to an element in the hash table) */
18        func,                       /* Function pointer */
19        symbol,
20        list
21      } type;                       /* Tells what kind of stack element */
22      
23    union {    union {
24      void* ptr;      void* ptr;                  /* Pointer to the content */
25      int val;      int val;                    /* ...or an integer */
26    } content;    } content;                    /* Stores a pointer or an integer */
27    
28    char* id;    char* id;                     /* Symbol name */
29    struct stack_item* next;    struct stack_item* next;      /* Next element */
30  } stackitem;  } stackitem;
31    
32    
33  typedef stackitem* hashtbl[HASHTBLSIZE];  typedef stackitem* hashtbl[HASHTBLSIZE]; /* Hash table declaration */
34  typedef void (*funcp)(stackitem**);  typedef void (*funcp)(stackitem**); /* Function pointer declaration */
35    
36    
37    /* Initiates a newly created hash table. */
38  void init_hashtbl(hashtbl out_hash)  void init_hashtbl(hashtbl out_hash)
39  {  {
40    long i;    long i;
# Line 33  void init_hashtbl(hashtbl out_hash) Line 43  void init_hashtbl(hashtbl out_hash)
43      out_hash[i]= NULL;      out_hash[i]= NULL;
44  }  }
45    
46    /* Returns a pointer to an element in the hash table. */
47  stackitem** hash(hashtbl in_hashtbl, const char* in_string)  stackitem** hash(hashtbl in_hashtbl, const char* in_string)
48  {  {
49    long i= 0;    long i= 0;
# Line 40  stackitem** hash(hashtbl in_hashtbl, con Line 51  stackitem** hash(hashtbl in_hashtbl, con
51    char key= 0;    char key= 0;
52    stackitem** position;    stackitem** position;
53        
54    while(1){    while(1){                     /* Hash in_string */
55      key= in_string[i++];      key= in_string[i++];
56      if(key=='\0')      if(key=='\0')
57        break;        break;
# Line 50  stackitem** hash(hashtbl in_hashtbl, con Line 61  stackitem** hash(hashtbl in_hashtbl, con
61    out_hash= out_hash%HASHTBLSIZE;    out_hash= out_hash%HASHTBLSIZE;
62    position= &(in_hashtbl[out_hash]);    position= &(in_hashtbl[out_hash]);
63    
64    while(1){    while(1){                     /* Return position if empty */
65      if(*position==NULL)      if(*position==NULL)
66        return position;        return position;
67            
68      if(strcmp(in_string, (*position)->id)==0)      if(strcmp(in_string, (*position)->id)==0) /* Return position if match */
69        return position;        return position;
70    
71      position= &((*position)->next);      position= &((*position)->next); /* Try next */
72    }    }
73  }  }
74    
75    /* Generic push function. */
76  int push(stackitem** stack_head, stackitem* in_item)  int push(stackitem** stack_head, stackitem* in_item)
77  {  {
78    in_item->next= *stack_head;    in_item->next= *stack_head;
# Line 69  int push(stackitem** stack_head, stackit Line 80  int push(stackitem** stack_head, stackit
80    return 1;    return 1;
81  }  }
82    
83    /* Push a value on the stack. */
84  int push_val(stackitem** stack_head, int in_val)  int push_val(stackitem** stack_head, int in_val)
85  {  {
86    stackitem* new_item= malloc(sizeof(stackitem));    stackitem* new_item= malloc(sizeof(stackitem));
# Line 79  int push_val(stackitem** stack_head, int Line 91  int push_val(stackitem** stack_head, int
91    return 1;    return 1;
92  }  }
93    
94    /* Copy a string onto the stack. */
95  int push_cstring(stackitem** stack_head, const char* in_string)  int push_cstring(stackitem** stack_head, const char* in_string)
96  {  {
97    stackitem* new_item= malloc(sizeof(stackitem));    stackitem* new_item= malloc(sizeof(stackitem));
# Line 90  int push_cstring(stackitem** stack_head, Line 103  int push_cstring(stackitem** stack_head,
103    return 1;    return 1;
104  }  }
105    
106    /* Create a new hash entry. */
107  int mk_hashentry(hashtbl in_hashtbl, stackitem* in_item, const char* id)  int mk_hashentry(hashtbl in_hashtbl, stackitem* in_item, const char* id)
108  {  {
109    in_item->id= malloc(strlen(id)+1);    in_item->id= malloc(strlen(id)+1);
# Line 100  int mk_hashentry(hashtbl in_hashtbl, sta Line 114  int mk_hashentry(hashtbl in_hashtbl, sta
114    return 1;    return 1;
115  }  }
116    
117    /* Define a function a new function in the hash table. */
118  void def_func(hashtbl in_hashtbl, funcp in_func, const char* id)  void def_func(hashtbl in_hashtbl, funcp in_func, const char* id)
119  {  {
120    stackitem* temp= malloc(sizeof(stackitem));    stackitem* temp= malloc(sizeof(stackitem));
# Line 110  void def_func(hashtbl in_hashtbl, funcp Line 125  void def_func(hashtbl in_hashtbl, funcp
125    mk_hashentry(in_hashtbl, temp, id);    mk_hashentry(in_hashtbl, temp, id);
126  }  }
127    
128    /* Define a new symbol in the hash table. */
129  void def_sym(hashtbl in_hashtbl, const char* id)  void def_sym(hashtbl in_hashtbl, const char* id)
130  {  {
131    stackitem* temp= malloc(sizeof(stackitem));    stackitem* temp= malloc(sizeof(stackitem));
132        
133    temp->type= symbol;    temp->type= symbol;
   
134    mk_hashentry(in_hashtbl, temp, id);    mk_hashentry(in_hashtbl, temp, id);
135  }  }
136    
137    /* Push a reference to an entry in the hash table onto the stack. */
138  int push_ref(stackitem** stack_head, hashtbl in_hash, const char* in_string)  int push_ref(stackitem** stack_head, hashtbl in_hash, const char* in_string)
139  {  {
140    static void* handle= NULL;    static void* handle= NULL;
# Line 128  int push_ref(stackitem** stack_head, has Line 144  int push_ref(stackitem** stack_head, has
144    new_item->content.ptr= *hash(in_hash, in_string);    new_item->content.ptr= *hash(in_hash, in_string);
145    new_item->type= ref;    new_item->type= ref;
146    
147    if(new_item->content.ptr==NULL) {    if(new_item->content.ptr==NULL) { /* If hash entry empty */
148      if(handle==NULL)      if(handle==NULL)            /* If no handle */
149        handle= dlopen(NULL, RTLD_LAZY);            handle= dlopen(NULL, RTLD_LAZY);    
150    
151      symbol= dlsym(handle, in_string);      symbol= dlsym(handle, in_string); /* Get function pointer */
152      if(dlerror()==NULL)      if(dlerror()==NULL)         /* If existing function pointer */
153        def_func(in_hash, symbol, in_string);        def_func(in_hash, symbol, in_string); /* Store function pointer */
154      else      else
155        def_sym(in_hash, in_string);        def_sym(in_hash, in_string); /* Make symbol */
156                
157      new_item->content.ptr= *hash(in_hash, in_string);      new_item->content.ptr= *hash(in_hash, in_string); /* XXX */
158      new_item->type= ref;      new_item->type= ref;
159    }    }
160    
# Line 146  int push_ref(stackitem** stack_head, has Line 162  int push_ref(stackitem** stack_head, has
162    return 1;    return 1;
163  }  }
164    
165    /* Discard the top element of the stack. */
166  extern void toss(stackitem** stack_head)  extern void toss(stackitem** stack_head)
167  {  {
168    stackitem* temp= *stack_head;    stackitem* temp= *stack_head;
# Line 160  extern void toss(stackitem** stack_head) Line 177  extern void toss(stackitem** stack_head)
177    free(temp);    free(temp);
178  }  }
179    
180    /* Print newline. */
181  extern void nl()  extern void nl()
182  {  {
183    printf("\n");    printf("\n");
184  }  }
185    
186  void prin(stackitem** stack_head)  /* Prints the top element of the stack. */
187    void print_(stackitem** stack_head)
188  {  {
189    if((*stack_head)==NULL)    if((*stack_head)==NULL)
190      return;      return;
# Line 187  void prin(stackitem** stack_head) Line 206  void prin(stackitem** stack_head)
206    }    }
207  }  }
208    
209    /* Prints the top element of the stack and then discards it. */
210  extern void print(stackitem** stack_head)  extern void print(stackitem** stack_head)
211  {  {
212    prin(stack_head);    print_(stack_head);
213    toss(stack_head);    toss(stack_head);
214  }  }
215    
216  /* print_stack(stack); */  /* Only to be called by function printstack. */
217  void print_st(stackitem* stack_head, long counter)  void print_st(stackitem* stack_head, long counter)
218  {  {
219    if(stack_head->next != NULL)    if(stack_head->next != NULL)
220      print_st(stack_head->next, counter+1);      print_st(stack_head->next, counter+1);
221    
222    printf("%ld: ", counter);    printf("%ld: ", counter);
223    prin(&stack_head);    print_(&stack_head);
224    nl();    nl();
225  }  }
226    
227    /* Prints the stack. */
228  extern void printstack(stackitem** stack_head)  extern void printstack(stackitem** stack_head)
229  {  {
230    if(*stack_head != NULL) {    if(*stack_head != NULL) {
# Line 212  extern void printstack(stackitem** stack Line 233  extern void printstack(stackitem** stack
233    }    }
234  }  }
235    
236    /* If the top element is a reference, determine if it's a reference to a
237       function, and if it is, toss the reference and execute the function. */
238  extern void eval(stackitem** stack_head)  extern void eval(stackitem** stack_head)
239  {  {
240    funcp in_func;    funcp in_func;
# Line 228  extern void eval(stackitem** stack_head) Line 250  extern void eval(stackitem** stack_head)
250    }    }
251  }  }
252    
253    /* Parse input. */
254  int stack_read(stackitem** stack_head, hashtbl in_hash, char* in_line)  int stack_read(stackitem** stack_head, hashtbl in_hash, char* in_line)
255  {  {
256    char *temp, *rest;    char *temp, *rest;
# Line 238  int stack_read(stackitem** stack_head, h Line 261  int stack_read(stackitem** stack_head, h
261    temp= malloc(inlength);    temp= malloc(inlength);
262    rest= malloc(inlength);    rest= malloc(inlength);
263    
264    if((convert= sscanf(in_line, "\"%[^\"\n\r]\" %[^\n\r]", temp, rest)) >= 1)    do {
265      push_cstring(stack_head, temp);      /* If string */
266    else if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest)) >= 1)      if((convert= sscanf(in_line, "\"%[^\"\n\r]\" %[^\n\r]", temp, rest))) {
267      push_val(stack_head, itemp);        push_cstring(stack_head, temp);
268    else if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest)) >= 1)        break;
269      push_ref(stack_head, in_hash, temp);      }
270    else if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest)) >= 1)      /* If value */
271      if(*temp==';')      if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest))) {
272        eval(stack_head);        push_val(stack_head, itemp);
273          break;
274        }
275        /* Escape ';' with '\' */
276        if((convert= sscanf(in_line, "\\%c%[^\n\r]", temp, rest))) {
277          temp[1]= '\0';
278          push_ref(stack_head, in_hash, temp);
279          break;
280        }
281        /* If symbol */
282        if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest))) {
283            push_ref(stack_head, in_hash, temp);
284            break;
285        }
286        /* If ';' */
287        if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest)) && *temp==';') {
288          eval(stack_head);         /* Evaluate top element */
289          break;
290        }
291      } while(0);
292    
293    
294    free(temp);    free(temp);
295    
# Line 261  int stack_read(stackitem** stack_head, h Line 304  int stack_read(stackitem** stack_head, h
304    return 1;    return 1;
305  }  }
306    
307    /* Make a list. */
308  extern void pack(stackitem** stack_head)  extern void pack(stackitem** stack_head)
309  {  {
310    void* delimiter;    void* delimiter;
311    stackitem *iterator, *temp, *pack;    stackitem *iterator, *temp, *pack;
312    
313    if((*stack_head)==NULL)    if((*stack_head)==NULL)       /* No delimiter */
314      return;      return;
315    
316    delimiter= (*stack_head)->content.ptr;    delimiter= (*stack_head)->content.ptr; /* Get delimiter */
317    toss(stack_head);    toss(stack_head);
318    
319    iterator= *stack_head;    iterator= *stack_head;
320    
321      /* Search for first delimiter */
322    while(iterator->next!=NULL && iterator->next->content.ptr!=delimiter)    while(iterator->next!=NULL && iterator->next->content.ptr!=delimiter)
323      iterator= iterator->next;      iterator= iterator->next;
324    
325      /* Extract list */
326    temp= *stack_head;    temp= *stack_head;
327    *stack_head= iterator->next;    *stack_head= iterator->next;
328    iterator->next= NULL;    iterator->next= NULL;
# Line 284  extern void pack(stackitem** stack_head) Line 330  extern void pack(stackitem** stack_head)
330    if(*stack_head!=NULL && (*stack_head)->content.ptr==delimiter)    if(*stack_head!=NULL && (*stack_head)->content.ptr==delimiter)
331      toss(stack_head);      toss(stack_head);
332    
333      /* Push list */
334    pack= malloc(sizeof(stackitem));    pack= malloc(sizeof(stackitem));
335    pack->type= list;    pack->type= list;
336    pack->content.ptr= temp;    pack->content.ptr= temp;
# Line 291  extern void pack(stackitem** stack_head) Line 338  extern void pack(stackitem** stack_head)
338    push(stack_head, pack);    push(stack_head, pack);
339  }  }
340    
341    /* Relocate elements of the list on the stack. */
342  extern void expand(stackitem** stack_head)  extern void expand(stackitem** stack_head)
343  {  {
344    stackitem *temp, *new_head;    stackitem *temp, *new_head;
345    
346      /* Is top element a list? */
347    if((*stack_head)==NULL || (*stack_head)->type!=list)    if((*stack_head)==NULL || (*stack_head)->type!=list)
348      return;      return;
349    
350      /* The first list element is the new stack head */
351    new_head= temp= (*stack_head)->content.ptr;    new_head= temp= (*stack_head)->content.ptr;
352    toss(stack_head);    toss(stack_head);
353    
354      /* Search the end of the list */
355    while(temp->next!=NULL)    while(temp->next!=NULL)
356      temp= temp->next;      temp= temp->next;
357    
358      /* Connect the the tail of the list with the old stack head */
359    temp->next= *stack_head;    temp->next= *stack_head;
360    *stack_head= new_head;    *stack_head= new_head;        /* ...and voila! */
361  }  }
362    
363    /* Swap the two top elements on the stack. */
364  extern void swap(stackitem** stack_head)  extern void swap(stackitem** stack_head)
365  {  {
366    stackitem* temp= (*stack_head);    stackitem* temp= (*stack_head);
# Line 320  extern void swap(stackitem** stack_head) Line 373  extern void swap(stackitem** stack_head)
373    (*stack_head)->next= temp;    (*stack_head)->next= temp;
374  }  }
375    
376    /* Compares two elements by reference. */
377    extern void eq(stackitem** stack_head)
378    {
379      void *left, *right;
380      int result;
381    
382      if((*stack_head)==NULL || (*stack_head)->next==NULL)
383        return;
384    
385      left= (*stack_head)->content.ptr;
386      swap(stack_head);
387      right= (*stack_head)->content.ptr;
388      result= (left==right);
389      
390      toss(stack_head); toss(stack_head);
391      push_val(stack_head, (left==right));
392    }
393    
394    /* Negates the top element on the stack. */
395    extern void not(stackitem** stack_head)
396    {
397      int value;
398    
399      if((*stack_head)==NULL || (*stack_head)->type!=value)
400        return;
401    
402      value= (*stack_head)->content.val;
403      toss(stack_head);
404      push_val(stack_head, !value);
405    }
406    
407    /* Compares the two top elements on the stack and return 0 if they're the
408       same. */
409    extern void neq(stackitem** stack_head)
410    {
411      eq(stack_head);
412      not(stack_head);
413    }
414    
415    /* Give a symbol some content. */
416    extern void def(stackitem** stack_head)
417    {
418      stackitem *temp, *value;
419    
420      if(*stack_head==NULL || (*stack_head)->next==NULL
421         || (*stack_head)->type!=ref)
422        return;
423    
424      temp= (*stack_head)->content.ptr;
425      value= (*stack_head)->next;
426      temp->content= value->content;
427      value->content.ptr=NULL;
428      temp->type= value->type;
429    
430      toss(stack_head); toss(stack_head);
431    }
432    
433    /* Quit stack. */
434  extern void quit()  extern void quit()
435  {  {
436    exit(EXIT_SUCCESS);    exit(EXIT_SUCCESS);

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.16

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26