--- stack/stack.c 2002/01/31 23:09:07 1.17 +++ stack/stack.c 2002/02/02 15:12:56 1.20 @@ -6,6 +6,8 @@ #include /* dlopen, dlsym, dlerror */ #include +/* assert */ +#include #define HASHTBLSIZE 65536 @@ -13,13 +15,14 @@ { enum { value, /* Integer */ - string, - ref, /* Reference (to an element in the hash table) */ + string, + ref, /* Reference (to an element in the + hash table) */ func, /* Function pointer */ symbol, list - } type; /* Tells what kind of stack element */ - + } type; /* Type of stack element */ + union { void* ptr; /* Pointer to the content */ int val; /* ...or an integer */ @@ -31,10 +34,10 @@ typedef stackitem* hashtbl[HASHTBLSIZE]; /* Hash table declaration */ -typedef void (*funcp)(stackitem**); /* Function pointer declaration */ - +typedef void (*funcp)(stackitem**); /* funcp is a pointer to a + void function (stackitem **) */ -/* Initiates a newly created hash table. */ +/* Initialize a newly created hash table. */ void init_hashtbl(hashtbl out_hash) { long i; @@ -48,7 +51,7 @@ { long i= 0; unsigned long out_hash= 0; - char key= 0; + char key= '\0'; stackitem** position; while(1){ /* Hash in_string */ @@ -61,15 +64,17 @@ out_hash= out_hash%HASHTBLSIZE; position= &(in_hashtbl[out_hash]); - while(1){ /* Return position if empty */ - if(*position==NULL) + while(position != NULL){ + if(*position==NULL) /* If empty */ return position; - if(strcmp(in_string, (*position)->id)==0) /* Return position if match */ + if(strcmp(in_string, (*position)->id)==0) /* If match */ return position; position= &((*position)->next); /* Try next */ } + return NULL; /* end of list reached without finding + an empty position */ } /* Generic push function. */ @@ -84,6 +89,7 @@ int push_val(stackitem** stack_head, int in_val) { stackitem* new_item= malloc(sizeof(stackitem)); + assert(new_item != NULL); new_item->content.val= in_val; new_item->type= value; @@ -114,7 +120,7 @@ return 1; } -/* Define a function a new function in the hash table. */ +/* Define a new function in the hash table. */ void def_func(hashtbl in_hashtbl, funcp in_func, const char* id) { stackitem* temp= malloc(sizeof(stackitem)); @@ -263,6 +269,42 @@ printerr("Not a function"); } +/* Make a list. */ +extern void pack(stackitem** stack_head) +{ + void* delimiter; + stackitem *iterator, *temp, *pack; + + if((*stack_head)==NULL) { + printerr("Stack empty"); + return; + } + + 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; + + 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; + + push(stack_head, pack); +} + /* Parse input. */ int stack_read(stackitem** stack_head, hashtbl in_hash, char* in_line) { @@ -270,6 +312,7 @@ int itemp; size_t inlength= strlen(in_line)+1; int convert= 0; + static int non_eval_flag= 0; temp= malloc(inlength); rest= malloc(inlength); @@ -292,14 +335,34 @@ break; } /* If symbol */ - if((convert= sscanf(in_line, "%[^ ;\n\r]%[^\n\r]", temp, rest))) { + 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); /* Evaluate top element */ - break; + /* If single char */ + if((convert= sscanf(in_line, "%c%[^\n\r]", temp, rest))) { + if(*temp==';') { + if(non_eval_flag) { + eval(stack_head); /* Evaluate top element */ + break; + } + + push_ref(stack_head, in_hash, ";"); + break; + } + + if(*temp==']') { + push_ref(stack_head, in_hash, "["); + pack(stack_head); + non_eval_flag--; + break; + } + + if(*temp=='[') { + push_ref(stack_head, in_hash, "["); + non_eval_flag++; + break; + } } } while(0); @@ -317,42 +380,6 @@ return 1; } -/* Make a list. */ -extern void pack(stackitem** stack_head) -{ - void* delimiter; - stackitem *iterator, *temp, *pack; - - if((*stack_head)==NULL) { - printerr("Stack empty"); - return; - } - - 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; - - 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; - - push(stack_head, pack); -} - /* Relocate elements of the list on the stack. */ extern void expand(stackitem** stack_head) {