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

Diff of /stack/stack.c

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

revision 1.1 by masse, Mon Jan 7 23:09:01 2002 UTC revision 1.14 by masse, Thu Jan 31 19:51:12 2002 UTC
# Line 4  Line 4 
4  #include <stdlib.h>  #include <stdlib.h>
5  /* NULL */  /* NULL */
6  #include <stddef.h>  #include <stddef.h>
7    /* dlopen, dlsym, dlerror */
8  #include <dlfcn.h>  #include <dlfcn.h>
9    
10  #define HASHTBLSIZE 65536  #define HASHTBLSIZE 65536
11    
12  typedef struct stack_item  typedef struct stack_item
13  {  {
14    enum {value, string, ref, func} type;    enum {value, string, ref, func, symbol, list} type;
15    union {    union {
16      void* ptr;      void* ptr;
17      int val;      int val;
# Line 24  typedef struct stack_item Line 25  typedef struct stack_item
25  typedef stackitem* hashtbl[HASHTBLSIZE];  typedef stackitem* hashtbl[HASHTBLSIZE];
26  typedef void (*funcp)(stackitem**);  typedef void (*funcp)(stackitem**);
27    
28    
29    /* Initiates a newly created hash table. */
30  void init_hashtbl(hashtbl out_hash)  void init_hashtbl(hashtbl out_hash)
31  {  {
32    long i;    long i;
# Line 32  void init_hashtbl(hashtbl out_hash) Line 35  void init_hashtbl(hashtbl out_hash)
35      out_hash[i]= NULL;      out_hash[i]= NULL;
36  }  }
37    
38    /* Returns a pointer to an element in the hash table. */
39  stackitem** hash(hashtbl in_hashtbl, const char* in_string)  stackitem** hash(hashtbl in_hashtbl, const char* in_string)
40  {  {
41    long i= 0;    long i= 0;
# Line 60  stackitem** hash(hashtbl in_hashtbl, con Line 64  stackitem** hash(hashtbl in_hashtbl, con
64    }    }
65  }  }
66    
67    /* Generic push function. */
68  int push(stackitem** stack_head, stackitem* in_item)  int push(stackitem** stack_head, stackitem* in_item)
69  {  {
70    in_item->next= *stack_head;    in_item->next= *stack_head;
# Line 68  int push(stackitem** stack_head, stackit Line 72  int push(stackitem** stack_head, stackit
72    return 1;    return 1;
73  }  }
74    
75    /* Push a value on the stack. */
76  int push_val(stackitem** stack_head, int in_val)  int push_val(stackitem** stack_head, int in_val)
77  {  {
78    stackitem* new_item= malloc(sizeof(stackitem));    stackitem* new_item= malloc(sizeof(stackitem));
# Line 78  int push_val(stackitem** stack_head, int Line 83  int push_val(stackitem** stack_head, int
83    return 1;    return 1;
84  }  }
85    
86    /* Copy a string onto the stack. */
87  int push_cstring(stackitem** stack_head, const char* in_string)  int push_cstring(stackitem** stack_head, const char* in_string)
88  {  {
89    stackitem* new_item= malloc(sizeof(stackitem));    stackitem* new_item= malloc(sizeof(stackitem));
# Line 89  int push_cstring(stackitem** stack_head, Line 95  int push_cstring(stackitem** stack_head,
95    return 1;    return 1;
96  }  }
97    
98    /* Create a new hash entry. */
99  int mk_hashentry(hashtbl in_hashtbl, stackitem* in_item, const char* id)  int mk_hashentry(hashtbl in_hashtbl, stackitem* in_item, const char* id)
100  {  {
101    in_item->id= malloc(strlen(id)+1);    in_item->id= malloc(strlen(id)+1);
# Line 99  int mk_hashentry(hashtbl in_hashtbl, sta Line 106  int mk_hashentry(hashtbl in_hashtbl, sta
106    return 1;    return 1;
107  }  }
108    
109    /* Define a function a new function in the hash table. */
110  void def_func(hashtbl in_hashtbl, funcp in_func, const char* id)  void def_func(hashtbl in_hashtbl, funcp in_func, const char* id)
111  {  {
112    stackitem* temp= malloc(sizeof(stackitem));    stackitem* temp= malloc(sizeof(stackitem));
# Line 109  void def_func(hashtbl in_hashtbl, funcp Line 117  void def_func(hashtbl in_hashtbl, funcp
117    mk_hashentry(in_hashtbl, temp, id);    mk_hashentry(in_hashtbl, temp, id);
118  }  }
119    
120    /* Define a new symbol in the hash table. */
121    void def_sym(hashtbl in_hashtbl, const char* id)
122    {
123      stackitem* temp= malloc(sizeof(stackitem));
124      
125      temp->type= symbol;
126    
127      mk_hashentry(in_hashtbl, temp, id);
128    }
129    
130    /* Push a reference to an entry in the hash table onto the stack. */
131  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)
132  {  {
133    void* handle;    static void* handle= NULL;
134    void* symbol;    void* symbol;
135      
136    stackitem* new_item= malloc(sizeof(stackitem));    stackitem* new_item= malloc(sizeof(stackitem));
137    new_item->content.ptr= *hash(in_hash, in_string);    new_item->content.ptr= *hash(in_hash, in_string);
138    new_item->type= ref;    new_item->type= ref;
139    
140    if(new_item->content.ptr==NULL) {    if(new_item->content.ptr==NULL) {
141      handle= dlopen(NULL, RTLD_LAZY);      if(handle==NULL)
142          handle= dlopen(NULL, RTLD_LAZY);    
143    
144      symbol= dlsym(handle, in_string);      symbol= dlsym(handle, in_string);
145      if(dlerror()==NULL) {      if(dlerror()==NULL)
146        def_func(in_hash, symbol, in_string);        def_func(in_hash, symbol, in_string);
147        new_item->content.ptr= *hash(in_hash, in_string);      else
148        new_item->type= ref;        def_sym(in_hash, in_string);
149      }        
150        new_item->content.ptr= *hash(in_hash, in_string);
151        new_item->type= ref;
152    }    }
153    
154    push(stack_head, new_item);    push(stack_head, new_item);
155    return 1;    return 1;
156  }  }
157    
158    /* Discard the top element of the stack. */
159  extern void toss(stackitem** stack_head)  extern void toss(stackitem** stack_head)
160  {  {
161    stackitem* temp= *stack_head;    stackitem* temp= *stack_head;
162    
163      if((*stack_head)==NULL)
164        return;
165      
166      if((*stack_head)->type==string)
167        free((*stack_head)->content.ptr);
168    
169    *stack_head= (*stack_head)->next;    *stack_head= (*stack_head)->next;
170    free(temp);    free(temp);
171  }  }
172    
173    /* Print newline. */
174    extern void nl()
175    {
176      printf("\n");
177    }
178    
179  /* print_stack(stack); */  /* Prints the top element of the stack. */
180    void print_(stackitem** stack_head)
181    {
182      if((*stack_head)==NULL)
183        return;
184    
185      switch((*stack_head)->type) {
186      case value:
187        printf("%d", (*stack_head)->content.val);
188        break;
189      case string:
190        printf("%s", (char*)(*stack_head)->content.ptr);
191        break;
192      case ref:
193        printf("%s", ((stackitem*)(*stack_head)->content.ptr)->id);
194        break;
195      case symbol:
196      default:
197        printf("%p", (*stack_head)->content.ptr);
198        break;
199      }
200    }
201    
202    /* Prints the top element of the stack and then discards it. */
203    extern void print(stackitem** stack_head)
204    {
205      print_(stack_head);
206      toss(stack_head);
207    }
208    
209    /* Only to be called by function printstack. */
210  void print_st(stackitem* stack_head, long counter)  void print_st(stackitem* stack_head, long counter)
211  {  {
212    if(stack_head->next != NULL)    if(stack_head->next != NULL)
213      print_st(stack_head->next, counter+1);      print_st(stack_head->next, counter+1);
214    
215    if(stack_head->type==value)    printf("%ld: ", counter);
216      printf("%ld: %d\n", counter, (int)stack_head->content.val);    print_(&stack_head);
217    else if(stack_head->type==string)    nl();
     printf("%ld: \"%s\"\n", counter, (char*)stack_head->content.ptr);  
   else  
     printf("%ld: %p\n", counter, stack_head->content.ptr);  
218  }  }
219    
220    /* Prints the stack. */
221  extern void printstack(stackitem** stack_head)  extern void printstack(stackitem** stack_head)
222  {  {
223    if(*stack_head != NULL) {    if(*stack_head != NULL) {
# Line 163  extern void printstack(stackitem** stack Line 226  extern void printstack(stackitem** stack
226    }    }
227  }  }
228    
229    /* If the top element is a reference, determine if it's a reference to a
230       function, and if it is execute and pop the reference and execute the
231       function. */
232  extern void eval(stackitem** stack_head)  extern void eval(stackitem** stack_head)
233  {  {
234    funcp in_func;    funcp in_func;
# Line 179  extern void eval(stackitem** stack_head) Line 244  extern void eval(stackitem** stack_head)
244    }    }
245  }  }
246    
247    /* Parse input. */
248  int stack_read(stackitem** stack_head, hashtbl in_hash, char* in_line)  int stack_read(stackitem** stack_head, hashtbl in_hash, char* in_line)
249  {  {
250    char *temp, *rest;    char *temp, *rest;
# Line 193  int stack_read(stackitem** stack_head, h Line 259  int stack_read(stackitem** stack_head, h
259      push_cstring(stack_head, temp);      push_cstring(stack_head, temp);
260    else if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest)) >= 1)    else if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest)) >= 1)
261      push_val(stack_head, itemp);      push_val(stack_head, itemp);
262    else if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest)) >= 1)    else if((convert= sscanf(in_line, "\\%c%[^\n\r]", temp, rest)) >= 1) {
263        temp[1]= '\0'; push_ref(stack_head, in_hash, temp);
264      } else if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest)) >= 1)
265      push_ref(stack_head, in_hash, temp);      push_ref(stack_head, in_hash, temp);
266    else if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest)) >= 1)    else if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest)) >= 1)
267      if(*temp==';')      if(*temp==';')
# Line 212  int stack_read(stackitem** stack_head, h Line 280  int stack_read(stackitem** stack_head, h
280    return 1;    return 1;
281  }  }
282    
283  extern void print(stackitem** stack_head)  /* Make a list. */
284    extern void pack(stackitem** stack_head)
285  {  {
286      void* delimiter;
287      stackitem *iterator, *temp, *pack;
288    
289    if((*stack_head)==NULL)    if((*stack_head)==NULL)
290      return;      return;
291    
292    if((*stack_head)->type==value)    delimiter= (*stack_head)->content.ptr;
293      printf("%d", (*stack_head)->content.val);    toss(stack_head);
294    else if((*stack_head)->type==string)  
295      printf("%s", (char*)(*stack_head)->content.ptr);    iterator= *stack_head;
   else  
     printf("%p", (*stack_head)->content.ptr);  
296    
297      while(iterator->next!=NULL && iterator->next->content.ptr!=delimiter)
298        iterator= iterator->next;
299    
300      temp= *stack_head;
301      *stack_head= iterator->next;
302      iterator->next= NULL;
303      
304      if(*stack_head!=NULL && (*stack_head)->content.ptr==delimiter)
305        toss(stack_head);
306    
307      pack= malloc(sizeof(stackitem));
308      pack->type= list;
309      pack->content.ptr= temp;
310    
311      push(stack_head, pack);
312    }
313    
314    /* Push elements of the list on the stack. */
315    extern void expand(stackitem** stack_head)
316    {
317      stackitem *temp, *new_head;
318    
319      if((*stack_head)==NULL || (*stack_head)->type!=list)
320        return;
321    
322      new_head= temp= (*stack_head)->content.ptr;
323    toss(stack_head);    toss(stack_head);
324    
325      while(temp->next!=NULL)
326        temp= temp->next;
327    
328      temp->next= *stack_head;
329      *stack_head= new_head;
330  }  }
331    
332  extern void nl()  /* Swap the two top elements on the stack. */
333    extern void swap(stackitem** stack_head)
334  {  {
335    printf("\n");    stackitem* temp= (*stack_head);
336      
337      if((*stack_head)==NULL || (*stack_head)->next==NULL)
338        return;
339    
340      *stack_head= (*stack_head)->next;
341      temp->next= (*stack_head)->next;
342      (*stack_head)->next= temp;
343    }
344    
345    /* Compares two elements by reference. */
346    extern void eq(stackitem** stack_head)
347    {
348      void *left, *right;
349      int result;
350    
351      if((*stack_head)==NULL || (*stack_head)->next==NULL)
352        return;
353    
354      left= (*stack_head)->content.ptr;
355      swap(stack_head);
356      right= (*stack_head)->content.ptr;
357      result= (left==right);
358      
359      toss(stack_head); toss(stack_head);
360      push_val(stack_head, (left==right));
361    }
362    
363    /* Negates the top element on the stack. */
364    extern void not(stackitem** stack_head)
365    {
366      int value;
367    
368      if((*stack_head)==NULL)
369        return;
370    
371      value= (*stack_head)->content.val;
372      toss(stack_head);
373      push_val(stack_head, !value);
374    }
375    
376    /* Compares the two top elements on the stack and return 0 if they're the
377       same. */
378    extern void neq(stackitem** stack_head)
379    {
380      eq(stack_head);
381      not(stack_head);
382    }
383    
384    /* Give a symbol some content. */
385    extern void def(stackitem** stack_head)
386    {
387      stackitem *temp, *value;
388    
389      if(*stack_head==NULL || (*stack_head)->next==NULL
390         || (*stack_head)->type!=ref)
391        return;
392    
393      temp= (*stack_head)->content.ptr;
394      value= (*stack_head)->next;
395      temp->content= value->content;
396      value->content.ptr=NULL;
397      temp->type= value->type;
398    
399      toss(stack_head); toss(stack_head);
400    }
401    
402    /* Quit stack. */
403    extern void quit()
404    {
405      exit(EXIT_SUCCESS);
406  }  }
407    
408  int main()  int main()
# Line 247  int main() Line 420  int main()
420      printf("okidok\n ");      printf("okidok\n ");
421    }    }
422    
423      exit(EXIT_SUCCESS);
   return EXIT_SUCCESS;  
424  }  }
425    
426    /* Local Variables: */
427    /* compile-command:"make CFLAGS=\"-Wall -g -rdynamic -ldl\" stack" */
428    /* End: */

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.14

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26