58 |
typedef struct { |
typedef struct { |
59 |
stackitem *head; /* Head of the stack */ |
stackitem *head; /* Head of the stack */ |
60 |
hashtbl symbols; /* Hash table of all variable bindings */ |
hashtbl symbols; /* Hash table of all variable bindings */ |
61 |
|
int err; /* Error flag */ |
62 |
} environment; |
} environment; |
63 |
|
|
64 |
/* A type for pointers to external functions */ |
/* A type for pointers to external functions */ |
179 |
new_symbol= hash(env->symbols, in_string); |
new_symbol= hash(env->symbols, in_string); |
180 |
new_value->content.ptr= *new_symbol; |
new_value->content.ptr= *new_symbol; |
181 |
|
|
182 |
if(new_value->content.ptr==NULL) { /* If symbol was undefined */ |
if(*new_symbol==NULL) { /* If symbol was undefined */ |
183 |
|
|
184 |
/* Create a new symbol */ |
/* Create a new symbol */ |
185 |
*new_symbol= malloc(sizeof(symbol)); |
(*new_symbol)= malloc(sizeof(symbol)); |
186 |
(*new_symbol)->val= NULL; /* undefined value */ |
(*new_symbol)->val= NULL; /* undefined value */ |
187 |
(*new_symbol)->next= NULL; |
(*new_symbol)->next= NULL; |
188 |
(*new_symbol)->id= malloc(strlen(in_string)+1); |
(*new_symbol)->id= malloc(strlen(in_string)+1); |
349 |
return out_item; |
return out_item; |
350 |
} |
} |
351 |
|
|
352 |
|
/* Recall a value from a symbol, if bound */ |
353 |
|
extern void rcl(environment *env) |
354 |
|
{ |
355 |
|
value *val; |
356 |
|
|
357 |
|
if(env->head == NULL) { |
358 |
|
printerr("Stack empty"); |
359 |
|
return; |
360 |
|
} |
361 |
|
|
362 |
|
if(env->head->item->type!=symb) { |
363 |
|
printerr("Not a symbol"); |
364 |
|
return; |
365 |
|
} |
366 |
|
val=((symbol *)(env->head->item->content.ptr))->val; |
367 |
|
if(val == NULL){ |
368 |
|
printerr("Unbound variable"); |
369 |
|
return; |
370 |
|
} |
371 |
|
toss(env); /* toss the symbol */ |
372 |
|
push_val(&(env->head), val); /* Return its bound value */ |
373 |
|
} |
374 |
|
|
375 |
/* If the top element is a symbol, determine if it's bound to a |
/* If the top element is a symbol, determine if it's bound to a |
376 |
function value, and if it is, toss the symbol and execute the |
function value, and if it is, toss the symbol and execute the |
415 |
return; |
return; |
416 |
} |
} |
417 |
|
|
|
/* push(&(env->head), copy(env->head)); */ |
|
|
/* swap(env); */ |
|
|
/* toss(env); */ |
|
418 |
} |
} |
419 |
|
|
420 |
/* Make a list. */ |
/* Make a list. */ |
489 |
break; |
break; |
490 |
} |
} |
491 |
/* If symbol */ |
/* If symbol */ |
492 |
if((convert= sscanf(in_line, "%[^][ ;\n\r_]%[^\n\r]", temp, rest))) { |
if((convert= sscanf(in_line, "%[^][ ;\n\r]%[^\n\r]", temp, rest))) { |
493 |
push_sym(env, temp); |
push_sym(env, temp); |
494 |
break; |
break; |
495 |
} |
} |
644 |
toss(env); |
toss(env); |
645 |
} |
} |
646 |
|
|
647 |
|
/* List all defined words */ |
648 |
|
extern void words(environment *env) |
649 |
|
{ |
650 |
|
symbol *temp; |
651 |
|
int i; |
652 |
|
|
653 |
|
for(i= 0; i<HASHTBLSIZE; i++) { |
654 |
|
temp= env->symbols[i]; |
655 |
|
while(temp!=NULL) { |
656 |
|
printf("%s\n", temp->id); |
657 |
|
temp= temp->next; |
658 |
|
} |
659 |
|
} |
660 |
|
} |
661 |
|
|
662 |
|
/* Forgets a symbol (remove it from the hash table) */ |
663 |
|
extern void forget(environment *env) |
664 |
|
{ |
665 |
|
char* sym_id; |
666 |
|
stackitem *stack_head= env->head; |
667 |
|
symbol **hash_entry, *temp; |
668 |
|
|
669 |
|
if(stack_head==NULL || stack_head->item->type!=symb) { |
670 |
|
printerr("Stack empty or not a symbol"); |
671 |
|
return; |
672 |
|
} |
673 |
|
|
674 |
|
sym_id= ((symbol*)(stack_head->item->content.ptr))->id; |
675 |
|
toss(env); |
676 |
|
|
677 |
|
hash_entry= hash(env->symbols, sym_id); |
678 |
|
temp= *hash_entry; |
679 |
|
*hash_entry= (*hash_entry)->next; |
680 |
|
|
681 |
|
if(temp->val!=NULL) { |
682 |
|
free_val(temp->val); |
683 |
|
} |
684 |
|
free(temp->id); |
685 |
|
free(temp); |
686 |
|
} |
687 |
|
|
688 |
int main() |
int main() |
689 |
{ |
{ |
690 |
environment myenv; |
environment myenv; |