--- stack/stack.c 2002/02/06 00:52:31 1.36 +++ stack/stack.c 2002/02/07 01:06:44 1.45 @@ -218,6 +218,7 @@ switch (val->type){ /* and free the contents if necessary */ case string: free(val->content.ptr); + break; case list: /* lists needs to be freed recursively */ item=val->content.ptr; while(item != NULL) { /* for all stack items */ @@ -256,6 +257,39 @@ printf("\n"); } +/* Gets the type of a value */ +extern void type(environment *env){ + int typenum; + + if((env->head)==NULL) { + printerr("Too Few Arguments"); + env->err=1; + return; + } + typenum=env->head->item->type; + toss(env); + switch(typenum){ + case integer: + push_sym(env, "integer"); + break; + case string: + push_sym(env, "string"); + break; + case symb: + push_sym(env, "symbol"); + break; + case func: + push_sym(env, "function"); + break; + case list: + push_sym(env, "list"); + break; + default: + push_sym(env, "unknown"); + break; + } +} + /* Prints the top element of the stack. */ void print_h(stackitem *stack_head) { @@ -267,16 +301,24 @@ printf("\"%s\"", (char*)stack_head->item->content.ptr); break; case symb: - printf("'%s'", ((symbol *)(stack_head->item->content.ptr))->id); + printf("%s", ((symbol *)(stack_head->item->content.ptr))->id); break; case func: printf("#", (funcp)(stack_head->item->content.ptr)); break; case list: - printf("#", (funcp)(stack_head->item->content.ptr)); + /* A list is just a stack, so make stack_head point to it */ + stack_head=(stackitem *)(stack_head->item->content.ptr); + printf("[ "); + while(stack_head != NULL) { + print_h(stack_head); + printf(" "); + stack_head=stack_head->next; + } + printf("]"); break; default: - printf("#", (funcp)(stack_head->item->content.ptr)); + printf("#", (stack_head->item->content.ptr)); break; } } @@ -314,8 +356,6 @@ extern void printstack(environment *env) { if(env->head == NULL) { - printerr("Too Few Arguments"); - env->err=1; return; } print_st(env->head, 1); @@ -388,6 +428,9 @@ extern void eval(environment *env) { funcp in_func; + value* temp_val; + stackitem* iterator; + if(env->head==NULL) { printerr("Too Few Arguments"); env->err=1; @@ -411,7 +454,55 @@ toss(env); if(env->err) return; (*in_func)(env); + return; + } + + /* If it's a list */ + if(env->head->item->type==list) { + temp_val= env->head->item; + env->head->item->refcount++; + toss(env); + if(env->err) return; + iterator= (stackitem*)temp_val->content.ptr; + while(iterator!=NULL && iterator->item!=NULL) { + push_val(&(env->head), iterator->item); + if(env->head->item->type==symb + && strcmp(";", ((symbol*)(env->head->item->content.ptr))->id)==0) { + toss(env); + if(env->err) return; + eval(env); + } + iterator= iterator->next; + } + free_val(temp_val); + } +} + +/* Reverse (flip) a list */ +extern void rev(environment *env){ + stackitem *old_head, *new_head, *item; + + if((env->head)==NULL) { + printerr("Too Few Arguments"); + env->err=1; + return; + } + + if(env->head->item->type!=list) { + printerr("Bad Argument Type"); + env->err=2; + return; + } + + old_head=(stackitem *)(env->head->item->content.ptr); + new_head=NULL; + while(old_head != NULL){ + item=old_head; + old_head=old_head->next; + item->next=new_head; + new_head=item; } + env->head->item->content.ptr=new_head; } /* Make a list. */ @@ -454,10 +545,11 @@ temp->item= pack; push(&(env->head), temp); + rev(env); } /* Parse input. */ -int stack_read(environment *env, char *in_line) +void stack_read(environment *env, char *in_line) { char *temp, *rest; int itemp; @@ -469,6 +561,12 @@ rest= malloc(inlength); do { + /* If comment */ + if((convert= sscanf(in_line, "#%[^\n\r]", rest))) { + free(temp); free(rest); + return; + } + /* If string */ if((convert= sscanf(in_line, "\"%[^\"\n\r]\" %[^\n\r]", temp, rest))) { push_cstring(&(env->head), temp); @@ -518,18 +616,16 @@ } } while(0); - free(temp); if(convert<2) { free(rest); - return 0; + return; } stack_read(env, rest); free(rest); - return 1; } /* Relocate elements of the list on the stack. */ @@ -549,6 +645,11 @@ return; } + rev(env); + + if(env->err) + return; + /* The first list element is the new stack head */ new_head= temp= env->head->item->content.ptr; @@ -731,6 +832,6 @@ } printf("okidok\n "); } - - exit(EXIT_SUCCESS); + quit(&myenv); + return EXIT_FAILURE; }