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

Diff of /stack/stack.c

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

revision 1.15 by masse, Thu Jan 31 21:47:20 2002 UTC revision 1.17 by masse, Thu Jan 31 23:09:07 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. */  /* Initiates a newly created hash table. */
# Line 43  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 53  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    
# Line 123  void def_sym(hashtbl in_hashtbl, const c Line 131  void def_sym(hashtbl in_hashtbl, const c
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    
# Line 137  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 155  int push_ref(stackitem** stack_head, has Line 162  int push_ref(stackitem** stack_head, has
162    return 1;    return 1;
163  }  }
164    
165    void printerr(const char* in_string) {
166      fprintf(stderr, "Err: %s\n", in_string);
167    }
168    
169  /* Discard the top element of the stack. */  /* Discard the top element of the stack. */
170  extern void toss(stackitem** stack_head)  extern void toss(stackitem** stack_head)
171  {  {
172    stackitem* temp= *stack_head;    stackitem* temp= *stack_head;
173    
174    if((*stack_head)==NULL)    if((*stack_head)==NULL) {
175        printerr("Stack empty");
176      return;      return;
177      }
178        
179    if((*stack_head)->type==string)    if((*stack_head)->type==string)
180      free((*stack_head)->content.ptr);      free((*stack_head)->content.ptr);
# Line 179  extern void nl() Line 192  extern void nl()
192  /* Prints the top element of the stack. */  /* Prints the top element of the stack. */
193  void print_(stackitem** stack_head)  void print_(stackitem** stack_head)
194  {  {
195    if((*stack_head)==NULL)    if((*stack_head)==NULL) {
196        printerr("Stack empty");
197      return;      return;
198      }
199    
200    switch((*stack_head)->type) {    switch((*stack_head)->type) {
201    case value:    case value:
# Line 223  extern void printstack(stackitem** stack Line 238  extern void printstack(stackitem** stack
238    if(*stack_head != NULL) {    if(*stack_head != NULL) {
239      print_st(*stack_head, 1);      print_st(*stack_head, 1);
240      printf("\n");      printf("\n");
241      } else {
242        printerr("Stack empty");
243    }    }
244  }  }
245    
246  /* If the top element is a reference, determine if it's a reference to a  /* If the top element is a reference, determine if it's a reference to a
247     function, and if it is execute and pop the reference and execute the     function, and if it is, toss the reference and execute the function. */
    function. */  
248  extern void eval(stackitem** stack_head)  extern void eval(stackitem** stack_head)
249  {  {
250    funcp in_func;    funcp in_func;
251    
252    if((*stack_head)==NULL || (*stack_head)->type!=ref)    if((*stack_head)==NULL || (*stack_head)->type!=ref) {
253        printerr("Stack empty or not a reference");
254      return;      return;
255      }
256    
257    if(((stackitem*)(*stack_head)->content.ptr)->type==func) {    if(((stackitem*)(*stack_head)->content.ptr)->type==func) {
258      in_func= (funcp)((stackitem*)(*stack_head)->content.ptr)->content.ptr;      in_func= (funcp)((stackitem*)(*stack_head)->content.ptr)->content.ptr;
259      toss(stack_head);      toss(stack_head);
260      (*in_func)(stack_head);      (*in_func)(stack_head);
261      return;      return;
262    }    } else
263        printerr("Not a function");
264  }  }
265    
266  /* Parse input. */  /* Parse input. */
# Line 256  int stack_read(stackitem** stack_head, h Line 275  int stack_read(stackitem** stack_head, h
275    rest= malloc(inlength);    rest= malloc(inlength);
276    
277    do {    do {
278        /* If string */
279      if((convert= sscanf(in_line, "\"%[^\"\n\r]\" %[^\n\r]", temp, rest))) {      if((convert= sscanf(in_line, "\"%[^\"\n\r]\" %[^\n\r]", temp, rest))) {
280        push_cstring(stack_head, temp);        push_cstring(stack_head, temp);
281        break;        break;
282      }      }
283        /* If value */
284      if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest))) {      if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest))) {
285        push_val(stack_head, itemp);        push_val(stack_head, itemp);
286        break;        break;
287      }      }
288        /* Escape ';' with '\' */
289      if((convert= sscanf(in_line, "\\%c%[^\n\r]", temp, rest))) {      if((convert= sscanf(in_line, "\\%c%[^\n\r]", temp, rest))) {
290        temp[1]= '\0';        temp[1]= '\0';
291        push_ref(stack_head, in_hash, temp);        push_ref(stack_head, in_hash, temp);
292        break;        break;
293      }      }
294              /* If symbol */
295      if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest))) {      if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest))) {
296          push_ref(stack_head, in_hash, temp);          push_ref(stack_head, in_hash, temp);
297          break;          break;
298      }      }
299          /* If ';' */
300      if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest)) && *temp==';') {      if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest)) && *temp==';') {
301        eval(stack_head);        eval(stack_head);         /* Evaluate top element */
302        break;        break;
303      }      }
304    } while(0);    } while(0);
# Line 303  extern void pack(stackitem** stack_head) Line 323  extern void pack(stackitem** stack_head)
323    void* delimiter;    void* delimiter;
324    stackitem *iterator, *temp, *pack;    stackitem *iterator, *temp, *pack;
325    
326    if((*stack_head)==NULL)    if((*stack_head)==NULL) {
327        printerr("Stack empty");
328      return;      return;
329      }
330    
331    delimiter= (*stack_head)->content.ptr;    delimiter= (*stack_head)->content.ptr; /* Get delimiter */
332    toss(stack_head);    toss(stack_head);
333    
334    iterator= *stack_head;    iterator= *stack_head;
335    
336      /* Search for first delimiter */
337    while(iterator->next!=NULL && iterator->next->content.ptr!=delimiter)    while(iterator->next!=NULL && iterator->next->content.ptr!=delimiter)
338      iterator= iterator->next;      iterator= iterator->next;
339    
340      /* Extract list */
341    temp= *stack_head;    temp= *stack_head;
342    *stack_head= iterator->next;    *stack_head= iterator->next;
343    iterator->next= NULL;    iterator->next= NULL;
# Line 321  extern void pack(stackitem** stack_head) Line 345  extern void pack(stackitem** stack_head)
345    if(*stack_head!=NULL && (*stack_head)->content.ptr==delimiter)    if(*stack_head!=NULL && (*stack_head)->content.ptr==delimiter)
346      toss(stack_head);      toss(stack_head);
347    
348      /* Push list */
349    pack= malloc(sizeof(stackitem));    pack= malloc(sizeof(stackitem));
350    pack->type= list;    pack->type= list;
351    pack->content.ptr= temp;    pack->content.ptr= temp;
# Line 328  extern void pack(stackitem** stack_head) Line 353  extern void pack(stackitem** stack_head)
353    push(stack_head, pack);    push(stack_head, pack);
354  }  }
355    
356  /* Push elements of the list on the stack. */  /* Relocate elements of the list on the stack. */
357  extern void expand(stackitem** stack_head)  extern void expand(stackitem** stack_head)
358  {  {
359    stackitem *temp, *new_head;    stackitem *temp, *new_head;
360    
361    if((*stack_head)==NULL || (*stack_head)->type!=list)    /* Is top element a list? */
362      if((*stack_head)==NULL || (*stack_head)->type!=list) {
363        printerr("Stack empty or not a list");
364      return;      return;
365      }
366    
367      /* The first list element is the new stack head */
368    new_head= temp= (*stack_head)->content.ptr;    new_head= temp= (*stack_head)->content.ptr;
369    toss(stack_head);    toss(stack_head);
370    
371      /* Search the end of the list */
372    while(temp->next!=NULL)    while(temp->next!=NULL)
373      temp= temp->next;      temp= temp->next;
374    
375      /* Connect the the tail of the list with the old stack head */
376    temp->next= *stack_head;    temp->next= *stack_head;
377    *stack_head= new_head;    *stack_head= new_head;        /* ...and voila! */
378  }  }
379    
380  /* Swap the two top elements on the stack. */  /* Swap the two top elements on the stack. */
# Line 351  extern void swap(stackitem** stack_head) Line 382  extern void swap(stackitem** stack_head)
382  {  {
383    stackitem* temp= (*stack_head);    stackitem* temp= (*stack_head);
384        
385    if((*stack_head)==NULL || (*stack_head)->next==NULL)    if((*stack_head)==NULL) {
386        printerr("Stack empty");
387        return;
388      }
389    
390      if((*stack_head)->next==NULL)
391      return;      return;
392    
393    *stack_head= (*stack_head)->next;    *stack_head= (*stack_head)->next;
# Line 365  extern void eq(stackitem** stack_head) Line 401  extern void eq(stackitem** stack_head)
401    void *left, *right;    void *left, *right;
402    int result;    int result;
403    
404    if((*stack_head)==NULL || (*stack_head)->next==NULL)    if((*stack_head)==NULL || (*stack_head)->next==NULL) {
405        printerr("Not enough elements to compare");
406      return;      return;
407      }
408    
409    left= (*stack_head)->content.ptr;    left= (*stack_head)->content.ptr;
410    swap(stack_head);    swap(stack_head);
# Line 382  extern void not(stackitem** stack_head) Line 420  extern void not(stackitem** stack_head)
420  {  {
421    int value;    int value;
422    
423    if((*stack_head)==NULL)    if((*stack_head)==NULL || (*stack_head)->type!=value) {
424        printerr("Stack empty or element is not a value");
425      return;      return;
426      }
427    
428    value= (*stack_head)->content.val;    value= (*stack_head)->content.val;
429    toss(stack_head);    toss(stack_head);
# Line 404  extern void def(stackitem** stack_head) Line 444  extern void def(stackitem** stack_head)
444    stackitem *temp, *value;    stackitem *temp, *value;
445    
446    if(*stack_head==NULL || (*stack_head)->next==NULL    if(*stack_head==NULL || (*stack_head)->next==NULL
447       || (*stack_head)->type!=ref)       || (*stack_head)->type!=ref) {
448        printerr("Define what?");
449      return;      return;
450      }
451    
452    temp= (*stack_head)->content.ptr;    temp= (*stack_head)->content.ptr;
453    value= (*stack_head)->next;    value= (*stack_head)->next;

Legend:
Removed from v.1.15  
changed lines
  Added in v.1.17

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26