⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 storage.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* storage.c:  Code and data storage manipulations.  This includes labels. *//*  This file is part of bc written for MINIX.    Copyright (C) 1991, 1992 Free Software Foundation, Inc.    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License , or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; see the file COPYING.  If not, write to    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.    You may contact the author by:       e-mail:  phil@cs.wwu.edu      us-mail:  Philip A. Nelson                Computer Science Department, 9062                Western Washington University                Bellingham, WA 98226-9062       *************************************************************************/#include "bcdefs.h"#include "global.h"#include "proto.h"/* Initialize the storage at the beginning of the run. */voidinit_storage (){  /* Functions: we start with none and ask for more. */  f_count = 0;  more_functions ();  f_names[0] = "(main)";  /* Variables. */  v_count = 0;  more_variables ();    /* Arrays. */  a_count = 0;  more_arrays ();  /* Other things... */  ex_stack = NULL;  fn_stack = NULL;  i_base = 10;  o_base = 10;  scale  = 0;  c_code = FALSE;  init_numbers();}/* Three functions for increasing the number of functions, variables, or   arrays that are needed.  This adds another 32 of the requested object. */voidmore_functions (VOID){  int old_count;  int indx1, indx2;  bc_function *old_f;  bc_function *f;  char **old_names;  /* Save old information. */  old_count = f_count;  old_f = functions;  old_names = f_names;  /* Add a fixed amount and allocate new space. */  f_count += STORE_INCR;  functions = (bc_function *) bc_malloc (f_count*sizeof (bc_function));  f_names = (char **) bc_malloc (f_count*sizeof (char *));  /* Copy old ones. */  for (indx1 = 0; indx1 < old_count; indx1++)    {      functions[indx1] = old_f[indx1];      f_names[indx1] = old_names[indx1];    }  /* Initialize the new ones. */  for (; indx1 < f_count; indx1++)    {      f = &functions[indx1];      f->f_defined = FALSE;      for (indx2 = 0; indx2 < BC_MAX_SEGS; indx2++)	f->f_body [indx2] = NULL;      f->f_code_size = 0;      f->f_label = NULL;      f->f_autos = NULL;      f->f_params = NULL;    }  /* Free the old elements. */  if (old_count != 0)    {      free (old_f);      free (old_names);    }}voidmore_variables (){  int indx;  int old_count;  bc_var **old_var;  char **old_names;  /* Save the old values. */  old_count = v_count;  old_var = variables;  old_names = v_names;  /* Increment by a fixed amount and allocate. */  v_count += STORE_INCR;  variables = (bc_var **) bc_malloc (v_count*sizeof(bc_var *));  v_names = (char **) bc_malloc (v_count*sizeof(char *));  /* Copy the old variables. */  for (indx = 3; indx < old_count; indx++)    variables[indx] = old_var[indx];  /* Initialize the new elements. */  for (; indx < v_count; indx++)    variables[indx] = NULL;  /* Free the old elements. */  if (old_count != 0)    {      free (old_var);      free (old_names);    }}voidmore_arrays (){  int indx;  int old_count;  bc_var_array **old_ary;  char **old_names;  /* Save the old values. */  old_count = a_count;  old_ary = arrays;  old_names = a_names;  /* Increment by a fixed amount and allocate. */  a_count += STORE_INCR;  arrays = (bc_var_array **) bc_malloc (a_count*sizeof(bc_var_array *));  a_names = (char **) bc_malloc (a_count*sizeof(char *));  /* Copy the old arrays. */  for (indx = 1; indx < old_count; indx++)    arrays[indx] = old_ary[indx];  /* Initialize the new elements. */  for (; indx < v_count; indx++)    arrays[indx] = NULL;  /* Free the old elements. */  if (old_count != 0)    {      free (old_ary);      free (old_names);    }}/* clear_func clears out function FUNC and makes it ready to redefine. */voidclear_func (func)     char func;{  bc_function *f;  int indx;  bc_label_group *lg;  /* Set the pointer to the function. */  f = &functions[func];  f->f_defined = FALSE;  /* Clear the code segments. */  for (indx = 0; indx < BC_MAX_SEGS; indx++)    {      if (f->f_body[indx] != NULL)	{	  free (f->f_body[indx]);	  f->f_body[indx] = NULL;	}    }  f->f_code_size = 0;  if (f->f_autos != NULL)    {      free_args (f->f_autos);      f->f_autos = NULL;    }  if (f->f_params != NULL)    {      free_args (f->f_params);      f->f_params = NULL;    }  while (f->f_label != NULL)    {      lg = f->f_label->l_next;      free (f->f_label);      f->f_label = lg;    }}/*  Pop the function execution stack and return the top. */intfpop(){  fstack_rec *temp;  int retval;    if (fn_stack != NULL)    {      temp = fn_stack;      fn_stack = temp->s_next;      retval = temp->s_val;      free (temp);    }  return (retval);}/* Push VAL on to the function stack. */voidfpush (val)     int val;{  fstack_rec *temp;    temp = (fstack_rec *) bc_malloc (sizeof (fstack_rec));  temp->s_next = fn_stack;  temp->s_val = val;  fn_stack = temp;}/* Pop and discard the top element of the regular execution stack. */voidpop (){  estack_rec *temp;    if (ex_stack != NULL)    {      temp = ex_stack;      ex_stack = temp->s_next;      free_num (&temp->s_num);      free (temp);    }}/* Push a copy of NUM on to the regular execution stack. */voidpush_copy (num)     bc_num num;{  estack_rec *temp;  temp = (estack_rec *) bc_malloc (sizeof (estack_rec));  temp->s_num = copy_num (num);  temp->s_next = ex_stack;  ex_stack = temp;}/* Push NUM on to the regular execution stack.  Do NOT push a copy. */voidpush_num (num)     bc_num num;{  estack_rec *temp;  temp = (estack_rec *) bc_malloc (sizeof (estack_rec));  temp->s_num = num;  temp->s_next = ex_stack;  ex_stack = temp;}/* Make sure the ex_stack has at least DEPTH elements on it.   Return TRUE if it has at least DEPTH elements, otherwise   return FALSE. */charcheck_stack (depth)     int depth;{  estack_rec *temp;  temp = ex_stack;  while ((temp != NULL) && (depth > 0))    {      temp = temp->s_next;      depth--;    }  if (depth > 0)    {      rt_error ("Stack error.");      return FALSE;    }  return TRUE;}/* The following routines manipulate simple variables and   array variables. *//* get_var returns a pointer to the variable VAR_NAME.  If one does not   exist, one is created. */bc_var *get_var (var_name)     int var_name;{  bc_var *var_ptr;  var_ptr = variables[var_name];  if (var_ptr == NULL)    {      var_ptr = variables[var_name] = (bc_var *) bc_malloc (sizeof (bc_var));      init_num (&var_ptr->v_value);    }  return var_ptr;}/* get_array_num returns the address of the bc_num in the array   structure.  If more structure is requried to get to the index,   this routine does the work to create that structure. VAR_INDEX   is a zero based index into the arrays storage array. INDEX is   the index into the bc array. */bc_num *get_array_num (var_index, index)     int var_index;     long  index;{  bc_var_array *ary_ptr;  bc_array *a_var;  bc_array_node *temp;  int log, ix, ix1;  int sub [NODE_DEPTH];  /* Get the array entry. */  ary_ptr = arrays[var_index];  if (ary_ptr == NULL)    {      ary_ptr = arrays[var_index] =	(bc_var_array *) bc_malloc (sizeof (bc_var_array));      ary_ptr->a_value = NULL;      ary_ptr->a_next = NULL;      ary_ptr->a_param = FALSE;    }  a_var = ary_ptr->a_value;  if (a_var == NULL) {    a_var = ary_ptr->a_value = (bc_array *) bc_malloc (sizeof (bc_array));    a_var->a_tree = NULL;    a_var->a_depth = 0;  }  /* Get the index variable. */  sub[0] = index & NODE_MASK;  ix = index >> NODE_SHIFT;  log = 1;  while (ix > 0 || log < a_var->a_depth)    {      sub[log] = ix & NODE_MASK;      ix >>= NODE_SHIFT;      log++;    }    /* Build any tree that is necessary. */  while (log > a_var->a_depth)    {      temp = (bc_array_node *) bc_malloc (sizeof(bc_array_node));      if (a_var->a_depth != 0)	{	  temp->n_items.n_down[0] = a_var->a_tree;	  for (ix=1; ix < NODE_SIZE; ix++)	    temp->n_items.n_down[ix] = NULL;	}      else	{	  for (ix=0; ix < NODE_SIZE; ix++)	    temp->n_items.n_num[ix] = copy_num(_zero_);	}      a_var->a_tree = temp;      a_var->a_depth++;    }    /* Find the indexed variable. */  temp = a_var->a_tree;  while ( log-- > 1)    {      ix1 = sub[log];      if (temp->n_items.n_down[ix1] == NULL)	{	  temp->n_items.n_down[ix1] =	    (bc_array_node *) bc_malloc (sizeof(bc_array_node));	  temp = temp->n_items.n_down[ix1];	  if (log > 1)	    for (ix=0; ix < NODE_SIZE; ix++)	      temp->n_items.n_down[ix] = NULL;	  else	    for (ix=0; ix < NODE_SIZE; ix++)	      temp->n_items.n_num[ix] = copy_num(_zero_);	}      else	temp = temp->n_items.n_down[ix1];    }    /* Return the address of the indexed variable. */  return &(temp->n_items.n_num[sub[0]]);}/* Store the top of the execution stack into VAR_NAME.     This includes the special variables ibase, obase, and scale. */voidstore_var (var_name)     int var_name;{  bc_var *var_ptr;  long temp;  char toobig;  if (var_name > 2)    {      /* It is a simple variable. */      var_ptr = get_var (var_name);      if (var_ptr != NULL)	{	  free_num(&var_ptr->v_value);	  var_ptr->v_value = copy_num (ex_stack->s_num);	}    }  else    {      /* It is a special variable... */      toobig = FALSE;      if (is_neg (ex_stack->s_num))	{	  switch (var_name)	    {	    case 0:	      rt_warn ("negative ibase, set to 2");	      temp = 2;	      break;	    case 1:	      rt_warn ("negative obase, set to 2");	      temp = 2;	      break;	    case 2:	      rt_warn ("negative scale, set to 0");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -