/* util.c: Utility routines for bc. */

/*  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 <stdarg.h>
#include "global.h"
#include "proto.h"


/* strcopyof mallocs new memory and copies a string to to the new
   memory. */

char *
strcopyof (char * str)
{
  char * temp;

  temp = (char *)malloc(strlen (str)+1);
  strcpy (temp,str);
  return (temp);
}


/* nextarg adds another value to the list of arguments. */

arg_list *
nextarg (arg_list * args, char val)
{ arg_list * temp;

  temp = (arg_list *)malloc(sizeof (arg_list));
  temp->av_name = val;
  temp->next = args;
 
  return (temp);
}


/* For generate, we must produce a string in the form
    "val,val,...,val".  We also need a couple of static variables
   for retaining old generated strings.  It also uses a recursive
   function that builds the string. */

static char * arglist1;
static char * arglist2;


/* make_arg_str does the actual construction of the argument string.
   ARGS is the pointer to the list and LEN is the maximum number of
   characters needed.  1 char is the minimum needed. COMMAS tells
   if each number should be seperated by commas.*/

_PROTOTYPE (static char * make_arg_str, (arg_list * args, int len, int commas));

static char *
make_arg_str (arg_list * args, int len, int commas)
{
  char * temp;
  char sval[20];

  /* Recursive call. */
  if (args != NULL)
    temp = make_arg_str (args->next, len+11, commas);
  else
    {
      temp = (char *)malloc(len);
      *temp = 0;
      return temp;
    }

  /* Add the current number to the end of the string. */
  if (len != 1 && commas) 
    sprintf (sval, "%d,", args->av_name);
  else
    sprintf (sval, "%d", args->av_name);
  /* XXX temp = */ strcat (temp, sval);
  return (temp);
}

char *
arg_str (arg_list * args, int commas)
{
  if (arglist2 != NULL) 
    free(arglist2);
  arglist2 = arglist1;
  arglist1 = make_arg_str (args, 1, commas);
  return (arglist1);
}


/* free_args frees an argument list ARGS. */

void
free_args (arg_list * args)
{ 
  arg_list * temp;
 
  temp = args;
  while (temp != NULL)
    {
      args = args->next;
      free(temp);
      temp = args;
    }
}


/* Check for valid parameter (PARAMS) and auto (AUTOS) lists.
   There must be no duplicates any where.  Also, this is where
   warnings are generated for array parameters. */

void
check_params ( arg_list * params, arg_list * autos )
{
  arg_list * tmp1;
  arg_list * tmp2;

  /* Check for duplicate parameters. */
  if (params != NULL)
    {
      tmp1 = params;
      while (tmp1 != NULL)
	{
	  tmp2 = tmp1->next;
	  while (tmp2 != NULL)
	    {
	      if (tmp2->av_name == tmp1->av_name) 
		yyerror ("duplicate parameter names");
	      tmp2 = tmp2->next;
	    }
	  if (tmp1->av_name < 0)
	    warn ("Array parameter");
	  tmp1 = tmp1->next;
	}
    }

  /* Check for duplicate autos. */
  if (autos != NULL)
    {
      tmp1 = autos;
      while (tmp1 != NULL)
	{
	  tmp2 = tmp1->next;
	  while (tmp2 != NULL)
	    {
	      if (tmp2->av_name == tmp1->av_name) 
		yyerror ("duplicate auto variable names");
	      tmp2 = tmp2->next;
	    }
	  tmp1 = tmp1->next;
	}
    }

  /* Check for duplicate between parameters and autos. */
  if ((params != NULL) && (autos != NULL))
    {
      tmp1 = params;
      while (tmp1 != NULL)
	{
	  tmp2 = autos;
	  while (tmp2 != NULL)
	    {
	      if (tmp2->av_name == tmp1->av_name) 
		yyerror ("variable in both parameter and auto lists");
	      tmp2 = tmp2->next;
	    }
	  tmp1 = tmp1->next;
	}
    }
}


/* Initialize the code generator the parser. */

