--- stack/stack.c 2002/01/31 21:47:20 1.15 +++ stack/stack.c 2002/01/31 22:32:59 1.16 @@ -11,19 +11,27 @@ typedef struct stack_item { - enum {value, string, ref, func, symbol, list} type; + enum { + value, /* Integer */ + string, + ref, /* Reference (to an element in the hash table) */ + func, /* Function pointer */ + symbol, + list + } type; /* Tells what kind of stack element */ + union { - void* ptr; - int val; - } content; + void* ptr; /* Pointer to the content */ + int val; /* ...or an integer */ + } content; /* Stores a pointer or an integer */ - char* id; - struct stack_item* next; + char* id; /* Symbol name */ + struct stack_item* next; /* Next element */ } stackitem; -typedef stackitem* hashtbl[HASHTBLSIZE]; -typedef void (*funcp)(stackitem**); +typedef stackitem* hashtbl[HASHTBLSIZE]; /* Hash table declaration */ +typedef void (*funcp)(stackitem**); /* Function pointer declaration */ /* Initiates a newly created hash table. */ @@ -43,7 +51,7 @@ char key= 0; stackitem** position; - while(1){ + while(1){ /* Hash in_string */ key= in_string[i++]; if(key=='\0') break; @@ -53,14 +61,14 @@ out_hash= out_hash%HASHTBLSIZE; position= &(in_hashtbl[out_hash]); - while(1){ + while(1){ /* Return position if empty */ if(*position==NULL) return position; - if(strcmp(in_string, (*position)->id)==0) + if(strcmp(in_string, (*position)->id)==0) /* Return position if match */ return position; - position= &((*position)->next); + position= &((*position)->next); /* Try next */ } } @@ -123,7 +131,6 @@ stackitem* temp= malloc(sizeof(stackitem)); temp->type= symbol; - mk_hashentry(in_hashtbl, temp, id); } @@ -137,17 +144,17 @@ new_item->content.ptr= *hash(in_hash, in_string); new_item->type= ref; - if(new_item->content.ptr==NULL) { - if(handle==NULL) + if(new_item->content.ptr==NULL) { /* If hash entry empty */ + if(handle==NULL) /* If no handle */ handle= dlopen(NULL, RTLD_LAZY); - symbol= dlsym(handle, in_string); - if(dlerror()==NULL) - def_func(in_hash, symbol, in_string); + symbol= dlsym(handle, in_string); /* Get function pointer */ + if(dlerror()==NULL) /* If existing function pointer */ + def_func(in_hash, symbol, in_string); /* Store function pointer */ else - def_sym(in_hash, in_string); + def_sym(in_hash, in_string); /* Make symbol */ - new_item->content.ptr= *hash(in_hash, in_string); + new_item->content.ptr= *hash(in_hash, in_string); /* XXX */ new_item->type= ref; } @@ -227,8 +234,7 @@ } /* If the top element is a reference, determine if it's a reference to a - function, and if it is execute and pop the reference and execute the - function. */ + function, and if it is, toss the reference and execute the function. */ extern void eval(stackitem** stack_head) { funcp in_func; @@ -256,29 +262,30 @@ rest= malloc(inlength); do { + /* If string */ if((convert= sscanf(in_line, "\"%[^\"\n\r]\" %[^\n\r]", temp, rest))) { push_cstring(stack_head, temp); break; } - + /* If value */ if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest))) { push_val(stack_head, itemp); break; } - + /* Escape ';' with '\' */ if((convert= sscanf(in_line, "\\%c%[^\n\r]", temp, rest))) { temp[1]= '\0'; push_ref(stack_head, in_hash, temp); break; } - + /* If symbol */ if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest))) { push_ref(stack_head, in_hash, temp); break; } - + /* If ';' */ if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest)) && *temp==';') { - eval(stack_head); + eval(stack_head); /* Evaluate top element */ break; } } while(0); @@ -303,17 +310,19 @@ void* delimiter; stackitem *iterator, *temp, *pack; - if((*stack_head)==NULL) + if((*stack_head)==NULL) /* No delimiter */ return; - delimiter= (*stack_head)->content.ptr; + delimiter= (*stack_head)->content.ptr; /* Get delimiter */ toss(stack_head); iterator= *stack_head; + /* Search for first delimiter */ while(iterator->next!=NULL && iterator->next->content.ptr!=delimiter) iterator= iterator->next; + /* Extract list */ temp= *stack_head; *stack_head= iterator->next; iterator->next= NULL; @@ -321,6 +330,7 @@ if(*stack_head!=NULL && (*stack_head)->content.ptr==delimiter) toss(stack_head); + /* Push list */ pack= malloc(sizeof(stackitem)); pack->type= list; pack->content.ptr= temp; @@ -328,22 +338,26 @@ push(stack_head, pack); } -/* Push elements of the list on the stack. */ +/* Relocate elements of the list on the stack. */ extern void expand(stackitem** stack_head) { stackitem *temp, *new_head; + /* Is top element a list? */ if((*stack_head)==NULL || (*stack_head)->type!=list) return; + /* The first list element is the new stack head */ new_head= temp= (*stack_head)->content.ptr; toss(stack_head); + /* Search the end of the list */ while(temp->next!=NULL) temp= temp->next; + /* Connect the the tail of the list with the old stack head */ temp->next= *stack_head; - *stack_head= new_head; + *stack_head= new_head; /* ...and voila! */ } /* Swap the two top elements on the stack. */ @@ -382,7 +396,7 @@ { int value; - if((*stack_head)==NULL) + if((*stack_head)==NULL || (*stack_head)->type!=value) return; value= (*stack_head)->content.val;