storage.c

Go to the documentation of this file.
00001 /* storage.c:  Code and data storage manipulations.  This includes labels. */
00002 
00003 /*  This file is part of bc written for MINIX.
00004     Copyright (C) 1991, 1992 Free Software Foundation, Inc.
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License , or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; see the file COPYING.  If not, write to
00018     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
00019 
00020     You may contact the author by:
00021        e-mail:  phil@cs.wwu.edu
00022       us-mail:  Philip A. Nelson
00023                 Computer Science Department, 9062
00024                 Western Washington University
00025                 Bellingham, WA 98226-9062
00026        
00027 *************************************************************************/
00028 
00029 #include "bcdefs.h"
00030 #include "global.h"
00031 #include "proto.h"
00032 
00033 
00034 /* Initialize the storage at the beginning of the run. */
00035 
00036 void
00037 init_storage ()
00038 {
00039 
00040   /* Functions: we start with none and ask for more. */
00041   f_count = 0;
00042   more_functions ();
00043   f_names[0] = "(main)";
00044 
00045   /* Variables. */
00046   v_count = 0;
00047   more_variables ();
00048   
00049   /* Arrays. */
00050   a_count = 0;
00051   more_arrays ();
00052 
00053   /* Other things... */
00054   ex_stack = NULL;
00055   fn_stack = NULL;
00056   i_base = 10;
00057   o_base = 10;
00058   scale  = 0;
00059   c_code = FALSE;
00060   init_numbers();
00061 }
00062 
00063 /* Three functions for increasing the number of functions, variables, or
00064    arrays that are needed.  This adds another 32 of the requested object. */
00065 
00066 void
00067 more_functions (VOID)
00068 {
00069   int old_count;
00070   int indx1, indx2;
00071   bc_function *old_f;
00072   bc_function *f;
00073   char **old_names;
00074 
00075   /* Save old information. */
00076   old_count = f_count;
00077   old_f = functions;
00078   old_names = f_names;
00079 
00080   /* Add a fixed amount and allocate new space. */
00081   f_count += STORE_INCR;
00082   functions = (bc_function *) bc_malloc (f_count*sizeof (bc_function));
00083   f_names = (char **) bc_malloc (f_count*sizeof (char *));
00084 
00085   /* Copy old ones. */
00086   for (indx1 = 0; indx1 < old_count; indx1++)
00087     {
00088       functions[indx1] = old_f[indx1];
00089       f_names[indx1] = old_names[indx1];
00090     }
00091 
00092   /* Initialize the new ones. */
00093   for (; indx1 < f_count; indx1++)
00094     {
00095       f = &functions[indx1];
00096       f->f_defined = FALSE;
00097       for (indx2 = 0; indx2 < BC_MAX_SEGS; indx2++)
00098         f->f_body [indx2] = NULL;
00099       f->f_code_size = 0;
00100       f->f_label = NULL;
00101       f->f_autos = NULL;
00102       f->f_params = NULL;
00103     }
00104 
00105   /* Free the old elements. */
00106   if (old_count != 0)
00107     {
00108       free (old_f);
00109       free (old_names);
00110     }
00111 }
00112 
00113 void
00114 more_variables ()
00115 {
00116   int indx;
00117   int old_count;
00118   bc_var **old_var;
00119   char **old_names;
00120 
00121   /* Save the old values. */
00122   old_count = v_count;
00123   old_var = variables;
00124   old_names = v_names;
00125 
00126   /* Increment by a fixed amount and allocate. */
00127   v_count += STORE_INCR;
00128   variables = (bc_var **) bc_malloc (v_count*sizeof(bc_var *));
00129   v_names = (char **) bc_malloc (v_count*sizeof(char *));
00130 
00131   /* Copy the old variables. */
00132   for (indx = 3; indx < old_count; indx++)
00133     variables[indx] = old_var[indx];
00134 
00135   /* Initialize the new elements. */
00136   for (; indx < v_count; indx++)
00137     variables[indx] = NULL;
00138 
00139   /* Free the old elements. */
00140   if (old_count != 0)
00141     {
00142       free (old_var);
00143       free (old_names);
00144     }
00145 }
00146 
00147 void
00148 more_arrays ()
00149 {
00150   int indx;
00151   int old_count;
00152   bc_var_array **old_ary;
00153   char **old_names;
00154 
00155   /* Save the old values. */
00156   old_count = a_count;
00157   old_ary = arrays;
00158   old_names = a_names;
00159 
00160   /* Increment by a fixed amount and allocate. */
00161   a_count += STORE_INCR;
00162   arrays = (bc_var_array **) bc_malloc (a_count*sizeof(bc_var_array *));
00163   a_names = (char **) bc_malloc (a_count*sizeof(char *));
00164 
00165   /* Copy the old arrays. */
00166   for (indx = 1; indx < old_count; indx++)
00167     arrays[indx] = old_ary[indx];
00168 
00169 
00170   /* Initialize the new elements. */
00171   for (; indx < v_count; indx++)
00172     arrays[indx] = NULL;
00173 
00174   /* Free the old elements. */
00175   if (old_count != 0)
00176     {
00177       free (old_ary);
00178       free (old_names);
00179     }
00180 }
00181 
00182 
00183 /* clear_func clears out function FUNC and makes it ready to redefine. */
00184 
00185 void
00186 clear_func (func)
00187      char func;
00188 {
00189   bc_function *f;
00190   int indx;
00191   bc_label_group *lg;
00192 
00193   /* Set the pointer to the function. */
00194   f = &functions[func];
00195   f->f_defined = FALSE;
00196 
00197   /* Clear the code segments. */
00198   for (indx = 0; indx < BC_MAX_SEGS; indx++)
00199     {
00200       if (f->f_body[indx] != NULL)
00201         {
00202           free (f->f_body[indx]);
00203           f->f_body[indx] = NULL;
00204         }
00205     }
00206 
00207   f->f_code_size = 0;
00208   if (f->f_autos != NULL)
00209     {
00210       free_args (f->f_autos);
00211       f->f_autos = NULL;
00212     }
00213   if (f->f_params != NULL)
00214     {
00215       free_args (f->f_params);
00216       f->f_params = NULL;
00217     }
00218   while (f->f_label != NULL)
00219     {
00220       lg = f->f_label->l_next;
00221       free (f->f_label);
00222       f->f_label = lg;
00223     }
00224 }
00225 
00226 
00227 /*  Pop the function execution stack and return the top. */
00228 
00229 int
00230 fpop()
00231 {
00232   fstack_rec *temp;
00233   int retval;
00234   
00235   if (fn_stack != NULL)
00236     {
00237       temp = fn_stack;
00238       fn_stack = temp->s_next;
00239       retval = temp->s_val;
00240       free (temp);
00241     }
00242   return (retval);
00243 }
00244 
00245 
00246 /* Push VAL on to the function stack. */
00247 
00248 void
00249 fpush (val)
00250      int val;
00251 {
00252   fstack_rec *temp;
00253   
00254   temp = (fstack_rec *) bc_malloc (sizeof (fstack_rec));
00255   temp->s_next = fn_stack;
00256   temp->s_val = val;
00257   fn_stack = temp;
00258 }
00259 
00260 
00261 /* Pop and discard the top element of the regular execution stack. */
00262 
00263 void
00264 pop ()
00265 {
00266   estack_rec *temp;
00267   
00268   if (ex_stack != NULL)
00269     {
00270       temp = ex_stack;
00271       ex_stack = temp->s_next;
00272       free_num (&temp->s_num);
00273       free (temp);
00274     }
00275 }
00276 
00277 
00278 /* Push a copy of NUM on to the regular execution stack. */
00279 
00280 void
00281 push_copy (num)
00282      bc_num num;
00283 {
00284   estack_rec *temp;
00285 
00286   temp = (estack_rec *) bc_malloc (sizeof (estack_rec));
00287   temp->s_num = copy_num (num);
00288   temp->s_next = ex_stack;
00289   ex_stack = temp;
00290 }
00291 
00292 
00293 /* Push NUM on to the regular execution stack.  Do NOT push a copy. */
00294 
00295 void
00296 push_num (num)
00297      bc_num num;
00298 {
00299   estack_rec *temp;
00300 
00301   temp = (estack_rec *) bc_malloc (sizeof (estack_rec));
00302   temp->s_num = num;
00303   temp->s_next = ex_stack;
00304   ex_stack = temp;
00305 }
00306 
00307 
00308 /* Make sure the ex_stack has at least DEPTH elements on it.
00309    Return TRUE if it has at least DEPTH elements, otherwise
00310    return FALSE. */
00311 
00312 char
00313 check_stack (depth)
00314      int depth;
00315 {
00316   estack_rec *temp;
00317 
00318   temp = ex_stack;
00319   while ((temp != NULL) && (depth > 0))
00320     {
00321       temp = temp->s_next;
00322       depth--;
00323     }
00324   if (depth > 0)
00325     {
00326       rt_error ("Stack error.");
00327       return FALSE;
00328     }
00329   return TRUE;
00330 }
00331 
00332 
00333 /* The following routines manipulate simple variables and
00334    array variables. */
00335 
00336 /* get_var returns a pointer to the variable VAR_NAME.  If one does not
00337    exist, one is created. */
00338 
00339 bc_var *
00340 get_var (var_name)
00341      int var_name;
00342 {
00343   bc_var *var_ptr;
00344 
00345   var_ptr = variables[var_name];
00346   if (var_ptr == NULL)
00347     {
00348       var_ptr = variables[var_name] = (bc_var *) bc_malloc (sizeof (bc_var));
00349       init_num (&var_ptr->v_value);
00350     }
00351   return var_ptr;
00352 }
00353 
00354 
00355 /* get_array_num returns the address of the bc_num in the array
00356    structure.  If more structure is requried to get to the index,
00357    this routine does the work to create that structure. VAR_INDEX
00358    is a zero based index into the arrays storage array. INDEX is
00359    the index into the bc array. */
00360 
00361 bc_num *
00362 get_array_num (var_index, index)
00363      int var_index;
00364      long  index;
00365 {
00366   bc_var_array *ary_ptr;
00367   bc_array *a_var;
00368   bc_array_node *temp;
00369   int log, ix, ix1;
00370   int sub [NODE_DEPTH];
00371 
00372   /* Get the array entry. */
00373   ary_ptr = arrays[var_index];
00374   if (ary_ptr == NULL)
00375     {
00376       ary_ptr = arrays[var_index] =
00377         (bc_var_array *) bc_malloc (sizeof (bc_var_array));
00378       ary_ptr->a_value = NULL;
00379       ary_ptr->a_next = NULL;
00380       ary_ptr->a_param = FALSE;
00381     }
00382 
00383   a_var = ary_ptr->a_value;
00384   if (a_var == NULL) {
00385     a_var = ary_ptr->a_value = (bc_array *) bc_malloc (sizeof (bc_array));
00386     a_var->a_tree = NULL;
00387     a_var->a_depth = 0;
00388   }
00389 
00390   /* Get the index variable. */
00391   sub[0] = index & NODE_MASK;
00392   ix = index >> NODE_SHIFT;
00393   log = 1;
00394   while (ix > 0 || log < a_var->a_depth)
00395     {
00396       sub[log] = ix & NODE_MASK;
00397       ix >>= NODE_SHIFT;
00398       log++;
00399     }
00400   
00401   /* Build any tree that is necessary. */
00402   while (log > a_var->a_depth)
00403     {
00404       temp = (bc_array_node *) bc_malloc (sizeof(bc_array_node));
00405       if (a_var->a_depth != 0)
00406         {
00407           temp->n_items.n_down[0] = a_var->a_tree;
00408           for (ix=1; ix < NODE_SIZE; ix++)
00409             temp->n_items.n_down[ix] = NULL;
00410         }
00411       else
00412         {
00413           for (ix=0; ix < NODE_SIZE; ix++)
00414             temp->n_items.n_num[ix] = copy_num(_zero_);
00415         }
00416       a_var->a_tree = temp;
00417       a_var->a_depth++;
00418     }
00419   
00420   /* Find the indexed variable. */
00421   temp = a_var->a_tree;
00422   while ( log-- > 1)
00423     {
00424       ix1 = sub[log];
00425       if (temp->n_items.n_down[ix1] == NULL)
00426         {
00427           temp->n_items.n_down[ix1] =
00428             (bc_array_node *) bc_malloc (sizeof(bc_array_node));
00429           temp = temp->n_items.n_down[ix1];
00430           if (log > 1)
00431             for (ix=0; ix < NODE_SIZE; ix++)
00432               temp->n_items.n_down[ix] = NULL;
00433           else
00434             for (ix=0; ix < NODE_SIZE; ix++)
00435               temp->n_items.n_num[ix] = copy_num(_zero_);
00436         }
00437       else
00438         temp = temp->n_items.n_down[ix1];
00439     }
00440   
00441   /* Return the address of the indexed variable. */
00442   return &(temp->n_items.n_num[sub[0]]);
00443 }
00444 
00445 
00446 /* Store the top of the execution stack into VAR_NAME.  
00447    This includes the special variables ibase, obase, and scale. */
00448 
00449 void
00450 store_var (var_name)
00451      int var_name;
00452 {
00453   bc_var *var_ptr;
00454   long temp;
00455   char toobig;
00456 
00457   if (var_name > 2)
00458     {
00459       /* It is a simple variable. */
00460       var_ptr = get_var (var_name);
00461       if (var_ptr != NULL)
00462         {
00463           free_num(&var_ptr->v_value);
00464           var_ptr->v_value = copy_num (ex_stack->s_num);
00465         }
00466     }
00467   else
00468     {
00469       /* It is a special variable... */
00470       toobig = FALSE;
00471       if (is_neg (ex_stack->s_num))
00472         {
00473           switch (var_name)
00474             {
00475             case 0:
00476               rt_warn ("negative ibase, set to 2");
00477               temp = 2;
00478               break;
00479             case 1:
00480               rt_warn ("negative obase, set to 2");
00481               temp = 2;
00482               break;
00483             case 2:
00484               rt_warn ("negative scale, set to 0");
00485               temp = 0;
00486               break;
00487             }
00488         }
00489       else
00490         {
00491           temp = num2long (ex_stack->s_num);
00492           if (!is_zero (ex_stack->s_num) && temp == 0)
00493             toobig = TRUE;
00494         }
00495       switch (var_name)
00496         {
00497         case 0:
00498           if (temp < 2 && !toobig)
00499             {
00500               i_base = 2;
00501               rt_warn ("ibase too small, set to 2");
00502             }
00503           else
00504             if (temp > 16 || toobig)
00505               {
00506                 i_base = 16;
00507                 rt_warn ("ibase too large, set to 16");
00508               }
00509             else
00510               i_base = (int) temp;
00511           break;
00512 
00513         case 1:
00514           if (temp < 2 && !toobig)
00515             {
00516               o_base = 2;
00517               rt_warn ("obase too small, set to 2");
00518             }
00519           else
00520             if (temp > BC_BASE_MAX || toobig)
00521               {
00522                 o_base = BC_BASE_MAX;
00523                 rt_warn ("obase too large, set to %d", BC_BASE_MAX);
00524               }
00525             else
00526               o_base = (int) temp;
00527           break;
00528 
00529         case 2:
00530           /*  WARNING:  The following if statement may generate a compiler
00531               warning if INT_MAX == LONG_MAX.  This is NOT a problem. */
00532           if (temp > BC_SCALE_MAX || toobig )
00533             {
00534               scale = BC_SCALE_MAX;
00535               rt_warn ("scale too large, set to %d", BC_SCALE_MAX);
00536             }
00537           else
00538             scale = (int) temp;
00539         }
00540     }
00541 }
00542 
00543 
00544 /* Store the top of the execution stack into array VAR_NAME. 
00545    VAR_NAME is the name of an array, and the next to the top
00546    of stack for the index into the array. */
00547 
00548 void
00549 store_array (var_name)
00550      int var_name;
00551 {
00552   bc_num *num_ptr;
00553   long index;
00554 
00555   if (!check_stack(2)) return;
00556   index = num2long (ex_stack->s_next->s_num);
00557   if (index < 0 || index > BC_DIM_MAX ||
00558       (index == 0 && !is_zero(ex_stack->s_next->s_num))) 
00559     rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
00560   else
00561     {
00562       num_ptr = get_array_num (var_name, index);
00563       if (num_ptr != NULL)
00564         {
00565           free_num (num_ptr);
00566           *num_ptr = copy_num (ex_stack->s_num);
00567           free_num (&ex_stack->s_next->s_num);
00568           ex_stack->s_next->s_num = ex_stack->s_num;
00569           init_num (&ex_stack->s_num);
00570           pop();
00571         }
00572     }
00573 }
00574 
00575 
00576 /*  Load a copy of VAR_NAME on to the execution stack.  This includes
00577     the special variables ibase, obase and scale.  */
00578 
00579 void
00580 load_var (var_name)
00581      int var_name;
00582 {
00583   bc_var *var_ptr;
00584 
00585   switch (var_name)
00586     {
00587 
00588     case 0:
00589       /* Special variable ibase. */
00590       push_copy (_zero_);
00591       int2num (&ex_stack->s_num, i_base);
00592       break;
00593 
00594     case 1:
00595       /* Special variable obase. */
00596       push_copy (_zero_);
00597       int2num (&ex_stack->s_num, o_base);
00598       break;
00599 
00600     case 2:
00601       /* Special variable scale. */
00602       push_copy (_zero_);
00603       int2num (&ex_stack->s_num, scale);
00604       break;
00605 
00606     default:
00607       /* It is a simple variable. */
00608       var_ptr = variables[var_name];
00609       if (var_ptr != NULL)
00610         push_copy (var_ptr->v_value);
00611       else
00612         push_copy (_zero_);
00613     }
00614 }
00615 
00616 
00617 /*  Load a copy of VAR_NAME on to the execution stack.  This includes
00618     the special variables ibase, obase and scale.  */
00619 
00620 void
00621 load_array (var_name)
00622      int var_name;
00623 {
00624   bc_num *num_ptr;
00625   long   index;
00626 
00627   if (!check_stack(1)) return;
00628   index = num2long (ex_stack->s_num);
00629   if (index < 0 || index > BC_DIM_MAX ||
00630      (index == 0 && !is_zero(ex_stack->s_num))) 
00631     rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
00632   else
00633     {
00634       num_ptr = get_array_num (var_name, index);
00635       if (num_ptr != NULL)
00636         {
00637           pop();
00638           push_copy (*num_ptr);
00639         }
00640     }
00641 }
00642 
00643 
00644 /* Decrement VAR_NAME by one.  This includes the special variables
00645    ibase, obase, and scale. */
00646 
00647 void
00648 decr_var (var_name)
00649      int var_name;
00650 {
00651   bc_var *var_ptr;
00652 
00653   switch (var_name)
00654     {
00655 
00656     case 0: /* ibase */
00657       if (i_base > 2)
00658         i_base--;
00659       else
00660         rt_warn ("ibase too small in --");
00661       break;
00662       
00663     case 1: /* obase */
00664       if (o_base > 2)
00665         o_base--;
00666       else
00667         rt_warn ("obase too small in --");
00668       break;
00669 
00670     case 2: /* scale */
00671       if (scale > 0)
00672         scale--;
00673       else
00674         rt_warn ("scale can not be negative in -- ");
00675       break;
00676 
00677     default: /* It is a simple variable. */
00678       var_ptr = get_var (var_name);
00679       if (var_ptr != NULL)
00680         bc_sub (var_ptr->v_value,_one_,&var_ptr->v_value);
00681     }
00682 }
00683 
00684 
00685 /* Decrement VAR_NAME by one.  VAR_NAME is an array, and the top of
00686    the execution stack is the index and it is popped off the stack. */
00687 
00688 void
00689 decr_array (var_name)
00690      char var_name;
00691 {
00692   bc_num *num_ptr;
00693   long   index;
00694 
00695   /* It is an array variable. */
00696   if (!check_stack (1)) return;
00697   index = num2long (ex_stack->s_num);
00698   if (index < 0 || index > BC_DIM_MAX ||
00699      (index == 0 && !is_zero (ex_stack->s_num))) 
00700     rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
00701   else
00702     {
00703       num_ptr = get_array_num (var_name, index);
00704       if (num_ptr != NULL)
00705         {
00706           pop ();
00707           bc_sub (*num_ptr, _one_, num_ptr);
00708         }
00709     }
00710 }
00711 
00712 
00713 /* Increment VAR_NAME by one.  This includes the special variables
00714    ibase, obase, and scale. */
00715 
00716 void
00717 incr_var (var_name)
00718      int var_name;
00719 {
00720   bc_var *var_ptr;
00721 
00722   switch (var_name)
00723     {
00724 
00725     case 0: /* ibase */
00726       if (i_base < 16)
00727         i_base++;
00728       else
00729         rt_warn ("ibase too big in ++");
00730       break;
00731 
00732     case 1: /* obase */
00733       if (o_base < BC_BASE_MAX)
00734         o_base++;
00735       else
00736         rt_warn ("obase too big in ++");
00737       break;
00738 
00739     case 2:
00740       if (scale < BC_SCALE_MAX)
00741         scale++;
00742       else
00743         rt_warn ("Scale too big in ++");
00744       break;
00745 
00746     default:  /* It is a simple variable. */
00747       var_ptr = get_var (var_name);
00748       if (var_ptr != NULL)
00749         bc_add (var_ptr->v_value, _one_, &var_ptr->v_value);
00750 
00751     }
00752 }
00753 
00754 
00755 /* Increment VAR_NAME by one.  VAR_NAME is an array and top of
00756    execution stack is the index and is popped off the stack. */
00757 
00758 void
00759 incr_array (var_name)
00760      int var_name;
00761 {
00762   bc_num *num_ptr;
00763   long   index;
00764 
00765   if (!check_stack (1)) return;
00766   index = num2long (ex_stack->s_num);
00767   if (index < 0 || index > BC_DIM_MAX ||
00768       (index == 0 && !is_zero (ex_stack->s_num))) 
00769     rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
00770   else
00771     {
00772       num_ptr = get_array_num (var_name, index);
00773       if (num_ptr != NULL)
00774         {
00775           pop ();
00776           bc_add (*num_ptr, _one_, num_ptr);
00777         }
00778     }
00779 }
00780 
00781 
00782 /* Routines for processing autos variables and parameters. */
00783 
00784 /* NAME is an auto variable that needs to be pushed on its stack. */
00785 
00786 void
00787 auto_var (name)
00788      int name;
00789 {
00790   bc_var *v_temp;
00791   bc_var_array *a_temp;
00792   int ix;
00793 
00794   if (name > 0)
00795     {
00796       /* A simple variable. */
00797       ix = name;
00798       v_temp = (bc_var *) bc_malloc (sizeof (bc_var));
00799       v_temp->v_next = variables[ix];
00800       init_num (&v_temp->v_value);
00801       variables[ix] = v_temp;
00802     }
00803   else
00804     {
00805       /* An array variable. */
00806       ix = -name;
00807       a_temp = (bc_var_array *) bc_malloc (sizeof (bc_var_array));
00808       a_temp->a_next = arrays[ix];
00809       a_temp->a_value = NULL;
00810       a_temp->a_param = FALSE;
00811       arrays[ix] = a_temp;
00812     } 
00813 }
00814 
00815 
00816 /* Free_a_tree frees everything associated with an array variable tree.
00817    This is used when popping an array variable off its auto stack.  */
00818 
00819 void
00820 free_a_tree ( root, depth )
00821      bc_array_node *root;
00822      int depth;
00823 {
00824   int ix;
00825 
00826   if (root != NULL)
00827     {
00828       if (depth > 1)
00829         for (ix = 0; ix < NODE_SIZE; ix++)
00830           free_a_tree (root->n_items.n_down[ix], depth-1);
00831       else
00832         for (ix = 0; ix < NODE_SIZE; ix++)
00833           free_num ( &(root->n_items.n_num[ix]));
00834       free (root);
00835     }
00836 }
00837 
00838 
00839 /* LIST is an NULL terminated list of varible names that need to be
00840    popped off their auto stacks. */
00841 
00842 void
00843 pop_vars (list)
00844      arg_list *list;
00845 {
00846   bc_var *v_temp;
00847   bc_var_array *a_temp;
00848   int    ix;
00849 
00850   while (list != NULL)
00851     {
00852       ix = list->av_name;
00853       if (ix > 0)
00854         {
00855           /* A simple variable. */
00856           v_temp = variables[ix];
00857           if (v_temp != NULL)
00858             {
00859               variables[ix] = v_temp->v_next;
00860               free_num (&v_temp->v_value);
00861               free (v_temp);
00862             }
00863         }
00864       else
00865         {
00866           /* An array variable. */
00867           ix = -ix;
00868           a_temp = arrays[ix];
00869           if (a_temp != NULL)
00870             {
00871               arrays[ix] = a_temp->a_next;
00872               if (!a_temp->a_param && a_temp->a_value != NULL)
00873                 {
00874                   free_a_tree (a_temp->a_value->a_tree,
00875                                a_temp->a_value->a_depth);
00876                   free (a_temp->a_value);
00877                 }
00878               free (a_temp);
00879             }
00880         } 
00881       list = list->next;
00882     }
00883 }
00884 
00885 
00886 /* A call is being made to FUNC.  The call types are at PC.  Process
00887    the parameters by doing an auto on the parameter variable and then
00888    store the value at the new variable or put a pointer the the array
00889    variable. */
00890 
00891 void
00892 process_params (pc, func)
00893      program_counter *pc;
00894      int func;
00895 {
00896   char ch;
00897   arg_list *params;
00898   char warned = FALSE;
00899   int ix, ix1;
00900   bc_var *v_temp;
00901   bc_var_array *a_src, *a_dest;
00902   bc_num *n_temp;
00903   
00904   /* Get the parameter names from the function. */
00905   params = functions[func].f_params;
00906 
00907   while ((ch = byte(pc)) != ':')
00908     {
00909       if (params != NULL)
00910         {
00911           if ((ch == '0') && params->av_name > 0)
00912             {
00913               /* A simple variable. */
00914               ix = params->av_name;
00915               v_temp = (bc_var *) bc_malloc (sizeof(bc_var));
00916               v_temp->v_next = variables[ix];
00917               v_temp->v_value = ex_stack->s_num;
00918               init_num (&ex_stack->s_num);
00919               variables[ix] = v_temp;
00920             }
00921           else
00922             if ((ch == '1') && (params->av_name < 0))
00923               {
00924                 /* The variables is an array variable. */
00925         
00926                 /* Compute source index and make sure some structure exists. */
00927                 ix = (int) num2long (ex_stack->s_num);
00928                 n_temp = get_array_num (ix, 0);    
00929         
00930                 /* Push a new array and Compute Destination index */
00931                 auto_var (params->av_name);  
00932                 ix1 = -params->av_name;
00933 
00934                 /* Set up the correct pointers in the structure. */
00935                 if (ix == ix1) 
00936                   a_src = arrays[ix]->a_next;
00937                 else
00938                   a_src = arrays[ix];
00939                 a_dest = arrays[ix1];
00940                 a_dest->a_param = TRUE;
00941                 a_dest->a_value = a_src->a_value;
00942               }
00943             else
00944               {
00945                 if (params->av_name < 0)
00946                   rt_error ("Parameter type mismatch parameter %s.",
00947                             a_names[-params->av_name]);
00948                 else
00949                   rt_error ("Parameter type mismatch, parameter %s.",
00950                             v_names[params->av_name]);
00951                 params++;
00952               }
00953           pop ();
00954         }
00955       else
00956         {
00957           if (!warned)
00958             {
00959               rt_error ("Parameter number mismatch");
00960               warned = TRUE;
00961             }
00962         }
00963       params = params->next;
00964     }
00965   if (params != NULL) 
00966     rt_error ("Parameter number mismatch");
00967 }

Generated on Fri Apr 14 22:56:45 2006 for minix by  doxygen 1.4.6