void
init_gen (void)
{
  /* Get things ready. */
  break_label = 0;
  continue_label = 0;
  next_label  = 1;
  out_count = 2;
  if (compile_only) 
    printf ("@i");
  else
    init_load ();
  had_error = FALSE;
  did_gen = FALSE;
}


/* generate code STR for the machine. */

void
generate (char * str)
{
  did_gen = TRUE;
  if (compile_only)
    {
      printf ("%s",str);
      out_count += strlen(str);
      if (out_count > 60)
	{
	  printf ("\n");
	  out_count = 0;
	}
    }
  else
    load_code (str);
}


/* Execute the current code as loaded. */

void
run_code(void)
{
  /* If no compile errors run the current code. */
  if (!had_error && did_gen)
    {
      if (compile_only)
	{
	  printf ("@r\n"); 
	  out_count = 0;
	}
      else
	execute ();
    }

  /* Reinitialize the code generation and machine. */
  if (did_gen)
    init_gen();
  else
    had_error = FALSE;
}


/* Output routines: Write a character CH to the standard output.
   It keeps track of the number of characters output and may
   break the output with a "\<cr>". */

void
out_char (char ch)
{
  if (ch == '\n')
    {
      out_col = 0;
      putchar ('\n');
    }
  else
    {
      out_col++;
      if (out_col == 70)
	{
	  putchar ('\\');
	  putchar ('\n');
	  out_col = 1;
	}
      putchar (ch);
    }
}


/* The following are "Symbol Table" routines for the parser. */

/*  find_id returns a pointer to node in TREE that has the correct
    ID.  If there is no node in TREE with ID, NULL is returned. */

id_rec *
find_id (id_rec * tree, char * id)
{
  int cmp_result;
  
  /* Check for an empty tree. */
  if (tree == NULL)
    return NULL;

  /* Recursively search the tree. */
  cmp_result = strcmp (id, tree->id);
  if (cmp_result == 0)
    return tree;  /* This is the item. */
  else if (cmp_result < 0)
    return find_id (tree->left, id);
  else
    return find_id (tree->right, id);  
}


/* insert_id_rec inserts a NEW_ID rec into the tree whose ROOT is
   provided.  insert_id_rec returns TRUE if the tree height from
   ROOT down is increased otherwise it returns FALSE.  This is a
   recursive balanced binary tree insertion algorithm. */

int insert_id_rec (id_rec * * root, id_rec * new_id)
{
  id_rec * A;
  id_rec * B;

  /* If root is NULL, this where it is to be inserted. */
  if (*root == NULL)
    {
      *root = new_id;
      new_id->left = NULL;
      new_id->right = NULL;
      new_id->balance = 0;
      return (TRUE);
    }

  /* We need to search for a leaf. */
  if (strcmp (new_id->id, (*root)->id) < 0)
    {
      /* Insert it on the left. */
      if (insert_id_rec (&(*root)->left, new_id))
	{
	  /* The height increased. */
	  (*root)->balance --;
	  
      switch ((*root)->balance)
	{
	case  0:  /* no height increase. */
	  return (FALSE);
	case -1:  /* height increase. */
	  return (FALSE);
	case -2:  /* we need to do a rebalancing act. */
	  A = *root;
	  B = (*root)->left;
	  if (B->balance <= 0)
	    {
	      /* Single Rotate. */
	      A->left = B->right;
	      B->right = A;
	      *root = B;
	      A->balance = 0;
	      B->balance = 0;
	    }
	  else
	    {
	      /* Double Rotate. */
	      *root = B->right;
	      B->right = (*root)->left;
	      A->left = (*root)->right;
	      (*root)->left = B;
	      (*root)->right = A;
	      switch ((*root)->balance)
		{
		case -1:
		  A->balance = 1;
		  B->balance = 0;
		  break;
		case  0:
		  A->balance = 0;
		  B->balance = 0;
		  break;
		case  1:
		  A->balance = 0;
		  B->balance = -1;
		  break;
		}
	      (*root)->balance = 0;
	    }
	}     
	} 
    }
  else
    {
      /* Insert it on the right. */
      if (insert_id_rec (&(*root)->right, new_id))
	{
	  /* The height increased. */
	  (*root)->balance ++;
	  switch ((*root)->balance)
	    {
	    case 0:  /* no height increase. */
	      return (FALSE);
	    case 1:  /* height increase. */
	      return (FALSE);
	    case 2:  /* we need to do a rebalancing act. */
	      A = *root;
	      B = (*root)->right;
	      if (B->balance >= 0)
		{
		  /* Single Rotate. */
		  A->right = B->left;
		  B->left = A;
		  *root = B;
		  A->balance = 0;
		  B->balance = 0;
		}
	      else
		{
		  /* Double Rotate. */
		  *root = B->left;
		  B->left = (*root)->right;
		  A->right = (*root)->left;
		  (*root)->left = A;
		  (*root)->right = B;
		  switch ((*root)->balance)
		    {
		    case -1:
		      A->balance = 0;
		      B->balance = 1;
		      break;
		    case  0:
		      A->balance = 0;
		      B->balance = 0;
		      break;
		    case  1:
		      A->balance = -1;
		      B->balance = 0;
		      break;
		    }
		  (*root)->balance = 0;
		}
	    }     
	} 
    }
  
  /* If we fall through to here, the tree did not grow in height. */
  return (FALSE);
}


