1 /* storage.c: Code and data storage manipulations. This includes labels. */
3 /* This file is part of GNU bc.
4 Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License , or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not, write to
18 The Free Software Foundation, Inc.
19 59 Temple Place, Suite 330
22 You may contact the author by:
23 e-mail: philnelson@acm.org
24 us-mail: Philip A. Nelson
25 Computer Science Department, 9062
26 Western Washington University
27 Bellingham, WA 98226-9062
29 *************************************************************************/
36 /* Initialize the storage at the beginning of the run. */
42 /* Functions: we start with none and ask for more. */
45 f_names[0] = "(main)";
61 #if defined(READLINE) || defined(LIBEDIT)
68 /* Three functions for increasing the number of functions, variables, or
69 arrays that are needed. This adds another 32 of the requested object. */
80 /* Save old information. */
85 /* Add a fixed amount and allocate new space. */
86 f_count += STORE_INCR;
87 functions = (bc_function *) bc_malloc (f_count*sizeof (bc_function));
88 f_names = (char **) bc_malloc (f_count*sizeof (char *));
91 for (indx = 0; indx < old_count; indx++)
93 functions[indx] = old_f[indx];
94 f_names[indx] = old_names[indx];
97 /* Initialize the new ones. */
98 for (; indx < f_count; indx++)
100 f = &functions[indx];
101 f->f_defined = FALSE;
102 f->f_body = (char *) bc_malloc (BC_START_SIZE);
103 f->f_body_size = BC_START_SIZE;
110 /* Free the old elements. */
126 /* Save the old values. */
131 /* Increment by a fixed amount and allocate. */
132 v_count += STORE_INCR;
133 variables = (bc_var **) bc_malloc (v_count*sizeof(bc_var *));
134 v_names = (char **) bc_malloc (v_count*sizeof(char *));
136 /* Copy the old variables. */
137 for (indx = 3; indx < old_count; indx++)
138 variables[indx] = old_var[indx];
140 /* Initialize the new elements. */
141 for (; indx < v_count; indx++)
142 variables[indx] = NULL;
144 /* Free the old elements. */
157 bc_var_array **old_ary;
160 /* Save the old values. */
165 /* Increment by a fixed amount and allocate. */
166 a_count += STORE_INCR;
167 arrays = (bc_var_array **) bc_malloc (a_count*sizeof(bc_var_array *));
168 a_names = (char **) bc_malloc (a_count*sizeof(char *));
170 /* Copy the old arrays. */
171 for (indx = 1; indx < old_count; indx++)
172 arrays[indx] = old_ary[indx];
175 /* Initialize the new elements. */
176 for (; indx < v_count; indx++)
179 /* Free the old elements. */
188 /* clear_func clears out function FUNC and makes it ready to redefine. */
197 /* Set the pointer to the function. */
198 f = &functions[func];
199 f->f_defined = FALSE;
200 /* XXX restore f_body to initial size??? */
202 if (f->f_autos != NULL)
204 free_args (f->f_autos);
207 if (f->f_params != NULL)
209 free_args (f->f_params);
212 while (f->f_label != NULL)
214 lg = f->f_label->l_next;
221 /* Pop the function execution stack and return the top. */
229 if (fn_stack != NULL)
232 fn_stack = temp->s_next;
233 retval = temp->s_val;
239 rt_error ("function stack underflow, contact maintainer.");
245 /* Push VAL on to the function stack. */
253 temp = (fstack_rec *) bc_malloc (sizeof (fstack_rec));
254 temp->s_next = fn_stack;
260 /* Pop and discard the top element of the regular execution stack. */
267 if (ex_stack != NULL)
270 ex_stack = temp->s_next;
271 bc_free_num (&temp->s_num);
277 /* Push a copy of NUM on to the regular execution stack. */
285 temp = (estack_rec *) bc_malloc (sizeof (estack_rec));
286 temp->s_num = bc_copy_num (num);
287 temp->s_next = ex_stack;
292 /* Push NUM on to the regular execution stack. Do NOT push a copy. */
300 temp = (estack_rec *) bc_malloc (sizeof (estack_rec));
302 temp->s_next = ex_stack;
307 /* Make sure the ex_stack has at least DEPTH elements on it.
308 Return TRUE if it has at least DEPTH elements, otherwise
318 while ((temp != NULL) && (depth > 0))
325 rt_error ("Stack error.");
332 /* The following routines manipulate simple variables and
335 /* get_var returns a pointer to the variable VAR_NAME. If one does not
336 exist, one is created. */
344 var_ptr = variables[var_name];
347 var_ptr = variables[var_name] = (bc_var *) bc_malloc (sizeof (bc_var));
348 bc_init_num (&var_ptr->v_value);
354 /* get_array_num returns the address of the bc_num in the array
355 structure. If more structure is requried to get to the index,
356 this routine does the work to create that structure. VAR_INDEX
357 is a zero based index into the arrays storage array. INDEX is
358 the index into the bc array. */
361 get_array_num (var_index, index)
365 bc_var_array *ary_ptr;
369 int sub [NODE_DEPTH];
371 /* Get the array entry. */
372 ary_ptr = arrays[var_index];
375 ary_ptr = arrays[var_index] =
376 (bc_var_array *) bc_malloc (sizeof (bc_var_array));
377 ary_ptr->a_value = NULL;
378 ary_ptr->a_next = NULL;
379 ary_ptr->a_param = FALSE;
382 a_var = ary_ptr->a_value;
384 a_var = ary_ptr->a_value = (bc_array *) bc_malloc (sizeof (bc_array));
385 a_var->a_tree = NULL;
389 /* Get the index variable. */
390 sub[0] = index & NODE_MASK;
391 ix = index >> NODE_SHIFT;
393 while (ix > 0 || log < a_var->a_depth)
395 sub[log] = ix & NODE_MASK;
400 /* Build any tree that is necessary. */
401 while (log > a_var->a_depth)
403 temp = (bc_array_node *) bc_malloc (sizeof(bc_array_node));
404 if (a_var->a_depth != 0)
406 temp->n_items.n_down[0] = a_var->a_tree;
407 for (ix=1; ix < NODE_SIZE; ix++)
408 temp->n_items.n_down[ix] = NULL;
412 for (ix=0; ix < NODE_SIZE; ix++)
413 temp->n_items.n_num[ix] = bc_copy_num(_zero_);
415 a_var->a_tree = temp;
419 /* Find the indexed variable. */
420 temp = a_var->a_tree;
424 if (temp->n_items.n_down[ix1] == NULL)
426 temp->n_items.n_down[ix1] =
427 (bc_array_node *) bc_malloc (sizeof(bc_array_node));
428 temp = temp->n_items.n_down[ix1];
430 for (ix=0; ix < NODE_SIZE; ix++)
431 temp->n_items.n_down[ix] = NULL;
433 for (ix=0; ix < NODE_SIZE; ix++)
434 temp->n_items.n_num[ix] = bc_copy_num(_zero_);
437 temp = temp->n_items.n_down[ix1];
440 /* Return the address of the indexed variable. */
441 return &(temp->n_items.n_num[sub[0]]);
445 /* Store the top of the execution stack into VAR_NAME.
446 This includes the special variables ibase, obase, and scale. */
458 /* It is a simple variable. */
459 var_ptr = get_var (var_name);
462 bc_free_num(&var_ptr->v_value);
463 var_ptr->v_value = bc_copy_num (ex_stack->s_num);
468 /* It is a special variable... */
471 if (bc_is_neg (ex_stack->s_num))
476 rt_warn ("negative ibase, set to 2");
480 rt_warn ("negative obase, set to 2");
484 rt_warn ("negative scale, set to 0");
487 #if defined(READLINE) || defined(LIBEDIT)
496 temp = bc_num2long (ex_stack->s_num);
497 if (!bc_is_zero (ex_stack->s_num) && temp == 0)
503 if (temp < 2 && !toobig)
506 rt_warn ("ibase too small, set to 2");
509 if (temp > 16 || toobig)
512 rt_warn ("ibase too large, set to 16");
519 if (temp < 2 && !toobig)
522 rt_warn ("obase too small, set to 2");
525 if (temp > BC_BASE_MAX || toobig)
527 o_base = BC_BASE_MAX;
528 rt_warn ("obase too large, set to %d", BC_BASE_MAX);
535 /* WARNING: The following if statement may generate a compiler
536 warning if INT_MAX == LONG_MAX. This is NOT a problem. */
537 if (temp > BC_SCALE_MAX || toobig )
539 scale = BC_SCALE_MAX;
540 rt_warn ("scale too large, set to %d", BC_SCALE_MAX);
546 #if defined(READLINE) || defined(LIBEDIT)
551 rt_warn ("history too large, set to unlimited");
560 HISTORY_SIZE(n_history);
568 /* Store the top of the execution stack into array VAR_NAME.
569 VAR_NAME is the name of an array, and the next to the top
570 of stack for the index into the array. */
573 store_array (var_name)
579 if (!check_stack(2)) return;
580 index = bc_num2long (ex_stack->s_next->s_num);
581 if (index < 0 || index > BC_DIM_MAX ||
582 (index == 0 && !bc_is_zero(ex_stack->s_next->s_num)))
583 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
586 num_ptr = get_array_num (var_name, index);
589 bc_free_num (num_ptr);
590 *num_ptr = bc_copy_num (ex_stack->s_num);
591 bc_free_num (&ex_stack->s_next->s_num);
592 ex_stack->s_next->s_num = ex_stack->s_num;
593 bc_init_num (&ex_stack->s_num);
600 /* Load a copy of VAR_NAME on to the execution stack. This includes
601 the special variables ibase, obase and scale. */
613 /* Special variable ibase. */
615 bc_int2num (&ex_stack->s_num, i_base);
619 /* Special variable obase. */
621 bc_int2num (&ex_stack->s_num, o_base);
625 /* Special variable scale. */
627 bc_int2num (&ex_stack->s_num, scale);
630 #if defined(READLINE) || defined(LIBEDIT)
632 /* Special variable history. */
634 bc_int2num (&ex_stack->s_num, n_history);
639 /* It is a simple variable. */
640 var_ptr = variables[var_name];
642 push_copy (var_ptr->v_value);
649 /* Load a copy of VAR_NAME on to the execution stack. This includes
650 the special variables ibase, obase and scale. */
653 load_array (var_name)
659 if (!check_stack(1)) return;
660 index = bc_num2long (ex_stack->s_num);
661 if (index < 0 || index > BC_DIM_MAX ||
662 (index == 0 && !bc_is_zero(ex_stack->s_num)))
663 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
666 num_ptr = get_array_num (var_name, index);
670 push_copy (*num_ptr);
676 /* Decrement VAR_NAME by one. This includes the special variables
677 ibase, obase, and scale. */
692 rt_warn ("ibase too small in --");
699 rt_warn ("obase too small in --");
706 rt_warn ("scale can not be negative in -- ");
709 #if defined(READLINE) || defined(LIBEDIT)
710 case 3: /* history */
713 HISTORY_SIZE(n_history);
717 rt_warn ("history is negative, set to unlimited");
722 default: /* It is a simple variable. */
723 var_ptr = get_var (var_name);
725 bc_sub (var_ptr->v_value,_one_,&var_ptr->v_value, 0);
730 /* Decrement VAR_NAME by one. VAR_NAME is an array, and the top of
731 the execution stack is the index and it is popped off the stack. */
734 decr_array (var_name)
740 /* It is an array variable. */
741 if (!check_stack (1)) return;
742 index = bc_num2long (ex_stack->s_num);
743 if (index < 0 || index > BC_DIM_MAX ||
744 (index == 0 && !bc_is_zero (ex_stack->s_num)))
745 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
748 num_ptr = get_array_num (var_name, index);
752 bc_sub (*num_ptr, _one_, num_ptr, 0);
758 /* Increment VAR_NAME by one. This includes the special variables
759 ibase, obase, and scale. */
774 rt_warn ("ibase too big in ++");
778 if (o_base < BC_BASE_MAX)
781 rt_warn ("obase too big in ++");
785 if (scale < BC_SCALE_MAX)
788 rt_warn ("Scale too big in ++");
791 #if defined(READLINE) || defined(LIBEDIT)
792 case 3: /* history */
795 HISTORY_SIZE(n_history);
799 rt_warn ("history set to unlimited");
804 default: /* It is a simple variable. */
805 var_ptr = get_var (var_name);
807 bc_add (var_ptr->v_value, _one_, &var_ptr->v_value, 0);
813 /* Increment VAR_NAME by one. VAR_NAME is an array and top of
814 execution stack is the index and is popped off the stack. */
817 incr_array (var_name)
823 if (!check_stack (1)) return;
824 index = bc_num2long (ex_stack->s_num);
825 if (index < 0 || index > BC_DIM_MAX ||
826 (index == 0 && !bc_is_zero (ex_stack->s_num)))
827 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
830 num_ptr = get_array_num (var_name, index);
834 bc_add (*num_ptr, _one_, num_ptr, 0);
840 /* Routines for processing autos variables and parameters. */
842 /* NAME is an auto variable that needs to be pushed on its stack. */
849 bc_var_array *a_temp;
854 /* A simple variable. */
856 v_temp = (bc_var *) bc_malloc (sizeof (bc_var));
857 v_temp->v_next = variables[ix];
858 bc_init_num (&v_temp->v_value);
859 variables[ix] = v_temp;
863 /* An array variable. */
865 a_temp = (bc_var_array *) bc_malloc (sizeof (bc_var_array));
866 a_temp->a_next = arrays[ix];
867 a_temp->a_value = NULL;
868 a_temp->a_param = FALSE;
874 /* Free_a_tree frees everything associated with an array variable tree.
875 This is used when popping an array variable off its auto stack. */
878 free_a_tree ( root, depth )
887 for (ix = 0; ix < NODE_SIZE; ix++)
888 free_a_tree (root->n_items.n_down[ix], depth-1);
890 for (ix = 0; ix < NODE_SIZE; ix++)
891 bc_free_num ( &(root->n_items.n_num[ix]));
897 /* LIST is an NULL terminated list of varible names that need to be
898 popped off their auto stacks. */
905 bc_var_array *a_temp;
913 /* A simple variable. */
914 v_temp = variables[ix];
917 variables[ix] = v_temp->v_next;
918 bc_free_num (&v_temp->v_value);
924 /* An array variable. */
929 arrays[ix] = a_temp->a_next;
930 if (!a_temp->a_param && a_temp->a_value != NULL)
932 free_a_tree (a_temp->a_value->a_tree,
933 a_temp->a_value->a_depth);
934 free (a_temp->a_value);
943 /* COPY_NODE: Copies an array node for a call by value parameter. */
945 copy_tree (ary_node, depth)
946 bc_array_node *ary_node;
949 bc_array_node *res = (bc_array_node *) bc_malloc (sizeof(bc_array_node));
953 for (i=0; i<NODE_SIZE; i++)
954 if (ary_node->n_items.n_down[i] != NULL)
955 res->n_items.n_down[i] =
956 copy_tree (ary_node->n_items.n_down[i], depth - 1);
958 res->n_items.n_down[i] = NULL;
960 for (i=0; i<NODE_SIZE; i++)
961 if (ary_node->n_items.n_num[i] != NULL)
962 res->n_items.n_num[i] = bc_copy_num (ary_node->n_items.n_num[i]);
964 res->n_items.n_num[i] = NULL;
968 /* COPY_ARRAY: Copies an array for a call by value array parameter.
969 ARY is the pointer to the bc_array structure. */
975 bc_array *res = (bc_array *) bc_malloc (sizeof(bc_array));
976 res->a_depth = ary->a_depth;
977 res->a_tree = copy_tree (ary->a_tree, ary->a_depth);
982 /* A call is being made to FUNC. The call types are at PC. Process
983 the parameters by doing an auto on the parameter variable and then
984 store the value at the new variable or put a pointer the the array
988 process_params (pc, func)
996 bc_var_array *a_src, *a_dest;
999 /* Get the parameter names from the function. */
1000 params = functions[func].f_params;
1002 while ((ch = byte(pc)) != ':')
1006 if ((ch == '0') && params->av_name > 0)
1008 /* A simple variable. */
1009 ix = params->av_name;
1010 v_temp = (bc_var *) bc_malloc (sizeof(bc_var));
1011 v_temp->v_next = variables[ix];
1012 v_temp->v_value = ex_stack->s_num;
1013 bc_init_num (&ex_stack->s_num);
1014 variables[ix] = v_temp;
1017 if ((ch == '1') && (params->av_name < 0))
1019 /* The variables is an array variable. */
1021 /* Compute source index and make sure some structure exists. */
1022 ix = (int) bc_num2long (ex_stack->s_num);
1023 n_temp = get_array_num (ix, 0);
1025 /* Push a new array and Compute Destination index */
1026 auto_var (params->av_name);
1027 ix1 = -params->av_name;
1029 /* Set up the correct pointers in the structure. */
1031 a_src = arrays[ix]->a_next;
1034 a_dest = arrays[ix1];
1035 if (params->arg_is_var)
1037 a_dest->a_param = TRUE;
1038 a_dest->a_value = a_src->a_value;
1042 a_dest->a_param = FALSE;
1043 a_dest->a_value = copy_array (a_src->a_value);
1048 if (params->av_name < 0)
1049 rt_error ("Parameter type mismatch parameter %s.",
1050 a_names[-params->av_name]);
1052 rt_error ("Parameter type mismatch, parameter %s.",
1053 v_names[params->av_name]);
1060 rt_error ("Parameter number mismatch");
1063 params = params->next;
1066 rt_error ("Parameter number mismatch");