/[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.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. */  /* 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 227  extern void printstack(stackitem** stack Line 234  extern void printstack(stackitem** stack
234  }  }
235    
236  /* 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
237     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. */  
238  extern void eval(stackitem** stack_head)  extern void eval(stackitem** stack_head)
239  {  {
240    funcp in_func;    funcp in_func;
# Line 256  int stack_read(stackitem** stack_head, h Line 262  int stack_read(stackitem** stack_head, h
262    rest= malloc(inlength);    rest= malloc(inlength);
263    
264    do {    do {
265        /* If string */
266      if((convert= sscanf(in_line, "\"%[^\"\n\r]\" %[^\n\r]", temp, rest))) {      if((convert= sscanf(in_line, "\"%[^\"\n\r]\" %[^\n\r]", temp, rest))) {
267        push_cstring(stack_head, temp);        push_cstring(stack_head, temp);
268        break;        break;
269      }      }
270        /* If value */
271      if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest))) {      if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest))) {
272        push_val(stack_head, itemp);        push_val(stack_head, itemp);
273        break;        break;
274      }      }
275        /* Escape ';' with '\' */
276      if((convert= sscanf(in_line, "\\%c%[^\n\r]", temp, rest))) {      if((convert= sscanf(in_line, "\\%c%[^\n\r]", temp, rest))) {
277        temp[1]= '\0';        temp[1]= '\0';
278        push_ref(stack_head, in_hash, temp);        push_ref(stack_head, in_hash, temp);
279        break;        break;
280      }      }
281              /* If symbol */
282      if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest))) {      if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest))) {
283          push_ref(stack_head, in_hash, temp);          push_ref(stack_head, in_hash, temp);
284          break;          break;
285      }      }
286          /* If ';' */
287      if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest)) && *temp==';') {      if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest)) && *temp==';') {
288        eval(stack_head);        eval(stack_head);         /* Evaluate top element */
289        break;        break;
290      }      }
291    } while(0);    } while(0);
# Line 303  extern void pack(stackitem** stack_head) Line 310  extern void pack(stackitem** stack_head)
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 321  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 328  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  /* Push elements of the list on the stack. */  /* 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. */  /* Swap the two top elements on the stack. */
# Line 382  extern void not(stackitem** stack_head) Line 396  extern void not(stackitem** stack_head)
396  {  {
397    int value;    int value;
398    
399    if((*stack_head)==NULL)    if((*stack_head)==NULL || (*stack_head)->type!=value)
400      return;      return;
401    
402    value= (*stack_head)->content.val;    value= (*stack_head)->content.val;

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

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26