--- stack/stack.c 2002/02/05 12:14:42 1.29 +++ stack/stack.c 2002/02/05 23:26:46 1.34 @@ -58,6 +58,7 @@ typedef struct { stackitem *head; /* Head of the stack */ hashtbl symbols; /* Hash table of all variable bindings */ + int err; /* Error flag */ } environment; /* A type for pointers to external functions */ @@ -178,10 +179,10 @@ new_symbol= hash(env->symbols, in_string); new_value->content.ptr= *new_symbol; - if(new_value->content.ptr==NULL) { /* If symbol was undefined */ + if(*new_symbol==NULL) { /* If symbol was undefined */ /* Create a new symbol */ - *new_symbol= malloc(sizeof(symbol)); + (*new_symbol)= malloc(sizeof(symbol)); (*new_symbol)->val= NULL; /* undefined value */ (*new_symbol)->next= NULL; (*new_symbol)->id= malloc(strlen(in_string)+1); @@ -348,6 +349,28 @@ return out_item; } +/* Recall a value from a symbol, if bound */ +extern void rcl(environment *env) +{ + value *val; + + if(env->head == NULL) { + printerr("Stack empty"); + return; + } + + if(env->head->item->type!=symb) { + printerr("Not a symbol"); + return; + } + val=((symbol *)(env->head->item->content.ptr))->val; + if(val == NULL){ + printerr("Unbound variable"); + return; + } + toss(env); /* toss the symbol */ + push_val(&(env->head), val); /* Return its bound value */ +} /* If the top element is a symbol, determine if it's bound to a function value, and if it is, toss the symbol and execute the @@ -392,9 +415,6 @@ return; } -/* push(&(env->head), copy(env->head)); */ -/* swap(env); */ -/* toss(env); */ } /* Make a list. */ @@ -469,7 +489,7 @@ 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_sym(env, temp); break; } @@ -624,6 +644,47 @@ toss(env); } +/* List all defined words */ +extern void words(environment *env) +{ + symbol *temp; + int i; + + for(i= 0; isymbols[i]; + while(temp!=NULL) { + printf("%s\n", temp->id); + temp= temp->next; + } + } +} + +/* Forgets a symbol (remove it from the hash table) */ +extern void forget(environment *env) +{ + char* sym_id; + stackitem *stack_head= env->head; + symbol **hash_entry, *temp; + + if(stack_head==NULL || stack_head->item->type!=symb) { + printerr("Stack empty or not a symbol"); + return; + } + + sym_id= ((symbol*)(stack_head->item->content.ptr))->id; + toss(env); + + hash_entry= hash(env->symbols, sym_id); + temp= *hash_entry; + *hash_entry= (*hash_entry)->next; + + if(temp->val!=NULL) { + free_val(temp->val); + } + free(temp->id); + free(temp); +} + int main() { environment myenv;