1 /* storage.c: Code and data storage manipulations. This includes labels. */
3 /* This file is part of bc written for MINIX.
4 Copyright (C) 1991, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA.
20 You may contact the author by:
21 e-mail: phil@cs.wwu.edu
22 us-mail: Philip A. Nelson
23 Computer Science Department, 9062
24 Western Washington University
25 Bellingham, WA 98226-9062
27 *************************************************************************/
34 /* Initialize the storage at the beginning of the run. */
40 /* Functions: we start with none and ask for more. */
43 f_names[0] = "(main)";
63 /* Three functions for increasing the number of functions, variables, or
64 arrays that are needed. This adds another 32 of the requested object. */
75 /* Save old information. */
80 /* Add a fixed amount and allocate new space. */
81 f_count += STORE_INCR;
82 functions = (bc_function *) bc_malloc (f_count*sizeof (bc_function));
83 f_names = (char **) bc_malloc (f_count*sizeof (char *));
86 for (indx1 = 0; indx1 < old_count; indx1++)
88 functions[indx1] = old_f[indx1];
89 f_names[indx1] = old_names[indx1];
92 /* Initialize the new ones. */
93 for (; indx1 < f_count; indx1++)
95 f = &functions[indx1];
97 for (indx2 = 0; indx2 < BC_MAX_SEGS; indx2++)
98 f->f_body [indx2] = NULL;
105 /* Free the old elements. */
121 /* Save the old values. */
126 /* Increment by a fixed amount and allocate. */
127 v_count += STORE_INCR;
128 variables = (bc_var **) bc_malloc (v_count*sizeof(bc_var *));
129 v_names = (char **) bc_malloc (v_count*sizeof(char *));
131 /* Copy the old variables. */
132 for (indx = 3; indx < old_count; indx++)
133 variables[indx] = old_var[indx];
135 /* Initialize the new elements. */
136 for (; indx < v_count; indx++)
137 variables[indx] = NULL;
139 /* Free the old elements. */
152 bc_var_array **old_ary;
155 /* Save the old values. */
160 /* Increment by a fixed amount and allocate. */
161 a_count += STORE_INCR;
162 arrays = (bc_var_array **) bc_malloc (a_count*sizeof(bc_var_array *));
163 a_names = (char **) bc_malloc (a_count*sizeof(char *));
165 /* Copy the old arrays. */
166 for (indx = 1; indx < old_count; indx++)
167 arrays[indx] = old_ary[indx];
170 /* Initialize the new elements. */
171 for (; indx < v_count; indx++)
174 /* Free the old elements. */
183 /* clear_func clears out function FUNC and makes it ready to redefine. */
193 /* Set the pointer to the function. */
194 f = &functions[func];
195 f->f_defined = FALSE;
197 /* Clear the code segments. */
198 for (indx = 0; indx < BC_MAX_SEGS; indx++)
200 if (f->f_body[indx] != NULL)
202 free (f->f_body[indx]);
203 f->f_body[indx] = NULL;
208 if (f->f_autos != NULL)
210 free_args (f->f_autos);
213 if (f->f_params != NULL)
215 free_args (f->f_params);
218 while (f->f_label != NULL)
220 lg = f->f_label->l_next;
227 /* Pop the function execution stack and return the top. */
235 if (fn_stack != NULL)
238 fn_stack = temp->s_next;
239 retval = temp->s_val;
246 /* Push VAL on to the function stack. */
254 temp = (fstack_rec *) bc_malloc (sizeof (fstack_rec));
255 temp->s_next = fn_stack;
261 /* Pop and discard the top element of the regular execution stack. */
268 if (ex_stack != NULL)
271 ex_stack = temp->s_next;
272 free_num (&temp->s_num);
278 /* Push a copy of NUM on to the regular execution stack. */
286 temp = (estack_rec *) bc_malloc (sizeof (estack_rec));
287 temp->s_num = copy_num (num);
288 temp->s_next = ex_stack;
293 /* Push NUM on to the regular execution stack. Do NOT push a copy. */
301 temp = (estack_rec *) bc_malloc (sizeof (estack_rec));
303 temp->s_next = ex_stack;
308 /* Make sure the ex_stack has at least DEPTH elements on it.
309 Return TRUE if it has at least DEPTH elements, otherwise
319 while ((temp != NULL) && (depth > 0))
326 rt_error ("Stack error.");
333 /* The following routines manipulate simple variables and
336 /* get_var returns a pointer to the variable VAR_NAME. If one does not
337 exist, one is created. */
345 var_ptr = variables[var_name];
348 var_ptr = variables[var_name] = (bc_var *) bc_malloc (sizeof (bc_var));
349 init_num (&var_ptr->v_value);
355 /* get_array_num returns the address of the bc_num in the array
356 structure. If more structure is requried to get to the index,
357 this routine does the work to create that structure. VAR_INDEX
358 is a zero based index into the arrays storage array. INDEX is
359 the index into the bc array. */
362 get_array_num (var_index, index)
366 bc_var_array *ary_ptr;
370 int sub [NODE_DEPTH];
372 /* Get the array entry. */
373 ary_ptr = arrays[var_index];
376 ary_ptr = arrays[var_index] =
377 (bc_var_array *) bc_malloc (sizeof (bc_var_array));
378 ary_ptr->a_value = NULL;
379 ary_ptr->a_next = NULL;
380 ary_ptr->a_param = FALSE;
383 a_var = ary_ptr->a_value;
385 a_var = ary_ptr->a_value = (bc_array *) bc_malloc (sizeof (bc_array));
386 a_var->a_tree = NULL;
390 /* Get the index variable. */
391 sub[0] = index & NODE_MASK;
392 ix = index >> NODE_SHIFT;
394 while (ix > 0 || log < a_var->a_depth)
396 sub[log] = ix & NODE_MASK;
401 /* Build any tree that is necessary. */
402 while (log > a_var->a_depth)
404 temp = (bc_array_node *) bc_malloc (sizeof(bc_array_node));
405 if (a_var->a_depth != 0)
407 temp->n_items.n_down[0] = a_var->a_tree;
408 for (ix=1; ix < NODE_SIZE; ix++)
409 temp->n_items.n_down[ix] = NULL;
413 for (ix=0; ix < NODE_SIZE; ix++)
414 temp->n_items.n_num[ix] = copy_num(_zero_);
416 a_var->a_tree = temp;
420 /* Find the indexed variable. */
421 temp = a_var->a_tree;
425 if (temp->n_items.n_down[ix1] == NULL)
427 temp->n_items.n_down[ix1] =
428 (bc_array_node *) bc_malloc (sizeof(bc_array_node));
429 temp = temp->n_items.n_down[ix1];
431 for (ix=0; ix < NODE_SIZE; ix++)
432 temp->n_items.n_down[ix] = NULL;
434 for (ix=0; ix < NODE_SIZE; ix++)
435 temp->n_items.n_num[ix] = copy_num(_zero_);
438 temp = temp->n_items.n_down[ix1];
441 /* Return the address of the indexed variable. */
442 return &(temp->n_items.n_num[sub[0]]);
446 /* Store the top of the execution stack into VAR_NAME.
447 This includes the special variables ibase, obase, and scale. */
459 /* It is a simple variable. */
460 var_ptr = get_var (var_name);
463 free_num(&var_ptr->v_value);
464 var_ptr->v_value = copy_num (ex_stack->s_num);
469 /* It is a special variable... */
471 if (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");
491 temp = num2long (ex_stack->s_num);
492 if (!is_zero (ex_stack->s_num) && temp == 0)
498 if (temp < 2 && !toobig)
501 rt_warn ("ibase too small, set to 2");
504 if (temp > 16 || toobig)
507 rt_warn ("ibase too large, set to 16");
514 if (temp < 2 && !toobig)
517 rt_warn ("obase too small, set to 2");
520 if (temp > BC_BASE_MAX || toobig)
522 o_base = BC_BASE_MAX;
523 rt_warn ("obase too large, set to %d", BC_BASE_MAX);
530 /* WARNING: The following if statement may generate a compiler
531 warning if INT_MAX == LONG_MAX. This is NOT a problem. */
532 if (temp > BC_SCALE_MAX || toobig )
534 scale = BC_SCALE_MAX;
535 rt_warn ("scale too large, set to %d", BC_SCALE_MAX);
544 /* Store the top of the execution stack into array VAR_NAME.
545 VAR_NAME is the name of an array, and the next to the top
546 of stack for the index into the array. */
549 store_array (var_name)
555 if (!check_stack(2)) return;
556 index = num2long (ex_stack->s_next->s_num);
557 if (index < 0 || index > BC_DIM_MAX ||
558 (index == 0 && !is_zero(ex_stack->s_next->s_num)))
559 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
562 num_ptr = get_array_num (var_name, index);
566 *num_ptr = copy_num (ex_stack->s_num);
567 free_num (&ex_stack->s_next->s_num);
568 ex_stack->s_next->s_num = ex_stack->s_num;
569 init_num (&ex_stack->s_num);
576 /* Load a copy of VAR_NAME on to the execution stack. This includes
577 the special variables ibase, obase and scale. */
589 /* Special variable ibase. */
591 int2num (&ex_stack->s_num, i_base);
595 /* Special variable obase. */
597 int2num (&ex_stack->s_num, o_base);
601 /* Special variable scale. */
603 int2num (&ex_stack->s_num, scale);
607 /* It is a simple variable. */
608 var_ptr = variables[var_name];
610 push_copy (var_ptr->v_value);
617 /* Load a copy of VAR_NAME on to the execution stack. This includes
618 the special variables ibase, obase and scale. */
621 load_array (var_name)
627 if (!check_stack(1)) return;
628 index = num2long (ex_stack->s_num);
629 if (index < 0 || index > BC_DIM_MAX ||
630 (index == 0 && !is_zero(ex_stack->s_num)))
631 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
634 num_ptr = get_array_num (var_name, index);
638 push_copy (*num_ptr);
644 /* Decrement VAR_NAME by one. This includes the special variables
645 ibase, obase, and scale. */
660 rt_warn ("ibase too small in --");
667 rt_warn ("obase too small in --");
674 rt_warn ("scale can not be negative in -- ");
677 default: /* It is a simple variable. */
678 var_ptr = get_var (var_name);
680 bc_sub (var_ptr->v_value,_one_,&var_ptr->v_value);
685 /* Decrement VAR_NAME by one. VAR_NAME is an array, and the top of
686 the execution stack is the index and it is popped off the stack. */
689 decr_array (var_name)
695 /* It is an array variable. */
696 if (!check_stack (1)) return;
697 index = num2long (ex_stack->s_num);
698 if (index < 0 || index > BC_DIM_MAX ||
699 (index == 0 && !is_zero (ex_stack->s_num)))
700 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
703 num_ptr = get_array_num (var_name, index);
707 bc_sub (*num_ptr, _one_, num_ptr);
713 /* Increment VAR_NAME by one. This includes the special variables
714 ibase, obase, and scale. */
729 rt_warn ("ibase too big in ++");
733 if (o_base < BC_BASE_MAX)
736 rt_warn ("obase too big in ++");
740 if (scale < BC_SCALE_MAX)
743 rt_warn ("Scale too big in ++");
746 default: /* It is a simple variable. */
747 var_ptr = get_var (var_name);
749 bc_add (var_ptr->v_value, _one_, &var_ptr->v_value);
755 /* Increment VAR_NAME by one. VAR_NAME is an array and top of
756 execution stack is the index and is popped off the stack. */
759 incr_array (var_name)
765 if (!check_stack (1)) return;
766 index = num2long (ex_stack->s_num);
767 if (index < 0 || index > BC_DIM_MAX ||
768 (index == 0 && !is_zero (ex_stack->s_num)))
769 rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
772 num_ptr = get_array_num (var_name, index);
776 bc_add (*num_ptr, _one_, num_ptr);
782 /* Routines for processing autos variables and parameters. */
784 /* NAME is an auto variable that needs to be pushed on its stack. */
791 bc_var_array *a_temp;
796 /* A simple variable. */
798 v_temp = (bc_var *) bc_malloc (sizeof (bc_var));
799 v_temp->v_next = variables[ix];
800 init_num (&v_temp->v_value);
801 variables[ix] = v_temp;
805 /* An array variable. */
807 a_temp = (bc_var_array *) bc_malloc (sizeof (bc_var_array));
808 a_temp->a_next = arrays[ix];
809 a_temp->a_value = NULL;
810 a_temp->a_param = FALSE;
816 /* Free_a_tree frees everything associated with an array variable tree.
817 This is used when popping an array variable off its auto stack. */
820 free_a_tree ( root, depth )
829 for (ix = 0; ix < NODE_SIZE; ix++)
830 free_a_tree (root->n_items.n_down[ix], depth-1);
832 for (ix = 0; ix < NODE_SIZE; ix++)
833 free_num ( &(root->n_items.n_num[ix]));
839 /* LIST is an NULL terminated list of varible names that need to be
840 popped off their auto stacks. */
847 bc_var_array *a_temp;
855 /* A simple variable. */
856 v_temp = variables[ix];
859 variables[ix] = v_temp->v_next;
860 free_num (&v_temp->v_value);
866 /* An array variable. */
871 arrays[ix] = a_temp->a_next;
872 if (!a_temp->a_param && a_temp->a_value != NULL)
874 free_a_tree (a_temp->a_value->a_tree,
875 a_temp->a_value->a_depth);
876 free (a_temp->a_value);
886 /* A call is being made to FUNC. The call types are at PC. Process
887 the parameters by doing an auto on the parameter variable and then
888 store the value at the new variable or put a pointer the the array
892 process_params (pc, func)
901 bc_var_array *a_src, *a_dest;
904 /* Get the parameter names from the function. */
905 params = functions[func].f_params;
907 while ((ch = byte(pc)) != ':')
911 if ((ch == '0') && params->av_name > 0)
913 /* A simple variable. */
914 ix = params->av_name;
915 v_temp = (bc_var *) bc_malloc (sizeof(bc_var));
916 v_temp->v_next = variables[ix];
917 v_temp->v_value = ex_stack->s_num;
918 init_num (&ex_stack->s_num);
919 variables[ix] = v_temp;
922 if ((ch == '1') && (params->av_name < 0))
924 /* The variables is an array variable. */
926 /* Compute source index and make sure some structure exists. */
927 ix = (int) num2long (ex_stack->s_num);
928 n_temp = get_array_num (ix, 0);
930 /* Push a new array and Compute Destination index */
931 auto_var (params->av_name);
932 ix1 = -params->av_name;
934 /* Set up the correct pointers in the structure. */
936 a_src = arrays[ix]->a_next;
939 a_dest = arrays[ix1];
940 a_dest->a_param = TRUE;
941 a_dest->a_value = a_src->a_value;
945 if (params->av_name < 0)
946 rt_error ("Parameter type mismatch parameter %s.",
947 a_names[-params->av_name]);
949 rt_error ("Parameter type mismatch, parameter %s.",
950 v_names[params->av_name]);
959 rt_error ("Parameter number mismatch");
963 params = params->next;
966 rt_error ("Parameter number mismatch");