/* Initialize variables for the symbol table tree. */

void
init_tree(void)
{
  name_tree  = NULL;
  next_array = 1;
  next_func  = 1;
  next_var   = 4;  /* 0 => ibase, 1 => obase, 2 => scale, 3 => last. */
}


/* Lookup routines for symbol table names. */

int
lookup (char * name, int namekind)
{
  id_rec * id;

  /* Warn about non-standard name. */
  if (strlen(name) != 1)
    warn ("multiple letter name - %s", name);

  /* Look for the id. */
  id = find_id (name_tree, name);
  if (id == NULL)
    {
      /* We need to make a new item. */
      id = (id_rec *)malloc(sizeof (id_rec));
      id->id = strcopyof (name);
      id->a_name = 0;
      id->f_name = 0;
      id->v_name = 0;
      insert_id_rec (&(name_tree), id);
    }

  /* Return the correct value. */
  switch (namekind)
    {
      
    case ARRAY:
      /* ARRAY variable numbers are returned as negative numbers. */
      if (id->a_name != 0)
	{
	  free(name);
	  return (-id->a_name);
	}
      id->a_name = next_array++;
      a_names[id->a_name] = name;
      if (id->a_name < MAX_STORE)
	{
	  if (id->a_name >= a_count)
	    more_arrays ();
	  return (-id->a_name);
	}
      yyerror ("Too many array variables");
      exit (1);

    case FUNCT:
      if (id->f_name != 0)
	{
	  free(name);
	  return (id->f_name);
	}
      id->f_name = next_func++;
      f_names[id->f_name] = name;
      if (id->f_name < MAX_STORE)
	{
	  if (id->f_name >= f_count)
	    more_functions ();
	  return (id->f_name);
	}
      yyerror ("Too many functions");
      exit (1);

    case SIMPLE:
      if (id->v_name != 0)
	{
	  free(name);
	  return (id->v_name);
	}
      id->v_name = next_var++;
      v_names[id->v_name - 1] = name;
      if (id->v_name <= MAX_STORE)
	{
	  if (id->v_name >= v_count)
	    more_variables ();
	  return (id->v_name);
	}
      yyerror ("Too many variables");
      exit (1);
    }
}


/* Print the welcome banner. */

void 
welcome(void)
{
  printf ("This is free software with ABSOLUTELY NO WARRANTY.\n");
  printf ("For details type . \n");
}


/* Print out the warranty information. */

void 
warranty(char * prefix)
{
  printf ("\n%s%s\n\n", prefix, BC_VERSION);
  printf ("%s%s%s%s%s%s%s%s%s%s%s",
"    This program is free software; you can redistribute it and/or modify\n",
"    it under the terms of the GNU General Public License as published by\n",
"    the Free Software Foundation; either version 2 of the License , or\n",
"    (at your option) any later version.\n\n",
"    This program is distributed in the hope that it will be useful,\n",
"    but WITHOUT ANY WARRANTY; without even the implied warranty of\n",
"    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n",
"    GNU General Public License for more details.\n\n",
"    You should have received a copy of the GNU General Public License\n",
"    along with this program. If not, write to the Free Software\n",
"    Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n\n");
}

