/[cvs]/stack/stack.c
ViewVC logotype

Diff of /stack/stack.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.28 by teddy, Mon Feb 4 21:47:26 2002 UTC revision 1.33 by teddy, Tue Feb 5 23:00:42 2002 UTC
# Line 58  typedef struct stackitem_struct Line 58  typedef struct stackitem_struct
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 */
# Line 110  int push(stackitem** stack_head, stackit Line 111  int push(stackitem** stack_head, stackit
111    return 1;    return 1;
112  }  }
113    
114    /* Push a value onto the stack */
115    void push_val(stackitem **stack_head, value *val)
116    {
117      stackitem *new_item= malloc(sizeof(stackitem));
118      new_item->item= val;
119      val->refcount++;
120      push(stack_head, new_item);
121    }
122    
123  /* Push an integer onto the stack. */  /* Push an integer onto the stack. */
124  int push_val(stackitem **stack_head, int in_val)  int push_int(stackitem **stack_head, int in_val)
125  {  {
126    value *new_value= malloc(sizeof(value));    value *new_value= malloc(sizeof(value));
127    stackitem *new_item= malloc(sizeof(stackitem));    stackitem *new_item= malloc(sizeof(stackitem));
# Line 148  int push_sym(environment *env, const cha Line 158  int push_sym(environment *env, const cha
158    /* ...which will contain... */    /* ...which will contain... */
159    value *new_value;             /* A new symbol value */    value *new_value;             /* A new symbol value */
160    /* ...which might point to... */    /* ...which might point to... */
161    symbol *new_symbol;           /* (if needed) A new actual symbol */    symbol **new_symbol;          /* (if needed) A new actual symbol */
162    /* ...which, if possible, will be bound to... */    /* ...which, if possible, will be bound to... */
163    value *new_fvalue;            /* (if needed) A new function value */    value *new_fvalue;            /* (if needed) A new function value */
164    /* ...which will point to... */    /* ...which will point to... */
# Line 166  int push_sym(environment *env, const cha Line 176  int push_sym(environment *env, const cha
176    new_value->refcount= 1;    new_value->refcount= 1;
177    
178    /* Look up the symbol name in the hash table */    /* Look up the symbol name in the hash table */
179    new_value->content.ptr= *hash(env->symbols, in_string);    new_symbol= hash(env->symbols, in_string);
180      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);
189      strcpy(new_symbol->id, in_string);      strcpy((*new_symbol)->id, in_string);
190    
191      /* Intern the new symbol in the hash table */      /* Intern the new symbol in the hash table */
192      new_value->content.ptr= new_symbol;      new_value->content.ptr= *new_symbol;
193    
194      /* Try to load the symbol name as an external function, to see if      /* Try to load the symbol name as an external function, to see if
195         we should bind the symbol to a new function pointer value */         we should bind the symbol to a new function pointer value */
# Line 190  int push_sym(environment *env, const cha Line 201  int push_sym(environment *env, const cha
201        new_fvalue= malloc(sizeof(value)); /* Create a new value */        new_fvalue= malloc(sizeof(value)); /* Create a new value */
202        new_fvalue->type=func;    /* The new value is a function pointer */        new_fvalue->type=func;    /* The new value is a function pointer */
203        new_fvalue->content.ptr=funcptr; /* Store function pointer */        new_fvalue->content.ptr=funcptr; /* Store function pointer */
204        new_symbol->val= new_fvalue;      /* Bind the symbol to the new        (*new_symbol)->val= new_fvalue; /* Bind the symbol to the new
205                                             function value */                                           function value */
206        new_fvalue->refcount= 1;        new_fvalue->refcount= 1;
207      }      }
208    }    }
# Line 244  extern void toss(environment *env) Line 255  extern void toss(environment *env)
255  }  }
256    
257  /* Print newline. */  /* Print newline. */
258  extern void nl()  extern void nl(environment *env)
259  {  {
260    printf("\n");    printf("\n");
261  }  }
# Line 338  stackitem* copy(stackitem* in_item) Line 349  stackitem* copy(stackitem* in_item)
349    return out_item;    return out_item;
350  }  }
351    
352    /* Recall a value from a symbol, if bound */
353  /* If the top element is a reference, determine if it's a reference to a  extern void rcl(environment *env)
    function, and if it is, toss the reference and execute the function. */  
 extern void eval(environment *env)  
