--- stack/stack.c 2002/02/07 04:11:10 1.47 +++ stack/stack.c 2002/02/07 04:34:42 1.48 @@ -77,6 +77,52 @@ env->symbols[i]= NULL; } +void printerr(const char* in_string) { + fprintf(stderr, "Err: %s\n", in_string); +} + +/* Throw away a value */ +void free_val(value *val){ + stackitem *item, *temp; + + val->refcount--; /* Decrease the reference count */ + if(val->refcount == 0){ + 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 */ + free_val(item->item); /* free the value */ + temp=item->next; /* save next ptr */ + free(item); /* free the stackitem */ + item=temp; /* go to next stackitem */ + } + free(val); /* Free the actual list value */ + break; + default: + break; + } + } +} + +/* Discard the top element of the stack. */ +extern void toss(environment *env) +{ + stackitem *temp= env->head; + + if((env->head)==NULL) { + printerr("Too Few Arguments"); + env->err=1; + return; + } + + free_val(env->head->item); /* Free the value */ + env->head= env->head->next; /* Remove the top stack item */ + free(temp); /* Free the old top stack item */ +} + /* Returns a pointer to a pointer to an element in the hash table. */ symbol **hash(hashtbl in_hashtbl, const char *in_string) { @@ -151,6 +197,55 @@ push(stack_head, new_item); } +/* Mangle a symbol name to a valid C identifier name */ +char *mangle_(const char *old_string){ + char validchars[] + ="0123456789abcdef"; + char *new_string, *current; + + new_string=malloc(strlen(old_string)+4); + strcpy(new_string, "sx_"); /* Stack eXternal */ + current=new_string+3; + while(old_string[0] != '\0'){ + current[0]=validchars[old_string[0]/16]; + current[1]=validchars[old_string[0]%16]; + current+=2; + old_string++; + } + current[0]='\0'; + + return new_string; /* The caller must free() it */ +} + +extern void mangle(environment *env){ + value *new_value; + char *new_string; + + if((env->head)==NULL) { + printerr("Too Few Arguments"); + env->err=1; + return; + } + + if(env->head->item->type!=string) { + printerr("Bad Argument Type"); + env->err=2; + return; + } + + new_string= mangle_((const char *)(env->head->item->content.ptr)); + + toss(env); + if(env->err) return; + + new_value= malloc(sizeof(value)); + new_value->content.ptr= new_string; + new_value->type= string; + new_value->refcount=1; + + push_val(&(env->head), new_value); +} + /* Push a symbol onto the stack. */ void push_sym(environment *env, const char *in_string) { @@ -165,6 +260,8 @@ void *funcptr; /* A function pointer */ static void *handle= NULL; /* Dynamic linker handle */ + const char *dlerr; /* Dynamic linker error */ + char *mangled; /* Mangled function name */ /* Create a new stack item containing a new value */ new_item= malloc(sizeof(stackitem)); @@ -197,7 +294,14 @@ handle= dlopen(NULL, RTLD_LAZY); funcptr= dlsym(handle, in_string); /* Get function pointer */ - if(dlerror()==NULL) { /* If a function was found */ + dlerr=dlerror(); + if(dlerr != NULL) { /* If no function was found */ + mangled=mangle_(in_string); + funcptr= dlsym(handle, mangled); /* try mangling it */ + free(mangled); + dlerr=dlerror(); + } + if(dlerr==NULL) { /* If a function was found */ new_fvalue= malloc(sizeof(value)); /* Create a new value */ new_fvalue->type=func; /* The new value is a function pointer */ new_fvalue->content.ptr=funcptr; /* Store function pointer */ @@ -209,52 +313,6 @@ push(&(env->head), new_item); } -void printerr(const char* in_string) { - fprintf(stderr, "Err: %s\n", in_string); -} - -/* Throw away a value */ -void free_val(value *val){ - stackitem *item, *temp; - - val->refcount--; /* Decrease the reference count */ - if(val->refcount == 0){ - 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 */ - free_val(item->item); /* free the value */ - temp=item->next; /* save next ptr */ - free(item); /* free the stackitem */ - item=temp; /* go to next stackitem */ - } - free(val); /* Free the actual list value */ - break; - default: - break; - } - } -} - -/* Discard the top element of the stack. */ -extern void toss(environment *env) -{ - stackitem *temp= env->head; - - if((env->head)==NULL) { - printerr("Too Few Arguments"); - env->err=1; - return; - } - - free_val(env->head->item); /* Free the value */ - env->head= env->head->next; /* Remove the top stack item */ - free(temp); /* Free the old top stack item */ -} - /* Print newline. */ extern void nl() { @@ -843,3 +901,28 @@ quit(&myenv); return EXIT_FAILURE; } + +/* + */ +extern void sx_2b(environment *env) { + int a, b; + + if((env->head)==NULL || env->head->next==NULL) { + printerr("Too Few Arguments"); + env->err=1; + return; + } + + if(env->head->item->type!=integer + || env->head->next->item->type!=integer) { + printerr("Bad Argument Type"); + env->err=2; + return; + } + a=env->head->item->content.val; + toss(env); + if(env->err) return; + b=env->head->item->content.val; + toss(env); + if(env->err) return; + push_int(&(env->head), a+b); +}