/[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.29 by teddy, Tue Feb 5 12:14:42 2002 UTC
# Line 110  int push(stackitem** stack_head, stackit Line 110  int push(stackitem** stack_head, stackit
110    return 1;    return 1;
111  }  }
112    
113    /* Push a value onto the stack */
114    void push_val(stackitem **stack_head, value *val)
115    {
116      stackitem *new_item= malloc(sizeof(stackitem));
117      new_item->item= val;
118      val->refcount++;
119      push(stack_head, new_item);
120    }
121    
122  /* Push an integer onto the stack. */  /* Push an integer onto the stack. */
123  int push_val(stackitem **stack_head, int in_val)  int push_int(stackitem **stack_head, int in_val)
124  {  {
125    value *new_value= malloc(sizeof(value));    value *new_value= malloc(sizeof(value));
126    stackitem *new_item= malloc(sizeof(stackitem));    stackitem *new_item= malloc(sizeof(stackitem));
# Line 148  int push_sym(environment *env, const cha Line 157  int push_sym(environment *env, const cha
157    /* ...which will contain... */    /* ...which will contain... */
158    value *new_value;             /* A new symbol value */    value *new_value;             /* A new symbol value */
159    /* ...which might point to... */    /* ...which might point to... */
160    symbol *new_symbol;           /* (if needed) A new actual symbol */    symbol **new_symbol;          /* (if needed) A new actual symbol */
161    /* ...which, if possible, will be bound to... */    /* ...which, if possible, will be bound to... */
162    value *new_fvalue;            /* (if needed) A new function value */    value *new_fvalue;            /* (if needed) A new function value */
163    /* ...which will point to... */    /* ...which will point to... */
# Line 166  int push_sym(environment *env, const cha Line 175  int push_sym(environment *env, const cha
175    new_value->refcount= 1;    new_value->refcount= 1;
176    
177    /* Look up the symbol name in the hash table */    /* Look up the symbol name in the hash table */
178    new_value->content.ptr= *hash(env->symbols, in_string);    new_symbol= hash(env->symbols, in_string);
179      new_value->content.ptr= *new_symbol;
180    
181    if(new_value->content.ptr==NULL) { /* If symbol was undefined */    if(new_value->content.ptr==NULL) { /* If symbol was undefined */
182    
183      /* Create a new symbol */      /* Create a new symbol */
184      new_symbol= malloc(sizeof(symbol));      *new_symbol= malloc(sizeof(symbol));
185      new_symbol->val= NULL;      /* undefined value */      (*new_symbol)->val= NULL;   /* undefined value */
186      new_symbol->next= NULL;      (*new_symbol)->next= NULL;
187      new_symbol->id= malloc(strlen(in_string)+1);      (*new_symbol)->id= malloc(strlen(in_string)+1);
188      strcpy(new_symbol->id, in_string);      strcpy((*new_symbol)->id, in_string);
189    
190      /* Intern the new symbol in the hash table */      /* Intern the new symbol in the hash table */
191      new_value->content.ptr= new_symbol;      new_value->content.ptr= *new_symbol;
192    
193      /* 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
194         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 200  int push_sym(environment *env, const cha
200        new_fvalue= malloc(sizeof(value)); /* Create a new value */        new_fvalue= malloc(sizeof(value)); /* Create a new value */
201        new_fvalue->type=func;    /* The new value is a function pointer */        new_fvalue->type=func;    /* The new value is a function pointer */
202        new_fvalue->content.ptr=funcptr; /* Store function pointer */        new_fvalue->content.ptr=funcptr; /* Store function pointer */
203        new_symbol->val= new_fvalue;      /* Bind the symbol to the new        (*new_symbol)->val= new_fvalue; /* Bind the symbol to the new
204                                             function value */                                           function value */
205        new_fvalue->refcount= 1;        new_fvalue->refcount= 1;
206      }      }
207    }    }
# Line 339  stackitem* copy(stackitem* in_item) Line 349  stackitem* copy(stackitem* in_item)
349  }  }
350    
351    
352  /* If the top element is a reference, determine if it's a reference to a  /* If the top element is a symbol, determine if it's bound to a
353     function, and if it is, toss the reference and execute the function. */     function value, and if it is, toss the symbol and execute the
354       function. */
355  extern void eval(environment *env)  extern void eval(environment *env)
356  {  {
357    funcp in_func;    funcp in_func;
358    stackitem* temp= env->head;    value* val;
359      if(env->head==NULL) {
   if(temp==NULL) {  
360      printerr("Stack empty");      printerr("Stack empty");
361      return;      return;
362    }    }
363    
364    if(temp->item->type==symb    /* if it's a symbol */
365       && ((symbol *)(temp->item->content.ptr))->val != NULL    if(env->head->item->type==symb) {
366       && ((symbol *)(temp->item->content.ptr))->val->type == func) {  
367      in_func= (funcp)(((symbol *)(temp->item->content.ptr))->val->content.ptr);      /* If it's not bound to anything */
368      toss(env);      if (((symbol *)(env->head->item->content.ptr))->val == NULL) {
369      (*in_func)(env);        printerr("Unbound variable");
370      return;        return;
371    }      }
372            
373        /* If it contains a function */
374        if (((symbol *)(env->head->item->content.ptr))->val->type == func) {
375          in_func=
376            (funcp)(((symbol *)(env->head->item->content.ptr))->val->content.ptr);
377          toss(env);
378          (*in_func)(env);          /* Run the function */
379          return;
380        } else {                    /* If it's not a function */
381          val=((symbol *)(env->head->item->content.ptr))->val;
382          toss(env);                /* toss the symbol */
383          push_val(&(env->head), val); /* Return its bound value */
384        }
385      }
386    
387    if(temp->item->type==func) {    /* If it's a lone function value, run it */
388      in_func= (funcp)(temp->item->content.ptr);    if(env->head->item->type==func) {
389        in_func= (funcp)(env->head->item->content.ptr);
390      toss(env);      toss(env);
391      (*in_func)(env);      (*in_func)(env);
392      return;      return;
393    }    }
394    
395    push(&(env->head), copy(temp));  /*    push(&(env->head), copy(env->head)); */
396    swap(env);  /*    swap(env); */
397    toss(env);  /*    toss(env); */
398  }  }
399    
400  /* Make a list. */  /* Make a list. */
# Line 435  int stack_read(environment *env, char *i Line 459  int stack_read(environment *env, char *i
459      }      }
460      /* If integer */      /* If integer */
461      if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest))) {      if((convert= sscanf(in_line, "%d %[^\n\r]", &itemp, rest))) {
462        push_val(&(env->head), itemp);        push_int(&(env->head), itemp);
463        break;        break;
464      }      }
465      /* Escape ';' with '\' */      /* Escape ';' with '\' */
# Line 535  extern void eq(environment *env) Line 559  extern void eq(environment *env)
559    result= (left==right);    result= (left==right);
560        
561    toss(env); toss(env);    toss(env); toss(env);
562    push_val(&(env->head), result);    push_int(&(env->head), result);
563  }  }
564    
565  /* Negates the top element on the stack. */  /* Negates the top element on the stack. */
# Line 550  extern void not(environment *env) Line 574  extern void not(environment *env)
574    
575    val= env->head->item->content.val;    val= env->head->item->content.val;
576    toss(env);    toss(env);
577    push_val(&(env->head), !val);    push_int(&(env->head), !val);
578  }  }
579    
580  /* 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

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

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26