/* Print out the limits of this program. */

void
limits(void)
{
  printf ("BC_BASE_MAX     = %d\n",  BC_BASE_MAX);
  printf ("BC_DIM_MAX      = %ld\n", (long) BC_DIM_MAX);
  printf ("BC_SCALE_MAX    = %d\n",  BC_SCALE_MAX);
  printf ("BC_STRING_MAX   = %d\n",  BC_STRING_MAX);
  printf ("MAX Exponent    = %ld\n", (long) LONG_MAX);
  printf ("MAX code        = %ld\n", (long) BC_MAX_SEGS * (long) BC_SEG_SIZE);
  printf ("multiply digits = %ld\n", (long) LONG_MAX / (long) 90);
  printf ("Number of vars  = %ld\n", (long) MAX_STORE);
#ifdef OLD_EQ_OP
  printf ("Old assignment operatiors are valid. (=-, =+, ...)\n");
#endif 
}


#ifdef notdef

/* bc_malloc will check the return value so all other places do not
   have to do it!  SIZE is the number of types to allocate. */

char *
bc_malloc (size)
     int size;
{
  char *ptr;

  ptr = (char *) malloc (size);
  if (ptr == NULL)
    out_of_memory ();

  return ptr;
}


/* The following routines are error routines for various problems. */

/* Malloc could not get enought memory. */

void
out_of_memory()
{
  fprintf (stderr, "Fatal error: Out of memory for malloc.\n");
  exit (1);
}

#endif


/* The standard yyerror routine.  Built with variable number of argumnets. */

void
yyerror (char *str, ...)
{
  char *name;
  va_list args;

  va_start (args, str);

  if (is_std_in)
    name = "(standard_in)";
  else
    name = g_argv[optind-1];
  fprintf (stderr,"%s %d: ",name,line_no);
  vfprintf (stderr, str, args);
  fprintf (stderr, "\n");
  had_error = TRUE;
  va_end (args);
}


/* The routine to produce warnings about non-standard features
   found during parsing. */

void
warn (char *mesg, ...)
{
  char *name;
  va_list args;

  va_start (args, mesg);

  if (std_only)
    {
      if (is_std_in)
	name = "(standard_in)";
      else
	name = g_argv[optind-1];
      fprintf (stderr,"%s %d: ",name,line_no);
      vfprintf (stderr, mesg, args);
      fprintf (stderr, "\n");
      had_error = TRUE;
    }
  else
    if (warn_not_std)
      {
	if (is_std_in)
	  name = "(standard_in)";
	else
	  name = g_argv[optind-1];
	fprintf (stderr,"%s %d: (Warning) ",name,line_no);
	vfprintf (stderr, mesg, args);
	fprintf (stderr, "\n");
      }
  va_end (args);
}

/* Runtime error will  print a message and stop the machine. */

void
rt_error (char *mesg, ...)
{
  va_list args;
  char error_mesg [255];

  va_start (args, mesg);

  vsprintf (error_mesg, mesg, args);
  va_end (args);
  
  fprintf (stderr, "Runtime error (func=%s, adr=%d): %s\n",
	   f_names[pc.pc_func], pc.pc_addr, error_mesg);
  runtime_error = TRUE;
}


/* A runtime warning tells of some action taken by the processor that
   may change the program execution but was not enough of a problem
   to stop the execution. */

void
rt_warn (char *mesg, ...)
{
  va_list args;
  char error_mesg [255];

  va_start (args, mesg);

  vsprintf (error_mesg, mesg, args);
  va_end (args);

  fprintf (stderr, "Runtime warning (func=%s, adr=%d): %s\n",
	   f_names[pc.pc_func], pc.pc_addr, error_mesg);
}
