--- stack/stack.c 2002/02/15 18:27:18 1.87 +++ stack/stack.c 2002/02/17 04:03:57 1.89 @@ -15,68 +15,7 @@ /* mtrace, muntrace */ #include -#define HASHTBLSIZE 2048 - -/* First, define some types. */ - -/* A value of some type */ -typedef struct { - enum { - integer, - string, - func, /* Function pointer */ - symb, - list - } type; /* Type of stack element */ - - union { - void *ptr; /* Pointer to the content */ - int val; /* ...or an integer */ - } content; /* Stores a pointer or an integer */ - - int gc_garb; - -} value; - -/* A symbol with a name and possible value */ -/* (These do not need reference counters, they are kept unique by - hashing.) */ -typedef struct symbol_struct { - char *id; /* Symbol name */ - value *val; /* The value (if any) bound to it */ - struct symbol_struct *next; /* In case of hashing conflicts, a */ -} symbol; /* symbol is a kind of stack item. */ - -/* A type for a hash table for symbols */ -typedef symbol *hashtbl[HASHTBLSIZE]; /* Hash table declaration */ - -/* An item (value) on a stack */ -typedef struct stackitem_struct -{ - value *item; /* The value on the stack */ - /* (This is never NULL) */ - struct stackitem_struct *next; /* Next item */ -} stackitem; - -/* An environment; gives access to the stack and a hash table of - defined symbols */ -typedef struct { - stackitem *gc_ref; - int gc_limit, gc_count; - - stackitem *head; /* Head of the stack */ - hashtbl symbols; /* Hash table of all variable bindings */ - int err; /* Error flag */ - char *in_string; /* Input pending to be read */ - char *free_string; /* Free this string when all input is - read from in_string */ - FILE *inputstream; /* stdin or a file, most likely */ - int interactive; /* print prompts, stack, etc */ -} environment; - -/* A type for pointers to external functions */ -typedef void (*funcp)(environment *); /* funcp is a pointer to a void - function (environment *) */ +#include "stack.h" /* Initialize a newly created environment */ void init_env(environment *env) @@ -144,15 +83,10 @@ } } -extern void gc_init(environment*); - value* new_val(environment *env) { value *nval= malloc(sizeof(value)); stackitem *nitem= malloc(sizeof(stackitem)); - if(env->gc_count >= env->gc_limit) - gc_init(env); - nval->content.ptr= NULL; nitem->item= nval; @@ -187,6 +121,9 @@ symbol *tsymb; int i; + if(env->gc_count < env->gc_limit) + return; + while(iterator!=NULL) { iterator->item->gc_garb= 1; iterator= iterator->next; @@ -241,7 +178,7 @@ } } - env->gc_limit= env->gc_count+20; + env->gc_limit= env->gc_count*2; env->gc_ref= new_head; } @@ -597,7 +534,7 @@ in_func= (funcp)(env->head->item->content.ptr); toss(env); if(env->err) return; - return (*in_func)(env); + return in_func(env); /* If it's a list */ case list: @@ -808,9 +745,6 @@ toss(env); toss(env); } -extern void clear(environment *); -void forget_sym(symbol **); - /* Quit stack. */ extern void quit(environment *env) { @@ -898,8 +832,6 @@ push_int(env, env->err); } -extern void sx_72656164(environment*); - int main(int argc, char **argv) { environment myenv; @@ -957,6 +889,7 @@ toss(&myenv); /* No error check in main */ eval(&myenv); } + gc_init(&myenv); } quit(&myenv); return EXIT_FAILURE; @@ -1211,8 +1144,54 @@ } while(truth); } -/* "for"; For-loop */ + +/* "for"; for-loop */ extern void sx_666f72(environment *env) { + value *loop; + int foo1, foo2; + + if(env->head==NULL || env->head->next==NULL + || env->head->next->next==NULL) { + printerr("Too Few Arguments"); + env->err= 1; + return; + } + + if(env->head->next->item->type!=integer + || env->head->next->next->item->type!=integer) { + printerr("Bad Argument Type"); + env->err= 2; + return; + } + + loop= env->head->item; + toss(env); if(env->err) return; + + foo2= env->head->item->content.val; + toss(env); if(env->err) return; + + foo1= env->head->item->content.val; + toss(env); if(env->err) return; + + if(foo1<=foo2) { + while(foo1<=foo2) { + push_int(env, foo1); + push_val(env, loop); + eval(env); if(env->err) return; + foo1++; + } + } else { + while(foo1>=foo2) { + push_int(env, foo1); + push_val(env, loop); + eval(env); if(env->err) return; + foo1--; + } + } +} + +/* Variant of for-loop */ +extern void foreach(environment *env) { value *loop, *foo; stackitem *iterator;