354  {  {
355    funcp in_func;    value *val;
   stackitem* temp= env->head;  
356    
357    if(temp==NULL) {    if(env->head == NULL) {
358      printerr("Stack empty");      printerr("Stack empty");
359      return;      return;
360    }    }
361    
362    if(temp->item->type==symb    if(env->head->item->type!=symb) {
363       && ((symbol *)(temp->item->content.ptr))->val != NULL      printerr("Not a symbol");
364       && ((symbol *)(temp->item->content.ptr))->val->type == func) {      return;
365      in_func= (funcp)(((symbol *)(temp->item->content.ptr))->val->content.ptr);    }
366      toss(env);    val=((symbol *)(env->head->item->content.ptr))->val;
367      (*in_func)(env);    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
376       function value, and if it is, toss the symbol and execute the
377       function. */
378    extern void eval(environment *env)
379    {
380      funcp in_func;
381      value* val;
382      if(env->head==NULL) {
383        printerr("Stack empty");
384      return;      return;
385    }    }
386    
387      /* if it's a symbol */
388      if(env->head->item->type==symb) {
389    
390        /* If it's not bound to anything */
391        if (((symbol *)(env->head->item->content.ptr))->val == NULL) {
392          printerr("Unbound variable");
393          return;
394        }
395            
396        /* If it contains a function */
397        if (((symbol *)(env->head->item->content.ptr))->val->type == func) {
398          in_func=
399            (funcp)(((symbol *)(env->head->item->content.ptr))->val->content.ptr);
400          toss(env);
401          (*in_func)(env);          /* Run the function */
402          return;
403        } else {                    /* If it's not a function */
404          val=((symbol *)(env->head->item->content.ptr))->val;
405          toss(env);                /* toss the symbol */
406          push_val(&(env->head), val); /* Return its bound value */
407        }
408      }
409    
410    if(temp->item->type==func) {    /* If it's a lone function value, run it */
411      in_func= (funcp)(temp->item->content.ptr);    if(env->head->item->type==func) {
412        in_func= (funcp)(env->head->item->content.ptr);
413      toss(env);      toss(env);
414      (*in_func)(env);      (*in_func)(env);
415      return;      return;
416    }    }
417    
   push(&(env->head), copy(temp));  
   swap(env);  
   toss(env);  
418  }  }
419    
420  /* Make a list. */  /* Make a list. */
# Line 435  int stack_read(environment *env, char *i Line 479  int stack_read(environment *env, char *i
479      }      }
480      /* If integer */      /* If integer */
481      if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest))) {      if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest))) {
482        push_val(&(env->head), itemp);        push_int(&(env->head), itemp);
483        break;        break;
484      }      }
485      /* Escape ';' with '\' */      /* Escape ';' with '\' */
# Line 535  extern void eq(environment *env) Line 579  extern void eq(environment *env)
579    result= (left==right);    result= (left==right);
580        
581    toss(env); toss(env);    toss(env); toss(env);
582    push_val(&(env->head), result);    push_int(&(env->head), result);
583  }  }
584    
585  /* Negates the top element on the stack. */  /* Negates the top element on the stack. */
# Line 550  extern void not(environment *env) Line 594  extern void not(environment *env)
594    
595    val= env->head->item->content.val;    val= env->head->item->content.val;
596    toss(env);    toss(env);
597    push_val(&(env->head), !val);    push_int(&(env->head), !val);
598  }  }
599    
600  /* Compares the two top elements on the stack and return 0 if they're the  /* Compares the two top elements on the stack and return 0 if they're the
# Line 600  extern void clear(environment *env) Line 644  extern void clear(environment *env)
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  int main()  int main()
663  {  {
664    environment myenv;    environment myenv;

Legend:
Removed from v.1.28  
changed lines
  Added in v.1.33

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26